[QUESTION] How do I use a string-formatted BaseModel as a path param?
See original GitHub issueExample
from fastapi import FastAPI
from pydantic import BaseModel
class Multihash(BaseModel):
func: int
digest: bytes
class MultihashHex(Multihash):
@classmethod
def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
field_schema.update({"type": "string", "format": "multihash-hex"})
@classmethod
def __get_validators__(cls) -> Iterator[Callable[..., Any]]:
yield cls.validate
@classmethod
def validate(cls, value: Union[str, bytes]) -> Multihash:
if isinstance(value, str):
value = bytes.fromhex(value)
return Multihash(...)
app = FastAPI()
@app.get("/data/{mh}")
def read(mh:MultihashHex):
return ...
Description
When I run the above, I get:
$ uvicorn test:app
...
File "./test.py", line 32, in <module>
def read(mh:MultihashHex):
File "/home/amnesia/Persistent/venv/lib/python3.7/site-packages/fastapi/routing.py", line 574, in decorator
callbacks=callbacks,
File "/home/amnesia/Persistent/venv/lib/python3.7/site-packages/fastapi/routing.py", line 520, in add_api_route
callbacks=current_callbacks,
File "/home/amnesia/Persistent/venv/lib/python3.7/site-packages/fastapi/routing.py", line 380, in __init__
self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
File "/home/amnesia/Persistent/venv/lib/python3.7/site-packages/fastapi/dependencies/utils.py", line 308, in get_dependant
), "Path params must be of one of the supported types"
AssertionError: Path params must be of one of the supported types
I’m building an app that vends content-addressable data. I’d like to use a multihash as a path param. Multihash is just a (hash-function, hash-digest) tuple, with well-defined encoding.
My intent is to have my path param be a hexadecimal multihash, and use the Multihash
type internally. There seem to be other examples of string-representable objects, like NameEmail
or IPv4Address
.
But, I can’t seem to make my Multihash
class be a BaseModel
. I get the above error.
I can make Multihash
a base object
instead, but I lose pydantic features.
Is it an error that BaseModel
objects can’t be used this way, or is there a better way to do what I’m doing?
Environment
- OS: tails 4.17
- python: 3.7.3
- packages:
fastapi==0.63.0
pydantic==1.8.1
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:5
Top Results From Across the Web
How to pass the path parameter to the Pydantic model?
Pydantic in FastAPI is used to define data model. You can do as follows: from typing import Optional from fastapi import FastAPI from...
Read more >Vincit/objection.js - Gitter
is there a way to use modify on a relation definition to filter on something that's relevant to the originating object? Basically, I'd...
Read more >What is the String.format() method in Java? - Educative.io
The Java String.format() method returns the formatted string by a given locale, format, and argument. If the locale is not specified in the...
Read more >Body - Nested Models - FastAPI
To declare types that have type parameters (internal types), like list , dict , tuple : If you are in a Python version...
Read more >Parse JSON-encoded query strings in FastAPI
Can I turn complex parameters in the query string into Pydantic models? class Quarter(BaseModel): q: int year: int @app.get("/api/v1/chart") ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Reading that:
Reading it in order, I thought it says plainly that if a parameter is declared in the path then it’s used as a path parameter, even if it’s a
BaseModel
.If it intends to say that “
BaseModel
s will always be interpreted as request body”, then… I feel it should be written differently 😃I know
is_scalar_field
is part of the stack that blocks this usage. But surely an undocumented utility function is not ground truth for APIs or intentExtending my example from above:
Pydantic lets me parse a string field into a
BaseModel
just fine, so I expect to be able to parse a path parameter into aBaseModel
as well. The two seem perfectly analogous to meCame to the exact same issue when I wanted to provide a path parameter which is an object with several keys. As mentioned previously, a test in source code prevent us from being able to provide something else than scalars as path parameters…
However, the OpenAPI specification currently allow and define a way to document path parameters as objects or arrays thanks to
schema
,style
andexplode
properties of path parameter objects, see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-objectIMO, It could be interesting to implement such a thing