Skip to main content

faceplant

Build a faceplant platform service in ~30 lines. Identity, the 30-second broker heartbeat, dashboards, the runtime plugin host, the daily garbage collector, and MCP tool serving are all under the hood — you write domain code.

pip install faceplant

Quickstart — a whole service

from faceplant import Service, Table, Column

svc = Service(
    "billing",
    description="Track usage bills.",
    icon="receipt",
    category="tools",
)

@svc.get("/data")
async def bills(user):                       # user.email, user.slug, user.dir
    rows = load_bills(user.dir)              # per-user private storage, created for you
    return Table(
        title="Bills",
        columns=[Column(key="month", header="Month"),
                 Column(key="amount", header="Amount")],
        rows=rows,
    )

@svc.responder("billing.total")              # a broker API other services can call
async def total(data):
    return {"total": sum_bills()}

app = svc.app                                # uvicorn src.main:app

That's the entire service. Service(...) already gave you:

  • a gateway card heartbeated every 30s (stop the pod → the card disappears);
  • /health, /manifest, /_plugins and CORS;
  • identity: user is injected from the platform JWT (401 when absent), with user.dir for per-user storage and user.tags / user.services;
  • the runtime plugin host: other services can extend this one with signed wheels, with zero code here (svc.registry if you want to add hook points);
  • the daily GC that reclaims a user's data ~10 days after they're gone.

More surfaces (each one decorator)

@svc.consumer("CHAT", filter_keys=["chat.>"])   # subscribe to broker events
async def on_chat(data): ...

@svc.mcp_tool()                                  # a tool for coding agents  (pip install faceplant[mcp])
async def get_bill(month: str) -> str: ...

svc.announce_wheel(target="faceplant-users",     # ship an extension wheel AT another service
                   wheel="plugin", entrypoint="billing_gate.plugin:register")

@svc.manifest                                    # compute the dashboard per request
def dash(user): return Stack(children=[...])

Escape hatches, always available: svc.app is a real FastAPI app (add WebSockets, SSE, middleware); svc.broker.request(key, data) / .publish(...); await svc.provision(fn) for blocking work off the DNS-critical event loop; @svc.background for startup loops; @svc.on_purge / @svc.gc_verdict to customize GC.

Testing is safe by default

Service only starts its heartbeat when a broker is actually configured (BROKER_URL set). A bare pytest or with TestClient(app) runs offline — no accidental registration against a live gateway. To test online behavior, use the in-process stub:

from fastapi.testclient import TestClient
from faceplant.testing import StubBroker, dev_jwt

def test_bills():
    with TestClient(svc.app) as client:                    # offline: no heartbeat
        r = client.get("/data", headers={"authorization": f"Bearer {dev_jwt('a@b.co')}"})
        assert r.status_code == 200

async def test_registration():
    stub = StubBroker(); stub.install(svc)
    await stub.beat(svc)
    assert "billing.total" in stub.responders

Deployment is boilerplate-free too

Your repo needs no Dockerfile and no k8s/values-prod.yaml — the SDK generates them. A deployable service is just src/main.py, pyproject.toml, and a ~10-line deploy workflow that calls the SDK's reusable one:

jobs:
  deploy:
    uses: faceplant-ai/faceplant-sdk/.github/workflows/deploy-service.yml@v1
    with: { service: billing, kind: stateless }
    secrets: inherit

Or generate the files to check in: faceplant init --name billing. See docs/deployment.md.

Docs

One page per concept in docs/: identity, widgets, plugin-host, providers, consumers & responders, mcp, gc, escape hatches, testing, and migrating from the template.

License

MIT.

Metadata

Release files for faceplant 0.7.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for faceplant 0.7.5
File Size Uploaded
faceplant-0.7.5.tar.gz 173.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for faceplant 0.7.5
File Interpreter ABI Platform
faceplant-0.7.5-py3-none-any.whl Python 3 none any Details

Total release size: 241.1 kB

Release files / faceplant-0.7.5.tar.gz

Download URL faceplant-0.7.5.tar.gz
Size 173.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ecad88fc9710b158ad1d2e5ca09e7932b97d827162030e99d684d6d672b484c7
BLAKE2b-256 checksum
How to use checksums
89dcdc396e857d33d4f978937997f92c0eeb103ab857d1a5999fd2ab7aab94e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / faceplant-0.7.5-py3-none-any.whl

Download URL faceplant-0.7.5-py3-none-any.whl
Size 68.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b1d07e3162d60978e5d0f982a78d4210453411afbb18be03e450785930be541c
BLAKE2b-256 checksum
How to use checksums
e78ba926f87f81ebbadbd17ff82914f265e7d9848f87d51d5c115b56bda31ee0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.7

2 release files

0.7.6

2 release files

This release

0.7.5 This release

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page