SkillAgentSearch skills...

Clastic

🏔️ A functional web framework that streamlines explicit development practices while eliminating global state.

Install / Use

/learn @mahmoud/Clastic
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Clastic

.. raw:: html

<a href="https://pypi.org/project/clastic/"><img src="https://img.shields.io/pypi/v/clastic.svg"></a> <a href="https://calver.org/"><img src="https://img.shields.io/badge/calver-YY.MINOR.MICRO-22bfda.svg"></a>

A functional Python web framework that streamlines explicit development practices while eliminating global state.

Clastic is pure-Python, tested on Python 3.7+, and documented <https://python-clastic.readthedocs.io/>, with tutorials <https://python-clastic.readthedocs.io/en/latest/tutorial.html>.

.. contents:: :depth: 2 :backlinks: top :local:

Quick Start Guide

Installation ^^^^^^^^^^^^

Clastic is available on PyPI <https://pypi.python.org/pypi/clastic>_. You can install it by running this command::

easy_install clastic

(pip works, too.)

Hello World! ^^^^^^^^^^^^

Getting up and running with Clastic is exceedingly difficult. Just try and create a file called hello.py with the following indecipherable runes:

.. code-block:: python

from clastic import Application, render_basic

def hello(name='world'): return 'Hello, %s!' % name

routes = [('/', hello, render_basic), ('/<name>', hello, render_basic)]

app = Application(routes) app.serve()

If you run python hello.py at the command line and visit http://localhost:5000 in your browser, you will see the text Hello, world!. If instead, you visit http://localhost:5000/Ben then you will see the text Hello, Ben!. Madness.

Getting fancy with request objects ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If we add the request argument to any endpoint function, we get access to all of the request data, including any GET or POST parameters or cookies that may have been sent with the request.:

.. code-block:: python

from clastic import Application, render_basic

def fancy(request): result = '' # iterate through all of the GET and POST variables for k in request.values: result += "Found argument '%s' with value '%s'\n" % (k, request.values[k]) # iterate through all of the cookies for k in request.cookies: result += "Found cookie '%s' with value '%s'\n" % (k, request.cookies[k]) return result

routes = [('/fancy', fancy, render_basic)]

app = Application(routes) app.serve()

Since we're being fancy, let's create a curl request which sends a GET parameter, a POST parameter, and a cookie::

curl -X POST --data "post=posted" --cookie "cookie_crisp=delicious" --url "http://0.0.0.0:5000/fancy?get=gotten"

In response, Clastic sends the following::

Found argument 'post' with value 'posted' Found argument 'get' with value 'gotten' Found cookie 'cookie_crisp' with value 'delicious'

So fancy.

If you're curious how request got there, read past the end of the Quickstart.

Pushing the envelope with Response objects ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In the previous examples, we have been returning strings from our endpoints, letting the trusty render_basic handle the rest. If we want more control, then we can remove render_basic from the route, opting to instantiate and return our own Response object directly.

In the following example, we alter the response headers and status code to forward the browser back to the main page:

.. code-block:: python

from clastic import Application, render_basic, Response, redirect

def home(): return 'Home, Sweet Home!'

def return_home(): response = Response()

  # Forward the client browser to the home page.
  response.headers['Location'] = '/'
  response.status_code = 301

  return response

def redirect_home(): return redirect('/')

routes = [('/', home, render_basic), ('/return-home', return_home), ('/redirect-home', redirect_home]

app = Application(routes) app.serve()

If you visit the page http://localhost:5000/return-home in your browser, it will immediately redirect you to the root URL and show the text Home, Sweet Home!.

The Response object gives you complete control over all HTTP headers, enabling you to set and delete cookies, play with page caching, set page encoding, and so forth. If that sort of fine-grained responsibility sounds daunting or tedious, you're not alone, which is why the most common operations usually have convenience functions, like redirect(), which is demonstrated in redirect_home() above. Clastic also has no-nonsense drop-ins for cookies, HTTP caching, and more.

Testimonials

While originally built to host a simple train schedule site <https://github.com/mahmoud/etavta>_ and a few Wikipedia-related projects <https://github.com/hatnote>_, Clastic is also used for both internal and production-grade applications at PayPal.

(If your project or company uses Clastic, feel free to file an issue or submit a pull request to get added to this section.)

Motivation

Clastic was created to fill the need for a minimalist web framework that does exactly what you tell it to, while eliminating common pitfalls and delays in error discovery. The result is a streamlined and deterministic web development experience.

To put it another way, Clastic is designed such that, by the time your application has loaded, the framework has done all its work and gotten out of the way. It doesn't wait until the first request or the first time a URL is hit to raise an exception.

What is a web application?

In a way, every web framework is a systematic answer to the age-old question that has baffled humankind until just a few years ago.

.. note:: The following is a conceptual introduction, not class reference. Also, don't be fooled by Capital Letters, Clastic really isn't type-heavy.

Request A single incoming communication from a client (to your application). Encapsulates the WSGI environ, which is just Python's representation of an HTTP request.

Response An outgoing reply from your application to the client.

A web application exists to accept Requests and produce Responses. (Clastic knows that every Request has its Response <3)::

Request --> [Application] --> Response

Route A regex-like URL pattern, as associated with an endpoint (and optional renderer).

Endpoint The function or callable that is called when an incoming request matches its associated Route. In Django, this is called a view, in most MVC frameworks this is called a controller.

Renderer A function that usually takes a dictionary of values and produces a Response. For a typical website, the content of the response is usually the result of a templating engine, JSON encoder, or file reader.

A web application matches a Request's URL to its Routes' patterns. If there are no matches, it returns a 404 Response. If a matching Route is found, the Route's endpoint is called. If it returns a Response or the Route doesn't have a Renderer, the Response is sent back directly. Otherwise, the endpoint's return value is fed into the Renderer, which produces the actual Response::

Request --> Routes --> Endpoint --> (Renderer) --> Response

.. admonition:: A bit of context

It can be useful to think of an application's behavior in terms of overlapping contexts, each with its own lifespan. For instance, a logged-in user's session is a context which can span multiple requests. A database connection has a context, which may be shorter than a Request's context, or longer if your application uses connection pooling.

Application code can introduce dozens of logical contexts, specific to its function, but at the Clastic level, there are two primary contexts to consider:

  • The Request context, which begins when the Request is constructed by the framework, and usually ends when the Response has been sent back to the client.
  • The Application context, which begins once an Application is successfully constructed at server startup, and ends when the server running the Application shuts down.

Concepts discussed above were more oriented to the Request context, the following items are more Application focused.

.. _Resources:

Resources A resource is a value that is valid for the lifespan of the Application. An example might be a database connection factory, a logger object, or the path of a configuration file. An Application's resources refers to a map that gives each resource a name.

Render Factory A callable which, when called with an argument, returns a suitable renderer. Consider a TemplateRenderFactory, which, when called with the template filename index.html, returns a function that can be passed a dictionary to render the application's home page.

A Render Factory is optional. Here are some cases where a Render Factory can be omitted:

  • an application's endpoints return Responses directly (as many applications based directly on Werkzeug do)
  • render functions are specified explicitly on a per-route basis
  • the application is using some fancy middleware to generate Responses

Middleware_ Middleware is a way of splitting up and ordering logic in discrete layers. When installed in an Application, Middleware has access to the Request before and after the endpoint and render steps. In Python itself, decorators could be thought of as a form of function middleware.

There's a lot more to middleware in Clastic, so check out the Middleware_ section for more information, including diagrams of middleware's role in the request flow.

Armed with this information, it's now possible to define what constitutes a web application, and indeed a Clastic Application:

Application A collection of Resources, list of Routes, and list of Middleware instances, with an optional Render Factory to create the rendering step for each of

View on GitHub
GitHub Stars159
CategoryDevelopment
Updated1mo ago
Forks20

Languages

Python

Security Score

85/100

Audited on Feb 26, 2026

No findings