Skip to content

Python-Katsina/haske

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

71 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌟 Haske Web Framework

Haske is a modern Python web framework that combines the simplicity of Flask, the power of FastAPI, and the performance of Rust extensions. It is designed for developers who want to build fast, scalable, and maintainable web applications without unnecessary complexity.


πŸ“– Table of Contents

  1. Introduction
  2. Installation
  3. Quickstart
  4. Routing
  5. Requests & Responses
  6. Middleware
  7. Sessions
  8. Templates
  9. ORM & Database
  10. Authentication
  11. CLI
  12. WebSockets
  13. Error Handling
  14. Testing
  15. Deployment
  16. Contributing
  17. License

πŸ“Œ Introduction

Haske was built to solve a common problem in Python web development:

  • Flask is simple, but too minimal for large apps.
  • Django is powerful, but heavy and opinionated.
  • FastAPI is fast, but focused mostly on APIs.

Haske combines the best of all worlds:

  • πŸŒ€ Simple API β€” inspired by Flask.
  • ⚑ Fast β€” powered by Rust extensions.
  • πŸ”§ Flexible β€” lets you add only what you need.
  • 🌍 Full-stack ready β€” supports templates, ORM, sessions, and WebSockets.

βš™οΈ Installation

Requirements

  • Python 3.8+
  • Rust (for building extensions)
  • pip / virtualenv

Install Haske

pip install haske

Or, from source:

git clone https://github.com/Python-Katsina/haske-python.git
cd haske-python
python setup.py

πŸš€ Quickstart

Create a file app.py:

from haske import Haske, Request, Response

app = Haske(__name__)

@app.route("/")
async def home(request: Request) -> Response:
    return {"message": "Hello, Haske!"}

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, reload=True)

Run the app:

python app.py

Visit: http://localhost:8000 πŸŽ‰


πŸ”€ Routing

Routing is how Haske connects URLs to functions.

Basic Route

@app.route("/hello")
async def say_hello(request: Request):
    return {"message": "Hello World"}

Path Parameters

@app.route("/user/{username}")
async def greet_user(request: Request, username: str):
    return {"message": f"Hello {username}"}

Query Parameters

@app.route("/search")
async def search(request: Request):
    query = request.query.get("q", "none")
    return {"search_for": query}

HTTP Methods

@app.route("/submit", methods=["POST"])
async def submit(request: Request):
    data = await request.json()
    return {"received": data}

πŸ“₯ Requests & Responses

Haske provides easy access to HTTP requests and responses.

Request Object

@app.route("/headers")
async def headers(request: Request):
    return {"user_agent": request.headers.get("User-Agent")}

JSON Response

@app.route("/json")
async def json_response(request: Request):
    return {"framework": "Haske", "type": "JSON"}

Redirect

from haske.responses import RedirectResponse

@app.route("/go")
async def go(request: Request):
    return RedirectResponse(url="/hello")

🧩 Middleware

What is Middleware?

Middleware is code that runs before or after each request.
Uses include: logging, authentication, CORS, compression, etc.

Example: Logging Middleware

from haske.middleware import Middleware

class LoggingMiddleware(Middleware):
    async def before_request(self, request):
        print(f"➑️ Incoming request: {request.url}")

    async def after_response(self, request, response):
        print(f"⬅️ Response status: {response.status_code}")

app.add_middleware(LoggingMiddleware)

πŸ”‘ Sessions

What are Sessions?

HTTP is stateless β€” it doesn’t remember users between requests.
Sessions allow you to store user data (like logins or cart items) across multiple requests.

Why Sessions Matter

  • πŸ” Authentication (keep users logged in)
  • πŸ›’ Shopping carts
  • πŸŽ› Preferences & personalization

Example: Using Sessions

@app.route("/login", methods=["POST"])
async def login(request: Request):
    data = await request.json()
    username = data.get("username")

    # Save to session
    request.session["user"] = username
    return {"message": f"Welcome {username}"}

@app.route("/profile")
async def profile(request: Request):
    user = request.session.get("user")
    if not user:
        return {"error": "Not logged in"}
    return {"profile": f"User profile for {user}"}

🎨 Templates

Haske supports rendering HTML templates (Jinja2 or similar).

Example

@app.route("/welcome")
async def welcome(request: Request):
    return app.template("welcome.html", {"name": "Haske User"})

templates/welcome.html:

<html>
  <body>
    <h1>Welcome {{ name }}!</h1>
  </body>
</html>

πŸ—„οΈ ORM & Database

Haske can integrate with SQLAlchemy or other ORMs.

Example: SQLAlchemy

from haske.orm import Model, Column, Integer, String

class User(Model):
    id = Column(Integer, primary_key=True)
    name = Column(String)

# Create
new_user = User(name="Alice")
db.session.add(new_user)
db.session.commit()

# Query
user = User.query.filter_by(name="Alice").first()

πŸ” Authentication

Authentication is usually built on top of sessions.

Example

@app.route("/auth/login", methods=["POST"])
async def auth_login(request: Request):
    data = await request.json()
    if data["username"] == "admin" and data["password"] == "123":
        request.session["user"] = "admin"
        return {"status": "logged_in"}
    return {"error": "Invalid credentials"}

@app.route("/auth/protected")
async def protected(request: Request):
    if request.session.get("user") != "admin":
        return {"error": "Unauthorized"}
    return {"message": "Welcome, admin!"}

πŸ–₯️ CLI

Haske comes with a command-line interface.

Create New Project

haske new myproject

Run Server

haske run

πŸ“‘ WebSockets

Haske supports real-time apps with WebSockets.

Example: Chat

@app.websocket("/ws")
async def websocket_endpoint(socket):
    await socket.send("Welcome to Haske Chat!")
    async for message in socket:
        await socket.send(f"You said: {message}")

⚠️ Error Handling

Custom Error Handler

@app.exception_handler(404)
async def not_found(request: Request, exc):
    return {"error": "Page not found"}

πŸ§ͺ Testing

Haske makes testing simple.

Example: Using pytest

from haske.testing import TestClient

def test_homepage():
    client = TestClient(app)
    response = client.get("/")
    assert response.status_code == 200
    assert response.json()["message"] == "Hello, Haske!"

πŸš€ Deployment

Run with Uvicorn

uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4

Run with Gunicorn

gunicorn -k uvicorn.workers.UvicornWorker app:app

🀝 Contributing

  1. Fork the repo.
  2. Create a feature branch.
  3. Submit a pull request.

We welcome contributions in:

  • Bug fixes
  • New features
  • Docs improvements

πŸ“œ License

MIT License Β© 2025 Python Katsina Community