Skip to main content

PebaRest Framework, fast to code, take the control of your application.

Project description

PebaREST

A lightweight Python web framework for building REST APIs with simplicity and total control.

PebaREST is a WSGI-based micro-framework built from the ground up as an academic project (TCC — Trabalho de Conclusão de Curso). Its philosophy is straightforward: give the developer a clean, transparent request/response cycle with no hidden magic, while keeping the code minimal and readable. No auto-wiring, no black boxes — just routes, resources, and the request object in your hands.


Table of Contents


Installation

PebaREST is not yet published on PyPI. Install it directly from GitHub:

pip install git+https://github.com/EderMiqueias/PebaREST.git

No external dependencies are required — the framework runs on Python's standard library.


Key Features

  • Resource-based routing — map URL paths to classes with HTTP method handlers (get, post, put, patch, delete, …).
  • Dynamic routes — declare path parameters with {param} syntax; access them via request.path_params.
  • Typed body validation — use BaseModel to automatically parse and validate the JSON request body.
  • Built-in authentication — plug in APIKeyAuthenticator or implement your own BaseAuthenticator.
  • Zero magic — the WSGI callable is explicit, testable, and fully transparent.
  • Test generation — generate unittest files from a simple test-case dictionary via app.generate_tests().
  • OpenAPI docs — enable a /docs endpoint with a single constructor flag.

Quickstart

The minimal example: one route, one resource, one server.

from wsgiref.simple_server import make_server

from pebarest import App
from pebarest.models import Resource, Request


class HelloResource(Resource):
    def get(self, request: Request):
        return {"message": "Hello, World!"}


app = App(__name__, default_headers={"Content-Type": "application/json"})
app.add_route("/", HelloResource())

with make_server("", 8000, app) as httpd:
    print("Server listening on http://127.0.0.1:8000")
    httpd.serve_forever()
$ curl http://127.0.0.1:8000/
{"message": "Hello, World!"}

Dynamic Routes

Declare a path parameter by wrapping its name in curly braces. PebaREST automatically populates request.path_params with the matched values.

from wsgiref.simple_server import make_server

from pebarest import App
from pebarest.models import Resource, Request


USERS = {
    "1": {"id": "1", "name": "Alice"},
    "2": {"id": "2", "name": "Bob"},
}


class UserDetailResource(Resource):
    def get(self, request: Request):
        user_id = request.path_params.get("user_id")
        user = USERS.get(user_id)
        if user is None:
            return {"error": f"User '{user_id}' not found."}, 404
        return user

    def delete(self, request: Request):
        user_id = request.path_params.get("user_id")
        user = USERS.pop(user_id, None)
        if user is None:
            return {"error": f"User '{user_id}' not found."}, 404
        return {"deleted": user}


app = App(__name__, default_headers={"Content-Type": "application/json"})
app.add_route("/users/{user_id}", UserDetailResource())

with make_server("", 8000, app) as httpd:
    print("Server listening on http://127.0.0.1:8000")
    httpd.serve_forever()
$ curl http://127.0.0.1:8000/users/1
{"id": "1", "name": "Alice"}

$ curl http://127.0.0.1:8000/users/99
{"error": "User '99' not found."}

Multiple dynamic segments are supported in the same path:

app.add_route("/posts/{post_id}/comments/{comment_id}", CommentDetailResource())

Both post_id and comment_id will be available in request.path_params.


Request Body Validation with BaseModel

Annotate the request parameter with Request[YourModel] to have the JSON body automatically parsed and validated against a typed model.

from wsgiref.simple_server import make_server

from pebarest import App, BaseModel
from pebarest.models import Resource, Request


class Item(BaseModel):
    name: str
    quantity: int


class ItemResource(Resource):
    def post(self, request: Request[Item]):
        item: Item = request.body  # already validated and typed
        return {"received": item.name, "qty": item.quantity}, 201


app = App(__name__, default_headers={"Content-Type": "application/json"})
app.add_route("/items", ItemResource())

with make_server("", 8000, app) as httpd:
    print("Server listening on http://127.0.0.1:8000")
    httpd.serve_forever()

If a required field is missing or has the wrong type, PebaREST returns a 422 Unprocessable Entity response automatically.


API Key Authentication

Pass an APIKeyAuthenticator instance when creating the App. Every request will be validated before reaching the resource handler, and the resolved client info is available on request.client_info.

from pebarest import App
from pebarest.auth import APIKeyAuthenticator
from pebarest.models import Resource, Request

auth = APIKeyAuthenticator(
    valid_keys={"supersecret-key-123": "client-A"},
    header_name="X-API-Key",
)


class ProtectedResource(Resource):
    def get(self, request: Request):
        return {"client": request.client_info["client_id"]}


app = App(__name__, auth_handler=auth)
app.add_route("/protected", ProtectedResource())

Generating Unit Tests

PebaREST can scaffold a unittest file for your API from a declarative test-case dictionary:

app.generate_tests(
    {
        "/items": {
            "POST": {"name": "Apple", "quantity": 10}
        }
    },
    output_file="tests/test_items_api.py",
)

Run the script once (e.g., python app.py) and the test file is created. Requires is_debug=True (the default).


Auto-generated Docs

Enable the built-in OpenAPI 3.1.0 documentation endpoint with a single flag:

app = App(__name__, generate_docs=True)

The schema is then available at GET /docs.


License

See LICENSE for details. PebaRest Framework, fast to code, take the control of your application.

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

pebarest-1.0.1.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

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

pebarest-1.0.1-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file pebarest-1.0.1.tar.gz.

File metadata

  • Download URL: pebarest-1.0.1.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for pebarest-1.0.1.tar.gz
Algorithm Hash digest
SHA256 6944726c439f7c7f82fa367161e7b74eb6ee9295229f51e8689b8abe9749a32f
MD5 3e998229d26ea7bb33140ca6293596c7
BLAKE2b-256 bbaf9c19d99da6932e35d9096411dc19a64141e0d55b55c433a35318156dd185

See more details on using hashes here.

File details

Details for the file pebarest-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pebarest-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for pebarest-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 15ce90771914e1fbde15ca8a1bfceff4da90581befe0df4a524865b49c462294
MD5 a5742ec2f33c7f0b99f49af6ae0bc633
BLAKE2b-256 e59128253a50a4de2d39025e86b5e18b321b2d4ca0c4cc5893694ff6335cb92b

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