上一篇集成在了gatway上了,但给别人使用swagger的时候还是没有文档,如何集成swagger呢?
python版本:Python 3.11.5
Django版本:4.2.7
0、Swagger 文档介绍
Swagger 是一种用于 RESTful API 的开源框架,可以帮助开发者快速构建和文档化 API。Swagger 文档提供了一种自动生成和可视化 API 文档的方式,使得 API 的设计和使用更加简单和易懂。Swagger 文档通过描述 API 的路径、参数、请求体、响应和错误码等信息,让开发者可以快速了解 API 的设计和使用方式,方便开发者进行 API 的集成和调用。
Swagger 2.0 是 Swagger 规范的第二个版本,引入了许多新的功能和改进。与第一个版本相比,Swagger 2.0 添加了对 WebSockets、OAuth2、文件上传和下载等功能的支持,并且提高了描述 API 的精确度和可读性。Swagger 2.0 还提供了一种可扩展的方式,让开发者可以为自己的 API 添加自定义的元数据信息。
OpenAPI 3.0 是 Swagger 的下一代规范,为 RESTful API 提供了一种标准的描述和交互方式。与 Swagger 2.0 相比,OpenAPI 3.0 提供了更严格的模式验证和错误处理,支持更多的数据类型和协议,同时还提供了更好的安全性和可扩展性。OpenAPI 3.0 还提供了更好的分层描述方式,让开发者可以更好地组织和管理 API 的文档。
那么我们怎么在 Django 项目中集成 Swagger 功能呢?我介绍两个工具 drf-yasg 和 drf-spectacular。
1、drf-yasg和drf-spectacular介绍
drf-yasg 介绍
https://github.com/axnsan12/drf-yasg
drf-yasg 也是一个基于 DRF 的 API 文档生成工具,同样支持 Swagger 2.0规范,并提供了自动生成文档和交互式文档页面的功能。它的特点是支持动态生成 Swagger UI,支持多种主题,可以自定义 API 文档样式,同时也提供了一些有用的功能,比如支持在文档中隐藏指定字段、支持在文档中添加额外的参数等。
drf-spectacular介绍
https://github.com/tfranzel/drf-spectacular
drf-spectacular 是一个基于 DRF 的 API 文档生成工具,支持 OpenAPI 3.0规范,并提供了自动生成文档和交互式文档页面的功能。它支持自定义的扩展和重载,可以满足不同项目的需求,同时还提供了一些有用的功能,比如支持通过代码自动注册 API 视图、支持自定义请求和响应验证器等。
2、使用drf-spectacular 自动生成 OpenAPI 3.0 文档
如果新使用的是 OpenAPI 3.0 的文档,那么只能采用的是 drf-spectacular。
Drf-spectacular源码路径:GitHub - tfranzel/drf-spectacular: Sane and flexible OpenAPI 3 schema generation for Django REST framework.
版本信息查看,符合我的版本要求
大体安装流程
2.1安装 drf-spectacula
pip install drf-spectacular
2.2 在 settings.py 中配置
配置安装程序
INSTALLED_APPS = [
# ALL YOUR APPS
'drf_spectacular',
]
在settings.py最下面注册到 DRF Django Rest Framework=>配置DRF默认schema
REST_FRAMEWORK = {
# YOUR SETTINGS
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
还是在settings.py最下面,自定义OpenApi 描述
SPECTACULAR_SETTINGS = {
'TITLE': 'Your Project API',
'DESCRIPTION': 'Your project description',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
# OTHER SETTINGS
}
2.3静态资源引入
drf-spectacular 默认不包含UI资源,采用CDN方式引入网络外部资源,如果需要本地使用UI资源,可以按照一下方式引入:
安装ui命令:
pip 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
}
注意:SPECTACULAR_SETTINGS,与之前的重复进行合并处理
2.4路由配置
在根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
]
2.5访问测试
访问路径:http://localhost:8000/swagger/ui/
文档没有接口,是因为我们接口还没有添加api注释相关的内容。如何使用呢?
2.6 接口添加注释
官方给的截图
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample
from drf_spectacular.types import OpenApiTypes
class AlbumViewset(viewset.ModelViewset):
serializer_class = AlbumSerializer
@extend_schema(
request=AlbumCreationSerializer,
responses={201: AlbumSerializer},
)
def create(self, request):
# your non-standard behaviour
return super().create(request)
@extend_schema(
# extra parameters added to the schema
parameters=[
OpenApiParameter(name='artist', description='Filter by artist', required=False, type=str),
OpenApiParameter(
name='release',
type=OpenApiTypes.DATE,
location=OpenApiParameter.QUERY,
description='Filter by release date',
examples=[
OpenApiExample(
'Example 1',
summary='short optional summary',
description='longer description',
value='1993-08-23'
),
...
],
),
],
# override default docstring extraction
description='More descriptive text',
# provide Authentication class that deviates from the views default
auth=None,
# change the auto-generated operation name
operation_id=None,
# or even completely override what AutoSchema would generate. Provide raw Open API spec as Dict.
operation=None,
# attach request/response examples to the operation.
examples=[
OpenApiExample(
'Example 1',
description='longer description',
value=...
),
...
],
)
def list(self, request):
# your non-standard behaviour
return super().list(request)
@extend_schema(
request=AlbumLikeSerializer,
responses={204: None},
methods=["POST"]
)
@extend_schema(description='Override a specific method', methods=["GET"])
@action(detail=True, methods=['post', 'get'])
def set_password(self, request, pk=None):
# your action behaviour
...
找一个最简单的接口添加
from rest_framework.decorators import api_view
from drf_spectacular.utils import extend_schema, OpenApiExample, inline_serializer
@extend_schema(
responses={
(200, 'text/html'): {
'description': 'Simple HTML page',
'type': 'string',
'example': '<html>Example text</html>'
},
(202, 'application/json'): {
'description': 'JSON response',
'type': 'object',
'properties': {
'title': {
'type': 'string',
'minLength': 1,
'maxLength': 128
}
},
'required': [
'title'
]
},
}
)
@api_view(['GET'])
def test2(request):
# cache.set('hobby', 'film')
print(cache.get('hobby'))
return HttpResponse('缓存成功')
2.7 再次访问测试验证
在访问刚才的swagger地址
2.8 属性标签介绍
如果想要修改指定接口所属的标签,我们可以使用drf-spectacular提供的extend_schema装饰器函数,函数定义如下:
def extend_schema(
operation_id: Optional[str] = None,
parameters: Optional[Sequence[Union[OpenApiParameter, _SerializerType]]] = None,
request: Any = empty,
responses: Any = empty,
auth: Optional[Sequence[str]] = None,
description: Optional[_StrOrPromise] = None,
summary: Optional[_StrOrPromise] = None,
deprecated: Optional[bool] = None,
tags: Optional[Sequence[str]] = None,
filters: Optional[bool] = None,
exclude: Optional[bool] = None,
operation: Optional[Dict] = None,
methods: Optional[Sequence[str]] = None,
versions: Optional[Sequence[str]] = None,
examples: Optional[Sequence[OpenApiExample]] = None,
extensions: Optional[Dict[str, Any]] = None,
callbacks: Optional[Sequence[OpenApiCallback]] = None,
external_docs: Optional[Union[Dict[str, str], str]] = 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:规范扩展