Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/boardpack/reforms

Reforms is a fresh pydantic-based forms validation and rendering library for Python 3.6+.
https://github.com/boardpack/reforms

form forms html package pydantic pypi python validation

Last synced: about 1 month ago
JSON representation

Reforms is a fresh pydantic-based forms validation and rendering library for Python 3.6+.

Awesome Lists containing this project

README

        


Reforms



Test


Coverage


Package version

Code style: black
Imports: isort

CURRENTLY, LIBRARY ISN'T UNDER ACTIVE DEVELOPMENT!

---

**Documentation**: https://reforms.boardpack.org

**Source Code**: https://github.com/boardpack/reforms

---

Reforms is a fresh pydantic-based forms validation and rendering library for Python 3.6+.

The key features are:

* **Familiar**: Expanded Pydantic retaining all data validation and model creation
capabilities.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Theming**: Supported the usage of existing template pack and the creation of your
own.

## Requirements

Python 3.6+

Reforms has the next hard dependencies:

* Pydantic for the data parts.
* Jinja2 for the templates.

## Installation

```console
$ pip install git+http://github.com/boardpack/reforms

---> 100%
```

## Example

In the next example, we will use FastAPI
as a web framework. So you need to install `fastapi` and `uvicorn` first. Also, you
need to install `python-multipart` library to turn on forms support in FastAPI.

```console
$ pip install fastapi uvicorn python-multipart

---> 100%
```

### Create it

* Create a file `models.py` with `UserModel` pydantic model:

```Python
from pydantic import BaseModel

from reforms import StringField, BooleanField, EmailField
from reforms.validators import Length

class UserModel(BaseModel):
first_name: StringField(
label="First Name",
field_id="firstName",
placeholder="John",
validators=[Length(min=5)],
)
last_name: StringField(
label="Last Name",
field_id="lastName",
placeholder="Doe",
validators=[Length(min=5)],
)
email: EmailField(
label="Email",
field_id="email",
placeholder="[email protected]",
)
has_github: BooleanField(label="Has Github account?", field_id="hasGithub") = False

```
_(This script is complete, it should run "as is")_

* Then you can create a FastAPI application and use this model to generate form
layout and validate data. Reforms has special `on_model` function, which works
with `Depends` from FastAPI to convert raw form data into pydantic model object.
Create a file `main.py` with:

```Python hl_lines="8 19 23 28"
import uvicorn
from fastapi import FastAPI, Request, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from starlette.status import HTTP_302_FOUND
from reforms import Reforms, on_model

from models import UserModel

app = FastAPI()

forms = Reforms(package="reforms")

templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
user_form = forms.Form(UserModel)

return templates.TemplateResponse(
"index.html",
{"request": request, "form": user_form},
)

@app.post("/", response_class=RedirectResponse)
async def handle_form(form: UserModel = Depends(on_model(UserModel))):
print(form)
return RedirectResponse("/", status_code=HTTP_302_FOUND)

if __name__ == '__main__':
uvicorn.run(app)

```
_(This script is complete, it should run "as is")_

* As the last coding step, you need to create a template (now **reforms** supports only
**jinja2** templates). You can use just form object to render all fields
simultaneously or render every field separately (as it mentions in the selected
commented line).

```HTML hl_lines="10"



Example reforms page



{{ form }}
{#{{ form.first_name }}#}




```
_(This template is complete, it should use "as is")_

### Run it

Run the server with:

```console
$ uvicorn main:app --reload

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```

About the command uvicorn main:app --reload...

The command `uvicorn main:app` refers to:

* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
* `--reload`: make the server restart after code changes. Only do this for development.

or just with:

```console
$ python main.py

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```

### Send it

Open your browser at http://127.0.0.1:8000.

You will see the web form:

![Example form](docs/en/docs/img/index/index-01-web-form.png)

Add some information like this and click "Send" button:

![Passed example form](docs/en/docs/img/index/index-02-web-form-passed.png)

### Check it

Finally, you can see a printed validated model object in your console:

```bash hl_lines="8"
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.

INFO: 127.0.0.1:33612 - "GET / HTTP/1.1" 200 OK
first_name='Roman' last_name='Dukkee' email='[email protected]' has_github=True
INFO: 127.0.0.1:33872 - "POST / HTTP/1.1" 302 Found
INFO: 127.0.0.1:33872 - "GET / HTTP/1.1" 200 OK
```

## Acknowledgments

Special thanks to:

* [Sebastián Ramírez](https://github.com/tiangolo) and his [FastAPI](https://github.com/tiangolo/fastapi) project, some scripts and documentation structure and parts were used from there.

* [Samuel Colvin](https://github.com/samuelcolvin) and his [Pydantic](https://github.com/samuelcolvin/pydantic/) project.

## License

This project is licensed under the terms of the MIT license.