flask-jeroboam


Nameflask-jeroboam JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryA Flask extension, inspired by FastAPI that uses Pydantic to provide easy-to-configure data validation for request parsing and response serialization.
upload_time2025-01-17 13:28:38
maintainerNone
docs_urlNone
authorJean-Christophe Bianic
requires_python>=3.9
licenseMIT
keywords flask pydantic validation serialization
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">
    <img
        src="https://github.com/jcbianic/flask-jeroboam/blob/main/docs/_static/img/jeroboam_logo_with_text.png"
        width="400px"
        alt="jeroboam-logo">
    </img>
</div>
<h1 align="center">Flask-Jeroboam</h1>

<div align="center">

<i>Flask-Jeroboam is a Flask extension modelled after FastAPI. It uses Pydantic to provide easy-to-configure data validation in request parsing and response serialization.</i>

[![PyPI](https://img.shields.io/pypi/v/flask-jeroboam.svg)][pypi_]
[![Python Version](https://img.shields.io/pypi/pyversions/flask-jeroboam)][python version]
[![License](https://img.shields.io/github/license/jcbianic/flask-jeroboam?color=green)][license]
[![Commit](https://img.shields.io/github/last-commit/jcbianic/flask-jeroboam?color=green)][commit]

[![Read the documentation at https://flask-jeroboam.readthedocs.io/](https://img.shields.io/readthedocs/flask-jeroboam/latest.svg?label=Read%20the%20Docs)][read the docs]
[![Maintainability](https://api.codeclimate.com/v1/badges/181b7355cee7b1316893/maintainability)](https://img.shields.io/codeclimate/maintainability/jcbianic/flask-jeroboam?color=green)
[![Test Coverage](https://api.codeclimate.com/v1/badges/181b7355cee7b1316893/test_coverage)](https://img.shields.io/codeclimate/coverage/jcbianic/flask-jeroboam?color=green)
[![Tests](https://github.com/jcbianic/flask-jeroboam/workflows/Tests/badge.svg)][tests]
[![Black](https://img.shields.io/badge/code%20style-black-000000.svg)][black]

[pypi_]: https://pypi.org/project/flask-jeroboam/
[status]: https://pypi.org/project/flask-jeroboam/
[python version]: https://pypi.org/project/flask-jeroboam
[read the docs]: https://flask-jeroboam.readthedocs.io/
[tests]: https://github.com/jcbianic/flask-jeroboam/actions?workflow=Tests
[codecov]: https://app.codecov.io/gh/jcbianic/flask-jeroboam
[pre-commit]: https://github.com/pre-commit/pre-commit
[black]: https://github.com/psf/black
[commit]: https://img.shields.io/github/last-commit/jcbianic/flask-jeroboam

</div>

---

**Documentation**: [https://flask-jeroboam.readthedocs.io/](https://flask-jeroboam.readthedocs.io/)

**Source Code**: [https://github.com/jcbianic/flask-jeroboam](https://github.com/jcbianic/flask-jeroboam)

---

Flask-Jeroboam is a thin layer on top of Flask to make request parsing, response serialization and auto-documentation as smooth and easy as in FastAPI.

Its main features are:

- Request parsing based on typed annotations of endpoint arguments
- Response serialization facilitation
- (Planned) OpenAPI auto-Documentation based on the first two

## How to install

You can install _flask-jeroboam_ via [pip] or any other tool wired to [PyPI]:

```console
$ pip install flask-jeroboam
```

## How to use

### A toy example

_Flask-Jeroboam_ subclasses both Flask and Blueprint classes. This means that the **Jeroboam** and **Blueprint** will behave exactly like their Flask counterparts unless you activate their specific behaviours.

```python
from flask_jeroboam import Jeroboam

app = Jeroboam()

@app.get("/ping")
def ping():
    return "pong"

if __name__ == "__main__":
    app.run()
```

This toy example would work exactly like a regular Flask app. If you run this file, then hitting the endpoint with `curl localhost:5000/ping` would return the text response `pong`.

Let's try a more significant and relevant example and build a simplified endpoint to retrieve a list of wines. We are wine-themed, after all.

### Searching for wines

Let's consider an endpoint that provides search capability onto a wine repository. It parses and validates three arguments from the query string and feeds them into a CRUD function `get_wines` that return a list of wines as dictionnaries.
Additionally, this endpoint only needs to return the name of the cuvee and the appellation, and discard any other informations. Let's take a look at what it might look like:

```python
from flask_jeroboam import Jeroboam, InboundModel, OutboundModel
from pydantic.fields import Field
from typing import List, Optional
from docs_src.readme.crud import get_wines

app = Jeroboam(__name__)


class GenericPagination(InboundModel):
    page: int = Field(1, ge=1)
    per_page: int = Field(10, ge=1, le=100)

    @property
    def offset(self) -> int:
        return (self.page - 1) * self.per_page


class WineOut(OutboundModel):
    cuvee: str
    appellation: str


@app.get("/wines", response_model=List[WineOut])
def read_wine_list(pagination: GenericPagination, search: Optional[str]):
    wines = get_wines(pagination, search)
    return wines


if __name__ == "__main__":
    app.run()
```

Once you've started your server, then hitting the endpoint with `curl "localhost:5000/wines?page=1&perPage=2&search=Champagne"` would return:

```json
[
  {
    "cuvee": "Brut - Blanc de Blancs",
    "appellation": "Champagne"
  },
  {
    "cuvee": "Grande Cuvée - 170ème Edition",
    "appellation": "Champagne"
  }
]
```

All examples in the documentation can be found in `docs_src/X` folder and should run as is. Their corresponding tests can be found in `tests/test_docs/X`.

See the documentation on more advanced usage: [https://flask-jeroboam.readthedocs.io/](https://flask-jeroboam.readthedocs.io/)

## Motivation

I just wanted to use **FastAPI's way** of defining view arguments and response models without leaving Flask.

## A word on performance

One thing **Flask-Jeroboam** won't give you is performance improvement. Underneath Flask, werkzeug still handles the heavy lifting of a wsgi, so transitioning to **Flask-Jeroboam** won't speed up your app. Please remember that FastAPI's performance comes from Starlette, not FastAPI itself.

## Intended audience

The intended audience of **Flask-Jeroboam** is Flask developers who find FastAPI very convincing but also have excellent reasons to stick to Flask.

## About the name of the project

A **Jeroboam** is a large bottle, or flask, containing 5 litres of wine[^1], instead of 0,75. Winemakers use this format for fine wines destined for ageing because it provides better ageing conditions. First, the ratio between the volume of wine it contains and the surface of exchange between the wine and the air is more favourable and slows down the oxidation reaction. These larger containers also take longer to cool down or warm up, leading to less thermal violence to the wine during conservation.

In other words, they are more durable flasks for fine wines. The intention is to hold this promise for APIs.

The wine-themed name is a tribute to the Bordeaux-based wine tech startup where the development of this package started.

[^1]: Outside of the Bordeaux region Jeroboam bottle contain 3 litres, like in Burgundy or Champagne.

## License

Distributed under the terms of the [MIT license][license], **Flask-Jeroboam** is free and open-source software.

## Issues

If you encounter any problems, please [file an issue] following available templates. Templates are available for feature requests, bug reports, documentation updates and implementation betterments.

## Credits

The main inspiration for this project comes from [@tiangolo]'s [FastAPI].
Starting from v0.1.0 it also includes forked code from [FastAPI].
Appropriate credits are added to the module or functions docstrings.

[Flask] and [pydantic] are the two direct dependencies and do most of the work.

I used [@cjolowicz]'s [Hypermodern Python Cookiecutter] template to generate this project.

[@cjolowicz]: https://github.com/cjolowicz
[@tiangolo]: https://github.com/tiangolo
[fastapi]: https://fastapi.tiangolo.com/
[starlette]: https://www.starlette.io/
[flask]: https://flask.palletsprojects.com/
[pydantic]: https://pydantic-docs.helpmanual.io/
[pypi]: https://pypi.org/
[hypermodern python cookiecutter]: https://github.com/cjolowicz/cookiecutter-hypermodern-python
[file an issue]: https://github.com/jcbianic/flask-jeroboam/issues
[pip]: https://pip.pypa.io/

<!-- github-only -->

[license]: https://github.com/jcbianic/flask-jeroboam/blob/main/LICENSE
[contributor guide]: https://github.com/jcbianic/flask-jeroboam/blob/main/CONTRIBUTING.md
[command-line reference]: https://flask-jeroboam.readthedocs.io/en/latest/usage.html


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "flask-jeroboam",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "flask, pydantic, validation, serialization",
    "author": "Jean-Christophe Bianic",
    "author_email": "jc.bianic@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/40/ab/402ac251d594e1592b12bed5eea5c52cd1fdc12d78a16328a141ba1f99db/flask_jeroboam-0.1.1.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n    <img\n        src=\"https://github.com/jcbianic/flask-jeroboam/blob/main/docs/_static/img/jeroboam_logo_with_text.png\"\n        width=\"400px\"\n        alt=\"jeroboam-logo\">\n    </img>\n</div>\n<h1 align=\"center\">Flask-Jeroboam</h1>\n\n<div align=\"center\">\n\n<i>Flask-Jeroboam is a Flask extension modelled after FastAPI. It uses Pydantic to provide easy-to-configure data validation in request parsing and response serialization.</i>\n\n[![PyPI](https://img.shields.io/pypi/v/flask-jeroboam.svg)][pypi_]\n[![Python Version](https://img.shields.io/pypi/pyversions/flask-jeroboam)][python version]\n[![License](https://img.shields.io/github/license/jcbianic/flask-jeroboam?color=green)][license]\n[![Commit](https://img.shields.io/github/last-commit/jcbianic/flask-jeroboam?color=green)][commit]\n\n[![Read the documentation at https://flask-jeroboam.readthedocs.io/](https://img.shields.io/readthedocs/flask-jeroboam/latest.svg?label=Read%20the%20Docs)][read the docs]\n[![Maintainability](https://api.codeclimate.com/v1/badges/181b7355cee7b1316893/maintainability)](https://img.shields.io/codeclimate/maintainability/jcbianic/flask-jeroboam?color=green)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/181b7355cee7b1316893/test_coverage)](https://img.shields.io/codeclimate/coverage/jcbianic/flask-jeroboam?color=green)\n[![Tests](https://github.com/jcbianic/flask-jeroboam/workflows/Tests/badge.svg)][tests]\n[![Black](https://img.shields.io/badge/code%20style-black-000000.svg)][black]\n\n[pypi_]: https://pypi.org/project/flask-jeroboam/\n[status]: https://pypi.org/project/flask-jeroboam/\n[python version]: https://pypi.org/project/flask-jeroboam\n[read the docs]: https://flask-jeroboam.readthedocs.io/\n[tests]: https://github.com/jcbianic/flask-jeroboam/actions?workflow=Tests\n[codecov]: https://app.codecov.io/gh/jcbianic/flask-jeroboam\n[pre-commit]: https://github.com/pre-commit/pre-commit\n[black]: https://github.com/psf/black\n[commit]: https://img.shields.io/github/last-commit/jcbianic/flask-jeroboam\n\n</div>\n\n---\n\n**Documentation**: [https://flask-jeroboam.readthedocs.io/](https://flask-jeroboam.readthedocs.io/)\n\n**Source Code**: [https://github.com/jcbianic/flask-jeroboam](https://github.com/jcbianic/flask-jeroboam)\n\n---\n\nFlask-Jeroboam is a thin layer on top of Flask to make request parsing, response serialization and auto-documentation as smooth and easy as in FastAPI.\n\nIts main features are:\n\n- Request parsing based on typed annotations of endpoint arguments\n- Response serialization facilitation\n- (Planned) OpenAPI auto-Documentation based on the first two\n\n## How to install\n\nYou can install _flask-jeroboam_ via [pip] or any other tool wired to [PyPI]:\n\n```console\n$ pip install flask-jeroboam\n```\n\n## How to use\n\n### A toy example\n\n_Flask-Jeroboam_ subclasses both Flask and Blueprint classes. This means that the **Jeroboam** and **Blueprint** will behave exactly like their Flask counterparts unless you activate their specific behaviours.\n\n```python\nfrom flask_jeroboam import Jeroboam\n\napp = Jeroboam()\n\n@app.get(\"/ping\")\ndef ping():\n    return \"pong\"\n\nif __name__ == \"__main__\":\n    app.run()\n```\n\nThis toy example would work exactly like a regular Flask app. If you run this file, then hitting the endpoint with `curl localhost:5000/ping` would return the text response `pong`.\n\nLet's try a more significant and relevant example and build a simplified endpoint to retrieve a list of wines. We are wine-themed, after all.\n\n### Searching for wines\n\nLet's consider an endpoint that provides search capability onto a wine repository. It parses and validates three arguments from the query string and feeds them into a CRUD function `get_wines` that return a list of wines as dictionnaries.\nAdditionally, this endpoint only needs to return the name of the cuvee and the appellation, and discard any other informations. Let's take a look at what it might look like:\n\n```python\nfrom flask_jeroboam import Jeroboam, InboundModel, OutboundModel\nfrom pydantic.fields import Field\nfrom typing import List, Optional\nfrom docs_src.readme.crud import get_wines\n\napp = Jeroboam(__name__)\n\n\nclass GenericPagination(InboundModel):\n    page: int = Field(1, ge=1)\n    per_page: int = Field(10, ge=1, le=100)\n\n    @property\n    def offset(self) -> int:\n        return (self.page - 1) * self.per_page\n\n\nclass WineOut(OutboundModel):\n    cuvee: str\n    appellation: str\n\n\n@app.get(\"/wines\", response_model=List[WineOut])\ndef read_wine_list(pagination: GenericPagination, search: Optional[str]):\n    wines = get_wines(pagination, search)\n    return wines\n\n\nif __name__ == \"__main__\":\n    app.run()\n```\n\nOnce you've started your server, then hitting the endpoint with `curl \"localhost:5000/wines?page=1&perPage=2&search=Champagne\"` would return:\n\n```json\n[\n  {\n    \"cuvee\": \"Brut - Blanc de Blancs\",\n    \"appellation\": \"Champagne\"\n  },\n  {\n    \"cuvee\": \"Grande Cuv\u00e9e - 170\u00e8me Edition\",\n    \"appellation\": \"Champagne\"\n  }\n]\n```\n\nAll examples in the documentation can be found in `docs_src/X` folder and should run as is. Their corresponding tests can be found in `tests/test_docs/X`.\n\nSee the documentation on more advanced usage: [https://flask-jeroboam.readthedocs.io/](https://flask-jeroboam.readthedocs.io/)\n\n## Motivation\n\nI just wanted to use **FastAPI's way** of defining view arguments and response models without leaving Flask.\n\n## A word on performance\n\nOne thing **Flask-Jeroboam** won't give you is performance improvement. Underneath Flask, werkzeug still handles the heavy lifting of a wsgi, so transitioning to **Flask-Jeroboam** won't speed up your app. Please remember that FastAPI's performance comes from Starlette, not FastAPI itself.\n\n## Intended audience\n\nThe intended audience of **Flask-Jeroboam** is Flask developers who find FastAPI very convincing but also have excellent reasons to stick to Flask.\n\n## About the name of the project\n\nA **Jeroboam** is a large bottle, or flask, containing 5 litres of wine[^1], instead of 0,75. Winemakers use this format for fine wines destined for ageing because it provides better ageing conditions. First, the ratio between the volume of wine it contains and the surface of exchange between the wine and the air is more favourable and slows down the oxidation reaction. These larger containers also take longer to cool down or warm up, leading to less thermal violence to the wine during conservation.\n\nIn other words, they are more durable flasks for fine wines. The intention is to hold this promise for APIs.\n\nThe wine-themed name is a tribute to the Bordeaux-based wine tech startup where the development of this package started.\n\n[^1]: Outside of the Bordeaux region Jeroboam bottle contain 3 litres, like in Burgundy or Champagne.\n\n## License\n\nDistributed under the terms of the [MIT license][license], **Flask-Jeroboam** is free and open-source software.\n\n## Issues\n\nIf you encounter any problems, please [file an issue] following available templates. Templates are available for feature requests, bug reports, documentation updates and implementation betterments.\n\n## Credits\n\nThe main inspiration for this project comes from [@tiangolo]'s [FastAPI].\nStarting from v0.1.0 it also includes forked code from [FastAPI].\nAppropriate credits are added to the module or functions docstrings.\n\n[Flask] and [pydantic] are the two direct dependencies and do most of the work.\n\nI used [@cjolowicz]'s [Hypermodern Python Cookiecutter] template to generate this project.\n\n[@cjolowicz]: https://github.com/cjolowicz\n[@tiangolo]: https://github.com/tiangolo\n[fastapi]: https://fastapi.tiangolo.com/\n[starlette]: https://www.starlette.io/\n[flask]: https://flask.palletsprojects.com/\n[pydantic]: https://pydantic-docs.helpmanual.io/\n[pypi]: https://pypi.org/\n[hypermodern python cookiecutter]: https://github.com/cjolowicz/cookiecutter-hypermodern-python\n[file an issue]: https://github.com/jcbianic/flask-jeroboam/issues\n[pip]: https://pip.pypa.io/\n\n<!-- github-only -->\n\n[license]: https://github.com/jcbianic/flask-jeroboam/blob/main/LICENSE\n[contributor guide]: https://github.com/jcbianic/flask-jeroboam/blob/main/CONTRIBUTING.md\n[command-line reference]: https://flask-jeroboam.readthedocs.io/en/latest/usage.html\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Flask extension, inspired by FastAPI that uses Pydantic to provide easy-to-configure data validation for request parsing and response serialization.",
    "version": "0.1.1",
    "project_urls": {
        "Documentation": "https://flask-jeroboam.readthedocs.io",
        "Homepage": "https://github.com/jcbianic/flask-jeroboam",
        "Repository": "https://github.com/jcbianic/flask-jeroboam"
    },
    "split_keywords": [
        "flask",
        " pydantic",
        " validation",
        " serialization"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c10ec6a818886709047687ec16516b8b79cfbbb4c92d039816f39dbbacd0ccdb",
                "md5": "0f635cc6b17bd48d283a3a38e5313687",
                "sha256": "d1c5763a13835cfb7d457f9b32c6b491bc3d8ad6b85741c491d34474e36d78dc"
            },
            "downloads": -1,
            "filename": "flask_jeroboam-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0f635cc6b17bd48d283a3a38e5313687",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 43163,
            "upload_time": "2025-01-17T13:28:36",
            "upload_time_iso_8601": "2025-01-17T13:28:36.076894Z",
            "url": "https://files.pythonhosted.org/packages/c1/0e/c6a818886709047687ec16516b8b79cfbbb4c92d039816f39dbbacd0ccdb/flask_jeroboam-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "40ab402ac251d594e1592b12bed5eea5c52cd1fdc12d78a16328a141ba1f99db",
                "md5": "af6fe45acb66fbaf4a3c3b4ab357049e",
                "sha256": "52a1d22a2d9e03d82cac70bc3090111be7966b315c54eb1848b748327d736c89"
            },
            "downloads": -1,
            "filename": "flask_jeroboam-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "af6fe45acb66fbaf4a3c3b4ab357049e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 33860,
            "upload_time": "2025-01-17T13:28:38",
            "upload_time_iso_8601": "2025-01-17T13:28:38.483443Z",
            "url": "https://files.pythonhosted.org/packages/40/ab/402ac251d594e1592b12bed5eea5c52cd1fdc12d78a16328a141ba1f99db/flask_jeroboam-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-17 13:28:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jcbianic",
    "github_project": "flask-jeroboam",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "flask-jeroboam"
}
        
Elapsed time: 3.46840s