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.9.1

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.9.1
File Size Uploaded
faceplant-0.9.1.tar.gz 199.9 kB Details

Built distribution (wheel)

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

Total release size: 285.2 kB

Release files / faceplant-0.9.1.tar.gz

Download URL faceplant-0.9.1.tar.gz
Size 199.9 kB
Tags Source
SHA-256 checksum
How to use checksums
41deefedfbfd12dc1b95a43871d40d9baad85d34c2cd536d15baa91bc5ca98cc
BLAKE2b-256 checksum
How to use checksums
5a504ceaa446b337e84469f0d5975630ecee3580af5fd782520ef25a1dbd080d
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.9.1-py3-none-any.whl

Download URL faceplant-0.9.1-py3-none-any.whl
Size 85.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17f2badb3ceb8a18449eca4dadbf528fad3ed8a4792f7526280d4c7bd9797277
BLAKE2b-256 checksum
How to use checksums
00256325e9aa47794addddbeb44e2853d0bac08ffff686ce0c5293d6818a7450
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

This release

0.9.1 This release

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

0.7.5

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