haske


Namehaske JSON
Version 0.2.12 PyPI version JSON
download
home_pageNone
SummaryA high-performance Python web framework with Rust extensions
upload_time2025-09-12 14:32:48
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT License
keywords
VCS
bugtrack_url
requirements starlette uvicorn jinja2 sqlalchemy aiosqlite maturin setuptools setuptools-rust bcrypt itsdangerous starlette-csrf typer watchdog
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 🌟 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"
}
        
Elapsed time: 0.48427s