Skip to main content

Rapid full stack development with JSON entities

Project description

Full-Stack Entity Generator

Generate a complete FastAPI + SQLAlchemy + Jinja2 application from JSON entity definitions.

This project uses JSON files as a single source of truth and generates:

  • Domain entities (dataclasses)
  • Application DTOs (Pydantic)
  • Repository ports and SQLAlchemy repository implementations
  • SQLAlchemy models
  • API routers (CRUD) with Bearer JWT authentication
  • Frontend routers and HTML templates with custom CSS
  • JWT authentication system (login, register, user management)
  • i18n scaffolding
  • App bootstrap files

Why this project exists

When building CRUD-heavy business apps, the same concepts are repeated in many layers:

  • Domain models
  • API schemas
  • Persistence models
  • Web forms and lists
  • Authentication and authorization
  • Basic translations

This generator removes repetitive boilerplate by deriving those layers from JSON entity specs.

Tech stack

  • Python 3.14+ for the generator itself
  • Jinja2 templates for code generation
  • Generated project stack:
    • FastAPI
    • SQLAlchemy
    • Pydantic
    • Jinja2 templates
    • PyJWT + bcrypt (authentication)
    • Custom CSS (no Bootstrap dependency)
    • SQLite (by default)

Repository layout

fsgenerator/
	cli.py                  # CLI entrypoint with argparse
	parser.py               # Parses app config and entity JSON files
	resolver.py             # Sorts entities by relation dependencies
	type_mapping.py         # Maps JSON field types to Python/SQLAlchemy/Pydantic
	writer.py               # Writes generated files and __init__.py markers
	generators/             # Per-layer file generators
	templates/              # Jinja2 templates used by generators
	sample_entities/        # Starter JSON files for -x/--init scaffolding
json_entities/            # Input JSON entity files (example)
generate.py               # Convenience wrapper for fsgenerator CLI

How generation works

  1. Load app config from app_config.json.
  2. Load all entity JSON files in the target directory.
  3. Validate relation targets.
  4. Topologically sort entities (based on many_to_one and one_to_one dependencies).
  5. Render templates for each entity and shared files.
  6. Write output into a generated project folder named by app_name.

Quick start

1. Install dependencies

uv sync

2. Scaffold a starter project (optional)

uv run generate.py -x

This creates a json_entities/ directory in the current folder with sample JSON files and a README explaining the entity format.

3. Generate using the default input folder

uv run generate.py

4. Generate from a custom folder path

uv run generate.py -i ./json_entities

5. Generate into a custom destination parent directory

uv run generate.py -i ./json_entities -o ./output

This creates ./output/<app_name>.

You can pass any directory that contains:

  • app_config.json
  • one or more entity JSON files

CLI

usage: fsgenerator [-h] [-x] [-i INPUT_DIR] [-o OUTPUT_DIR]

options:
	-h, --help            show this help message and exit
	-x, --init            Create a json_entities/ directory with sample starter
	                      files, then exit
	-i INPUT_DIR, --input-dir INPUT_DIR
	                      Path to the JSON entities directory (default: ./json_entities)
	-o OUTPUT_DIR, --output-dir OUTPUT_DIR
	                      Parent directory for generated output (default: current directory)

If --input-dir is omitted, it defaults to ./json_entities. If --output-dir is omitted, it defaults to the current directory.

Input format

app_config.json

{
	"app_name": "my_app",
	"id_type": "integer"
}

Fields:

  • app_name: Output directory name for the generated app
  • id_type: Global ID type for primary and foreign keys
    • integer
    • uuid

Entity JSON example

{
	"name": "company",
	"representation": ["name"],
	"fields": {
		"name": {"type": "string", "maxLength": 80},
		"afm": {"type": "string_numeric", "length": 9}
	},
	"relations": {
		"parent": {"type": "many_to_one", "entity": "company"}
	},
	"unique": {
		"unique_name": ["name"],
		"unique_parent_name": ["parent", "name"]
	}
}

Entity schema details

Root keys

  • name: Entity name (used for filenames, routes, table name)
  • representation: Fields used for display labels in dropdowns and list views
  • fields: Dictionary of scalar fields
  • relations: Dictionary of relations
  • unique: Named unique constraints

Field options

Option Type Default Description
type string Required. One of the supported types below
maxLength integer Maximum string length
minLength integer Minimum string length validation
length integer Exact string length (sets both min and max)
isnull boolean false Whether null is allowed (makes the field optional)
options array Required for select type. List of [value, "label"] pairs

Relation options

  • type: many_to_one (currently fully supported in generation)
  • entity: Target entity name (must match a JSON filename)

Supported scalar field types

Type Python type SQLAlchemy type Notes
integer int Integer
string str String(N) Use maxLength to set length
string_numeric str String(N) Adds ^\d+$ regex validation
iso-date datetime.date Date
iso-datetime datetime.datetime DateTime
time datetime.time Time
value Decimal Numeric(10,2) For monetary values
float float Float
percent Decimal Numeric(5,2) For percentage values
key int Integer Generic integer key
select int Integer Requires options field

Mapping behavior is defined in fsgenerator/type_mapping.py.

Relationship behavior

  • Relation definitions are parsed for all listed relation types.
  • Code generation currently emits foreign key columns and object relationships for:
    • many_to_one
    • one_to_one
  • Dependency sorting is based on many_to_one and one_to_one relations.
  • Relation fields are placed before data fields in all generated files (entities, DTOs, models, templates).

Unique constraints

Named unique constraints are generated at SQLAlchemy table level.

When a unique constraint references a relation field name, the generator maps it to the corresponding foreign key column name (for example, parent -> parent_id).

Authentication

The generated application includes a complete JWT-based authentication system:

  • Login/Register pages with bcrypt password hashing
  • JWT tokens stored in HTTP-only cookies (60-minute expiry)
  • Auth middleware that redirects unauthenticated users to the login page
  • API Bearer auth — all REST API endpoints require a valid JWT in the Authorization header
  • Admin user seeded on first startup (email: admin@admin.com, password: admin)
  • User management — admin users can toggle active/admin status of other users
  • Change password — authenticated users can change their own password

Public paths (login, register, static files, API docs) are accessible without authentication.

Generated output structure

For each entity named example, the generator produces:

  • domain/entities/example.py
  • application/dtos/example.py
  • domain/ports/example.py
  • application/use_cases/example.py
  • infrastructure/persistence/sqlalchemy/models/example.py
  • infrastructure/persistence/sqlalchemy/repositories/example.py
  • infrastructure/web/fastapi/routers/example.py (API)
  • infrastructure/web/fastapi/routers/example_frontend.py
  • templates/example_list.html
  • templates/example_form.html

Shared files:

  • main.py (FastAPI app with auth middleware and admin seeding)
  • pyproject.toml
  • static/style.css (custom CSS design system)
  • infrastructure/web/fastapi/dependencies.py
  • infrastructure/web/fastapi/routers/i18n.py
  • infrastructure/persistence/sqlalchemy/models/__init__.py
  • infrastructure/persistence/sqlalchemy/models/auth_models.py
  • auth_security.py (JWT + bcrypt utilities)
  • infrastructure/web/fastapi/routers/auth.py
  • templates/base.html
  • templates/home.html
  • templates/login.html
  • templates/register.html
  • templates/change_password.html
  • templates/admin_users.html
  • i18n_helper.py
  • i18n/en.json

The generator also creates missing __init__.py files in generated package directories.

i18n

The generator creates i18n/en.json with:

  • Common UI and error labels
  • Per-entity labels
  • Per-field labels
  • Labels for many_to_one and one_to_one relation selectors
  • Authentication labels (login, register, password, user management)

The generated app includes:

  • Translation loading helper
  • Language-switch router
  • HTML templates that call translation keys

Running the generated app

After generation, change into the generated app folder (the folder named by app_name), install dependencies, and run with uvicorn.

Typical flow:

cd my_app
uv sync
uv run uvicorn main:app --reload

Default database is SQLite at app.db. An admin user is created on first startup.

Default admin credentials:

Customizing output

Edit templates in fsgenerator/templates/ to change generated code shape:

  • API behavior
  • SQLAlchemy model patterns
  • HTML layout and UX
  • Authentication flow
  • Dependency wiring
  • CSS styling (static/style.css)
  • i18n runtime helper

After template changes, run the generator again.

Known limitations

  • The generator focuses on CRUD scaffolding.
  • many_to_many and one_to_many relations are parsed but are not fully emitted as SQLAlchemy relationship collections in current templates.
  • primary_key inside field definitions is parsed but global ID generation from app_config.id_type is used.
  • No migration generation is included (for example, Alembic).

Troubleshooting

  • Error about unknown relation target:
    • Ensure each relation entity points to an existing entity JSON file name.
  • Missing app_config.json:
    • Ensure the target input folder contains app_config.json.
  • Unexpected type behavior:
    • Check mappings in fsgenerator/type_mapping.py.
  • Wrong output folder:
    • Check app_name in app_config.json.
  • Delete errors showing raw JSON:
    • Entity delete endpoints display errors on the list page when a record has dependent relations.

Version

Current version: 0.5.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fsgenerator-0.6.0.tar.gz (34.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fsgenerator-0.6.0-py3-none-any.whl (47.3 kB view details)

Uploaded Python 3

File details

Details for the file fsgenerator-0.6.0.tar.gz.

File metadata

  • Download URL: fsgenerator-0.6.0.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fsgenerator-0.6.0.tar.gz
Algorithm Hash digest
SHA256 e2feea3ecd4d0a57264f49a943a9d14d35eb6ace8f68d6370f5c34d3e5e1e609
MD5 37341803aff24d9c39379e85c90e749c
BLAKE2b-256 5d326d93c758eb64876d0f5970bcee5f51fa94fd4911bbfd7f0e11ad7fb6eede

See more details on using hashes here.

File details

Details for the file fsgenerator-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: fsgenerator-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 47.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.0 {"installer":{"name":"uv","version":"0.11.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fsgenerator-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a089a6f5f3efbded10c94805b15a596835097c5bea1d13c678295819aeec3d49
MD5 78194694e55ac2a61a0d19dc2dd6bd17
BLAKE2b-256 abf16fb9ad7aaa5d6a6254889a3cb81ed8a8d229d758357dcf220da626b1309b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page