Skip to main content

Fancy toolkit for Starlette

Project description

Starlette Fancy

We add two more layer on top of Starlette: "validator" and "processor". Validators are responsible for data validations and processors do logic of the web app.

Installation

To install base package:

pip install starlette-fancy

we use "pydantic" package for "PydanticValidator" and "databases" package for "DatabaseProcessor" and to support different JSON libraries we use "starlette-marshal" package. You can install each with following commands:

pip install starlette-fancy[pydantic]
pip install starlette-fancy[databases]
pip install starlette-fancy[starlette-marshal]

to install all packages at once:

pip install starlette-marshal[full]

Validators

In validator layer we receive data from a request then validate them and return validated data. Input data can come from request body, querystring and sometimes in could be response body.

We don't specify any library or method to validate data. One may create its own validator from the scratch. All you need to do is to inherit from "Validator" class and then implement its __call__ method.

an example could be like this:

class CustomValidator(Validator):
    async def __call__(
            self,
            data: Union[list, dict],
            source: Literal["body", "query_params"] = "body",
            response: bool = False,
            partial: bool = False,
    ) -> dict:
        ...

PydanticValidator

There is built in validator that powered with Pydantic library. First you have to create models:

class PostParams(BaseModel):
    title: str
    slug: str
    content: str
    published_at: datetime


class PostBody(BaseModel):
    id: Optional[UUID]

now we can have a simple validator like this:

class PostValidator(PydanticValidator):
    params_model = PostParams
    request_model = PostBody

Processors

Processor layer is after validator, and it receives validated data. In this layer we write logic of our program, and we return the processed. You should inherit from "Processor" class and then override one of "get", "post", "put", "delete" or "patch" methods. Here an example:

class CustomProcessor(Processor):
    async def get(self, validated_data: dict) -> Any:
        return {
            'validated_data': validated_data,
        }

DatabaseProcessor

A common scenario is when we want to map an HTTP method to a database query. Suppose we have the following queries:

INSERT_POSTS: str = '''
    insert into posts (title, slug, content, published_at)
    values (:title, :slug, :content, :published_at)
    returning *
'''

SELECT_POSTS: str = '''
    select id, title, slug, content, published_at
    from posts
    where true
'''

UPDATE_POSTS: str = '''
    update posts
    set title        = coalesce(:title, title),
        slug         = coalesce(:slug, slug),
        content      = coalesce(:content, content),
        published_at = coalesce(:published_at, published_at)
    where id = :id
    returning *
'''

DELETE_POSTS: str = '''
    delete
    from posts
    where id = :id
    returning *
'''

now a DatabaseProcessor example is like this:

database: Database = Database(url=DATABASE_URL)


class PostProcessor(DatabaseProcessor):
    database = database
    insert_query = INSERT_POSTS
    select_query = SELECT_POSTS
    update_query = UPDATE_POSTS
    delete_query = DELETE_POSTS

Endpoints

This isn't a new thing, just normal Starlette endpoint. But we only handle request and response in this layer. We get request and pass the values to validator then receive validated data and give it to processor layer. At the end we create a response with what processor returned to us.

Here an example:

class CustomEndpoint(Endpoint):
    validator: Validator
    processor: Processor

    async def get(self, request: Request) -> Response:
        query_params: dict = dict(request.query_params)

        validated_data: dict = await self.validator(
            data=query_params,
            source="query_params",
        )
        processed_data: list = await self.processor.get(
            validated_data=validated_data,
        )

        return JSONResponse(content=processed_data)

CRUDEndpoint

To create a fast CRUD endpoint you can use this class. With "PydanticValidator" and "DatabaseProcessor" it's really simple:

class PostEndpoint(CRUDEndpoint):
    validator = PostValidator()
    processor = PostProcessor()

there's a function to generate routes for our CRUD resource:

routes = generate_crud_routes('/posts', endpoint=PostEndpoint, id_type='uuid')

TODO

  • Pydantic validator
  • marshmallow validator
  • ORM processor
  • database processor
  • CRUD endpoint
  • gRPC endpoint
  • proxy endpoint

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starlette-fancy-0.1.0.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

starlette_fancy-0.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file starlette-fancy-0.1.0.tar.gz.

File metadata

  • Download URL: starlette-fancy-0.1.0.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.1

File hashes

Hashes for starlette-fancy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 07ba351474b37cbf5e6f4d32286bd38bfa54c76813e77e6dadfbb37865ad834c
MD5 9c858fdbba7a3f9937fadeeb4fc6c1cf
BLAKE2b-256 f7b293498e816446c6176fd6539922ee0d3a903eeece727ba81281a683c8e96f

See more details on using hashes here.

File details

Details for the file starlette_fancy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: starlette_fancy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.1

File hashes

Hashes for starlette_fancy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cbc355ff4509a9422f3adb0fbc0c089433b174ca26d329f368f3b9b805f414bb
MD5 0d221a38d7f9f9c666a362dfafa0636d
BLAKE2b-256 7e0a44977d7d72d046a78bca8602d4c29221ed6652f6485ae30c178ff2c2f591

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page