Skip to main content

socar_api

基于 FastAPI + JSON:API 规范的 RESTful 接口框架。

version

简介

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)

类型转换: SchemaBase 自动将 int 值转为 str 字段(如 id=1"1"),兼容 Pydantic v1 行为。 如需禁用此行为以获得严格类型检查,使用 StrictSchemaBase

from socar_api import StrictSchemaBase, Field

class BookModel(StrictSchemaBase):
    id: str = Field(None)  # id=1 将抛出 ValidationError

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.dbBaseResource 自动注入,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.6

更新日志 包含完整的版本历史。

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

socar_api-0.7.6.tar.gz (138.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

socar_api-0.7.6-py3-none-any.whl (108.1 kB view details)

Uploaded Python 3

File details

Details for the file socar_api-0.7.6.tar.gz.

File metadata

  • Download URL: socar_api-0.7.6.tar.gz
  • Upload date:
  • Size: 138.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for socar_api-0.7.6.tar.gz
Algorithm Hash digest
SHA256 f4b827abfed61ea1c24f8a553f79d34c9f78df916ca01a3686af5cc7266e6bc4
MD5 132a21122d64fd00f01b15074ecdbd0a
BLAKE2b-256 9e4b5d3446eb2f814d1e446eec0d2172d800f49410578151e616e33bd3ada614

See more details on using hashes here.

File details

Details for the file socar_api-0.7.6-py3-none-any.whl.

File metadata

  • Download URL: socar_api-0.7.6-py3-none-any.whl
  • Upload date:
  • Size: 108.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for socar_api-0.7.6-py3-none-any.whl
Algorithm Hash digest
SHA256 87557fa8978ffb2fee4f7f7aa0f2cd32a7783f340b89ef5512e4eba244a960d9
MD5 a3a2fb300e8e6451d9af8ae202a0f7a6
BLAKE2b-256 b24280ff9f52d3e58f6f9498a45d88f701c6fd2efea7ab7fa6c47d558b08fd4c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.7.16

2 files

0.7.15

2 files

0.7.14

2 files

0.7.13

2 files

0.7.12

2 files

0.7.11

2 files

0.7.10

2 files

0.7.9

2 files

0.7.8

2 files

0.7.7

2 files

This release

0.7.6 This release

2 files

0.7.5

2 files

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

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