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
from pytisan.database.schema import Blueprint

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: Blueprint) -> None:
        table.id()
        table.string("name").not_null()
        table.string("email").not_null().unique()
        table.timestamps()
anvil make:migration create_users_table
anvil migrate
anvil migrate:status
anvil migrate:rollback
anvil migrate:fresh
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 (reads .env — DB_CONNECTION, DB_DATABASE, …)
anvil migrate
anvil migrate:status
anvil migrate:rollback
anvil migrate:fresh
anvil migrate --database storage/other.sqlite  # optional override

# Routes
anvil route:list
anvil route:list --method GET

# Dev server
anvil serve

# Routes
anvil route:list
anvil route:list --method GET

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: pytisan_framework-0.5.0.tar.gz
  • Upload date:
  • Size: 65.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.5.0.tar.gz
Algorithm Hash digest
SHA256 a719c43babbbf5396dfa4aeac9d576376ced211be949ae7d0c5c8e29caa67bf5
MD5 bc39a628b70bdd74b5b916cd66a0afe9
BLAKE2b-256 2dea991b193e6a2970791d12566d3d6dca815e2d0c2edbe2f1ea8f9fe3cc4f78

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pytisan_framework-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 68.0 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c439132b27be3326eb8983796f054dc171faaa02f3d4d29fcb4fe429cab367af
MD5 de7949363edd4cb2be7b8d3f12bdc51a
BLAKE2b-256 63c3ad1b24aba67e35c7daf9d8a559330d42eebaf5863581b6118da72f346be1

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