基于 FastAPI + JSON:API 规范的 RESTful 接口框架
Project description
socar_api
基于 FastAPI + JSON:API 规范的 RESTful 接口框架。
简介
socar_api 提供了从资源声明 → 路由生成 → 请求处理 → 响应序列化的完整链路,让开发者专注业务逻辑,无需重复实现接口规范。
框架提供两种资源基类:
BaseResource— 完整基类,支持connect_data()session 管理和子资源嵌套Resource(推荐) — 简化基类,内置 JSON:API 序列化管线,可直接访问self.db
from socar_api import Resource, SchemaBase, Field, Relationship
class ArticleModel(SchemaBase):
title: str = Field(None)
content: str = Field(None)
author_id: int = Field(None, isrel=True)
class Article(Resource):
model = ArticleModel
class Meta:
link = '/articles'
type_ = 'articles'
class RelResources:
author = Relationship(
rel_resource='Author',
mapping_field='author_id',
has_api=False,
)
async def get_many(self):
return self.db.query(ArticleModel).all()
async def post(self):
body = self.parse_body()
obj = ArticleModel(**body.model_dump())
self.db.add(obj)
self.db.commit()
return self.model.model_validate(obj)
一行 Article.register_routes(app) 即生成完整 JSON:API 接口。
核心特性
- JSON:API 规范 — 请求/响应格式、资源关系、稀疏字段、include 复合文档、分页
- 资源路由 — 类声明式路由,自动生成标准 CRUD 端点
- 关系管理 — 一对一/一对多关系,include 深层级联(最多支持 3 层)
- 权限系统 — 基于 scope 的 OAuth2 认证,API + 关系双层权限;支持
@scope声明式配置 - 原子操作 — JSON:API Atomic 扩展支持,批量操作 + 事务回滚
- 文件上传/下载 — 增强的
UploadFileResource/DownloadFileResource基类,文件类型验证、关系校验、可替换存储后端 - 响应缓存 —
@cached()装饰器一行启用接口缓存,Cache-Aside 模式,可替换后端 - 筛选过滤 — Deep Object 格式,40+ 操作符覆盖字符串/数值/列表/时间/布尔
- 自动模型 — 根据资源自动生成请求/响应模型
- 资源版本 — 内建 API 版本管理
- 自动文档 — 与 FastAPI OpenAPI 集成
安装
pip install socar-api
最低要求: Python 3.12+
第一个资源
1. 定义数据模型
from socar_api import SchemaBase, Field
class BookModel(SchemaBase):
id: str = Field(None)
title: str = Field(None)
author: str = Field(None, title='作者')
price: float = Field(None)
2. 定义资源
from socar_api import BaseResource
class Book(BaseResource):
model = BookModel
methods = {'GET', 'GETS', 'POST', 'PATCH', 'DELETE'}
class Meta:
link = '/books'
type_ = 'books'
3. 创建应用
from fastapi import FastAPI
from socar_api.util import register_jsonapi_exception_handlers, JSONAPIContentNegotiationMiddleware
from socar_api import BaseResource
app = FastAPI()
register_jsonapi_exception_handlers(app) # JSON:API 格式错误响应
app.add_middleware(JSONAPIContentNegotiationMiddleware) # Content-Type 校验(可选)
Book.register_routes(app)
4. 启动
uvicorn main:app --reload
访问 http://localhost:8000/docs 查看自动生成的接口文档。
启动后自动生成:
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/books |
资源列表 |
GET |
/books/{id} |
单个资源 |
POST |
/books |
新增资源 |
PATCH |
/books/{id} |
更新资源 |
DELETE |
/books/{id} |
删除资源 |
POST |
/atomic |
原子操作(register_routes() 自动注册) |
完整的 CRUD 资源
实现业务逻辑
from socar_api import BaseResource, SchemaBase, Field, Relationship
class ArticleModel(SchemaBase):
id: str = Field(None)
title: str = Field(None)
content: str = Field(None)
status: str = Field(None)
author_id: str = Field(None, isrel=True)
class Article(BaseResource):
model = ArticleModel
methods = {'GET', 'GETS', 'POST', 'PATCH', 'DELETE'}
class Meta:
link = '/articles'
type_ = 'articles'
class RelResources:
author = Relationship(
rel_resource='Author',
mapping_field='author_id',
has_api=False,
)
async def get_many(self):
skip = self.args.skip
limit = self.args.limit
query = self.db.query(ArticleModel)
return query.offset(skip).limit(limit).all()
async def get(self):
id_ = self.request.path_params.get('id')
return self.db.query(ArticleModel).filter_by(id=id_).one()
async def post(self):
body = self.parse_body()
obj = ArticleModel(**body.model_dump())
self.db.add(obj)
self.db.commit()
return obj
async def patch(self):
body = self.parse_body()
obj = self.db.query(ArticleModel).filter_by(id=body.id).one()
for key, value in body.model_dump(exclude_unset=True).items():
setattr(obj, key, value)
self.db.commit()
return obj
async def delete(self):
body = self.parse_body()
obj = self.db.query(ArticleModel).filter_by(id=body.id).one()
self.db.delete(obj)
self.db.commit()
return obj
self.db由BaseResource自动注入,CRUD 方法中可直接使用,无需额外包裹。
关系资源
from socar_api import BaseResource, SchemaBase, Field, Relationship
class AuthorModel(SchemaBase):
id: str = Field(None)
name: str = Field(None)
class Author(BaseResource):
model = AuthorModel
class Meta:
link = '/authors'
type_ = 'authors'
class RelResources:
articles = Relationship(
rel_resource='Article',
cond_fun='author_articles',
one_to_one=False,
has_api=False,
)
自动生成的关系接口:
GET /authors/{id}/relationships/articles— 获取关系GET /authors/{id}/articles— 获取相关资源GET /articles?include=author— 在文章列表中关联作者
查询与筛选
框架自动解析 URL 参数,支持 Deep Object 格式:
GET /articles?filter[title][op]=ct&filter[title][value]=Python
GET /articles?sort=-created_at
GET /articles?page[offset]=0&page[limit]=20
GET /articles?include=author.comments
GET /articles?fields[articles]=title,content
等价于编程式筛选:
from socar_api.data.spec import Filter, FilterAnd, FilterOr
filter = FilterAnd([
Filter(field='title', op='ct', value='Python'),
Filter(field='status', op='eq', value='published'),
])
v0.6.3+:每个 filter 字段的合法操作符集合和值类型已暴露到 OpenAPI schema 中。 前端 codegen 可以直接从
paths/{resource}/get/parameters读取filter[field]参数定义。
数据库与 Repository
安装数据库支持:
pip install socar-api[data] # SQLAlchemy + Redis
pip install socar-api[clickhouse] # ClickHouse 支持
初始化
from socar_api.data.session import init_db
# ORM · SQLAlchemy declarative base
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
# 在应用启动时初始化连接
init_db(
orm_base=Base,
mysql_url='mysql+pymysql://user:pass@host/db',
clickhouse_url='clickhouse://user:pass@host/db',
)
Repository 模式
使用 repo() 工厂一行创建数据库操作层,替代手写 CRUD 文件:
from socar_api.data.repository import repo
repo = repo(MyOrmModel, MySchema)
# 等价于:
# class CrudMyModel(DataCrud):
# orm = MyOrmModel
# schema = MySchema
repo.get_one(db=session, id_=1)
repo.get_multi(db=session, filters=filter, skip=0, limit=100, sort=sort)
repo.create_one(db=session, data=schema_instance)
repo.update_one(db=session, id_=1, data=schema_instance)
repo.count(db=session, filters=filter)
repo.delete_one(db=session, id_=1)
在资源类中使用:
from socar_api.data.repository import repo
from socar_api.manage import ManageResource
class CarType(ManageResource, BaseResource):
model = CarTypeModel
repo = repo(FactCarType, CarTypeModel) # ORM + Schema → Repository 实例
class Meta:
type_ = 'car_types'
link = '/car_types'
manage.py — 自动 CRUD 校验链
ManageResource 为后台管理类资源提供开箱即用的 CRUD 操作链:
| 方法 | 执行链 |
|---|---|
post() |
verify_duplicate → verify_rel → add_user → handle_request_data → repo.create_one |
patch() |
verify_rel → verify_exist → parse_patch_data → handle_request_data → repo.update_one |
delete() |
verify_exist → verify_auth → verify_use → add_user → repo.delete_one |
db_middleware — 请求级 Session
from fastapi.middleware.base import BaseHTTPMiddleware
from socar_api.data.session import db_middleware
app.add_middleware(BaseHTTPMiddleware, dispatch=db_middleware)
注册后每个请求自动获取/关闭数据库 session,资源内通过 self.db 访问。
文档
安装指定版本
pip install socar-api==0.7.0
更新日志 包含完整的版本历史。
Project details
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 socar_api-0.7.0.tar.gz.
File metadata
- Download URL: socar_api-0.7.0.tar.gz
- Upload date:
- Size: 122.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cce661b167035f97d7711ef45b62f268175ce19cb687039b50d6d747ff207bed
|
|
| MD5 |
ca91e28dd6644f7e63586da8b4986106
|
|
| BLAKE2b-256 |
e7b9bed159b2e7bd1235d04c2126a1e3063f3b2077ddd4520c1f619e3dcdd0e4
|
File details
Details for the file socar_api-0.7.0-py3-none-any.whl.
File metadata
- Download URL: socar_api-0.7.0-py3-none-any.whl
- Upload date:
- Size: 97.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a204cdf53962f635a22c0702615ce07cf1b09732c0256945381ce527be69f283
|
|
| MD5 |
820ae6d6401f58750f4459eb36ae7468
|
|
| BLAKE2b-256 |
5e58d0838bd2f41d983eb0aa7602ca9176b37ce61f1653791b8c10cd28144efa
|