Apothic Client Quickstart

Install the Apothic Python SDK, configure authentication, deploy your first app, and understand the next client features you can layer in.

Last updated: 4/23/2026
API Version: v0.1.0
apothic-clientpythonquickstartdeployment

Apothic Client Quickstart#

apothic-client is the Python SDK and CLI for packaging apps, deploying them to Apothic, and invoking functions, services, and shared primitives from your own code.

This guide gives you the shortest end-to-end path:

  1. Install the SDK.
  2. Define a function.
  3. Configure authentication.
  4. Deploy the app.
  5. Run it from Python or the CLI.

Once that works, you can widen the same client surface toward services, stateful resources, storage, and GPU placement filters.

Prerequisites#

  • Python 3.11 or newer
  • uv or pip
  • An Apothic account with access to https://run.apothic.ai

Install#

Use uv:

uv add apothic

Or use pip:

pip install apothic

The package installs the apothic CLI as well.

Your first app#

Create hello_app.py:

from apothic import App, RemoteFunction

app = App("hello-world")


@app.function(cpu=1, memory_mb=512, timeout_s=60)
def greet(name: str) -> str:
    return f"hello, {name}"


@app.local_entrypoint()
def main() -> None:
    deployment_id = app.deploy()
    remote = RemoteFunction.from_name("hello-world", "greet")
    print("deployment:", deployment_id)
    print(remote.remote("world"))

What this does:

  • creates an app named hello-world
  • defines one remote function named greet
  • deploys the app when you run the local entrypoint
  • looks the function up by name and invokes it remotely

Configure authentication#

Set your API key before you deploy or invoke:

export APOTHIC_API_KEY=your_apothic_api_key

The most common environment variables are:

  • APOTHIC_API_KEY
  • APOTHIC_AUTH_TOKEN
  • APOTHIC_AUTH_HEADER
  • APOTHIC_BASE_URL

Fund your account before billable work#

Runtime usage is tied to your Apothic account balance.

Before you run billable workloads, top up your balance from the website billing dashboard:

  • open /dashboard/billing
  • click Add Funds
  • complete the checkout flow

If your account is not funded, new runtime work may be blocked by billing policy.

Deploy from the CLI#

You can deploy the same file without writing any deployment glue:

apothic deploy hello_app.py

If the file contains multiple apps, pass the app name explicitly:

apothic deploy hello_app.py --app-name hello-world

Run a function from the CLI#

After deployment, invoke the function by app and function name:

apothic run greet \
  --app-name hello-world \
  --payload '{"args":["world"],"kwargs":{}}'

That returns the structured job response. If you want to follow execution as it happens, add --watch:

apothic run greet \
  --app-name hello-world \
  --payload '{"args":["world"],"kwargs":{}}' \
  --watch

Run a function from Python#

If you prefer Python for the invocation path:

from apothic import RemoteFunction

remote = RemoteFunction.from_name("hello-world", "greet")
result = remote.remote("team")
print(result)

For background jobs:

job = remote.spawn("background")
print(job.job_id)
print(job.wait())

Add a richer runtime shape when you need it#

The same client surface can also express:

  • explicit images and build context
  • mounted storage
  • secrets
  • GPU placement
  • structured capacity filters

For example:

from apothic import App, Image, Secret, Volume

app = App("gpu-demo")

fast_cache = Volume.vast_local("fast-cache", size_gb=50).mounted_at("/cache")


@app.function(
    image=Image.debian_slim().uv_pip_install("numpy"),
    secrets=[Secret.from_name("HF_TOKEN")],
    volumes=[fast_cache],
    gpu=["RTX_4070", "RTX_4070S", "RTX_4070_TI", "RTX_3080", "RTX_3060", "RTX_3060_TI"],
    gpu_count=1,
    min_vram_gb=10,
    geolocation=["US", "CA"],
    disk_gb=160,
    offer_filters={
        "verification": {"eq": "verified"},
        "cpu_arch": {"eq": "amd64"},
    },
)
def infer(prompt: str) -> str:
    return prompt

You do not need all of those fields for a first app. The point is that you can start small and widen the resource shape only where the workload actually demands it.

For simple custom base-image cases, the runtime can execute the base image directly. If a Linux base image does not already contain a suitable Python runtime, the current runtime can fall back to a managed CPython for execution and later reuse an optimized derived image when needed.

Common lookup signatures#

These are the two lookup forms most people use first:

RemoteFunction.from_name(
    app_name: str,
    function_name: str,
    *,
    client: ControlPlaneClient | None = None,
    base_url: str | None = None,
) -> RemoteFunction

remote.remote(*args, timeout_s: float = 600.0, **kwargs) -> Any
remote.spawn(*args, **kwargs) -> Job
remote.remote_events(*args, snapshot: bool = False, event_types: list[str] | tuple[str, ...] | None = None, **kwargs)

Once you move beyond a single stateless function, the rest of the API surface is covered in the dedicated guides below.

Generated functions with @apothic.liv(...)#

If you want Apothic to generate the implementation from a function stub before deploy, use @apothic.liv(...):

import apothic

app = apothic.App("generated-demo")


@apothic.liv(
    self_debug=True,
    cache="account",
    examples=[((" READY ",), {})],
)
@app.function(cpu=1, memory_mb=512, timeout_s=60)
def normalize_status(status: str) -> str:
    """Return exactly `status:` followed by the lowercase input stripped of outer whitespace."""
    raise NotImplementedError

The current integration mode is deploy-time freeze:

  • the generated implementation is materialized before deploy
  • Apothic packages the generated module into the app archive
  • the remote worker then runs ordinary frozen Python

Storage, secrets, and stateful resources#

The client now also exposes:

  • Volume.from_name(...), Volume.create(...), Volume.vast_local(...), and Volume.ephemeral(...)
  • CloudBucketMount(...)
  • Secret.create(...), Secret.set(...), Secret.list(...), and Secret.delete(...)
  • @app.cls(...) for stateful class-style resources
  • app.sandbox(...) for named workspaces with filesystem and command APIs

Those are covered in more detail in the dedicated storage and sandbox guide below.

Configuration#

apothic-client targets https://run.apothic.ai by default.

You can override the control plane URL in two ways:

export APOTHIC_BASE_URL=https://run.apothic.ai

or per command:

apothic deploy hello_app.py --base-url https://run.apothic.ai

What to learn next#