Skip to main content

A simple web framework for building web applications.

Project description

🔥 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.

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

framefire-0.2.0.tar.gz (8.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

framefire-0.2.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file framefire-0.2.0.tar.gz.

File metadata

  • Download URL: framefire-0.2.0.tar.gz
  • Upload date:
  • Size: 8.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for framefire-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5567a583259dadaad9e49d559c372cb45c005cc31be3d1826aa424b5dfaa5eea
MD5 4371cc48b041ed79fda56a15d6a146a1
BLAKE2b-256 b978161d5f50c25a4853ea2750eec59c04122d9878bfa4a148feb68e055cc610

See more details on using hashes here.

File details

Details for the file framefire-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: framefire-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for framefire-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 12774812dbff2f5259823bb67da84acc39f52cab0fbed1fd8368facc5acda762
MD5 275d1a60097d19fe7b321336ee9b73b2
BLAKE2b-256 594f7f29602ec10c487021e8d6c677c043d641f1e32a8c84b0270d6ec225d13e

See more details on using hashes here.

Supported by

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