Skip to content

Commit 5f8e975

Browse files
Merge pull request #40 from ZeroIntensity/type-validation
Type Validation
2 parents 8ce6ef7 + 6dd3ccb commit 5f8e975

File tree

12 files changed

+683
-136
lines changed

12 files changed

+683
-136
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.0-alpha4] - 2023-09-10
9+
- Added type validation (without support for `__view_body__`)
10+
- Patched query strings on app testing
11+
- Added tests for query and body parameters
12+
- Patched body parameters
13+
- Documented type validation
14+
- Patched bodies with testing
15+
816
## [1.0.0-alpha3] - 2023-09-9
917
- Patched header responses
1018
- Added tests for headers

docs/parameters.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@ app.run()
1919

2020
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.
2121

22-
!!! danger
23-
24-
view.py has not yet implemented type checking on parameters
25-
2622
## Body
2723

28-
Bodies work the exact same way, but with the `body` decorator instead:
24+
Bodies work the exact same way as queries, but with the `body` decorator instead:
2925

3026
```py
3127
@app.get("/goodbye")
@@ -62,3 +58,51 @@ async def token(user_id: str, token: str):
6258
!!! danger
6359

6460
This is extremely buggy and not yet recommended for general use.
61+
62+
## Type Validation
63+
64+
view.py will ensure that the type sent to the server is compatible with what you passed to the decorator. For example:
65+
66+
```py
67+
@app.get("/")
68+
@query("number", int)
69+
async def index(number: int):
70+
# number will always be an int.
71+
# if it isn't, an error 400 is sent back to the user automatically
72+
return "..."
73+
```
74+
75+
The following types are supported:
76+
77+
- `typing.Any`
78+
- `str`
79+
- `int`
80+
- `bool`
81+
- `float`
82+
- `dict` (or `typing.Dict`)
83+
- `None`
84+
85+
You can allow unions by just passing more parameters:
86+
87+
```py
88+
@app.get('/hello')
89+
@query("name", str, None)
90+
async def hello(name: str | None):
91+
if not name:
92+
return "hello world"
93+
94+
return f"hello {name}"
95+
```
96+
97+
You can pass type arguments to a `dict`, which are also validated by the server:
98+
99+
```py
100+
@app.get("/something")
101+
@body("data", dict[str, int]) # typing.Dict on 3.8 and 3.9
102+
async def something(data: dict[str, int]):
103+
# data will always be a dictionary of strings and integers
104+
return "..."
105+
```
106+
107+
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!)
108+

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
data = toml.load(f)
1212
setup(
1313
name="view.py",
14-
version="1.0.0-alpha3",
14+
version="1.0.0-alpha4",
1515
packages=["view"],
1616
project_urls=data["project"]["urls"],
1717
package_dir={"": "src"},

0 commit comments

Comments
 (0)