An extendable async API using FastAPI, Pydantic V2, SQLAlchemy 2.0, PostgreSQL and Redis.
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.12.4...v0.13.0
db.commit()
from async_get_db - thanks @mithun2003Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.12.3...v0.12.4
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.12.2...v0.12.3
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.11.1...v0.12.2
[!WARNING] Content-Type Header ReDoS - FastAPI vulnerability fixed
Update python-multipart to 0.0.7 as soon as possible.
https://github.com/tiangolo/fastapi/security/advisories/GHSA-qf9m-vfgh-m389
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.11.0...v0.11.1
create_tables_on_start
parameter added in setup functionruff
added as pre-commit
, thanks @luca-medeirosfrom fastapi import FastAPI
from fastcrud import FastCRUD, crud_router
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
# Database setup (Async SQLAlchemy)
DATABASE_URL = "sqlite+aiosqlite:///./test.db"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# FastAPI app
app = FastAPI()
# CRUD operations setup
crud = FastCRUD(Item)
# CRUD router setup
item_router = crud_router(
session=async_session,
model=Item,
crud=crud,
create_schema=ItemCreateSchema,
update_schema=ItemUpdateSchema,
path="/items",
tags=["Items"]
)
app.include_router(item_router)
For more control over your endpoints, you can use FastCRUD directly within your custom FastAPI route functions. Here's an example:
Usage:
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from fastcrud import FastCRUD
from yourapp.models import Item
from yourapp.schemas import ItemCreateSchema, ItemUpdateSchema
app = FastAPI()
# Assume async_session is already set up as per the previous example
# Instantiate FastCRUD with your model
item_crud = FastCRUD(Item)
@app.post("/custom/items/")
async def create_item(item_data: ItemCreateSchema, db: AsyncSession = Depends(async_session)):
return await item_crud.create(db, item_data)
@app.get("/custom/items/{item_id}")
async def read_item(item_id: int, db: AsyncSession = Depends(async_session)):
item = await item_crud.get(db, id=item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
# You can add more routes for update and delete operations in a similar fashion
To know all available methods, check it in fastcrud readme.
If you want to stop tables from being created every time you run the api, you should disable this here:
# app/main.py
from .api import router
from .core.config import settings
from .core.setup import create_application
# create_tables_on_start defaults to True
app = create_application(router=router, settings=settings, create_tables_on_start=False)
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.10.0...v0.11.0
datetime
refactored to be timezone aware #79 #82 (thanks @mithun2003)passlib
replaced with bcrypt
for password hashing #74validator
moved to v2 field_Validator
#72.env
, docker-compose.yml
and Dockerfile
:[!TIP] If you are in a hurry, you may use one of the following templates (containing a
.env
,docker-compose.yml
andDockerfile
):
[!WARNING] Do not forget to place
docker-compose.yml
andDockerfile
in theroot
folder, while.env
should be in thesrc
folder.
allow_reuse
removed #70Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.9.0...v0.10.0
The JWT in the boilerplate was updated to work in the following way:
access token
, which you'll use to access protected resources.The access token
is short lived (default 30 minutes) to reduce the damage of a potential leak. The refresh token
, on the other hand, is long lived (default 7 days), and you use it to renew your access token
without the need to provide username and password every time it expires.
Since the refresh token
lasts for a longer time, it's stored as a cookie in a secure way:
# app/api/v1/login
...
response.set_cookie(
key="refresh_token",
value=refresh_token,
httponly=True, # Prevent access through JavaScript
secure=True, # Ensure cookie is sent over HTTPS only
samesite='Lax', # Default to Lax for reasonable balance between security and usability
max_age=<number_of_seconds> # Set a max age for the cookie
)
...
You may change it to suit your needs. The possible options for samesite
are:
Lax
: Cookies will be sent in top-level navigations (like clicking on a link to go to another site), but not in API requests or images loaded from other sites.Strict
: Cookies will be sent in top-level navigations (like clicking on a link to go to another site), but not in API requests or images loaded from other sites.None
: Cookies will be sent with both same-site and cross-site requests.What you should do with the client is:
Login
: Send credentials to /api/v1/login
. Store the returned access token in memory for subsequent requests.Accessing Protected Routes
: Include the access token in the Authorization header.Token Renewal
: On access token expiry, the front end should automatically call /api/v1/refresh
for a new token.Login Again
: If refresh token is expired, credentials should be sent to /api/v1/login
again, storing the new access token in memory.Logout
: Call /api/v1/logout to end the session securely.This authentication setup in the provides a robust, secure, and user-friendly way to handle user sessions in your API applications.
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.8.3...v0.9.0
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.8.2...v0.8.3
Bugs fixed, stricter types with MyPy
, logout deleted users.
Full Changelog: https://github.com/igorbenav/FastAPI-boilerplate/compare/v0.8.1...v0.8.2