Start with your models
Keep your Peewee model definitions as the source of truth for generated resources.
Generate a Flask backend, a REST API, and an admin dashboard from the models you already have. Add authentication, live updates, and developer tools when you need them.
$ pipx install bro-sba-py
Starting a data-driven app often means repeating the same setup: API routes, service functions, admin tables, forms, and configuration. bro-sba-py generates that foundation from your Peewee models, so you can spend more time on the behavior that makes your application yours.
Your code stays yours. The generator runs locally. It reads model files as syntax instead of importing them, so scanning models does not start your app or connect to its database.
Keep your Peewee model definitions as the source of truth for generated resources.
Search, sort, paginate, edit, and export records through a browser-based dashboard.
Turn on auth, real-time events, audit history, API docs, tests, and migrations as needed.
Install the package in an isolated command-line environment. pipx keeps the generator's dependencies separate from the Python packages in your app.
pipx install bro-sba-pyThis installs two commands:
bro-py generates the Flask backend.bro-py-admin generates the browser-based admin interface.Run the commands from your own project folder—the folder that contains your models/ directory. The generated project includes code for your application; the generator package is an installable Python distribution.
Generate the admin pages, then generate the backend into the same output folder. If you leave setup options out, the interactive terminal asks you to choose them.
bro-py-admin --models-dir ./models --output-dir ./generatedbro-py --models-dir ./models --output-dir ./generatedInstall the generated dependencies and start the app:
python -m pip install -r requirements.txt
python app.pyOpen http://127.0.0.1:5000/admin/ in your browser. On first setup, answer the database and feature questions in the terminal.
Peewee fields describe your data. Optional class methods tell the generator which fields can be written, searched, displayed, protected, or turned into custom actions.
class User(Model):
name = CharField()
email = CharField()
password = CharField()
@classmethod
def insert_fields(cls):
return {
"name": {"required": True, "type": str},
"email": {"required": True, "type": str},
}
@classmethod
def search_fields(cls):
return ["name", "email"]
@classmethod
def sensitive_fields(cls):
return ["password"]| Model method | What it configures |
|---|---|
insert_fields() / update_fields() | Accepted form fields, required values, and field types. |
search_fields() | Fields searched by the generated API and admin search box. |
sensitive_fields() | Values such as passwords that must be protected from normal JSON output. |
admin_config() | Admin menu label, columns, visible actions, and role permissions. |
auth_config() | Authentication settings for the project's selected user model. |
custom_actions() | Operations that go beyond standard create, read, update, and delete. |
Try the examples. Download the sample models/ folder with user, product, and cart models, including field rules, search settings, admin configuration, and custom actions. Extract it into your project and adjust the database import in extensions to match your setup. Download model examples (.zip)
For each model, the backend creates endpoints for listing, creating, reading, updating, deleting, and searching records. List endpoints include pagination and sorting.
GET /api/users?page=2&per_page=20&sort=name&order=descGenerated view functions call service functions for model operations. This keeps the HTTP layer separate from the generated data-handling layer.
Use custom_actions() to describe operations that are specific to your application, such as approving an invoice or freezing an account. An action can be a route stub for your own code, generated from supported declarative logic, or kept internal without an API route.
@classmethod
def custom_actions(cls):
return {
"freeze": {
"method": "PATCH",
"label": "Freeze account",
"confirm": True,
},
}Generated custom-code markers preserve supported hand-written logic during regeneration. Always preview changes before using --force.
The frontend generator creates the admin pages, styles, browser JavaScript, and Flask blueprint. Generated tables support search, sorting, and pagination; forms follow the fields configured on each model.
Use forms, select related records, upload supported files, and run actions from model pages.
Depending on generated options, select rows for bulk deletion or updates and import/export CSV data.
In an interactive terminal, the generator asks which engine to use if you did not specify one. SQLite is a good choice for a local demo; MySQL connects to a database server.
Provide a file path, such as app.sqlite. The application creates the database file as it connects and creates tables.
Provide the database name, host, port, username, and password. Host defaults to localhost; port defaults to 3306. The database must already exist.
Credentials are saved in the generated .env. Keep that file private. Use .env.example when sharing placeholder configuration.
Enable --auth and define auth_config() on the model selected for authentication. The generated flow can include admin login, signup, email verification, JWT API authentication, role restrictions, CSRF protection for dashboard changes, and rate limiting for sensitive endpoints.
Configure SMTP settings to send verification email. In local development, the generated configuration can provide a console fallback. Use admin_config() to define which roles may read, create, update, delete, or run selected actions.
Review the generated security configuration and role rules before exposing an app to real users. The README and SECURITY_AND_LIMITS.md in your generated project contain environment-specific setup notes.
Enable --socketio in both generators. The backend publishes record events and operational status; the admin frontend receives them over Socket.IO without requiring a manual refresh.
Generated create, update, and delete routes emit dashboard events so connected admin pages know when records change.
The dashboard can surface notifications about actions and changes as they happen for connected admins.
The status panel shows Socket.IO connection state, app and database status, and the number of connected admin clients.
Send queued, running, completed, or failed updates from your own background jobs.
from extensions import publish_task_status
publish_task_status("catalog-sync", "running", "Checking products")
# Run your background work here
publish_task_status("catalog-sync", "completed", "Sync finished")Task status is held in process memory, so it is temporary and is not shared across multiple workers. For a multi-worker Socket.IO deployment, configure SOCKETIO_MESSAGE_QUEUE with Redis and set up sticky sessions at your host.
Enable --audit-log in both generators to record successful create, update, delete, and exposed custom-action calls. The generated admin home can display recent entries, including the actor when one is available. The API endpoint is /api/audit-logs.
Configure a model's insert or update field with a file or image type. The generated backend can save uploads and expose them under /uploads/; the admin form provides a file picker and can show image thumbnails.
For production, review allowed file types, upload size limits, storage permissions, access rules, and backup policy for your deployment.
| Option | Generated output | How you use it |
|---|---|---|
--docs | OpenAPI description and Swagger UI. | Open /api/docs after starting the app. |
--tests | pytest configuration and API tests. | Install the test dependencies, then run pytest in the generated folder. |
--migrations | manage.py commands for Peewee migrations. | Run python manage.py makemigration initial, then python manage.py migrate. |
--sync-db | Runs migration sync after generation. | Use with --migrations and an available database. |
--tests creates test files; it does not run them automatically. Use one consistent schema-management workflow once you start managing production migrations.
Pass --templates-dir with a directory that mirrors a supported template path. The generator uses your file instead of the built-in fallback for that template.
bro-py-admin --models-dir ./models --output-dir ./generated --templates-dir ./my-templatesSupported overrides include admin Jinja templates, frontend CSS and JavaScript, and backend service/view templates. Preserve required generator replacement fields in backend templates.
A plugin is a Python file with a generate_files(context) function. It receives the parsed models, output directory, and command options, then returns output paths mapped to text content.
def generate_files(context):
names = [model["class_name"] for model in context["models"]]
return {"MODEL_INDEX.md": "# Models\n" + "\n".join(names)}bro-py --models-dir ./models --output-dir ./generated --plugin ./plugins/model_index.pyYou can repeat --plugin to load more than one. Plugins execute Python code on your machine with your user permissions; only use plugins you trust. A dry run previews changes but does not execute plugins.
| Option | Purpose |
|---|---|
--models-dir PATH | Folder with the Peewee model source files. |
--output-dir PATH | Destination for generated application files. |
--database-engine sqlite|mysql | Set the database engine directly instead of answering the prompt. |
--auth | Enable generated authentication features. |
--socketio | Enable live dashboard updates, notifications, status, and task events. |
--audit-log | Enable audit history generation. |
--tests, --docs, --migrations | Generate the corresponding development tools. |
--sync-db | Run the generated migration sync after generation. |
--templates-dir PATH | Provide template overrides. |
--plugin PATH | Load a trusted file-generation plugin; repeatable. |
--dry-run | Preview generated changes without writing output or running plugins. |
--force | Allow replacing generated files. |
--non-interactive | Skip terminal prompts for scripts and automation. |
Run bro-py --help or bro-py-admin --help to see all options available in your installed version. Explicit positive or negative feature flags let you skip individual interactive questions.
The generated README, dependency files, .env.example, Dockerfile, and WSGI entry point provide a starting point. They are not a substitute for checking your hosting environment.
.env and real secrets out of version control.SECURITY_AND_LIMITS.md before deploying.Ready to try it? Go back to Getting started or run bro-py --help in your terminal.