Skip to content

Commit 9a238ec

Browse files
committed
feat: 从 drf_yasg 迁移到 drf_spectacular,修复子路径部署问题
- urls.py: 将 drf_yasg 替换为 drf_spectacular 的 SpectacularAPIView/SwaggerView/RedocView - default.py: 添加子路径支持(FORCE_SCRIPT_NAME/STATIC_URL),添加 SPECTACULAR_SETTINGS 配置 - schema.py: 新增 IgnoreExcludeAutoSchema 和 extend_schema patch,使 exclude=True 不生效 - pyproject.toml: 移除 drf-yasg 依赖
1 parent aefc776 commit 9a238ec

4 files changed

Lines changed: 47 additions & 20 deletions

File tree

runtime/bk-plugin-runtime/bk_plugin_runtime/config/default.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,16 @@ def logging_addition_settings(logging_dict):
239239
"DEFAULT_PERMISSION_CLASSES": [
240240
"apigw_manager.drf.permission.ApiGatewayPermission",
241241
],
242-
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
242+
"DEFAULT_SCHEMA_CLASS": "bk_plugin_runtime.schema.IgnoreExcludeAutoSchema",
243+
}
244+
245+
# drf-spectacular 配置
246+
import bk_plugin_runtime.schema # noqa: 应用 monkey-patch,使 @extend_schema(exclude=True) 不生效
247+
248+
SPECTACULAR_SETTINGS = {
249+
"TITLE": "PluginService API",
250+
"VERSION": "v1",
251+
"SERVE_INCLUDE_SCHEMA": False,
243252
}
244253

245254

@@ -266,6 +275,15 @@ def logging_addition_settings(logging_dict):
266275
BK_APIGW_STAGE_BACKEND_HOST = f"{app_scheme}://{app_domain}"
267276
BK_APIGW_STAGE_BACKEND_SUBPATH = app_subpath
268277

278+
# 子路径配置:当应用部署在子路径下时(如 /bk-plugin-demo-g/),
279+
# 需要设置 FORCE_SCRIPT_NAME 和 STATIC_URL 以确保 admin 样式和静态资源正常加载
280+
if app_subpath:
281+
FORCE_SCRIPT_NAME = f"/{app_subpath}"
282+
STATIC_URL = f"/{app_subpath}/static/"
283+
else:
284+
FORCE_SCRIPT_NAME = ""
285+
STATIC_URL = "/static/"
286+
269287
# 网关同步 API 文档语言, zh/en, 如果配置了BK_APIGW_RESOURCE_DOCS_BASE_DIR(使用自定义文档), 那么必须将这个变量置空
270288
BK_APIGW_RELEASE_DOC_LANGUAGE = os.getenv("BK_APIGW_RELEASE_DOC_LANGUAGE", "")
271289
# 在项目 docs目录下,通过 markdown文档自动化导入中英文文档; 注意markdown文件名必须等于接口的 operation_id; 见 demo 示例
@@ -302,7 +320,8 @@ def logging_addition_settings(logging_dict):
302320
# APIGW MANAGER
303321
BK_APP_CODE = os.getenv("BKPAAS_APP_ID")
304322
BK_APP_SECRET = os.getenv("BKPAAS_APP_SECRET")
305-
BK_APIGW_NAME = os.getenv("BKPAAS_BK_PLUGIN_APIGW_NAME")
323+
# 兼容不同部署环境的变量名
324+
BK_APIGW_NAME = os.getenv("BKPAAS_BK_PLUGIN_APIGW_NAME") or os.getenv("BK_PLUGIN_APIGW_NAME")
306325
# 兼容旧版环境变量 & PaaS V3 默认注入变量
307326
BK_API_URL_TMPL = (
308327
os.getenv("BK_APIGW_MANAGER_URL_TMPL") or os.getenv("BK_APIGW_MANAGER_URL_TEMPL") or os.getenv("BK_API_URL_TMPL")
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import drf_spectacular.openapi
2+
import drf_spectacular.utils
3+
4+
5+
class IgnoreExcludeAutoSchema(drf_spectacular.openapi.AutoSchema):
6+
"""忽略 @extend_schema(exclude=True),将所有 API 暴露到 Swagger 文档中"""
7+
8+
def is_excluded(self) -> bool:
9+
return False
10+
11+
12+
# Patch extend_schema 装饰器,使 exclude 参数无效
13+
_original_extend_schema = drf_spectacular.utils.extend_schema
14+
15+
16+
def _patched_extend_schema(*args, exclude=None, **kwargs):
17+
"""将 exclude 强制设为 None,使 @extend_schema(exclude=True) 不生效"""
18+
return _original_extend_schema(*args, exclude=None, **kwargs)
19+
20+
21+
drf_spectacular.utils.extend_schema = _patched_extend_schema

runtime/bk-plugin-runtime/bk_plugin_runtime/urls.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,14 @@
1212
from django.conf import settings
1313
from django.contrib import admin
1414
from django.urls import include, re_path
15-
from drf_yasg import openapi
16-
from drf_yasg.views import get_schema_view
17-
from rest_framework import permissions
18-
19-
schema_view = get_schema_view(
20-
openapi.Info(
21-
title="PluginService API",
22-
default_version="v1",
23-
),
24-
public=True,
25-
permission_classes=(permissions.AllowAny,),
26-
)
27-
15+
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
2816

2917
urlpatterns = [
3018
re_path(r"^admin/", admin.site.urls),
3119
re_path(r"^account/", include("blueapps.account.urls")),
3220
re_path(r"^i18n/", include("django.conf.urls.i18n")),
33-
re_path(r"^swagger(?P<format>\.json|\.yaml)$", schema_view.without_ui(cache_timeout=0), name="schema-json"),
34-
re_path(r"^redoc/$", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc"),
21+
re_path(r"^schema/$", SpectacularAPIView.as_view(), name="schema"),
22+
re_path(r"^redoc/$", SpectacularRedocView.as_view(url_name="schema"), name="redoc"),
3523
re_path(r"^bk_plugin/", include("bk_plugin_framework.services.bpf_service.urls")),
3624
]
3725

@@ -41,11 +29,11 @@
4129

4230
urlpatterns.extend(
4331
[
44-
re_path(r"^swagger/$", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui"),
32+
re_path(r"^swagger/$", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"),
4533
re_path(r"^$", debug_panel, name="debug-panel"),
4634
]
4735
)
4836
else:
4937
urlpatterns.append(
50-
re_path(r"^$", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui"),
38+
re_path(r"^$", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"),
5139
)

runtime/bk-plugin-runtime/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Django = ">=2.2.6,<5"
1212
pymysql = ">=1,<2"
1313
gunicorn = ">=19.6.0"
1414
djangorestframework = "^3.15"
15-
drf-yasg = "^1.21.5"
1615
raven = "^6.5.0"
1716
ddtrace = "^0.14.1"
1817
django-cors-headers = "^4.0.0"

0 commit comments

Comments
 (0)