airtai / faststream

FastStream is a powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ, NATS and Redis.
https://faststream.airt.ai/latest/
Apache License 2.0
2.55k stars 129 forks source link

feature: document RPC responses in AsyncAPI #1586

Open Lancetnik opened 3 months ago

Lancetnik commented 3 months ago

Discussed in https://github.com/airtai/faststream/discussions/1570

Originally posted by **gri38** July 1, 2024 Hello. When we subscribe to a queue to answer a RPC call, it seems we cannot document the return type. H§ere a small exemple: ```python import logging from faststream import FastStream from faststream.rabbit import RabbitBroker from pydantic import BaseModel, conint broker = RabbitBroker() app = FastStream(broker) class In(BaseModel): i: str j: conint(gt=0) class Out(BaseModel): k: str l: float @broker.subscriber("RPC", title="RPC", description="This queue is used to for RPC", ) async def rpc_handler(input: In) -> Out: logging.info(f"{input=}") return Out(k=input.i, l=input.j) ``` If I run with `faststream docs serve rpc:app` I cannot see Out in the doc (http://localhost:8000). Is there a way to do so ? When I use the RabbitRouter, I can see in the router @subscriber decorator: ```python # FastAPI args response_model: Annotated[ Any, Doc( """ The type to use for the response. It could be any valid Pydantic *field* type. So, it doesn't have to be a Pydantic model, it could be other things, like a `list`, `dict`, etc. It will be used for: * Documentation: the generated OpenAPI (and the UI at `/docs`) will show it as the response (JSON Schema). * Serialization: you could return an arbitrary object and the `response_model` would be used to serialize that object into the corresponding JSON. * Filtering: the JSON sent to the client will only contain the data (fields) defined in the `response_model`. If you returned an object that contains an attribute `password` but the `response_model` does not include that field, the JSON sent to the client would not have that `password`. * Validation: whatever you return will be serialized with the `response_model`, converting any data as necessary to generate the corresponding JSON. But if the data in the object returned is not valid, that would mean a violation of the contract with the client, so it's an error from the API developer. So, FastAPI will raise an error and return a 500 error code (Internal Server Error). Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). """ ), ``` But even with response_model: nothing in asyncAPI. Thanks for any tips, even for "it's not possible" ;-)
Lancetnik commented 3 months ago

This is the good point. I think, we should document RPC responses if subscriber has no no_reply=False option

AsyncAPI 3.0 has a special syntax for that case, but I can't find AsyncAPI 2.6.0 example to figure out how it should looks like