Skip to main content

Chasha

Chasha (rus: Chalice) is a microframework for use in serverless applications on lambdas/cloud functions. It does not have any dependencies only using standard library Since changing version on serverless functions is simple, the minimal python requirement is 3.10

Supported platforms:

  • Yandex Cloud
  • WSGI - for testing purposes (if you need something similar - just take FastAPI)

Installation

pip install chasha

Getting started

A minimal Chasha app looks like this

from chasha import Chasha

app = Chasha()

@app.route('/')
def hello():
    return {'message': 'hello'}

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    from chasha.contrib.adapters.wsgi import WSGIAdapter
    
    with make_server('', 8080, WSGIAdapter(app).handler) as httpd:
        httpd.serve_forever()

First you need to create an app, then you can use the following decorators to create route handlers:

  • route(path: str, http_methods: list[str] = None) Creates a route on the following path, when specified without http_methods kwargs handles any HTTp verb
  • get(path: str) Shortcut for route(path, http_methods=['GET'])
  • post(path: str) Shortcut for route(path, http_methods=['POST'])

The handler function returns content of the response, it could be of type dict for json responses, string for raw data response and special wrapper for html response

@app.route('/')
def hello():
    return app.html('<html><body>Hello World</body></html>')

Sub routers

In order to organize your api routes sub routers are introduced. The sub router called Chashka (Small Chasha, rus: cup)

app = Chasha()
api = Chashka(path_prefix='/api')

# routes

app.include_app(api)

Path parameters

Path parameters declared as python format string and passed to the handler function with the same name. Type will be converted based on function argument type annotation

@app.get('/items/{item_id}')
def get_item(item_id: int):
    return {'id': item_id}

Dependency Injection

Chasha supports simple but powerful DI mechanism, lets break down the following example

from chasha import Chasha, DI, InjectContext

app = Chasha()

def hello_world(context: InjectContext):
    # startup
    yield f"Hello, world from attr '{context.param_name}'"
    # teardown

@app.route('/')
def hello(greet: str = DI.inject(hello_world)):
    return {'message': greet}

Function hello_world will be injected into handler hello as greet function parameter.

There is a special non-required attribute in dependency function with the type InjectContext (name of the argument does not matter) which contains context of the current injection. InjectContext should be considered as advanced usage since there are already implemented dependencies for basic needs.

Request and Response object

Sometimes it's needed to access current Request and modify Response objects, there are corresponding dependencies for this case:

@app.route('/')
def hello(request: Request = DI.request(), response: Response = DI.response()):
    response.set_header('X-CHASHA-GREET', 'Hello, world')
    return {'message': request.get_header('user-agent')}

Query Params

It's possible to access query parameters via Request object, but it's preferred to use special injection

@app.route('/add')
def hello(a: int = DI.query(), b: int = DI.query()):
    return {'message': a + b}

Dependency query(name: str, default = None) can override name and provide default, in case the parameter is missing and no default provided response will fail with 405 code

Request payload

It's possible to access query parameters via Request object, but it's preferred to use special injection

@app.route('/add')
def hello(data: int = DI.json_body()):
    return {'message': data}

Cookies

To read and set cookies use special injection DI.cookies

@app.route('/')
def index(cookies: DI.Cookies = DI.cookies()):
    cookies.set('greeted', 'true')
    return {'message': cookies.get('greet')}

Exception handling

To handle uncaught exception use decorator Chasha.exception_handler and it's shortcuts handle_500 and handle_404 Handler takes one positional argument - raised exception, also handler fully supports dependencies.

@app.handle_500()
def on_500(_: Exception):
    return {'message': 'ooops'}

@app.route('/')
def hello():
    raise Exception()

Serve requests

After you create your app - you need to serve HTTP requests somehow, for this you need to use adapters. Add the following lines of code to your API Gateway Cloud Function handler to start using Chasha over Yandex Cloud

def handler(event, context):
    from chasha.contrib.adapters.yandex import YandexCloudAdapter
    return YandexCloudAdapter(app).handler(event, context)

WSGI Adapter

Chasha also ships with WSGI adapter to ease local development, it can be used with any wsgi app server of choice, or even with builtin server

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    from chasha.contrib.adapters.wsgi import WSGIAdapter

    with make_server('', 8080, WSGIAdapter(app).handler) as httpd:
        httpd.serve_forever()

Metadata

Release files for chasha 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chasha 0.0.2
File Size Uploaded Provenance Actions
chasha-0.0.2.tar.gz 15.4 kB Without provenance Details for chasha-0.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chasha 0.0.2
File Interpreter ABI Platform Actions
chasha-0.0.2-py3-none-any.whl Python 3 none any Details for chasha-0.0.2-py3-none-any.whl

Total release size: 28.1 kB

Release files / chasha-0.0.2.tar.gz

Download URL chasha-0.0.2.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2683db62ba74dc751feb79c75f0f54a84eb4277dec63a8bd53b1ff37959f43e2
BLAKE2b-256 checksum
How to use checksums
3ceed586e5b50d778358402870093911c1444bf8902d638344270788da0b8c79
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/4.0.1 CPython/3.11.4

Release files / chasha-0.0.2-py3-none-any.whl

Download URL chasha-0.0.2-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de2a26d3155f32e92f846f752f912e0580af4604b2d338f9cd8e4ab1f0cb7906
BLAKE2b-256 checksum
How to use checksums
19cb7562513857ce75455eb296f2ed31e481a169eb130e1b8bca374a98065915
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/4.0.1 CPython/3.11.4

Security for chasha 0.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page