
Security News
New React Server Components Vulnerabilities: DoS and Source Code Exposure
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.
fastapi-simple-crud
Advanced tools
pip install fastapi-simple-crud
A package to generate CRUD routers and API in a very simple way. Based on SQLAlchemy asynchronous operation and schema.
ExtendedRouterdisable_crud for both SimpleRouter() and ExtendedRouter() (previously disable_simple_crud and disable_extended_crud arguments)SimpleRouter() and ExtendedRouter() be accessed from their objectRouterMap.update_map() can be used to update ExtendedRouter()from fastapi import FastAPI
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from fastapi_simple_crud import RouterMap
engine = create_async_engine("sqlite+aiosqlite:///./test.db", echo=True, future=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()
async def get_session() -> AsyncSession:
async with async_session() as session:
yield session
class Country(Base):
__tablename__ = "country"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(100), nullable=False)
class President(Base):
__tablename__ = "president"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
country_id = Column(Integer, ForeignKey("country.id"))
country = relationship("Country")
class People(Base):
__tablename__ = "people"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
age = Column(Integer)
country_id = Column(Integer, ForeignKey("country.id"))
country = relationship("Country")
app = FastAPI()
@app.on_event("startup")
async def startup():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
## ULTRA SIMPLE OH MY GOD!
MyMap = RouterMap.create_router_map_from_base(base=Base)
RouterMap.generate(app, get_session)


simply set the extend parameter to True then you got the fully extended version
## ULTRA SIMPLE OH MY GOD!
RouterMap.create_router_map_from_base(Base, base_prefix="/v1", extend=True)
RouterMap.generate(app, get_session)

RouterMap superclassclass MyMap(RouterMap):
country = SimpleRouter(Country)
president = SimpleRouter(President)
people = ExtendedRouter(People)
from fastapi_simple_crud import SimpleCRUDGenerator, RouterMap, SimpleRouter, SimpleEndpoint
## ULTRA SIMPLE OH MY GOD!
class MyPresidentPydantic(BaseModel):
name: int
class MyMap(RouterMap):
country = SimpleRouter(Country, prefix="/v1/country")
president = SimpleRouter(President, prefix="/v1/president",
crud_update=None,
crud_create=SimpleEndpoint(pydantic_model=MyPresidentPydantic),
crud_read=SimpleEndpoint("/custom_read"))
RouterMap.generate(app, get_session)
RouterMap as a superclassNone in the SimpleRouter definition:
crud_createcrud_readcrud_updatecrud_deletedisable_crud (set this to True this will forcely disable all API generation)MyMap class) will be generated. From the example, People router is not exist.SimpleEndpoint() refers to your HTTP method definition (GET/POST/PUT/DELETE) in the API decorator (ex: @router.get(), etc.)RouterMap with ExtendedRouter()from fastapi_simple_crud import SimpleCRUDGenerator, RouterMap, ExtendedRouter, SimpleEndpoint
## ULTRA SIMPLE OH MY GOD!
class MyPresidentPydantic(BaseModel):
name: int
class MyMap(RouterMap):
country = ExtendedRouter(Country, prefix="/v1/country")
president = ExtendedRouter(President, prefix="/v1/president",
read_one=None,
read_many=SimpleEndpoint("/custom_read")),
update_one=SimpleEndpoint(pydantic_model=MyPresidentPydantic)
RouterMap.generate(app, get_session)
None in the ExtendedRouter definition:
create_onecreate_manyread_oneread_manyupdate_oneupdate_manydelete_onedelete_manydisable_crud (set this to True this will forcely disable all API generation)from fastapi import Depends
from sqlalchemy import select
from fastapi_simple_crud import SimpleCRUDGenerator, RouterMap, SimpleRouter, SimpleEndpoint
## ULTRA SIMPLE OH MY GOD!
class MyPresidentPydantic(BaseModel):
name: int
class MyMap(RouterMap):
country = SimpleRouter(Country, prefix="/v1/country", crud_read=None)
president = SimpleRouter(President, prefix="/v1/president")
@MyMap.country.get("/custom_read")
async def get_country(id: int, session: AsyncSession = Depends(get_session)):
query = select(Country).where(Country.id==id)
data = await session.execute(query)
data = data.scalars().first()
return data
RouterMap.generate(app, get_session)
from fastapi_simple_crud import SimpleCRUDGenerator, RouterMap, SimpleRouter, SimpleEndpoint
## ULTRA SIMPLE OH MY GOD!
MyMap = RouterMap.create_router_map_from_base(base=Base)
## you want to remove people from autogeneration
class NewMap(MyMap):
people = SimpleRouter(People, disable_crud=True)
RouterMap.generate(app, get_session)
or inherit from the RouterMap
class NewMap(RouterMap):
people = SimpleRouter(People, disable_crud=True)
or simply update from the RouterMap
people = SimpleRouter(People, disable_crud=True)
RouterMap.update_map(people)
or from the MyMap
MyMap.update_map(people)
You can override ExtendedRouter with SimpleRouter and vice versa.
class NewMap(RouterMap):
people = SimpleRouter(People)
class NewMap2(RouterMap):
people = ExtendedRouter(People)
RouterMap.create_router_map_from_base()from fastapi import Depends
from sqlalchemy import select
from fastapi_simple_crud import SimpleCRUDGenerator, RouterMap, SimpleRouter, SimpleEndpoint
class Country(Base):
__tablename__ = "country"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(100), nullable=False)
## ULTRA SIMPLE OH MY GOD!
MyMap = RouterMap.create_router_map_from_base(base=Base)
## use your tablename to get the router attribute from the created router map
## RouterMap in default will automatically mapped your router with its tablename
@MyMap.country.get("/custom_read")
async def get_country(id: int, session: AsyncSession = Depends(get_session)):
query = select(Country).where(Country.id==id)
data = await session.execute(query)
data = data.scalars().first()
return data
RouterMap.generate(app, get_session)
MyMap)RouterMap in default will automatically mapped your router with its tablename (in above Country tablename is country)class MyMap(RouterMap):
country = SimpleRouter(Country)
president = SimpleRouter(President)
people = ExtendedRouter(People)
## here you go
countryCreateOnePydanticModel = MyMap.country.create_one.pydanticModel
for example we have this class
class People(Base):
__tablename__ = "people"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
age = Column(Integer)
country_id = Column(Integer, ForeignKey("country.id"))
country = relationship("Country")
isAlive = Column(Boolean)
then simply put in to with generate_pydantic_model()
from fastapi import Query
from fastapi_simple_crud.dependencies.utils import generate_pydantic_model
myPeoplePydantic = generate_pydantic_model(People, modelName="myPeoplePydantic")
or with some params..
myPeoplePydantic = generate_pydantic_model(
classModel=People,
modelName="myPeoplePydantic",
exclude_attributes=["id"],
include_attributes_default={"isAlive": True},
include_attributes_paramsType={"isAlive": Query},
)
the code above will generate People pydantic model without id attribute
the available params are:
classModel >> your SQLAlchemy Model Schema ClassmodelName >> your pydantic model nameexclude_attributes >> put the attributes you dont want inside your pydanticModel (it will copy all relatied attributes from the SQLAlchemy schema)include_attributes_default >> set your attributes default paramsinclude_attributes_paramsType >> set your attributes default paramsuniform_attributes_default >> override all default value to uniformuniform_attributes_paramsType >> override all params type to uniformFAQs
Generate CRUD routers for you schema in a simple way
We found that fastapi-simple-crud demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.