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.7.tar.gz (48.7 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.7-py3-none-any.whl (52.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pytisan_framework-0.3.7.tar.gz
  • Upload date:
  • Size: 48.7 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.7.tar.gz
Algorithm Hash digest
SHA256 6bc065a54b4a7c593202c704290f2af165e187d2c4be15cdb6ee1565058269d2
MD5 a23b76b4063044293ac6135f760ca1ea
BLAKE2b-256 3b51a7a54f5d43d8b43442874fcb6ab1ce6c3c614ee54fbbe9610926aa302d88

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pytisan_framework-0.3.7-py3-none-any.whl
  • Upload date:
  • Size: 52.5 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.7-py3-none-any.whl
Algorithm Hash digest
SHA256 dfb301e9e4f1cc9494b9dfdce27c185ea366b61bb419241d82fbe2d7baf56aa4
MD5 60eef00773999b5e121febb76acab6b2
BLAKE2b-256 ecac0a0dcdb456dfc87954b6a9706b3cd59ec09445c1c88ef2f757682453a054

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