Apothic Client Liv and Generated Functions

Generate deployable Python implementations from function stubs with @apothic.liv(...) and LivConfig.

Last updated: 4/21/2026
API Version: v0.1.0
apothic-clientlivgenerated-codefunctions

Apothic Client Liv and Generated Functions#

apothic-client includes an optional liv integration for generated Python functions.

Use it when you want to:

  • start from a function stub
  • generate the implementation before deploy
  • preserve the generated result as part of a normal Apothic deployment
  • reuse generated artifacts through a cache that is scoped to your Apothic account or app

The current model#

The current integration mode is deploy-time freeze.

That means Apothic:

  1. materializes the implementation before deploy
  2. writes it into a generated Python module
  3. packages that generated module into the normal app source archive
  4. deploys the frozen result like ordinary Python

The remote worker runs the frozen generated module, not a generation loop at runtime.

Core signatures#

@apothic.liv(
    *,
    client: Any | None = None,
    model: str | None = None,
    base_url: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
    temperature: float | None = None,
    self_debug: bool | int | None = None,
    max_repair_attempts: int | None = None,
    sandbox: bool | None = None,
    allowed_modules: tuple[str, ...] | None = None,
    tools: tuple[Callable[..., Any], ...] = (),
    examples: tuple[tuple[tuple[Any, ...], dict[str, Any]], ...] = (),
    mode: str = "freeze",
    cache: str = "account",
    cache_namespace: str | None = None,
    prompt_salt: str | None = None,
    force_regenerate: bool = False,
    target_context: Mapping[str, Any] | None = None,
)

LivConfig(
    client: Any | None = None,
    model: str | None = None,
    base_url: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
    temperature: float | None = None,
    self_debug: bool | int | None = None,
    max_repair_attempts: int | None = None,
    sandbox: bool | None = None,
    allowed_modules: tuple[str, ...] | None = None,
    tools: tuple[Callable[..., Any], ...] = (),
    examples: tuple[tuple[tuple[Any, ...], dict[str, Any]], ...] = (),
    mode: str = "freeze",
    cache: str = "account",
    cache_namespace: str | None = None,
    prompt_salt: str | None = None,
    force_regenerate: bool = False,
    target_context: Mapping[str, Any] | None = None,
)

Basic example#

import apothic

app = apothic.App("liv-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

Once deployed, it behaves like any other remote function:

remote = apothic.RemoteFunction.from_name("liv-demo", "normalize_status")
print(remote.remote(" READY "))

LivConfig#

If you prefer to keep everything on the resource decorator, use LivConfig:

import apothic

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


@app.function(
    cpu=1,
    memory_mb=512,
    timeout_s=60,
    liv=apothic.LivConfig(
        self_debug=True,
        cache="account",
        examples=[((" READY ",), {})],
    ),
)
def normalize_status(status: str) -> str:
    raise NotImplementedError

Supported resource types#

The current liv integration is supported on:

  • @app.function(...)
  • @app.endpoint(...)

Cache modes#

The current cache modes are:

  • memory
  • account
  • app
  • custom

Recommended defaults:

  • use account when you want generated artifacts reusable across your own apps
  • use app when you want reuse only inside one app
  • use memory for isolated local experiments

Target-context-aware generation#

Generated code is not keyed only by the stub source. Apothic also folds the declared execution context into the materialization identity.

That includes:

  • function kind
  • CPU, memory, GPU, timeout, concurrency, and batching settings
  • offer_filters, disk_gb, and service_startup_timeout_s
  • image base, pip dependencies, apt packages, environment variables, commands, and build-context mounts
  • volumes
  • secret names
  • schedule metadata when present

That means changing the declared execution context changes the generation context too.

Generated endpoints#

You can also use liv on a lightweight endpoint:

import apothic

app = apothic.App("liv-endpoint")


@apothic.liv(
    self_debug=True,
    cache="account",
    examples=[((), {})],
)
@app.endpoint(cpu=1, memory_mb=512, timeout_s=120, keep_warm_s=300)
def status() -> dict[str, str]:
    """Return exactly a JSON object with two string keys: `status` set to `ready` and `source` set to `liv`."""
    raise NotImplementedError

That endpoint path is already validated against the current public stack.

Checked-in examples#

  • apps/apothic-client/examples/liv_freeze_preview.py
  • apps/apothic-client/examples/run_liv_roundtrip.py
  • apps/apothic-client/examples/run_liv_endpoint_roundtrip.py

What to learn next#