Install
openclaw skills install @abdur-rahmaanj/shopyoModular Flask framework for building scalable, maintainable web apps with isolated modules, event-driven communication, CLI tools, and built-in auth and data...
openclaw skills install @abdur-rahmaanj/shopyoShopyo is a modular Flask framework designed for maintainability, extensibility, and real-world scale.
A typical Shopyo project:
/project_root
├── app.py # Entry point, defines create_app()
├── init.py # Extension initializer (db, login_manager, etc.)
├── manage.py # CLI entry point
├── config.py # Profile-based configuration
└── modules/ # Modular code
├── box__default/
│ ├── auth/
│ └── settings/
└── my_custom_module/
# Environment setup
export SHOPYO_CONFIG_PROFILE=development
export FLASK_ENV=development
export FLASK_APP=app.py
# New project
shopyo new myproject --demo
cd myproject
shopyo initialise
# Create module
shopyo startapp modulename [boxname]
# Create box
shopyo startbox box__name
# Run server
shopyo run
flask run --debug
# Database
shopyo initialise # Fresh start (creates db, migrations, default users)
shopyo db migrate
shopyo db upgrade
shopyo clean # Reset local database
# Static files
shopyo collectstatic [module_path] # Collect static files from modules
# Other
shopyo routes # Show all routes
shopyo audit # Find project issues
shopyo rename old_name new_name # Rename module
shopyo startapp blog
# or with box
shopyo startapp blog box__ecommerce
Creates:
modules/blog/
├── __init__.py
├── forms.py
├── global.py
├── info.json
├── models.py
├── view.py
├── static/
├── templates/
│ └── blog/
│ ├── blocks/
│ │ └── sidebar.html
│ ├── dashboard.html
│ └── index.html
└── tests/
├── test_blog_functional.py
└── test_blog_models.py
{
"author": {"mail": "", "name": "", "website": ""},
"display_string": "Page",
"module_name": "page",
"type": "show",
"fa-icon": "fa fa-store",
"url_prefix": "/page",
"dashboard": "/dashboard"
}
from shopyo.api.module import ModuleHelp
mhelp = ModuleHelp(__file__, __name__)
blueprint = mhelp.blueprint
@blueprint.route("/")
def index():
context = mhelp.context()
context.update({'message': 'Hello'})
return mhelp.render('index.html', **context)
from init import db
from shopyo.api.models import PkModel
class MyModel(PkModel):
__tablename__ = 'mymodel'
name = db.Column(db.String(100))
Extend the base template:
{% extends "shopyo_base/main_base.html" %}
{% block content %}
<h1>Hello</h1>
{% endblock %}
Use yo_render:
from shopyo.api.templates import yo_render
@blueprint.route("/demo")
def demo():
return yo_render('blog/demo.html', {'key': 'value'})
Key imports:
from shopyo.api.module import ModuleHelp, get_module, dispatch
from shopyo.api.models import PkModel
from shopyo.api.templates import yo_render
from shopyo.api.database import db
from shopyo.api.enhance import enhance_html
Use the event system:
from shopyo.api.module import dispatch
# Dispatch event
dispatch("user:registered", {"email": user.email})
# Listen for event
@dispatch("user:registered")
def send_welcome_email(email):
pass
pytest
pytest -v
pytest path/to/test.py
pytest --cov=shopyo
tox
available_everywhere = {"x": 1}
configs = {
"development": {"CONFIG_VAR": "DEVVALUE"},
"production": {"CONFIG_VAR": "PRODVALUE"},
"testing": {"CONFIG_VAR": "TESTVALUE"}
}
After shopyo initialise:
admin@domain.compassbox__dispatch) for inter-module communicationshopyo initialise after adding/removing modulesstatic/modules/ - don't edit directlyshopyo clean to reset local development database