使用
blacksheep create
和以下选项来创建示例 API:
✨ Project name: soquestion
🚀 Project template: api
🤖 Use controllers? Yes
📜 Use OpenAPI Documentation? Yes
🔧 Library to read settings essentials-configuration
🔩 App settings format YAML
这将生成一个基于 BlackSheep 的简单 API,其端点在
app/controllers/examples.py
: 中定义
"""
Example API implemented using a controller.
"""
from typing import List, Optional
from blacksheep.server.controllers import Controller, get, post
class ExamplesController(Controller):
@classmethod
def route(cls) -> Optional[str]:
return "/api/examples"
@classmethod
def class_name(cls) -> str:
return "Examples"
@get()
async def get_examples(self) -> List[str]:
"""
Gets a list of examples.
Lorem Ipsum Dolor Sit amet
"""
return list(f"example {i}" for i in range(3))
@post()
async def add_example(self, example: str):
"""
Adds an example.
"""
当您使用
pip install ...
启动 API(不要忘记在执行 python dev.py
之前创建并激活虚拟环境)并导航到 http://localhost:44777/docs 时,您可以看到 OpenAPI 文档。
根据文档,您可以使用文档字符串来指定端点描述。
是否可以以某种方式为响应添加文档?
根据 documentation 您可以使用
@docs
装饰器,但这仅适用于预先定义 @docs
的简单文件。在生成的API中,@docs
在app/docs/__init.py__
中定义,但我找不到在example.py
中使用它的方法。
生成的
app/docs/__init.py__
看起来像这样:
"""
This module contains OpenAPI Documentation definition for the API.
It exposes a docs object that can be used to decorate request handlers with additional
information, used to generate OpenAPI documentation.
"""
from blacksheep import Application
from blacksheep.server.openapi.v3 import OpenAPIHandler
from openapidocs.v3 import Info
from app.docs.binders import set_binders_docs
from app.settings import Settings
def configure_docs(app: Application, settings: Settings):
docs = OpenAPIHandler(
info=Info(title=settings.info.title, version=settings.info.version),
anonymous_access=True,
)
# include only endpoints whose path starts with "/api/"
docs.include = lambda path, _: path.startswith("/api/")
set_binders_docs(docs)
docs.bind_app(app)
考虑到 BlackSheep 示例中文档处理程序的定义方式,您无法轻松使用该特定实例。 原因是
docs
是 configure_docs
函数的局部函数,因此不能在其外部使用。 但是,该文档装饰器只是 OpenAPIHandler
类的一个实例,因此您可以将其定义移到该函数之外,并在整个项目中自由使用它。 这是示例项目的“补丁”,用于展示幼稚的方法(抱歉,但 SO 不支持补丁/差异语法突出显示),其中 docs
重命名为 doc_handler
以更好地将其与 app.docs
模块区分开来:
diff --git a/app/controllers/examples.py b/app/controllers/examples.py
index 4bb984d..41989e5 100644
--- a/app/controllers/examples.py
+++ b/app/controllers/examples.py
@@ -5,6 +5,8 @@ from typing import List, Optional
from blacksheep.server.controllers import Controller, get, post
+from app.docs import docs_handler
+
class ExamplesController(Controller):
@classmethod
@@ -15,6 +17,7 @@ class ExamplesController(Controller):
def class_name(cls) -> str:
return "Examples"
+ @docs_handler(responses={200: "OK response", 404: "No example found"})
@get()
async def get_examples(self) -> List[str]:
"""
diff --git a/app/docs/__init__.py b/app/docs/__init__.py
index 0b3d0f1..f478864 100644
--- a/app/docs/__init__.py
+++ b/app/docs/__init__.py
@@ -9,18 +9,21 @@ from blacksheep.server.openapi.v3 import OpenAPIHandler
from openapidocs.v3 import Info
from app.docs.binders import set_binders_docs
-from app.settings import Settings
+from app.settings import load_settings, Settings
+settings = load_settings()
+
+docs_handler = OpenAPIHandler(
+ info=Info(title=settings.info.title, version=settings.info.version),
+ anonymous_access=True,
+)
+
def configure_docs(app: Application, settings: Settings):
- docs = OpenAPIHandler(
- info=Info(title=settings.info.title, version=settings.info.version),
- anonymous_access=True,
- )
# include only endpoints whose path starts with "/api/"
- docs.include = lambda path, _: path.startswith("/api/")
+ docs_handler.include = lambda path, _: path.startswith("/api/")
- set_binders_docs(docs)
+ set_binders_docs(docs_handler)
- docs.bind_app(app)
+ docs_handler.bind_app(app)
我对这里的项目结构不是特别满意,说实话,我什至考虑过将该处理程序实例移至单独的模块并使其成为单例类。 但它应该能让您继续前进,并且您可以根据您认为合适的情况将其调整到您的实际用例。