Coverage for opt/mealie/lib/python3.12/site-packages/mealie/schema/make_dependable.py: 61%
16 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 17:29 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 17:29 +0000
1from inspect import signature 1a
3from fastapi.exceptions import HTTPException, RequestValidationError 1a
4from pydantic import ValidationError 1a
7def format_exception(ex: Exception) -> str: 1a
8 return f"{ex.__class__.__name__}: {ex}"
11def make_dependable(cls): 1a
12 """
13 Pydantic BaseModels are very powerful because we get lots of validations and type checking right out of the box.
14 FastAPI can accept a BaseModel as a route Dependency and it will automatically handle things like documentation
15 and error handling. However, if we define custom validators then the errors they raise are not handled, leading
16 to HTTP 500's being returned.
18 To better understand this issue, you can visit https://github.com/tiangolo/fastapi/issues/1474 for context.
20 A workaround proposed there adds a classmethod which attempts to init the BaseModel and handles formatting of
21 any raised ValidationErrors, custom or otherwise. However, this means essentially duplicating the class's
22 signature. This function automates the creation of a workaround method with a matching signature so that you
23 can avoid code duplication.
25 usage:
26 async def fetch(thing_request: ThingRequest = Depends(make_dependable(ThingRequest))):
27 """
29 def init_cls_and_handle_errors(*args, **kwargs): 1a
30 try:
31 signature(init_cls_and_handle_errors).bind(*args, **kwargs)
32 return cls(*args, **kwargs)
33 except (ValidationError, RequestValidationError) as e:
34 for error in e.errors():
35 error["loc"] = ["query", *list(error["loc"])]
36 raise HTTPException(422, detail=[format_exception(ex) for ex in e.errors()]) from None
38 init_cls_and_handle_errors.__signature__ = signature(cls) 1a
39 return init_cls_and_handle_errors 1a