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

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.4
File Size Uploaded
faceplant-0.7.4.tar.gz 171.3 kB Details

Built distribution (wheel)

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

Total release size: 238.5 kB

Release files / faceplant-0.7.4.tar.gz

Download URL faceplant-0.7.4.tar.gz
Size 171.3 kB
Tags Source
SHA-256 checksum
How to use checksums
e93f631d8b8895da2c48d16e1bc74f17e62f648efb3bc3da043acefa365d6554
BLAKE2b-256 checksum
How to use checksums
a7e16efd581d83b7f553c9b16b82994811311373265967df8b03a51f152d579b
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.4-py3-none-any.whl

Download URL faceplant-0.7.4-py3-none-any.whl
Size 67.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f480f2a6755d7e302a4c52932db71dd6e4e4d8fe39c697d8e7a17f467e2c1d4a
BLAKE2b-256 checksum
How to use checksums
693d369ce89d641f36036e20bf809c7be485a16a931b1c80f87e1827064d80a8
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

0.7.5

2 release files

This release

0.7.4 This release

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