django-apis


Namedjango-apis JSON
Version 0.2.12 PyPI version JSON
download
home_pageNone
Summary基于Django的API接口开发框架。使用pydantic做接口参数验证,自动生成swagger接口管理界面,支持多种返回体封装。
upload_time2024-12-28 06:05:07
maintainerrRR0VrFP
docs_urlNone
authorrRR0VrFP
requires_pythonNone
licenseApache License, Version 2.0
keywords django apis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # django-apis

基于Django的API接口开发框架。使用pydantic做接口参数验证,自动生成swagger接口管理界面,支持多种返回体封装。

## 安装

```
pip install django-apis
```

## 兼容性要求

- Python 3.8及以上
- Django 3.2及以上

## 配置项

- DJANGO_APIS_OPENAPI_LOGIN_URL: Swagger管理界面访问受管理登录保护。在未登录访问时跳转的登录页面地址。
- DJANGO_APIS_SWAGGER_UI_PATH: Swagger管理界面二级路径(不包括django_apis.urls引入部分)。默认值为`/docs/`。
- DJANGO_APIS_OPENAPI_TITLES: Swagger标题。
- DJANGO_APIS_OPENAPI_VERSIONs: Swagger版本号。
- DJANGO_APIS_OPENAPI_DESCRIPTIONs: Swagger描述。
- DJANGO_APIS_OPENAPI_TAGS: 自定义标签
    ```python
    DJANGO_APIS_OPENAPI_TAGS = {
        "default": [
            {"name": "test1", "description": "测试1"},
        ],
        "another": [
            {"name": "test2", "description": "测试2"},
        ]
    }
    ```

- DJANGO_APIS_OPENAPI_SERVERS: Swagger服务器列表。

    ```python
    DJANGO_APIS_OPENAPI_SERVERS = {
        "default": [
            {"url": "http://127.0.0.1:8000", "description": "本地开发环境"},
            {"url": "http://192.168.1.1", "description": "测试环境"},
        ],
        "another": [
            {"url": "http://192.168.1.1:8000", "description": "本地开发环境"},
            {"url": "http://192.168.1.1:8001", "description": "测试环境"},
        ]
    }
    ```

- DJANGO_APIS_OPENAPI_SECURITY_DEFINITIONS: Swagger认证列表。

    ```python
    DJANGO_APIS_OPENAPI_DESCRIPTIONS = {
        "default": {
            "BasicAuth": {
                "type": "http",
                "scheme": "basic",
            },
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
            },
            "ApikeyAuth": {
                "type": "apiKey",
                "name": "X-API-Key",
                "in": "header",
            },
            "OpenID": {
                "type": "openIdConnect",
                "openIdConnectUrl": "https://example.com/.well-known/openid-configuration",
            },
            "OAuth2": {
                "type": "oauth2",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://example.com/oauth/authorize",
                        "tokenUrl": "https://example.com/oauth/token",
                        "scopes": {
                            "read": "Grants read access",
                            "write": "Grants write access",
                            "admin": "Grants access to admin operations",
                        },
                    }
                },
            },
        },
        "another": {
            "BasicAuth": {
                "type": "http",
                "scheme": "basic",
            },
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
            },
            "ApikeyAuth": {
                "type": "apiKey",
                "name": "X-API-Key",
                "in": "header",
            },
            "OpenID": {
                "type": "openIdConnect",
                "openIdConnectUrl": "https://example.com/.well-known/openid-configuration",
            },
            "OAuth2": {
                "type": "oauth2",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://example.com/oauth/authorize",
                        "tokenUrl": "https://example.com/oauth/token",
                        "scopes": {
                            "read": "Grants read access",
                            "write": "Grants write access",
                            "admin": "Grants access to admin operations",
                        },
                    }
                },
            },
        },
    }
    ```



## 如何自定义Apiview类型

### 注意事项
1. 定义自己的`base_response_class`,并重置自定义的`Apiview`中的`base_response_class`属性。
1. 重载`Apiview`中的`make_response`和`make_error_response`方法。

### 自定义Apiview类型案例

```python
from django.http import JsonResponse
from django_apis.views import Apiview
from django_apis.schemas import ResponseBase
from typing import Any
import pydantic

class ErrorInfo(pydantic.BaseModel):
    code: int = 0
    message: str = "OK"

# 响应体格式定义要与make_response及make_error_response实际响应匹配
class ExampleApiviewResponseBase(ResponseBase):
    success: bool = True
    error: ErrorInfo = ErrorInfo()
    result: Any = None

class ExampleApiview(Apiview):
    base_response_data_field = "result"
    base_response_class = ExampleApiviewResponseBase

    def make_response(self, data):
        return JsonResponse(
            {
                "success": True,
                "error": {
                    "code": 0,
                    "message": "OK",
                },
                "result": data,
            },
            json_dumps_params={
                "ensure_ascii": False,
            },
        )

    # 强制所有响应的http status_code值为200
    def make_error_response(self, code, message, status_code=200):
        return JsonResponse(
            {
                "success": True,
                "error": {
                    "code": code,
                    "message": message,
                },
                "result": None,
            },
            json_dumps_params={
                "ensure_ascii": False,
            },
        )

example_apiview = ExampleApiview()

```

## 使用案例

```python
import pydantic
from django_apis.views import apiview
from django_apis.schemas import OptionalUploadedFiles

@apiview()
def ping() -> str:
    return "pong"


class EchoPayload(pydantic.BaseMode):
    msg: str

@apiview(methods="post")
def echo(payload: EchoPayload) -> str:
    return payload.msg

class ApplyForm(pydantic.BaseMode):
    name: str
    start_date: str
    end_date: str
    files: OptionalUploadedFiles

@apiview(methods="post")
def apply(form: ApplyForm) -> bool:
    return True
```

## 版本记录

### v0.2.0

- 注意:不兼容0.1.x。

### v0.2.1

- 使用openapi 3.1.0版本.
- 添加并通过更多关于复合模型的测试用例。

### v0.2.2

- 通过`DJANGO_APIS_SWAGGER_LOGIN_REQUIRED`配置项控制Swagger管理界面是否受登录保护。

### v0.2.3

- 使用typing.Union以兼容python3.9。

### v0.2.4

- 为接口添加security字段。

### v0.2.5

- query字段添加default支持。

### v0.2.6

- get_response_schema结果必须为ResponseBase子类,否则均使用make_generic_response_type进行动态生成。

### v0.2.8

- 修正:是否为HttpResponseBase实例判断错误的问题。

### v0.2.10

- 添加:django_apis.helper.auth模型,提供http_bearer_auth_protect、http_basic_auth_protect、apikey_auth_protect等认证验证方法。
- 添加:视图级的tags定义支持。

### v0.2.11

- 修正: swagger中支持query参数可选。

### v0.2.12

- 添加:多site支持。
- 修改:开源协议从MIT调整为Apache License, Version 2.0。

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "django-apis",
    "maintainer": "rRR0VrFP",
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "django apis",
    "author": "rRR0VrFP",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/f7/da/720edadeda7dbda62dafe1f9586fb9f7115914dbbde159facfc4f08db46e/django-apis-0.2.12.tar.gz",
    "platform": null,
    "description": "# django-apis\r\n\r\n\u57fa\u4e8eDjango\u7684API\u63a5\u53e3\u5f00\u53d1\u6846\u67b6\u3002\u4f7f\u7528pydantic\u505a\u63a5\u53e3\u53c2\u6570\u9a8c\u8bc1\uff0c\u81ea\u52a8\u751f\u6210swagger\u63a5\u53e3\u7ba1\u7406\u754c\u9762\uff0c\u652f\u6301\u591a\u79cd\u8fd4\u56de\u4f53\u5c01\u88c5\u3002\r\n\r\n## \u5b89\u88c5\r\n\r\n```\r\npip install django-apis\r\n```\r\n\r\n## \u517c\u5bb9\u6027\u8981\u6c42\r\n\r\n- Python 3.8\u53ca\u4ee5\u4e0a\r\n- Django 3.2\u53ca\u4ee5\u4e0a\r\n\r\n## \u914d\u7f6e\u9879\r\n\r\n- DJANGO_APIS_OPENAPI_LOGIN_URL: Swagger\u7ba1\u7406\u754c\u9762\u8bbf\u95ee\u53d7\u7ba1\u7406\u767b\u5f55\u4fdd\u62a4\u3002\u5728\u672a\u767b\u5f55\u8bbf\u95ee\u65f6\u8df3\u8f6c\u7684\u767b\u5f55\u9875\u9762\u5730\u5740\u3002\r\n- DJANGO_APIS_SWAGGER_UI_PATH: Swagger\u7ba1\u7406\u754c\u9762\u4e8c\u7ea7\u8def\u5f84\uff08\u4e0d\u5305\u62ecdjango_apis.urls\u5f15\u5165\u90e8\u5206\uff09\u3002\u9ed8\u8ba4\u503c\u4e3a`/docs/`\u3002\r\n- DJANGO_APIS_OPENAPI_TITLES: Swagger\u6807\u9898\u3002\r\n- DJANGO_APIS_OPENAPI_VERSIONs: Swagger\u7248\u672c\u53f7\u3002\r\n- DJANGO_APIS_OPENAPI_DESCRIPTIONs: Swagger\u63cf\u8ff0\u3002\r\n- DJANGO_APIS_OPENAPI_TAGS: \u81ea\u5b9a\u4e49\u6807\u7b7e\r\n    ```python\r\n    DJANGO_APIS_OPENAPI_TAGS = {\r\n        \"default\": [\r\n            {\"name\": \"test1\", \"description\": \"\u6d4b\u8bd51\"},\r\n        ],\r\n        \"another\": [\r\n            {\"name\": \"test2\", \"description\": \"\u6d4b\u8bd52\"},\r\n        ]\r\n    }\r\n    ```\r\n\r\n- DJANGO_APIS_OPENAPI_SERVERS: Swagger\u670d\u52a1\u5668\u5217\u8868\u3002\r\n\r\n    ```python\r\n    DJANGO_APIS_OPENAPI_SERVERS = {\r\n        \"default\": [\r\n            {\"url\": \"http://127.0.0.1:8000\", \"description\": \"\u672c\u5730\u5f00\u53d1\u73af\u5883\"},\r\n            {\"url\": \"http://192.168.1.1\", \"description\": \"\u6d4b\u8bd5\u73af\u5883\"},\r\n        ],\r\n        \"another\": [\r\n            {\"url\": \"http://192.168.1.1:8000\", \"description\": \"\u672c\u5730\u5f00\u53d1\u73af\u5883\"},\r\n            {\"url\": \"http://192.168.1.1:8001\", \"description\": \"\u6d4b\u8bd5\u73af\u5883\"},\r\n        ]\r\n    }\r\n    ```\r\n\r\n- DJANGO_APIS_OPENAPI_SECURITY_DEFINITIONS: Swagger\u8ba4\u8bc1\u5217\u8868\u3002\r\n\r\n    ```python\r\n    DJANGO_APIS_OPENAPI_DESCRIPTIONS = {\r\n        \"default\": {\r\n            \"BasicAuth\": {\r\n                \"type\": \"http\",\r\n                \"scheme\": \"basic\",\r\n            },\r\n            \"BearerAuth\": {\r\n                \"type\": \"http\",\r\n                \"scheme\": \"bearer\",\r\n            },\r\n            \"ApikeyAuth\": {\r\n                \"type\": \"apiKey\",\r\n                \"name\": \"X-API-Key\",\r\n                \"in\": \"header\",\r\n            },\r\n            \"OpenID\": {\r\n                \"type\": \"openIdConnect\",\r\n                \"openIdConnectUrl\": \"https://example.com/.well-known/openid-configuration\",\r\n            },\r\n            \"OAuth2\": {\r\n                \"type\": \"oauth2\",\r\n                \"flows\": {\r\n                    \"authorizationCode\": {\r\n                        \"authorizationUrl\": \"https://example.com/oauth/authorize\",\r\n                        \"tokenUrl\": \"https://example.com/oauth/token\",\r\n                        \"scopes\": {\r\n                            \"read\": \"Grants read access\",\r\n                            \"write\": \"Grants write access\",\r\n                            \"admin\": \"Grants access to admin operations\",\r\n                        },\r\n                    }\r\n                },\r\n            },\r\n        },\r\n        \"another\": {\r\n            \"BasicAuth\": {\r\n                \"type\": \"http\",\r\n                \"scheme\": \"basic\",\r\n            },\r\n            \"BearerAuth\": {\r\n                \"type\": \"http\",\r\n                \"scheme\": \"bearer\",\r\n            },\r\n            \"ApikeyAuth\": {\r\n                \"type\": \"apiKey\",\r\n                \"name\": \"X-API-Key\",\r\n                \"in\": \"header\",\r\n            },\r\n            \"OpenID\": {\r\n                \"type\": \"openIdConnect\",\r\n                \"openIdConnectUrl\": \"https://example.com/.well-known/openid-configuration\",\r\n            },\r\n            \"OAuth2\": {\r\n                \"type\": \"oauth2\",\r\n                \"flows\": {\r\n                    \"authorizationCode\": {\r\n                        \"authorizationUrl\": \"https://example.com/oauth/authorize\",\r\n                        \"tokenUrl\": \"https://example.com/oauth/token\",\r\n                        \"scopes\": {\r\n                            \"read\": \"Grants read access\",\r\n                            \"write\": \"Grants write access\",\r\n                            \"admin\": \"Grants access to admin operations\",\r\n                        },\r\n                    }\r\n                },\r\n            },\r\n        },\r\n    }\r\n    ```\r\n\r\n\r\n\r\n## \u5982\u4f55\u81ea\u5b9a\u4e49Apiview\u7c7b\u578b\r\n\r\n### \u6ce8\u610f\u4e8b\u9879\r\n1. \u5b9a\u4e49\u81ea\u5df1\u7684`base_response_class`\uff0c\u5e76\u91cd\u7f6e\u81ea\u5b9a\u4e49\u7684`Apiview`\u4e2d\u7684`base_response_class`\u5c5e\u6027\u3002\r\n1. \u91cd\u8f7d`Apiview`\u4e2d\u7684`make_response`\u548c`make_error_response`\u65b9\u6cd5\u3002\r\n\r\n### \u81ea\u5b9a\u4e49Apiview\u7c7b\u578b\u6848\u4f8b\r\n\r\n```python\r\nfrom django.http import JsonResponse\r\nfrom django_apis.views import Apiview\r\nfrom django_apis.schemas import ResponseBase\r\nfrom typing import Any\r\nimport pydantic\r\n\r\nclass ErrorInfo(pydantic.BaseModel):\r\n    code: int = 0\r\n    message: str = \"OK\"\r\n\r\n# \u54cd\u5e94\u4f53\u683c\u5f0f\u5b9a\u4e49\u8981\u4e0emake_response\u53camake_error_response\u5b9e\u9645\u54cd\u5e94\u5339\u914d\r\nclass ExampleApiviewResponseBase(ResponseBase):\r\n    success: bool = True\r\n    error: ErrorInfo = ErrorInfo()\r\n    result: Any = None\r\n\r\nclass ExampleApiview(Apiview):\r\n    base_response_data_field = \"result\"\r\n    base_response_class = ExampleApiviewResponseBase\r\n\r\n    def make_response(self, data):\r\n        return JsonResponse(\r\n            {\r\n                \"success\": True,\r\n                \"error\": {\r\n                    \"code\": 0,\r\n                    \"message\": \"OK\",\r\n                },\r\n                \"result\": data,\r\n            },\r\n            json_dumps_params={\r\n                \"ensure_ascii\": False,\r\n            },\r\n        )\r\n\r\n    # \u5f3a\u5236\u6240\u6709\u54cd\u5e94\u7684http status_code\u503c\u4e3a200\r\n    def make_error_response(self, code, message, status_code=200):\r\n        return JsonResponse(\r\n            {\r\n                \"success\": True,\r\n                \"error\": {\r\n                    \"code\": code,\r\n                    \"message\": message,\r\n                },\r\n                \"result\": None,\r\n            },\r\n            json_dumps_params={\r\n                \"ensure_ascii\": False,\r\n            },\r\n        )\r\n\r\nexample_apiview = ExampleApiview()\r\n\r\n```\r\n\r\n## \u4f7f\u7528\u6848\u4f8b\r\n\r\n```python\r\nimport pydantic\r\nfrom django_apis.views import apiview\r\nfrom django_apis.schemas import OptionalUploadedFiles\r\n\r\n@apiview()\r\ndef ping() -> str:\r\n    return \"pong\"\r\n\r\n\r\nclass EchoPayload(pydantic.BaseMode):\r\n    msg: str\r\n\r\n@apiview(methods=\"post\")\r\ndef echo(payload: EchoPayload) -> str:\r\n    return payload.msg\r\n\r\nclass ApplyForm(pydantic.BaseMode):\r\n    name: str\r\n    start_date: str\r\n    end_date: str\r\n    files: OptionalUploadedFiles\r\n\r\n@apiview(methods=\"post\")\r\ndef apply(form: ApplyForm) -> bool:\r\n    return True\r\n```\r\n\r\n## \u7248\u672c\u8bb0\u5f55\r\n\r\n### v0.2.0\r\n\r\n- \u6ce8\u610f\uff1a\u4e0d\u517c\u5bb90.1.x\u3002\r\n\r\n### v0.2.1\r\n\r\n- \u4f7f\u7528openapi 3.1.0\u7248\u672c.\r\n- \u6dfb\u52a0\u5e76\u901a\u8fc7\u66f4\u591a\u5173\u4e8e\u590d\u5408\u6a21\u578b\u7684\u6d4b\u8bd5\u7528\u4f8b\u3002\r\n\r\n### v0.2.2\r\n\r\n- \u901a\u8fc7`DJANGO_APIS_SWAGGER_LOGIN_REQUIRED`\u914d\u7f6e\u9879\u63a7\u5236Swagger\u7ba1\u7406\u754c\u9762\u662f\u5426\u53d7\u767b\u5f55\u4fdd\u62a4\u3002\r\n\r\n### v0.2.3\r\n\r\n- \u4f7f\u7528typing.Union\u4ee5\u517c\u5bb9python3.9\u3002\r\n\r\n### v0.2.4\r\n\r\n- \u4e3a\u63a5\u53e3\u6dfb\u52a0security\u5b57\u6bb5\u3002\r\n\r\n### v0.2.5\r\n\r\n- query\u5b57\u6bb5\u6dfb\u52a0default\u652f\u6301\u3002\r\n\r\n### v0.2.6\r\n\r\n- get_response_schema\u7ed3\u679c\u5fc5\u987b\u4e3aResponseBase\u5b50\u7c7b\uff0c\u5426\u5219\u5747\u4f7f\u7528make_generic_response_type\u8fdb\u884c\u52a8\u6001\u751f\u6210\u3002\r\n\r\n### v0.2.8\r\n\r\n- \u4fee\u6b63\uff1a\u662f\u5426\u4e3aHttpResponseBase\u5b9e\u4f8b\u5224\u65ad\u9519\u8bef\u7684\u95ee\u9898\u3002\r\n\r\n### v0.2.10\r\n\r\n- \u6dfb\u52a0\uff1adjango_apis.helper.auth\u6a21\u578b\uff0c\u63d0\u4f9bhttp_bearer_auth_protect\u3001http_basic_auth_protect\u3001apikey_auth_protect\u7b49\u8ba4\u8bc1\u9a8c\u8bc1\u65b9\u6cd5\u3002\r\n- \u6dfb\u52a0\uff1a\u89c6\u56fe\u7ea7\u7684tags\u5b9a\u4e49\u652f\u6301\u3002\r\n\r\n### v0.2.11\r\n\r\n- \u4fee\u6b63: swagger\u4e2d\u652f\u6301query\u53c2\u6570\u53ef\u9009\u3002\r\n\r\n### v0.2.12\r\n\r\n- \u6dfb\u52a0\uff1a\u591asite\u652f\u6301\u3002\r\n- \u4fee\u6539\uff1a\u5f00\u6e90\u534f\u8bae\u4eceMIT\u8c03\u6574\u4e3aApache License, Version 2.0\u3002\r\n",
    "bugtrack_url": null,
    "license": "Apache License, Version 2.0",
    "summary": "\u57fa\u4e8eDjango\u7684API\u63a5\u53e3\u5f00\u53d1\u6846\u67b6\u3002\u4f7f\u7528pydantic\u505a\u63a5\u53e3\u53c2\u6570\u9a8c\u8bc1\uff0c\u81ea\u52a8\u751f\u6210swagger\u63a5\u53e3\u7ba1\u7406\u754c\u9762\uff0c\u652f\u6301\u591a\u79cd\u8fd4\u56de\u4f53\u5c01\u88c5\u3002",
    "version": "0.2.12",
    "project_urls": null,
    "split_keywords": [
        "django",
        "apis"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "aad0e0670498d6850402f66d615085f3b6f75a2b430153fd759849f7fb78d966",
                "md5": "1027803ea883a21710ba3c2f51c5dbe1",
                "sha256": "aab88985e7de61620848b0079fed3e2c576e066ad51f572156cbf555cd681eb7"
            },
            "downloads": -1,
            "filename": "django_apis-0.2.12-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1027803ea883a21710ba3c2f51c5dbe1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 21281,
            "upload_time": "2024-12-28T06:05:05",
            "upload_time_iso_8601": "2024-12-28T06:05:05.746163Z",
            "url": "https://files.pythonhosted.org/packages/aa/d0/e0670498d6850402f66d615085f3b6f75a2b430153fd759849f7fb78d966/django_apis-0.2.12-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f7da720edadeda7dbda62dafe1f9586fb9f7115914dbbde159facfc4f08db46e",
                "md5": "368ed8a5513ca29644a8eb5fcbe08100",
                "sha256": "923a2deacffeb1f549c97cd8f31845ff7fe7eb3e36e57c3eeb187c01cdd2829b"
            },
            "downloads": -1,
            "filename": "django-apis-0.2.12.tar.gz",
            "has_sig": false,
            "md5_digest": "368ed8a5513ca29644a8eb5fcbe08100",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 20306,
            "upload_time": "2024-12-28T06:05:07",
            "upload_time_iso_8601": "2024-12-28T06:05:07.050749Z",
            "url": "https://files.pythonhosted.org/packages/f7/da/720edadeda7dbda62dafe1f9586fb9f7115914dbbde159facfc4f08db46e/django-apis-0.2.12.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-28 06:05:07",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "django-apis"
}
        
Elapsed time: 0.43373s