首页 > 其他分享 >Django Swagger文档库drf-spectacular

Django Swagger文档库drf-spectacular

时间:2024-11-03 14:41:21浏览次数:3  
标签:None spectacular drf 文档 Swagger Optional schema

在使用DRF的时候,通常的文档有:默认文档RestFrameWork、CoreAPI、Swagger,Swagger是最流行的API文档库,在绝大多数服务端开发中都有用到,之前我们使用了CoreAPI来生成文档,一方面是它不够流行,没办法和其他工具结合,另一方面可能是我不熟悉,所有有些接口并不能按照我们的要求来使用。因此我选择使用Swagger文档,之前使用过drf-yasg,但是drf-yasg现在还不支持OpenAPI 3.0,而在drf-yasg的官方文档中为我们推荐了另一个库:drf-spectacular,而且声明了drf-yasg不太可能支持OpenAPI 3.0,因此推荐我们使用drf-spectacular这个库。

image

安装配置

pipenv install drf-spectacular

在app中注册

# settings.py
INSTALLED_APPS = [
    # ALL YOUR APPS
    'drf_spectacular',
]

配置DRF默认schema

# settings.py
REST_FRAMEWORK = {
    # YOUR SETTINGS
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

配置drf-spectacular

# settings.py
SPECTACULAR_SETTINGS = {
    'TITLE': '在线考试',
    'DESCRIPTION': '在线考试系统',
    'VERSION': '1.0.0',
    'SERVE_INCLUDE_SCHEMA': False,
    # OTHER SETTINGS
}

静态资源引入
drf-spectacular 默认不包含UI资源,采用CDN方式引入网络外部资源,如果需要本地使用UI资源,可以按照一下方式引入:

pipenv install drf-spectacular[sidecar]

配置settings.py文件

INSTALLED_APPS = [
    # ALL YOUR APPS
    'drf_spectacular',
    'drf_spectacular_sidecar',  # required for Django collectstatic discovery
]
SPECTACULAR_SETTINGS = {
    'SWAGGER_UI_DIST': 'SIDECAR',  # shorthand to use the sidecar instead
    'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
    'REDOC_DIST': 'SIDECAR',
    # OTHER SETTINGS
}

路由配置

在根urls.py中增加路由配置

from drf_spectacular.views import SpectacularJSONAPIView, SpectacularRedocView, SpectacularSwaggerView

urlpatterns = [
    path('swagger/json/', SpectacularJSONAPIView.as_view(), name='schema'),
    # Optional UI:
    path('swagger/ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
    path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
    # YOUR PATTERNS
]

访问:http://localhost:8000/swagger...
image
在swagger文档中为我们生成的接口标签是根据根路由前缀自动生成的,例如以上文档的路由为:

urlpatterns = [
    path('', RedirectView.as_view(url='docs')),
    path('swagger/json/', SpectacularJSONAPIView.as_view(), name='schema'),
    # Optional UI:
    path('swagger/ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
    path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
    # My Router
    path('user/', include('users.urls')),
    path('exam/', include('exam.urls')),
    path('question/', include('question.urls'))
]

如果想要修改指定接口所属的标签,我们可以使用drf-spectacular提供的extend_schema装饰器函数,函数定义如下:

def extend_schema(
        operation_id: Optional[str] = None,
        parameters: Optional[List[Union[OpenApiParameter, _SerializerType]]] = None,
        request: Any = empty,
        responses: Any = empty,
        auth: Optional[List[str]] = None,
        description: Optional[str] = None,
        summary: Optional[str] = None,
        deprecated: Optional[bool] = None,
        tags: Optional[List[str]] = None,
        exclude: bool = False,
        operation: Optional[Dict] = None,
        methods: Optional[List[str]] = None,
        versions: Optional[List[str]] = None,
        examples: Optional[List[OpenApiExample]] = None,
        extensions: Optional[Dict[str, Any]] = None,
) -> Callable[[F], F]:

这个装饰器主要用于修改view在文档中的定义,参数意义如下:

  • operation_id:一个唯一标识ID,基本用不到

  • parameters:添加到列表中的附加或替换参数去自动发现字段。

  • responses:替换Serializer。需要各种各样的可单独使用或组合使用的输入(有以下7种)

    • Serializer类
    • 序列化实例,比如:Serializer(many=True)
    • OpenApiTypes的基本类型或者实例
    • OpenApiResponse类
    • PolymorphicProxySerializer类
    • 1个字典,以状态码作为键, 以上其中一项作为值(是最常用的,格式{200, None})
    • 1个字典,以状态码作为键,以media_type作为值
  • request:替换序列化,接受各种输入

    • Serializer 类或者实例
    • OpenApiTypes基本类型或者实例
    • PolymorphicProxySerializer类
    • 1个字典,以media_type作为键,以上其中一项作为值
  • auth:用auth方法的显式列表替换发现的auth

  • description:替换发现的文档字符串

  • summary:一个可选的短的总结描述

  • deprecated:将操作标记为已弃用

  • tags:覆盖默认标记列表

  • exclude:设置为True以从schema中排除操作

  • operation:手动覆盖自动发现将生成的内容。你必须提供一个兼容OpenAPI3的字典,该字典可以直接翻译成YAML。

  • methods:检查extend_schema中特殊的方法,默认匹配所有

  • versions:检查extend_schema中特殊的API版本,默认匹配所有

  • example:将请求/响应示例附加到操作中

  • extensions:规范扩展
    最后我们将登录、注册接口修改为Common标签

from drf_spectacular.utils import extend_schema

class LoginView(GenericAPIView):
    ......

    @extend_schema(
        tags=['Common'],
        summary='Login',
        description='登录接口',
        responses={200: str, 401: str}
    )
    def post(self, request: Request):
        pass
        

class RegisterView(GenericAPIView):
    ......

    @extend_schema(
        tags=['Common'],
        summary='Register',
        description='注册接口',
        responses={201: UserInfoSerializer, 400: str}
    )
    def post(self, request: Request):
        pass

注意:

使用时要注意,对于不同app下的view和Serializer要尽量使用不同的命名,否则在渲染文档的时候可能会出现异常。

自定义认证方式

在项目中我们使用了JWT作为登录认证,而drf-spectacular只对Session、Basic、Token做了适配

rest_framework.authentication.SessionAuthentication
rest_framework.authentication.BasicAuthentication
rest_framework.authentication.TokenAuthentication

这个我们在drf-spectacular/authentication.py文件中可以看到,这个的作用就是在文档中显示什么样认证页面
image
对于认证页面的显示,主要是根据settings.py配置中的

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'utils.auth.authentication.JwtAuthentication'
    ],
    ......
}

如果drf-spectacular可以识别 DEFAULT_AUTHENTICATION_CLASSES 下的认证方式,就会在文档登录页面上显示对应的认证方式,这里我们有自定义的认证方式,如果需要显示,要做一下适配:

from drf_spectacular.extensions import OpenApiAuthenticationExtension
from drf_spectacular.plumbing import build_bearer_security_scheme_object


class JWTTokenScheme(OpenApiAuthenticationExtension):
    target_class = 'utils.auth.authentication.JwtAuthentication'
    name = 'JwtTokenAuth'
    match_subclasses = True
    priority = 1

    def get_security_definition(self, auto_schema):
        return build_bearer_security_scheme_object(
            header_name='Authorization',
            token_prefix=self.target.keyword,
            bearer_format='JWT'
        )

简单解释一下,首先要继承OpenApiAuthenticationExtension,然后target_class中要写我们在DEFAULT_AUTHENTICATION_CLASSES中配置的认证路径,然后重新get_security_definition函数,返回一个字典对象,字典的键可以在OpenAPI Specification v3.0.3 | Introduction, Definitions, & More网页访问
image
然后再看登录认证页面
image
因为我们在DEFAULT_AUTHENTICATION_CLASSES中配置了两种认证方式,因此页面就会显示两种认证方式

BUG

目前使用中存在一个BUG,就是对于read_only字段,按照我们的理解就是在查询请求是返回给客户端,而创建时在请求体中不需要包含。在默认生成的swagger界面上,我们看到的情况与理解的一样,对于JSON参数的请求是没有问题的,我们只需要输入必填的字段就可以了,但是如果是form-data参数,虽然显示的依然不包含read_only字段,请求却无法发送成功。作者也认为这是一个BUG,但是他却没有修正,

Callback schema with read-only/write-only fields · Issue #680 · tfranzel/drf-spectacular (github.com)

对于以上问题我们有两种解决方式:

只使用JSON格式的请求参数,缺点是必填和选填参数搞不清楚
在后端序列化的时候,针对不同的请求,明确的定义相对应的序列化类来处理,缺点是后端代码变多了,而且埋没了DRF为我们提供的很多使用方便的特性。
目前我采用的是第一种方式,宁愿API不明确一点,也不能增加后端的复制程度。

来源:https://segmentfault.com/a/1190000042454076

标签:None,spectacular,drf,文档,Swagger,Optional,schema
From: https://www.cnblogs.com/liuyanhang/p/18523423

相关文章

  • 咱就是说不想用swagger,替换swagger和postman的api接口神器 -- Apifox
    简介:        在当今快速发展的软件开发领域,寻找有效的API文档和测试工具对于提高开发效率和保证软件质量至关重要。        Swagger长久以来一直是开发者的首选,但新兴的工具Apifox逐渐显示出其独特的优势和潜力。本文将深入探讨如何使用Apifox来替换Swagger,......
  • 记录springboot 3.3.5 版本整合 swagger +spring security + jwt
    springboot版本security版本wagger版本jwt版本redis版本pom文件如下引入redis是为了存储token<version>3.3.5</version><!--security--><dependency><groupId>org.springframework.boot</groupId><arti......
  • DRF
    1.DRF组件详细文档:见附件1.1Web应用模式在开发web应用中,有两种应用模式:1.前后端不分离【客户端看到的内容和所有页面效果都是由服务端提供出来的】2.前后端分离【把前端的界面效果(html,css,js分离到另一个服务端,Python服务端只需要返回数据即可)】前端形成一个独立的网站,服务......
  • 根据swagger.yaml生成harbor私库api调用代码
    准备下载https://github.com/goharbor/harbor/blob/main/api/v2.0/swagger.yaml下载https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.43/swagger-codegen-cli-2.4.43.jar生成调用代码swagger-codegen-cli是用java写的,但是支持生成多种语言的调用代码,......
  • 解决:swagger2 Could not resolve reference because of: Could not resolve pointer:
    问题:使用swagger时页面出现报警信息mavaen依赖版本:2.8.0<!--swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.8.0<......
  • 【Swagger】Swagger2和Swagger3使用API文档的可视化工具(xiaoymin)
    Swagger时接口文档生成工具,在前后端分离时代很好用。不过,当接口多了,看起来不太符合国人的习惯。因为:缺乏搜索功能接口类多起来,找接口有如大海捞针。接口边上,没有带着接口注释看Model,需要拖拽到最后,没有很自然的切换。所以,xiaoymin在swagger的基础上,做到了更好的可视化......
  • 记录springboot 3.x 版本整合 swagger
    boot版本3.3.5jdk版本17pom文件依赖包导入org.springdocspringdoc-openapi-starter-webmvc-ui2.6.0建一个swagger配置文件@ConfigurationpublicclassSwaggerConfig{@BeanpublicOpenAPIopenAPI(){returnnewOpenAPI().info(newInfo().title("demo接口文......
  • DRF-Serializers序列化器组件源码分析及改编su
    1.源码分析注意:以下代码片段为方便理解已进行简化,只保留了与序列化功能相关的代码序列化的源码中涉及到了元类的概念,我在这里简单说明一下:元类(metaclass)是一个高级概念,用于定义类的创建行为。简单来说,元类是创建类的类,它决定了类的创建方式和行为。在Python中一切皆为对象,包......
  • Swagger UI、RESTful简介
    Swagger UI简介SwaggerUI允许任何人(无论您是开发团队还是最终用户)都可以可视化API资源并与之交互,而无需任何实现逻辑。它是根据您的OpenAPI(以前称为Swagger)规范自动生成的,具有可视化文档,可简化后端实现和客户端使用。SwaggerUI特点无依赖UI可以在任何开发环境中使用,无论......
  • DRF-Serializers序列化器组件源码分析及改编
    1.源码分析注意:以下代码片段为方便理解已进行简化,只保留了与序列化功能相关的代码序列化的源码中涉及到了元类的概念,我在这里简单说明一下:元类(metaclass)是一个高级概念,用于定义类的创建行为。简单来说,元类是创建类的类,它决定了类的创建方式和行为。在Python中一切皆为对象,包......