Tina4Python - This is not another framework for Python
Project description
Tina4 Python — This is not a framework
Laravel joy. Python speed. 10x less code.
Quickstart
pip install tina4-python
tina4 init my_project
cd my_project
python app.py
You've just built your first Tina4 app — zero configuration, zero classes, zero boilerplate!
Prefer uv? Replace
pip install tina4-pythonwithuv add tina4-python, then useuv run tina4 startto launch the dev server.
Features
- ASGI compliant — works with any ASGI server (uvicorn, hypercorn, daphne)
- Full async — every route handler is
asyncby default - Routing — decorator-based with path parameters, type hints, and auto-discovery
- Twig/Jinja2 templates — with inheritance, partials, custom filters, and globals
- ORM — define models with typed fields, save/load/select/delete with one line
- Database — SQLite, PostgreSQL, MySQL, MariaDB, MSSQL, Firebird
- Migrations — versioned SQL files, CLI scaffolding
- Sessions — file, Redis, Valkey, or MongoDB backends
- JWT authentication — auto-generated RSA keys, bearer tokens, form tokens
- Swagger/OpenAPI — auto-generated docs at
/swagger - CRUD scaffolding — instant admin UI with one line of code
- Middleware — before/after hooks per route or globally
- Queues — background processing with litequeue, RabbitMQ, Kafka, or MongoDB
- WebSockets — built-in support via
simple-websocket - WSDL/SOAP — auto-generated WSDL from Python classes
- REST client — built-in
Apiclass for external HTTP calls - SCSS compilation — auto-compiled to CSS on save
- Live reload — browser auto-refreshes during development
- Inline testing — decorator-based test cases with
@tests - Localization — i18n via gettext (English, French, Afrikaans)
Install
pip install tina4-python
Or with uv (recommended for dependency management):
uv add tina4-python
Routing
Routes live in src/routes/ and are auto-discovered on startup.
# src/routes/hello.py
from tina4_python import get
@get("/hello")
async def get_hello(request, response):
return response("Hello, Tina4 Python!")
@get("/hello/{name}")
async def get_hello_name(name, request, response):
return response(f"Hello, {name}")
@get("/hello/json")
async def get_hello_json(request, response):
return response([{"brand": "BMW"}, {"brand": "Toyota"}])
@get("/hello/template")
async def get_hello_template(request, response):
return response.render("index.twig", {"data": request.params})
@get("/hello/redirect")
async def get_hello_redirect(request, response):
return response.redirect("/hello/world")
ORM
# src/orm/User.py
from tina4_python import ORM, IntegerField, StringField
class User(ORM):
id = IntegerField(primary_key=True, auto_increment=True)
name = StringField()
email = StringField()
User({"name": "Alice", "email": "alice@example.com"}).save()
Database
from tina4_python.Database import Database
db = Database("sqlite3:app.db")
result = db.fetch("SELECT * FROM users WHERE age > ?", [18])
Works with SQLite, PostgreSQL, MySQL, MariaDB, MSSQL, and Firebird.
Migrations
tina4 migrate:create "create users table"
# Edit the generated SQL file in migrations/
tina4 migrate
Sessions
Built-in session management with pluggable backends:
| Handler | Backend | Package |
|---|---|---|
SessionFileHandler (default) |
File system | — |
SessionRedisHandler |
Redis | redis |
SessionValkeyHandler |
Valkey | valkey |
SessionMongoHandler |
MongoDB | pymongo |
request.session.set("name", "Joe")
name = request.session.get("name")
Queues
Background processing with litequeue (default), RabbitMQ, Kafka, or MongoDB.
from tina4_python.Queue import Queue, Producer, Consumer
Producer(Queue(topic="emails")).produce({"to": "alice@example.com"})
for msg in Consumer(Queue(topic="emails")).messages():
print(msg.data)
Middleware
from tina4_python.Router import get, middleware
class AuthCheck:
@staticmethod
def before_auth(request, response):
if "authorization" not in request.headers:
return request, response("Unauthorized", 401)
return request, response
@middleware(AuthCheck)
@get("/protected")
async def protected(request, response):
return response({"secret": True})
Swagger / OpenAPI
Auto-generated at /swagger. Add metadata with decorators:
from tina4_python import description, tags
@get("/users")
@description("Get all users")
@tags(["users"])
async def users(request, response):
return response(User().select("*"))
REST Client
from tina4_python import Api
api = Api("https://api.example.com", auth_header="Bearer xyz")
result = api.get("/users/42")
WSDL / SOAP
from tina4_python.WSDL import WSDL, wsdl_operation
class Calculator(WSDL):
SERVICE_URL = "http://localhost:7145/calculator"
def Add(self, a: int, b: int):
return {"Result": a + b}
Testing
from tina4_python import tests
@tests(
assert_equal((7, 7), 1),
assert_raises(ZeroDivisionError, (5, 0)),
)
def divide(a: int, b: int) -> float:
if b == 0:
raise ZeroDivisionError("division by zero")
return a / b
Run with tina4 test or uv run pytest --verbose.
Environment
Key .env settings:
SECRET=your-jwt-secret
API_KEY=your-api-key
DATABASE_NAME=sqlite3:app.db
TINA4_DEBUG_LEVEL=ALL
TINA4_LANGUAGE=en
TINA4_SESSION_HANDLER=SessionFileHandler
SWAGGER_TITLE=My API
Further Documentation
Community
License
MIT (c) 2007-2025 Tina4 Stack https://opensource.org/licenses/MIT
Tina4 — The framework that keeps out of the way of your coding.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tina4_python-0.2.193.tar.gz.
File metadata
- Download URL: tina4_python-0.2.193.tar.gz
- Upload date:
- Size: 396.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1f7f7e9f6baf69cb1aa526537d23da0545c9d0d5bcfff6b790495ad65002312
|
|
| MD5 |
7304eee12ae75972c1db64311b0f60f6
|
|
| BLAKE2b-256 |
6423cf29bf8d9f3f6af0d4e904b99d610337a767916d0622e0eacd23a2e1dd9e
|
File details
Details for the file tina4_python-0.2.193-py3-none-any.whl.
File metadata
- Download URL: tina4_python-0.2.193-py3-none-any.whl
- Upload date:
- Size: 440.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ade5ee8962fbe0cc9abd24971f080acbca471f31d1de3817e0807624dfdd9f1
|
|
| MD5 |
5e1b2088c7b16ed6c380728160d3d329
|
|
| BLAKE2b-256 |
89e1178cc24b10aec58551f7dd53a5885b965e511a6535f09ca756532fe0c408
|