Last edited 2023-09-23 17:07:56.401859+00:00
You can add a query string parameter to your route via the query
decorator:
from view import new_app, query
app = new_app()
@app.get("/hello")
@query("name", str)
async def hello(name: str):
return p(f"Hello, {name}")
app.run()
The first argument is the name of the parameter in the query string, not the argument name, and the second argument is the type that it should take.
Bodies work the exact same way as queries, but with the body
decorator instead:
@app.get("/goodbye")
@body("name", str)
async def goodbye(name: str):
return p(f"Bye, {name}")
Warning
As of now, only bodies sent in JSON are supported.
In a case where you have direct access to your App
instance (i.e. in manual loading), you don't have to even use body
and query
, and instead use the app methods instead:
@app.get("/hello")
@app.query("name", str)
async def hello(name: str):
return f"hello, {name}"
app.query
and app.body
work exactly the same as @query
and @body
.
Path parameters are even simpler, just wrap a route part in brackets, like so:
@app.get("/hello/{name}")
async def hello(name: str):
return p(f"Your name is: {name}")
Now in the browser, if you were to go to /hello/world
, the name
parameter above would be world
.
Here's a more complicated example:
@app.get("/auth/{user_id}/something/{token}")
async def token(user_id: str, token: str):
# ...
return p("Successfully authorized!")
Danger
This is extremely buggy and not yet recommended for general use.
view.py will ensure that the type sent to the server is compatible with what you passed to the decorator. For example:
@app.get("/")
@query("number", int)
async def index(number: int):
# number will always be an int.
# if it isn't, an error 400 is sent back to the user automatically
return "..."
The following types are supported:
typing.Any
str
int
bool
float
dict
(or typing.Dict
)None
You can allow unions by just passing more parameters:
@app.get('/hello')
@query("name", str, None)
async def hello(name: str | None):
if not name:
return "hello world"
return f"hello {name}"
You can pass type arguments to a dict
, which are also validated by the server:
@app.get("/something")
@body("data", dict[str, int]) # typing.Dict on 3.8 and 3.9
async def something(data: dict[str, int]):
# data will always be a dictionary of strings and integers
return "..."
The key in a dictionary must always be str
(i.e. dict[int, str]
is not allowed), but the value can be any supported type (including other dictionaries!)