Skip to main content

🔥 FrameFire

FrameFire is a simple, lightweight, and fast WSGI web framework for Python. Built on top of WebOb, it provides an intuitive and expressive API for building modern web applications with minimal boilerplate.

PyPI version Python Versions License: MIT


✨ Features

  • Expressive Routing: Decorator-based and method-based routing with support for dynamic URL parameters.
  • Class-Based Handlers: Group related logic into class-based views (GET, POST, PUT, DELETE).
  • Jinja2 Templates: Built-in support for rendering Jinja2 templates easily.
  • Static Files: Automatic serving of static files out of the box using WhiteNoise.
  • Middleware: Simple, class-based middleware architecture to process requests and responses.
  • Custom Exception Handling: Catch and handle exceptions gracefully globally.
  • Test Client Included: Built-in testing support making unit testing an absolute breeze.
  • JSON & Text Helpers: Simplified response creation with .json, .text, and .html attributes.

📦 Installation

FrameFire is available on PyPI. Install it using pip:

pip install framefire

🚀 Quickstart

Create a file named app.py:

from fireframe.app import FrameFire

app = FrameFire()

@app.route("/")
def home(request, response):
    response.text = "Hello, FrameFire!"

@app.route("/json")
def json_endpoint(request, response):
    response.json = {"framework": "FrameFire", "status": "Awesome"}

if __name__ == "__main__":
    # You can use a WSGI server like Gunicorn to run the app
    # gunicorn app:app
    pass

Run the application using gunicorn:

gunicorn app:app

📖 User Guide

🛣️ Routing & Dynamic Parameters

You can easily capture values from the URL and pass them to your handlers:

@app.route("/hello/{name}")
def greeting(request, response, name):
    response.text = f"Hello, {name}!"

🏛️ Class-Based Views

For more complex endpoints, you can use class-based handlers. Just implement methods corresponding to HTTP verbs:

@app.route("/books")
class BooksResource:
    def get(self, request, response):
        response.text = "List of books"

    def post(self, request, response):
        response.text = "Create a new book"

    def delete(self, request, response):
        response.text = "Delete a book"

🎨 Templates

FrameFire comes with Jinja2 integrated. By default, it looks for templates in a templates/ directory.

@app.route("/html")
def template_handler(request, response):
    # Renders 'index.html' from the 'templates' directory
    response.html = app.template(
        "index.html", 
        context={"title": "FrameFire", "body": "Welcome to my app!"}
    )

🗂️ Static Files

Static file serving is powered by WhiteNoise. Just place your static assets (CSS, JS, images) inside a static/ directory in the root of your project, and they will be served automatically!

<!-- Inside your template -->
<link rel="stylesheet" href="/style.css">

🛡️ Middleware

You can intercept and modify requests and responses globally using middleware:

from fireframe.middleware import Middleware

class LoggingMiddleware(Middleware):
    def process_request(self, request):
        print(f"Incoming Request: {request.method} {request.path}")

    def process_response(self, request, response):
        print(f"Outgoing Response: {response.status_code}")

app.add_middleware(LoggingMiddleware)

⚠️ Custom Exception Handling

Add a global exception handler to gracefully catch unexpected errors:

def on_exception(request, response, exc):
    response.text = f"Something went wrong: {str(exc)}"
    response.status_code = 500

app.add_exception_handler(on_exception)

🧪 Testing

FrameFire makes it easy to write unit tests using its built-in session client.

import pytest
from fireframe.app import FrameFire

@pytest.fixture
def app():
    return FrameFire()

@pytest.fixture
def test_client(app):
    return app.test_session()

def test_greeting(app, test_client):
    @app.route("/hello/{name}")
    def greeting(request, response, name):
        response.text = f"Hello {name}"

    response = test_client.get("http://testserver/hello/John")
    assert response.text == "Hello John"
    assert response.status_code == 200

📄 License

This project is licensed under the MIT License.

Metadata

Release files for framefire 0.2.0

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

Source distribution (sdist)

Source distribution for framefire 0.2.0
File Size Uploaded
framefire-0.2.0.tar.gz 8.7 kB Details

Built distribution (wheel)

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

Total release size: 16.3 kB

Release files / framefire-0.2.0.tar.gz

Download URL framefire-0.2.0.tar.gz
Size 8.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5567a583259dadaad9e49d559c372cb45c005cc31be3d1826aa424b5dfaa5eea
BLAKE2b-256 checksum
How to use checksums
b978161d5f50c25a4853ea2750eec59c04122d9878bfa4a148feb68e055cc610
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / framefire-0.2.0-py3-none-any.whl

Download URL framefire-0.2.0-py3-none-any.whl
Size 7.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12774812dbff2f5259823bb67da84acc39f52cab0fbed1fd8368facc5acda762
BLAKE2b-256 checksum
How to use checksums
594f7f29602ec10c487021e8d6c677c043d641f1e32a8c84b0270d6ec225d13e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

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