Skip to main content

Auto Endpoint

autoendpoint is a lightweight library for FastAPI that automatically generates asynchronous RESTful API endpoints for your SQLModel classes. It simplifies the creation of CRUD operations by dynamically building Pydantic models for data validation and handling database interactions using SQLAlchemy's AsyncSession.

Key Features

  • Full CRUD Endpoints: Automatically generates GET (all), POST (create), GET (by ID), PUT (update), PATCH (partial update), DELETE, GET (by unique field), and GET (by any field filter) endpoints for any SQLModel.
  • Dynamic GraphQL Endpoint: Automatically generates a GraphQL schema and adds a /graphql endpoint (powered by Strawberry) to query your models.
  • Model Consistency Check: Optional feature to verify that your SQLModel classes match the actual database tables (existence and columns) during development. See Model Consistency Check for more details.
  • Automatic Relationship Discovery: Automatically identifies and maps SQLModel relationships into the GraphQL schema, enabling seamless nested queries (e.g., fetching a Profile or Posts through a UserAccount) with automatic pre-loading to prevent MissingGreenlet errors.
  • String Representation in GraphQL: Automatically includes a string_representation field in GraphQL queries, which uses your model's __str__ method for flexible object display.
  • Enhanced OpenAPI Documentation: All generated endpoint parameters (Body, Path, Query) include clear, dynamic descriptions for better readability in tools like FastMCP and Swagger UI.
  • Asynchronous Support: Built for high-performance async workflows using AsyncSession.
  • Smart Model Generation: Dynamically creates schemas for creation, full updates, and partial updates (PATCH), excluding primary keys from request bodies.
  • Flexible Retrieval:
    • Unique Retrieval: Endpoint to fetch a single record by any unique field (e.g., email), with error handling for duplicates.
    • Generic Filtering: New endpoint to retrieve multiple records by any field and value.
  • FastAPI Integration: Seamlessly integrates with existing FastAPI applications using an APIRouter.
  • Type Safety: Leverages Python type hints and SQLModel/Pydantic for robust validation.
  • Google Style Docstrings: Fully documented for Sphinx compatibility.
  • JWT Authentication Support: Easy-to-use security middleware for protecting endpoints with JSON Web Tokens. Supports public endpoints and path patterns.

Installation

You can install autoendpoint using uv. To include asynchronous database support (e.g., PostgreSQL), use the postgresql extra:

# Basic installation
uv add autoendpoint

# Installation with PostgreSQL support (asyncpg, greenlet, psycopg2-binary)
uv add "autoendpoint[postgresql]"

Note: The library is designed to be driver-agnostic but requires greenlet and a compatible async driver (like asyncpg or aiosqlite) for SQLAlchemy's asynchronous operations.

Quick Start

Here's how to use AutoEndpoint in your FastAPI project:

1. Define your SQLModel

import uuid
from sqlmodel import Field, SQLModel
from typing import Optional

class Hero(SQLModel, table=True):
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    name: str
    secret_name: str
    age: Optional[int] = None
    email: str = Field(unique=True)

    def __str__(self):
        return f"{self.name} ({self.age or '?'})"

2. Set up the Async Engine and Session

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql+asyncpg://user:password@localhost/dbname"
engine = create_async_engine(DATABASE_URL)
async_session_maker = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

3. Initialize and Register Endpoints

from fastapi import FastAPI
from autoendpoint.core import AutoEndpoint

app = FastAPI()

@app.on_event("startup")
async def startup():
    async with async_session_maker() as session:
        # Create endpoints for the Hero model
        # Note: In a production app, you might want to manage the session differently
        # enable_graphql defaults to True
        # check_consistency=True checks if models match DB tables at startup
        my_endpoints = AutoEndpoint(
            db_session=session, 
            models=[Hero], 
            enable_graphql=True, 
            check_consistency=True
        )
        my_endpoints.init_app(app=app)

Generated Endpoints

For a model named Hero, the following endpoints are automatically generated:

  • GET /hero: List records. Supports pagination via query parameters:
    • limit: The maximum number of records to return (default: 10). Set limit=0 to return all records.
    • page: The page number to return (default: 1).
  • POST /hero: Create a new record. Primary key is excluded from the request body and expected to be server-side or factory generated.
  • POST /hero/bulk/csv: Bulk create records from a CSV file. The file must be UTF-8 encoded and have a .csv extension. Supports:
    • has_header (default: true): Whether the CSV file has a header row. If true, columns are mapped by header names. If false, columns are mapped by the model's field order as defined in the creation schema.
  • GET /hero/{id}: Retrieve a single record by its primary key.
  • PUT /hero/{id}: Update all fields of a record (excluding primary key).
  • PATCH /hero/{id}: Partially update fields of a record (excluding primary key).
  • DELETE /hero/{id}: Delete a record by its primary key.
  • GET /hero/unique/{field_name}?value=...: Retrieve a single record by any unique field (e.g., /hero/unique/email?value=test@example.com). Raises a 400 error if multiple records are found.
  • GET /hero/filter/{field_name}?value=...: Retrieve all records matching a specific field and value (e.g., /hero/filter/age?value=30).
  • GET /hero/{hero_id}/{relationship_name}: Retrieve related record(s) for a specific record:
    • Returns a list for one-to-many (1:n) relationships (e.g., /user/{user_id}/posts).
    • Returns a single object for one-to-one (1:1) relationships (e.g., /user/{user_id}/profile).
  • POST /hero/{hero_id}/{relationship_name}/{target_id}: Link a record to another record in a many-to-many relationship (e.g., /user/{user_id}/groups/{group_id}).
  • PATCH /hero/{hero_id}/{relationship_name}/{target_id}: Update the link record itself in a many-to-many relationship (useful if the link table has extra fields).
  • DELETE /hero/{hero_id}/{relationship_name}/{target_id}: Unlink a record from another record in a many-to-many relationship.
  • POST /graphql: The GraphQL endpoint (if enabled) for querying your models. Includes a string_representation field for each model that reflects its __str__ output.

FastMCP Compatibility

The generated endpoints are enhanced with description fields for all parameters, making them highly readable and easy to use with FastMCP and other LLM-friendly tools. Each parameter explicitly describes its role (e.g., "The Hero data to create" or "The Hero record to retrieve by id"). In Swagger UI, you will see detailed descriptions for every path parameter, query parameter, and request body.

Model Consistency Check

To ensure that your SQLModel definitions match the actual state of your database, AutoEndpoint includes an optional consistency check that runs at startup.

What it checks:

  • Table Existence: Verifies that the table for each model exists in the database.
  • Column Matching: Compares the columns defined in your model with the columns present in the database table. It identifies:
    • Columns present in the model but missing in the database.
    • Columns present in the database but missing in the model.
  • Schema Support: Handles models with specified database schemas.

How it works:

  • It runs as an asynchronous background task when the FastAPI application starts (inside AutoEndpoint.init_app logic).
  • If any inconsistency is found, it will raise a RuntimeError and print a detailed error message to stderr, explaining exactly what is missing or extra. This helps catch schema mismatches early during development.

How to use:

You can control the consistency check via the check_consistency parameter when initializing AutoEndpoint.

  • Enable: Set check_consistency=True (useful during development).
  • Disable: Set check_consistency=False (default, recommended for production).
my_endpoints = AutoEndpoint(
    db_session=session, 
    models=[Hero], 
    check_consistency=True # Enable the check
)
my_endpoints.init_app(app=app)

Security (JWT Authentication)

autoendpoint provides a JWTAuth class that can be used as a FastAPI dependency to secure your endpoints.

Usage

from fastapi import FastAPI, Depends
from autoendpoint.security import JWTAuth

app = FastAPI()

# Initialize JWT Authentication
auth = JWTAuth(
    secret_key="your-secret-key",
    algorithm="HS256",
    public_endpoints=["/health", "/docs", "/openapi.json"],
    public_endpoint_prefixes=["/public/*"]
)

# Apply to all endpoints in the app
app = FastAPI(dependencies=[Depends(auth)])

# Or use it to generate and decode tokens
@app.post("/login")
async def login():
    token = auth.create_token(data={"sub": "user_id"})
    return {"access_token": token, "token_type": "bearer"}

@app.get("/me")
async def get_me(payload: dict = Depends(auth)):
    return {"user_id": payload["sub"]}

Features:

  • Token Generation: auth.create_token(data, expires_delta). The expires_delta is a datetime.timedelta object, allowing you to specify expiration in seconds, minutes, hours, or days.
  • Token Validation: Automatically decodes and validates JWT tokens from the Authorization: Bearer <token> header.
  • Timezone Support: Defaults to Europe/London. You can specify a different timezone during initialization (e.g., JWTAuth(..., timezone="UTC")).
  • Public Endpoints: Specify exact paths that don't require authentication.
  • Public Prefix Patterns: Use wildcard patterns (e.g., /public/*) to allow unauthenticated access to specific path groups.

Documentation

The project includes Sphinx documentation and test coverage reports.

In GitLab CI, these are automatically generated and hosted via GitLab Pages:

  • Documentation: https://autoendpoint-beaddd.gitlab.io/docs/
  • Coverage Report: https://autoendpoint-beaddd.gitlab.io/coverage/

Methods are documented using the Google format.

License

Under construction.

Metadata

Release files for autoendpoint 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for autoendpoint 0.5.0
File Size Uploaded Provenance
autoendpoint-0.5.0.tar.gz 51.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for autoendpoint 0.5.0
File Interpreter ABI Platform
autoendpoint-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 70.3 kB

Release files / autoendpoint-0.5.0.tar.gz

Download URL autoendpoint-0.5.0.tar.gz
Size 51.9 kB
Tags Source
SHA-256 checksum
How to use checksums
1dc95e9b4474478ed734a1ca5d9785ddea24cd505eea210625d4ac7d5eb1b584
BLAKE2b-256 checksum
How to use checksums
d3ab1f461d80386f0f4fd09b8f933d90fc64de0ed2c0970efb0d9c0f5f690b27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / autoendpoint-0.5.0-py3-none-any.whl

Download URL autoendpoint-0.5.0-py3-none-any.whl
Size 18.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6942c73745f769614b22ace0f24d800921847a26f6dada12f6e5df48fddf8e75
BLAKE2b-256 checksum
How to use checksums
333a9b845b640a8bf50b672f38a048e871814e9693d38c89d33089447d88dcdb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for autoendpoint 0.5.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page