Skip to content

Commit

Permalink
Merge pull request #40 from ZeroIntensity/type-validation
Browse files Browse the repository at this point in the history
Type Validation
  • Loading branch information
ZeroIntensity authored Sep 10, 2023
2 parents 8ce6ef7 + 6dd3ccb commit 5f8e975
Show file tree
Hide file tree
Showing 12 changed files with 683 additions and 136 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0-alpha4] - 2023-09-10
- Added type validation (without support for `__view_body__`)
- Patched query strings on app testing
- Added tests for query and body parameters
- Patched body parameters
- Documented type validation
- Patched bodies with testing

## [1.0.0-alpha3] - 2023-09-9
- Patched header responses
- Added tests for headers
Expand Down
54 changes: 49 additions & 5 deletions docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@ 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.

!!! danger

view.py has not yet implemented type checking on parameters

## Body

Bodies work the exact same way, but with the `body` decorator instead:
Bodies work the exact same way as queries, but with the `body` decorator instead:

```py
@app.get("/goodbye")
Expand Down Expand Up @@ -62,3 +58,51 @@ async def token(user_id: str, token: str):
!!! danger

This is extremely buggy and not yet recommended for general use.

## Type Validation

view.py will ensure that the type sent to the server is compatible with what you passed to the decorator. For example:

```py
@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:

```py
@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:

```py
@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!)

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
data = toml.load(f)
setup(
name="view.py",
version="1.0.0-alpha3",
version="1.0.0-alpha4",
packages=["view"],
project_urls=data["project"]["urls"],
package_dir={"": "src"},
Expand Down
Loading

0 comments on commit 5f8e975

Please sign in to comment.