Replies: 2 comments
-
Example of code that thoes so: from fastapi import Query, Path, Header
import inspect
import typing
from typing import Annotated
import abc
T = typing.TypeVar('T')
class RequestAttribute(abc.ABC, typing.Generic[T]):
...
class RequestHeader(RequestAttribute[T]):
...
def convert_to_fastapi_annotations(func):
sig = inspect.signature(func)
new_params = []
for name, param in sig.parameters.items():
annotation = param.annotation
# Check if the annotation is RequestHeader[T]
if typing.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 unchanged
new_params.append(param)
# Create a new signature
new_sig = sig.replace(parameters=new_params)
# Update the function's signature
func.__signature__ = new_sig
return func
@convert_to_fastapi_annotations
def some_function(x: RequestHeader[int], y: int) -> int:
return x + y
def some_function_fastapi(x: typing.Annotated[int, Header()], y: int) -> int:
return x + y
# Testing
print(inspect.signature(some_function))
print(inspect.signature(some_function_fastapi))
print(some_function(10, 12)) output:
|
Beta Was this translation helpful? Give feedback.
-
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. from fastapi import Header
from typing import Annotation
import uuid
@Get("/")
def get_somthing(id: Annotation[uuid.uuid4, Header()]) -> None:
... the code passing it to fastapi. def add_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__,
}
if hasattr(method_function, "status_code"):
route_kwargs["status_code"] = method_function.status_code
router.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. from pynest import Get, Header, Response
@Get("/")
def find_one_by_id(self, id: Header[uuid.uuid4]) -> Response[str,StatusCode[200]]:
print(id, category)
return f`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. |
Beta Was this translation helpful? Give feedback.
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).
Beta Was this translation helpful? Give feedback.
All reactions