Question: Use blacksheep create with the following options to create an example API: ✨ Project name: soquestion 🚀 Project template: api 🤖 Use controllers? Yes 📜 Use OpenAPI Documentation? Yes 🔧 Library to read settings essentials-configuration 🔩 App settings format YAML  This will generate a simple API based on BlackSheep, with the endpoints defined in 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. """  When you start the API (don't forget to create and activate a virtual environment before you do the pip install ...) with python dev.py and navigate to http://localhost:44777/docs you can see the OpenAPI documentation. According to the documentation you can use the docstring to specify the endpoint description. Is it somehow possible to also add documentation for the responses? According to the documentation you can use the @docs decorator, but that only works in a simple file where @docs is defined beforehand. In the generated API @docs is defined in app/docs/__init.py__, but I can't find a way to use this inside the example.py. The generated app/docs/__init.py__ looks like this: """ 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) 

Answer: Given how documentation handler is defined in BlackSheep example, you cannot easily use that particular instance. The reason being docs is local to configure_docs function, therefore it cannot be used outside of it. However, that documentation decorator is simply an instance of OpenAPIHandler class, so you can move its definition outside of that function, and use it throughout your project freely. Here's a "patch" for the example project to show the naïve approach (sorry, but SO doesn't support patch/diff syntax highlight) with docs renamed to docs_handler to better distinguish it from app.docs module: 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)  I am not particularly happy about project structure here, to be honest, I even thought about moving that handler instance to a separate module and making it a singleton class. But it should get you going, and you can adapt it to you real use-case as you see fit.