Uh oh!
There was an error while loading. Please reload this page.
Replies: 2 comments
Example of code that thoes so: fromfastapiimportQuery, Path, HeaderimportinspectimporttypingfromtypingimportAnnotatedimportabcT=typing.TypeVar('T')
classRequestAttribute(abc.ABC, typing.Generic[T]):
...
classRequestHeader(RequestAttribute[T]):
...
defconvert_to_fastapi_annotations(func):
sig=inspect.signature(func)
new_params= []
forname, paraminsig.parameters.items():
annotation=param.annotation# Check if the annotation is RequestHeader[T]iftyping.get_origin(annotation) ==RequestHeader:
# Extract the type T from RequestHeader[T]inner_type=typing.get_args(annotation)[0]
# Replace with Annotated[T, Header()]new_annotation=Annotated[inner_type, Header()]
new_params.append(
inspect.Parameter(
name=name,
kind=param.kind,
default=param.default,
annotation=new_annotation
)
)
else:
# Keep other parameters unchangednew_params.append(param)
# Create a new signaturenew_sig=sig.replace(parameters=new_params)
# Update the function's signaturefunc.__signature__=new_sigreturnfunc@convert_to_fastapi_annotationsdefsome_function(x: RequestHeader[int], y: int) ->int:
returnx+ydefsome_function_fastapi(x: typing.Annotated[int, Header()], y: int) ->int:
returnx+y# Testingprint(inspect.signature(some_function))
print(inspect.signature(some_function_fastapi))
print(some_function(10, 12))output: |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
MotivationToday request attribute extraction is not done in the framework itself (bellow) but inside fastAPI. Request Attribute:Today request is done by passing extra attribute to the underline fastAPI decorator. fromfastapiimportHeaderfromtypingimportAnnotationimportuuid@Get("/")defget_somthing(id: Annotation[uuid.uuid4, Header()]) ->None:
...the code passing it to fastapi. defadd_route_to_router(router: APIRouter, method_function: callable) ->None:
"""Add the configured route to the router."""route_kwargs= {
"path": method_function.__route_path__,
"endpoint": method_function,
"methods": [method_function.__http_method__.value],
**method_function.__kwargs__,
}
ifhasattr(method_function, "status_code"):
route_kwargs["status_code"] =method_function.status_coderouter.add_api_route(**route_kwargs)By creating Request protocol inside the library we'll be able to deploy the package as plug&play while the underline engine can be swapped easier. A prime example is faststream and how same developer function can be Redis Broker or KafkaBroker with minimal codebase change. frompynestimportGet, Header, Response@Get("/")deffind_one_by_id(self, id: Header[uuid.uuid4]) ->Response[str,StatusCode[200]]:
print(id, category)
returnf`This action returns a #{id} cat with category of {category}`;NoteSame should be done for Route and Routing as Protocol which will map each one for the correct framework. |
Uh oh!
There was an error while loading. Please reload this page.
While reading NestJs docs I've stumble upon Request object that allow use attribute decorator to map attribute to request.
For example,
I would really be happy to see a use of this feature in PyNest.
Here is a description of couple of the features:
Path Param
can use regex with inspect module to validate all path param declared in route inside function signature
Query Param
Headers
Body
After reviewing the existing code I've notice a strong reliance of FastApi Router (I know I can use default implementation of FastAPI like Query, Headers).
By Providing an proxy types we can decoupling between PyNest and FastApi, Thus allowing usage of
other framework like Litestar, Blackship ....
Only by changing original function signature into desired one (like FastAPI or Lightstar).
All reactions