RESTAlchemy
RESTAlchemy is a Python toolkit for building HTTP REST APIs on top of a flexible data model and storage abstraction.
It combines:
A Data Model (DM) layer for defining domain models and validation.
A Storage layer for persisting models (for example, SQL databases).
An API layer for exposing models as RESTful HTTP resources.
Optional OpenAPI support for discoverable, documented APIs.
Features
Clear separation between domain models, storage implementation details, and HTTP API.
Strongly typed, validated data model with reusable properties.
Minimal boilerplate to expose models as REST resources.
Built-in migration tooling for evolving database schemas.
Performance
On all three request patterns, RESTAlchemy is the fastest framework measured here, and stands nearer to the floor of what such a request can cost at all than to any framework behind it. The benchmark in this repository asks six stacks the same three questions against the same PostgreSQL and the same rows: read a collection of 100, read one resource, create one. The first row of the table is not one of them: it is a hand-written query and orjson.dumps, which is what the database and the JSON cost before any framework has run.
15 rounds × best of 20 calls, 1000 rows in the table, 100 per page, Python 3.12, PostgreSQL 16, one AMD EPYC 7742. The full run, with confidence intervals and the machine it was measured on, is in bench/results/results.md; these are its numbers. In parentheses: the same number as a multiple of RESTAlchemy’s.
Stack |
Collection of 100 |
One resource |
POST one |
Per row |
|---|---|---|---|---|
raw psycopg + orjson † |
1272 µs (0.7×) |
174 µs (0.5×) |
229 µs (0.6×) |
11.1 µs (0.8×) |
RESTAlchemy |
1705 µs |
317 µs |
397 µs |
14.0 µs |
Flask + SQLAlchemy |
2267 µs (1.3×) |
636 µs (2.0×) |
606 µs (1.5×) |
16.5 µs (1.2×) |
FastAPI + SQLAlchemy |
2417 µs (1.4×) |
894 µs (2.8×) |
829 µs (2.1×) |
15.4 µs (1.1×) |
Litestar + SQLAlchemy |
2524 µs (1.5×) |
857 µs (2.7×) |
811 µs (2.0×) |
16.8 µs (1.2×) |
Django + DRF |
5276 µs (3.1×) |
943 µs (3.0×) |
895 µs (2.3×) |
43.8 µs (3.1×) |
† Not a framework, and faster than every framework under it, as it should be: it is the floor the rest are read against, not a stack anyone would build a service on.
RESTAlchemy adds 143 µs to that bare single-row query, 168 µs to the bare insert, and under three microseconds to each row of a collection — a REST service, routed, validated and packed, for a few microseconds over the floor.
Every stack is written the way its own documentation writes it, answers with the same rows — checked field by field before anything is timed — and is called at its own interface, so what is measured is the framework and its database work rather than a web server. The command that runs it, and what the numbers do not say, are in bench/README.md.
Documentation
The rendered documentation is published at https://infraguys.github.io/restalchemy/.
All documentation is available in four languages. The structure of files and sections is identical across languages:
English: docs/en/index.md
Russian: docs/ru/index.md
German: docs/de/index.md
Chinese: docs/zh/index.md
If you are new to RESTAlchemy, start with:
Quick start
Install from PyPI:
pip install restalchemy
Define a simple DM model (simplified from the getting started guide):
from restalchemy.dm import models
from restalchemy.dm import properties
from restalchemy.dm import types
class FooModel(models.ModelWithUUID):
value = properties.property(types.Integer(), required=True)
For a complete in-memory REST service example, including controllers, routes and a WSGI application, see docs/en/getting-started.md.
Examples
Real code examples live in the examples/ directory:
examples/restapi_foo_bar_service.py – a simple REST API service built with in-memory storage.
examples/dm_mysql_storage.py – data model with MySQL storage example.
examples/openapi_app.py – example API with OpenAPI specification generation.
Migration commands
RESTAlchemy provides command-line tools for managing database migrations.
<migration number>-<message>-<hash>.py
$ ra-rename-migrations -p <path-to-migrations>
Create migrations:
$ ra-new-migration --path examples/migrations/ --message "1st migration" $ ra-new-migration --path examples/migrations/ --message "2st migration" --depend 1st $ ra-new-migration --path examples/migrations/ --message "3st migration" --depend 2st $ ra-new-migration --path examples/migrations/ --message "4st migration" $ ra-new-migration --path examples/migrations/ --message "5st migration" --depend 3st --depend 4st
Apply migrations:
$ ra-apply-migration --path examples/migrations/ --db-connection mysql://test:test@localhost/test -m 5st > upgrade 1st > upgrade 2st > upgrade 3st > upgrade 4st > upgrade 5st
Rolled back migrations:
$ ra-rollback-migration --path examples/migrations/ --db-connection mysql://test:test@localhost/test -m 4st > downgrade 5st > downgrade 4st
$ ra-rollback-migration --path examples/migrations/ --db-connection mysql://test:test@localhost/test -m 1st > downgrade 3st > downgrade 2st > downgrade 1st
Tests
Tests are managed via tox. The default environment list includes Python 3.8, 3.10, 3.11, 3.12, 3.13 and 3.14.
Run the full test suite:
tox
Run tests for a specific Python version (for example, Python 3.10):
tox -e py310
Run functional tests (require access to a MySQL database):
export DATABASE_URI="mysql://root:@localhost:3306/radatabase"
tox -e py310-functional
Run functional tests with PostgreSQL:
export DATABASE_URI="postgresql://postgres:password@localhost:5432/radatabase"
tox -e py310-functional
Coverage
The current coverage percentage is shown by the badge at the top of this file. It is measured on every push by python-coverage-comment-action, which combines the unit and the MySQL and PostgreSQL functional suites of every supported Python version into one figure, with branch coverage enabled. The badge and the full HTML report are stored on the python-coverage-comment-action-data branch, and pull requests receive a comment describing how they change coverage. For reference, the unit suite alone covers roughly 75% of the restalchemy package.
Coverage measurement is wired into the default tox run. The begin environment erases previous data, every py3* environment records its own data file (.coverage.<envname>), and the end environment combines them into a single report:
tox
Reports are written to the cover/ directory (cover/index.html for the browsable HTML report and cover/coverage.xml for CI tools), and a summary of the files that are not fully covered is printed to the console.
To combine and render reports without re-running the tests (for example after tox -e py310):
tox -e end
To measure coverage for a single run directly, without tox:
pytest --cov --cov-report=term restalchemy/tests/unit
Use pytest --cov rather than coverage run: the suite runs under pytest-xdist, and coverage run does not measure the xdist worker processes, so it reports 0% coverage.
Coverage settings live in the [tool.coverage.*] sections of pyproject.toml: branch coverage is enabled, parallel data files are on so that several environments can be combined, restalchemy is the measured source, and the test packages themselves are excluded.
License
RESTAlchemy is licensed under the Apache License, Version 2.0.
Copyright (c) Genesis Corporation, 2025.
See the LICENSE file in this repository or https://www.apache.org/licenses/LICENSE-2.0 for the full license text.
Metadata
Release files for restalchemy 16.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| restalchemy-16.1.0.tar.gz | 642.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| restalchemy-16.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / restalchemy-16.1.0.tar.gz
| Download URL | restalchemy-16.1.0.tar.gz |
|---|---|
| Size | 642.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
700e38930b4dab3ae1d34fa4b075510f9bfae92f74dd9617c6f7b46aebad768e
|
|
BLAKE2b-256 checksum How to use checksums |
e4a2d759898b509adb729f83363d3201b5d5cda10ee4fc82d9a346ed60a743a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency logRelease files / restalchemy-16.1.0-py3-none-any.whl
| Download URL | restalchemy-16.1.0-py3-none-any.whl |
|---|---|
| Size | 681.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f8f9988ae3fcb0f159695ced1ccecdd072681153ce94d016f619a90bc4467f7c
|
|
BLAKE2b-256 checksum How to use checksums |
a229e9c2b700d7b3e944f360ead6f4c2b06a9087f2527312839f9e9535c61720
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency log