Creating FastAPIs from Frictionless Data Packages
Project description
fastapi-from-frictionless
Status: Work in Progress — API and generated output are subject to change.
Overview
fastapifromfrictionless is a Python scaffolding tool that reads Frictionless Data Package schema files and generates a fully-functional FastAPI + SQLModel application — including models, CRUD endpoints, and dynamic query support — with no hand-written boilerplate.
The driving goal is to bridge the gap between familiar flat-file workflows (Excel workbooks, CSV files, Frictionless packages) and a production-grade relational database with a queryable REST API. Data stewards continue working in Excel; the package handles ingestion, validation, and API synchronization behind the scenes.
Core capabilities:
- Generate
models.py,app.py, anddatabase.pyfrom*.schema.yamlfiles - Automatic SQLModel class hierarchy per schema (base, table, create, update, public, public-with-relations)
- Full CRUD + pagination + recent-records endpoints per resource
- Excel workbook as a data-entry interface — create or update API records from a
.xlsxfile - Frictionless package wraps the workbook for field-level validation before ingestion
- CLI entry point:
fastapifromfrictionless generate <schema-folder>
Requirements
- Python >= 3.10
- frictionless
- FastAPI
- SQLModel
- SQLAlchemy
- fastapi-querybuilder
- jinja2
- requests
- pandas
- xlsxwriter
An ASGI server such as uvicorn is required to run the generated application.
Installation
pip install -e .
Quick Start
1. Generate application files from schemas
Place *.schema.yaml files in a folder (see doc/data/ for examples), then run:
fastapifromfrictionless generate path/to/schemas --output path/to/output
Or from Python:
from fastapifromfrictionless.load import build_database
build_database(schema_folder="path/to/schemas", db_filename="app.db")
2. Start the generated API
cd path/to/output
uvicorn app:app --reload
3. Generated endpoints
For each schema resource (e.g. sensor), the generated app exposes:
| Method | Path | Description |
|---|---|---|
POST |
/sensor |
Create a record |
GET |
/sensor/all |
List all (paginated: ?offset=0&limit=100) |
GET |
/sensor/recent |
Most recent records (?limit=10) |
GET |
/sensor/{id} |
Get one by primary key |
PATCH |
/sensor/{id} |
Update a record |
DELETE |
/sensor/{id} |
Delete a record |
GET |
/sensor/query |
Dynamic filter query (FK schemas only) |
GET |
/excel/export |
Download all data as .xlsx |
POST |
/excel/import |
Upload and sync an .xlsx workbook |
4. Configuration via environment variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
sqlite:///database.db |
Database connection URL (overrides SQLite default) |
ALLOWED_ORIGINS |
* |
Comma-separated CORS allowed origins |
API_KEY |
(unset) | If set, all requests require X-API-Key: <value> header |
SCHEMA_FOLDER |
. |
Path to *.schema.yaml files (used by Excel import/export) |
API_URL |
http://localhost:8000 |
Base URL of this app (used by Excel export) |
5. Excel data workflow
from fastapifromfrictionless.load import empty_excel, create_package, update_api_from_package
# Create a blank workbook with one sheet per schema
empty_excel(schema_folder="path/to/schemas", output_filepath="data.xlsx")
# Fill in data, then validate and sync to the API
create_package(folder="path/to/schemas", filename="data.xlsx")
update_api_from_package(api_url="http://localhost:8000", package_file="data.package.yaml")
# Or export all current API data to Excel
from fastapifromfrictionless.load import dump_to_excel
dump_to_excel(api_url="http://localhost:8000", schema_folder="path/to/schemas", output_filepath="export.xlsx")
6. CLI reference
fastapifromfrictionless generate <schema_folder> [options]
Options:
--output DIR Output directory (default: current directory)
--db FILENAME SQLite database filename (default: database.db)
--dry-run Print generated code to stdout without writing files
--no-models Skip generating models.py
--no-app Skip generating app.py
--no-db Skip generating database.py
See doc/ for a worked example with real schemas and generated output.
Roadmap
Items are grouped by priority. Checked items are complete.
Foundation
- Generate SQLModel class hierarchies from Frictionless schemas
- Generate FastAPI CRUD + query endpoints per resource
- Generate
database.pywith SQLite engine setup - Excel workbook as data-entry interface (create and update)
- Frictionless package wrapping for field-level validation
- Export API data back to Excel (dump all records to workbook)
- Validate schemas before code generation; surface clear error messages on malformed input
Code Quality & Reliability
- Add a test suite (unit tests for generators, integration tests for generated app)
- Add CI pipeline (lint, type-check, tests on push)
- Enforce type hints throughout; run
mypyin CI - Replace raw string generation with a templating engine (e.g. Jinja2) for maintainability
- Structured logging with configurable verbosity
Production Readiness
- Async database support (replace sync SQLModel sessions with async SQLAlchemy)
- Database migrations via Alembic instead of
create_all - Configuration management — accept settings via environment variables or a config file (database URL, allowed origins, etc.)
- CORS and security headers in generated
app.py - API key / token authentication (FastAPI security)
- Pagination on list endpoints
- Proper HTTP error responses with consistent JSON error bodies
Developer Experience
- CLI entry point (
fastapifromfrictionless generate <schema-folder>) so users do not need to write Python - Dry-run / preview mode that prints generated code without writing files
- Configurable output — opt in/out of specific endpoint types, choose database backend
- Package versioning and automated releases (GitHub Actions → PyPI)
- Expand documentation and examples in
doc/
Optional / Future
- Support for PostgreSQL and other SQLAlchemy-compatible backends
- Auto-generated front-end form from schema fields
- DrawIO ERD → Frictionless schema converter
- Default query routes for common patterns derived from schema metadata
- GET/POST file endpoints for uploading and downloading the Excel workbook directly via the API
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapifromfrictionless-0.1.0.tar.gz.
File metadata
- Download URL: fastapifromfrictionless-0.1.0.tar.gz
- Upload date:
- Size: 28.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b99dd81e137bd0dcd68679a414ae0e95eb0beb5d746c9a87463d19503ef1b293
|
|
| MD5 |
8a43ec27e1c6751bfaa0e875f85c5cc1
|
|
| BLAKE2b-256 |
9ace061663bd2f1cbf7ded22d0808d6ceaf115ba0521e4e458a484672c25e243
|
Provenance
The following attestation bundles were made for fastapifromfrictionless-0.1.0.tar.gz:
Publisher:
python-publish.yml on jinskeep-morpc/fastapi-from-frictionless
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapifromfrictionless-0.1.0.tar.gz -
Subject digest:
b99dd81e137bd0dcd68679a414ae0e95eb0beb5d746c9a87463d19503ef1b293 - Sigstore transparency entry: 1536221341
- Sigstore integration time:
-
Permalink:
jinskeep-morpc/fastapi-from-frictionless@97358e073a83b77c92968869a9a35bf542769421 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jinskeep-morpc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@97358e073a83b77c92968869a9a35bf542769421 -
Trigger Event:
release
-
Statement type:
File details
Details for the file fastapifromfrictionless-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fastapifromfrictionless-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f490727461975e69f7384885bcae2e8912b74d5c2fef4260507c00a770960bb
|
|
| MD5 |
a5ae86372d1290e77af6e15197f820c3
|
|
| BLAKE2b-256 |
4a95772a9cda76d74cf243f2422c165038910e01ee95305990d93d3f4ed021bb
|
Provenance
The following attestation bundles were made for fastapifromfrictionless-0.1.0-py3-none-any.whl:
Publisher:
python-publish.yml on jinskeep-morpc/fastapi-from-frictionless
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapifromfrictionless-0.1.0-py3-none-any.whl -
Subject digest:
0f490727461975e69f7384885bcae2e8912b74d5c2fef4260507c00a770960bb - Sigstore transparency entry: 1536221420
- Sigstore integration time:
-
Permalink:
jinskeep-morpc/fastapi-from-frictionless@97358e073a83b77c92968869a9a35bf542769421 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jinskeep-morpc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@97358e073a83b77c92968869a9a35bf542769421 -
Trigger Event:
release
-
Statement type: