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.1.1.tar.gz (6.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.1.1-py2.py3-none-any.whl (5.8 kB view details)

Uploaded Python 2Python 3

File details

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

File metadata

  • Download URL: framefire-0.1.1.tar.gz
  • Upload date:
  • Size: 6.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.1.1.tar.gz
Algorithm Hash digest
SHA256 c9ba176089ddbe3b959b6ef8445d1796c9528902347476bae623daf427df44f4
MD5 e20db5fdf6ab640309d376ab2e7fffc2
BLAKE2b-256 78816b92c5c087615a365a3cd4541950ac5d7795bffeb76da16407919f2e543d

See more details on using hashes here.

File details

Details for the file framefire-0.1.1-py2.py3-none-any.whl.

File metadata

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

File hashes

Hashes for framefire-0.1.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 347770f29d3ced3c4d6b3dea380ee75870ba2d25a909adb903ee1e458530f139
MD5 4d09b371fc05fb89580e5a95fc049351
BLAKE2b-256 44b4b8fe2d00b92e170005b0eb233f80a1cb6793738511dbac59de8b1ebf8182

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