Skip to main content

Async-first web framework for Python — elegant, productive, fast.

Project description

Pytisan

Async-first web framework for Python — elegant, productive, and fast.

Create an application (no install)

Like django-admin startproject, use uv and uvx (never pip):

uvx pytisan new my-blog
uvx pytisan new              # interactive prompt
uvx pytisan                    # same as `pytisan new`

This scaffolds a full app, runs uv sync --group dev, then:

cd my-blog
uv run anvil serve

Framework development

cd framework
uv sync --group dev
uv run python -m pytest
from pytisan import Application, Database, DatabaseConfig, Route, json

app = Application()


@Route.get("/users")
async def users():
    rows = await Database.table("users").where("active", True).order_by("name").get()
    return json(rows)


async def boot():
    await Database.connect(DatabaseConfig.sqlite("app.db"))
    await Database.execute(
        "CREATE TABLE IF NOT EXISTS users ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, active INTEGER DEFAULT 1)"
    )


asgi = app.asgi()

Database (SQLite)

Uses aiosqlite (async driver over SQLite / sqlite3):

from pytisan import Database, DatabaseConfig

await Database.connect(DatabaseConfig.sqlite(":memory:"))  # or "storage/app.db"

user_id = await Database.table("users").insert({"name": "Ana", "email": "a@b.com", "active": 1})
user = await Database.table("users").find(user_id)
rows = await Database.table("users").where_like("name", "%An%").get()

Active Record (Model)

from pytisan import Database, DatabaseConfig, Model

class User(Model):
    __table__ = "users"

    id: int | None
    name: str
    email: str
    active: bool

    __casts__ = {"active": "bool"}
    __fillable__ = ("name", "email", "active")

await Database.connect(DatabaseConfig.sqlite("app.db"))

user = await User.create(name="Ana", email="ana@example.com", active=True)
users = await User.query().where(active=True).order_by("name").get()
user.name = "Ana Paula"
await user.save()

Migrations

from pytisan.database.migrations import Migration, schema

class CreateUsersTable(Migration):
    async def up(self) -> None:
        await schema.create("users", self._define)

    async def down(self) -> None:
        await schema.drop("users")

    @staticmethod
    def _define(table) -> None:
        table.id()
        table.string("name").not_null()
        table.string("email").not_null().unique()
        table.timestamps()
anvil make:migration create_users_table
anvil migrate run --database storage/app.db
anvil migrate status --database storage/app.db
anvil migrate rollback --database storage/app.db
uv run uvicorn examples.hello.main:asgi --reload

CLI

Installer (new projects): uvx pytisan new [name]

Anvil (inside a project):

uv run anvil --help

# Generators
anvil make:model User -m
anvil make:controller UserController
anvil make:request StoreUserRequest
anvil make:resource UserResource
anvil make:migration create_posts_table

# Migrations
anvil migrate run --database storage/app.db
anvil migrate status --database storage/app.db
anvil migrate rollback --database storage/app.db

# Dev server
anvil serve

Layout

framework/
├── core/           # Application
├── web/            # Request, Response, ASGI
├── routing/        # Router, Route
├── database/       # SQLite async connection
├── query/          # Fluent query builder
├── tests/
├── examples/
└── pyproject.toml

License

MIT

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

pytisan_framework-0.3.6.tar.gz (48.4 kB view details)

Uploaded Source

Built Distribution

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

pytisan_framework-0.3.6-py3-none-any.whl (52.1 kB view details)

Uploaded Python 3

File details

Details for the file pytisan_framework-0.3.6.tar.gz.

File metadata

  • Download URL: pytisan_framework-0.3.6.tar.gz
  • Upload date:
  • Size: 48.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytisan_framework-0.3.6.tar.gz
Algorithm Hash digest
SHA256 1790001bf5b65ab93682b34a0977090c254652f71ab508fbbeb5d3e1a0219c6a
MD5 52bb4ac79dc39bd69d8e377036558308
BLAKE2b-256 d34371e2a25ffb1406653047f72e01f9fc7b6f4a5b139f039300f3cb791dc269

See more details on using hashes here.

File details

Details for the file pytisan_framework-0.3.6-py3-none-any.whl.

File metadata

  • Download URL: pytisan_framework-0.3.6-py3-none-any.whl
  • Upload date:
  • Size: 52.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pytisan_framework-0.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 928423a85e64f01229b7586a806ee32d823ce9f8d22aa052050c4e3c0dfcb7dc
MD5 9df6151237788e1f7a3f171016554171
BLAKE2b-256 dcd24d92448f02f6fd7c02fa7aeb7885992b08481640144e596e8aa5c1478ee8

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