Skip to main content

Vanty App: headless content & blog (pages, collections, tags, authors, sitemap).

Project description

Vanty Content

PyPI Python

Headless content & blog toolkit for FastAPI with Tortoise ORM. Pages with BlockNote bodies, collections, tags, authors, content calendars, public blog endpoints, signed preview tokens, and an XML sitemap — in a single pip install.

Installation

pip install vanty-content
# or
uv pip install vanty-content

Quick start

from contextlib import asynccontextmanager

from fastapi import FastAPI

from vanty_content import ContentSettings, mount_content_router

settings = ContentSettings(
    database_url="sqlite://./vanty-content.db",
    base_url="https://example.com",
    preview_secret="change-me",
)

app = FastAPI()
kit = mount_content_router(app, settings)
app.include_router(kit.admin_router)


@asynccontextmanager
async def lifespan(_: FastAPI):
    await kit.init_orm(generate_schemas=True)
    try:
        yield
    finally:
        await kit.close_orm()


app.router.lifespan_context = lifespan

The package depends on vanty-core for events and the OrganizationScopedModel base, and integrates with vanty-auth only via the AuthContext resolver — never via direct ORM imports.

For documentation, see your hosted Docs site (Fumadocs / external) — this package no longer ships any docs surface itself.

BlockNote round-trip

Page bodies are opaque BlockNote JSON: a list[dict] of block nodes. The package never parses inner blocks; bodies round-trip exactly between write and read.

from uuid import uuid4

from vanty_content import ContentApp, ContentSettings
from vanty_content.schemas.page import PageCreate

org_id = uuid4()
kit = ContentApp(ContentSettings(database_url="sqlite://:memory:"))
await kit.init_orm(generate_schemas=True)

body = [
    {"type": "paragraph", "content": [{"type": "text", "text": "Hello"}]},
    {
        "type": "heading",
        "props": {"level": 2},
        "content": [{"type": "text", "text": "World"}],
    },
]

page = await kit.page_service.create(
    org_id, PageCreate(title="Hello, world", slug="hello-world", body=body)
)
await kit.page_service.publish(org_id, page.id)

# GET /content/blog/hello-world returns identical body bytes.
fresh = await kit.page_service.get_by_slug(org_id, "hello-world", published_only=True)
assert fresh.body == body

Public endpoints

Mounted under prefix="/content" by default:

Method Path Description
GET /content/blog Paginated published posts. Filters: collection, tag, page, size.
GET /content/blog/{slug} Single published post by slug.
GET /content/preview/{page_id} Preview a draft page using ?token=.
GET /content/sitemap.xml XML sitemap of all published pages for the resolved organization.

The organization is resolved from the X-Organization-ID header, the current vanty-auth AuthContext, or app.state.content_organization_id_override (used in tests).

Admin endpoints

ContentApp.admin_router is mounted by the host with require_superuser enforced. Routes live under /admin/content/: pages, collections, tags, authors, and projects/{id}/calendar.

Events

All events are typed dataclasses on the shared vanty-core event bus.

from vanty_core.events import on
from vanty_content.events import PagePublished


@on(PagePublished)
async def push_to_cdn(event: PagePublished) -> None:
    ...
Event name Dataclass
vanty_content.page.created PageCreated
vanty_content.page.updated PageUpdated
vanty_content.page.published PagePublished
vanty_content.page.unpublished PageUnpublished
vanty_content.page.scheduled PageScheduled
vanty_content.page.deleted PageDeleted
vanty_content.collection.created CollectionCreated
vanty_content.author.created AuthorCreated
vanty_content.calendar.item_scheduled CalendarItemScheduled

Publish to GitHub

This package lives inside the Vanty monorepo at vanty-all/vanty-content/. To publish a standalone, history-preserving GitHub repo using git filter-repo:

make publish-github REPO=git@github.com:advantch/vanty-content.git

The Makefile clones the monorepo to a scratch directory, filters to the vanty-content/ subdirectory, points origin at the requested repo, and prints the final git push command — it never pushes for you.

License

MIT — Themba themba@advantch.com

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

vanty_content-0.3.0.tar.gz (91.1 kB view details)

Uploaded Source

Built Distribution

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

vanty_content-0.3.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file vanty_content-0.3.0.tar.gz.

File metadata

  • Download URL: vanty_content-0.3.0.tar.gz
  • Upload date:
  • Size: 91.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vanty_content-0.3.0.tar.gz
Algorithm Hash digest
SHA256 3fa2b0fb283f56089ded50d5ab885e625c5c1d4da793fc1e4d51e82a1a36e99b
MD5 160317a57a718ce942f62c0450b22d02
BLAKE2b-256 b17922649d87f3dee8fef2a259bc418da027ff19b7a5818d956d7a65ff8ec5d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for vanty_content-0.3.0.tar.gz:

Publisher: release.yml on advantch/vanty-content

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vanty_content-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: vanty_content-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vanty_content-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 907c26f39a2894b817d09d1e69abf0a0e51df0190e6614c6cd49f721820aecb0
MD5 33f375a05eb03de7f8cf8570b7e3b735
BLAKE2b-256 c019adba9dbb18f85a5c48f913e058eb06974789007bf951a31d7a1f8d611726

See more details on using hashes here.

Provenance

The following attestation bundles were made for vanty_content-0.3.0-py3-none-any.whl:

Publisher: release.yml on advantch/vanty-content

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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