# π 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](#-introduction)
2. [Installation](#-installation)
3. [Quickstart](#-quickstart)
4. [Routing](#-routing)
5. [Requests & Responses](#-requests--responses)
6. [Middleware](#-middleware)
7. [Sessions](#-sessions)
8. [Templates](#-templates)
9. [ORM & Database](#-orm--database)
10. [Authentication](#-authentication)
11. [CLI](#-cli)
12. [WebSockets](#-websockets)
13. [Error Handling](#-error-handling)
14. [Testing](#-testing)
15. [Deployment](#-deployment)
16. [Contributing](#-contributing)
17. [License](#-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
```bash
pip install haske
```
Or, from source:
```bash
git clone https://github.com/Python-Katsina/haske-python.git
cd haske-python
python setup.py
```
---
## π Quickstart
Create a file `app.py`:
```python
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:
```bash
python app.py
```
Visit: [http://localhost:8000](http://localhost:8000) π
---
## π Routing
Routing is how Haske connects **URLs** to **functions**.
### Basic Route
```python
@app.route("/hello")
async def say_hello(request: Request):
return {"message": "Hello World"}
```
### Path Parameters
```python
@app.route("/user/{username}")
async def greet_user(request: Request, username: str):
return {"message": f"Hello {username}"}
```
### Query Parameters
```python
@app.route("/search")
async def search(request: Request):
query = request.query.get("q", "none")
return {"search_for": query}
```
### HTTP Methods
```python
@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
```python
@app.route("/headers")
async def headers(request: Request):
return {"user_agent": request.headers.get("User-Agent")}
```
### JSON Response
```python
@app.route("/json")
async def json_response(request: Request):
return {"framework": "Haske", "type": "JSON"}
```
### Redirect
```python
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
```python
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
```python
@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
```python
@app.route("/welcome")
async def welcome(request: Request):
return app.template("welcome.html", {"name": "Haske User"})
```
**`templates/welcome.html`:**
```html
<html>
<body>
<h1>Welcome {{ name }}!</h1>
</body>
</html>
```
---
## ποΈ ORM & Database
Haske can integrate with SQLAlchemy or other ORMs.
### Example: SQLAlchemy
```python
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
```python
@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
```bash
haske new myproject
```
### Run Server
```bash
haske run
```
---
## π‘ WebSockets
Haske supports **real-time apps** with WebSockets.
### Example: Chat
```python
@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
```python
@app.exception_handler(404)
async def not_found(request: Request, exc):
return {"error": "Page not found"}
```
---
## π§ͺ Testing
Haske makes testing simple.
### Example: Using pytest
```python
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
```bash
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
```
### Run with Gunicorn
```bash
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
Raw data
{
"_id": null,
"home_page": null,
"name": "haske",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": null,
"author_email": "Yusee Habibu <yusee201520@gmail.com>",
"download_url": null,
"platform": null,
"description": "# \ud83c\udf1f Haske Web Framework\r\n\r\nHaske 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.\r\n\r\n---\r\n\r\n## \ud83d\udcd6 Table of Contents\r\n\r\n1. [Introduction](#-introduction) \r\n2. [Installation](#-installation) \r\n3. [Quickstart](#-quickstart) \r\n4. [Routing](#-routing) \r\n5. [Requests & Responses](#-requests--responses) \r\n6. [Middleware](#-middleware) \r\n7. [Sessions](#-sessions) \r\n8. [Templates](#-templates) \r\n9. [ORM & Database](#-orm--database) \r\n10. [Authentication](#-authentication) \r\n11. [CLI](#-cli) \r\n12. [WebSockets](#-websockets) \r\n13. [Error Handling](#-error-handling) \r\n14. [Testing](#-testing) \r\n15. [Deployment](#-deployment) \r\n16. [Contributing](#-contributing) \r\n17. [License](#-license) \r\n\r\n---\r\n\r\n## \ud83d\udccc Introduction\r\n\r\nHaske was built to solve a common problem in Python web development:\r\n\r\n- **Flask** is simple, but too minimal for large apps. \r\n- **Django** is powerful, but heavy and opinionated. \r\n- **FastAPI** is fast, but focused mostly on APIs. \r\n\r\nHaske combines the best of all worlds:\r\n\r\n- \ud83c\udf00 **Simple API** \u2014 inspired by Flask. \r\n- \u26a1 **Fast** \u2014 powered by Rust extensions. \r\n- \ud83d\udd27 **Flexible** \u2014 lets you add only what you need. \r\n- \ud83c\udf0d **Full-stack ready** \u2014 supports templates, ORM, sessions, and WebSockets. \r\n\r\n---\r\n\r\n## \u2699\ufe0f Installation\r\n\r\n### Requirements\r\n- Python 3.8+\r\n- Rust (for building extensions)\r\n- pip / virtualenv\r\n\r\n### Install Haske\r\n\r\n```bash\r\npip install haske\r\n```\r\n\r\nOr, from source:\r\n\r\n```bash\r\ngit clone https://github.com/Python-Katsina/haske-python.git\r\ncd haske-python\r\npython setup.py\r\n```\r\n\r\n---\r\n\r\n## \ud83d\ude80 Quickstart\r\n\r\nCreate a file `app.py`:\r\n\r\n```python\r\nfrom haske import Haske, Request, Response\r\n\r\napp = Haske(__name__)\r\n\r\n@app.route(\"/\")\r\nasync def home(request: Request) -> Response:\r\n return {\"message\": \"Hello, Haske!\"}\r\n\r\nif __name__ == \"__main__\":\r\n app.run(host=\"0.0.0.0\", port=8000, reload=True)\r\n```\r\n\r\nRun the app:\r\n\r\n```bash\r\npython app.py\r\n```\r\n\r\nVisit: [http://localhost:8000](http://localhost:8000) \ud83c\udf89\r\n\r\n---\r\n\r\n## \ud83d\udd00 Routing\r\n\r\nRouting is how Haske connects **URLs** to **functions**.\r\n\r\n### Basic Route\r\n```python\r\n@app.route(\"/hello\")\r\nasync def say_hello(request: Request):\r\n return {\"message\": \"Hello World\"}\r\n```\r\n\r\n### Path Parameters\r\n```python\r\n@app.route(\"/user/{username}\")\r\nasync def greet_user(request: Request, username: str):\r\n return {\"message\": f\"Hello {username}\"}\r\n```\r\n\r\n### Query Parameters\r\n```python\r\n@app.route(\"/search\")\r\nasync def search(request: Request):\r\n query = request.query.get(\"q\", \"none\")\r\n return {\"search_for\": query}\r\n```\r\n\r\n### HTTP Methods\r\n```python\r\n@app.route(\"/submit\", methods=[\"POST\"])\r\nasync def submit(request: Request):\r\n data = await request.json()\r\n return {\"received\": data}\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udce5 Requests & Responses\r\n\r\nHaske provides easy access to HTTP requests and responses.\r\n\r\n### Request Object\r\n```python\r\n@app.route(\"/headers\")\r\nasync def headers(request: Request):\r\n return {\"user_agent\": request.headers.get(\"User-Agent\")}\r\n```\r\n\r\n### JSON Response\r\n```python\r\n@app.route(\"/json\")\r\nasync def json_response(request: Request):\r\n return {\"framework\": \"Haske\", \"type\": \"JSON\"}\r\n```\r\n\r\n### Redirect\r\n```python\r\nfrom haske.responses import RedirectResponse\r\n\r\n@app.route(\"/go\")\r\nasync def go(request: Request):\r\n return RedirectResponse(url=\"/hello\")\r\n```\r\n\r\n---\r\n\r\n## \ud83e\udde9 Middleware\r\n\r\n### What is Middleware?\r\nMiddleware is code that runs **before or after each request**. \r\nUses include: logging, authentication, CORS, compression, etc.\r\n\r\n### Example: Logging Middleware\r\n```python\r\nfrom haske.middleware import Middleware\r\n\r\nclass LoggingMiddleware(Middleware):\r\n async def before_request(self, request):\r\n print(f\"\u27a1\ufe0f Incoming request: {request.url}\")\r\n\r\n async def after_response(self, request, response):\r\n print(f\"\u2b05\ufe0f Response status: {response.status_code}\")\r\n\r\napp.add_middleware(LoggingMiddleware)\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udd11 Sessions\r\n\r\n### What are Sessions?\r\nHTTP is **stateless** \u2014 it doesn\u2019t remember users between requests. \r\nSessions allow you to **store user data** (like logins or cart items) across multiple requests.\r\n\r\n### Why Sessions Matter\r\n- \ud83d\udd10 Authentication (keep users logged in) \r\n- \ud83d\uded2 Shopping carts \r\n- \ud83c\udf9b Preferences & personalization \r\n\r\n### Example: Using Sessions\r\n```python\r\n@app.route(\"/login\", methods=[\"POST\"])\r\nasync def login(request: Request):\r\n data = await request.json()\r\n username = data.get(\"username\")\r\n\r\n # Save to session\r\n request.session[\"user\"] = username\r\n return {\"message\": f\"Welcome {username}\"}\r\n\r\n@app.route(\"/profile\")\r\nasync def profile(request: Request):\r\n user = request.session.get(\"user\")\r\n if not user:\r\n return {\"error\": \"Not logged in\"}\r\n return {\"profile\": f\"User profile for {user}\"}\r\n```\r\n\r\n---\r\n\r\n## \ud83c\udfa8 Templates\r\n\r\nHaske supports rendering HTML templates (Jinja2 or similar).\r\n\r\n### Example\r\n```python\r\n@app.route(\"/welcome\")\r\nasync def welcome(request: Request):\r\n return app.template(\"welcome.html\", {\"name\": \"Haske User\"})\r\n```\r\n\r\n**`templates/welcome.html`:**\r\n```html\r\n<html>\r\n <body>\r\n <h1>Welcome {{ name }}!</h1>\r\n </body>\r\n</html>\r\n```\r\n\r\n---\r\n\r\n## \ud83d\uddc4\ufe0f ORM & Database\r\n\r\nHaske can integrate with SQLAlchemy or other ORMs.\r\n\r\n### Example: SQLAlchemy\r\n```python\r\nfrom haske.orm import Model, Column, Integer, String\r\n\r\nclass User(Model):\r\n id = Column(Integer, primary_key=True)\r\n name = Column(String)\r\n\r\n# Create\r\nnew_user = User(name=\"Alice\")\r\ndb.session.add(new_user)\r\ndb.session.commit()\r\n\r\n# Query\r\nuser = User.query.filter_by(name=\"Alice\").first()\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udd10 Authentication\r\n\r\nAuthentication is usually built on top of **sessions**.\r\n\r\n### Example\r\n```python\r\n@app.route(\"/auth/login\", methods=[\"POST\"])\r\nasync def auth_login(request: Request):\r\n data = await request.json()\r\n if data[\"username\"] == \"admin\" and data[\"password\"] == \"123\":\r\n request.session[\"user\"] = \"admin\"\r\n return {\"status\": \"logged_in\"}\r\n return {\"error\": \"Invalid credentials\"}\r\n\r\n@app.route(\"/auth/protected\")\r\nasync def protected(request: Request):\r\n if request.session.get(\"user\") != \"admin\":\r\n return {\"error\": \"Unauthorized\"}\r\n return {\"message\": \"Welcome, admin!\"}\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udda5\ufe0f CLI\r\n\r\nHaske comes with a command-line interface.\r\n\r\n### Create New Project\r\n```bash\r\nhaske new myproject\r\n```\r\n\r\n### Run Server\r\n```bash\r\nhaske run\r\n```\r\n\r\n---\r\n\r\n## \ud83d\udce1 WebSockets\r\n\r\nHaske supports **real-time apps** with WebSockets.\r\n\r\n### Example: Chat\r\n```python\r\n@app.websocket(\"/ws\")\r\nasync def websocket_endpoint(socket):\r\n await socket.send(\"Welcome to Haske Chat!\")\r\n async for message in socket:\r\n await socket.send(f\"You said: {message}\")\r\n```\r\n\r\n---\r\n\r\n## \u26a0\ufe0f Error Handling\r\n\r\n### Custom Error Handler\r\n```python\r\n@app.exception_handler(404)\r\nasync def not_found(request: Request, exc):\r\n return {\"error\": \"Page not found\"}\r\n```\r\n\r\n---\r\n\r\n## \ud83e\uddea Testing\r\n\r\nHaske makes testing simple.\r\n\r\n### Example: Using pytest\r\n```python\r\nfrom haske.testing import TestClient\r\n\r\ndef test_homepage():\r\n client = TestClient(app)\r\n response = client.get(\"/\")\r\n assert response.status_code == 200\r\n assert response.json()[\"message\"] == \"Hello, Haske!\"\r\n```\r\n\r\n---\r\n\r\n## \ud83d\ude80 Deployment\r\n\r\n### Run with Uvicorn\r\n```bash\r\nuvicorn app:app --host 0.0.0.0 --port 8000 --workers 4\r\n```\r\n\r\n### Run with Gunicorn\r\n```bash\r\ngunicorn -k uvicorn.workers.UvicornWorker app:app\r\n```\r\n\r\n---\r\n\r\n## \ud83e\udd1d Contributing\r\n\r\n1. Fork the repo. \r\n2. Create a feature branch. \r\n3. Submit a pull request. \r\n\r\nWe welcome contributions in:\r\n- Bug fixes\r\n- New features\r\n- Docs improvements\r\n\r\n---\r\n\r\n## \ud83d\udcdc License\r\n\r\nMIT License \u00a9 2025 Python Katsina Community\r\n",
"bugtrack_url": null,
"license": "MIT License\r\n ",
"summary": "A high-performance Python web framework with Rust extensions",
"version": "0.2.12",
"project_urls": {
"Changelog": "https://github.com/Python-Katsina/haske-python/releases",
"Documentation": "https://haske.readthedocs.io",
"Homepage": "https://github.com/Python-Katsina/haske-python",
"Repository": "https://github.com/Python-Katsina/haske-python"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "0edbd380ea9acbdf958b4a7ab060136c77b5953718f052eb0ceaa42c8966fb67",
"md5": "48dcff5175b2e081f2ad00bd5d299fd6",
"sha256": "cc5190674e19fa0c9c7746aafae850150296fc0bd7731dcacc7883a88269db8b"
},
"downloads": -1,
"filename": "haske-0.2.12-py3-none-any.whl",
"has_sig": false,
"md5_digest": "48dcff5175b2e081f2ad00bd5d299fd6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 42055,
"upload_time": "2025-09-12T14:32:48",
"upload_time_iso_8601": "2025-09-12T14:32:48.260247Z",
"url": "https://files.pythonhosted.org/packages/0e/db/d380ea9acbdf958b4a7ab060136c77b5953718f052eb0ceaa42c8966fb67/haske-0.2.12-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-12 14:32:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Python-Katsina",
"github_project": "haske-python",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "starlette",
"specs": []
},
{
"name": "uvicorn",
"specs": []
},
{
"name": "jinja2",
"specs": []
},
{
"name": "sqlalchemy",
"specs": []
},
{
"name": "aiosqlite",
"specs": []
},
{
"name": "maturin",
"specs": [
[
"<",
"2.0"
],
[
">=",
"1.0"
]
]
},
{
"name": "setuptools",
"specs": []
},
{
"name": "setuptools-rust",
"specs": []
},
{
"name": "bcrypt",
"specs": []
},
{
"name": "itsdangerous",
"specs": []
},
{
"name": "starlette-csrf",
"specs": []
},
{
"name": "typer",
"specs": []
},
{
"name": "watchdog",
"specs": []
}
],
"lcname": "haske"
}