Python SDK

Install the foilengine package and integrate NPC conversations into your Python project.

Installation

pip install foilengine

Quick Start

from foilengine import FoilEngineClient

client = FoilEngineClient(api_key="pk_live_...")

# Discover your personas
personas = client.personas.list()
print(personas[0].name)  # "Grumpy Barista"

# Initialize a session
session = client.chat.init_session(
    persona_id=personas[0].id,
    user_session_id="player-001",
    player_name="Alex",
    player_gender="non-binary",
)
print(session.message)  # NPC's greeting

# Send a message
response = client.chat.send_message(
    persona_id=personas[0].id,
    message="What do you recommend?",
    user_session_id="player-001",
)
print(response.message)       # NPC's reply
print(response.current_state) # State machine state
print(response.score)         # Session score

Configuration

ParameterTypeDefaultDescription
api_keystrrequiredYour API key
base_urlstrhttps://api.foilengine.ioAPI base URL (override for local dev)
timeoutfloat30.0Request timeout in seconds
max_retriesint3Max retries on 429/5xx errors

Available Methods

Personas

MethodReturnsDescription
client.personas.list()list[Persona]List all published personas

Machines

MethodReturnsDescription
client.machines.list(persona_id, user_session_id)list[MachineInfo]List available machines for a player

Chat

MethodReturnsDescription
client.chat.init_session(...)SessionInitStart a new conversation
client.chat.send_message(...)ChatResponseSend a message, get NPC reply
client.chat.get_session(...)SessionStatusCheck if a session exists
client.chat.get_history(...)ChatHistoryGet full message history
client.chat.reset(...)ResetResultDelete a session

Async Support

Use AsyncFoilEngineClient for async/await:

from foilengine import AsyncFoilEngineClient

async def main():
    async with AsyncFoilEngineClient(api_key="pk_live_...") as client:
        personas = await client.personas.list_async()
        response = await client.chat.send_message_async(
            persona_id=personas[0].id,
            message="Hello!",
            user_session_id="player-001",
        )
        print(response.message)

Error Handling

All API errors are raised as typed exceptions:

from foilengine import (
    FoilEngineClient,
    AuthenticationError,
    NotFoundError,
    RateLimitError,
)

client = FoilEngineClient(api_key="pk_live_...")

try:
    session = client.chat.get_session("persona-id", "player-001")
except NotFoundError:
    # No existing session — initialize one
    session = client.chat.init_session(...)
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
ExceptionStatusWhen
BadRequestError400Invalid UUID, missing fields
AuthenticationError401Missing or invalid API key
ForbiddenError403Not owner or persona unpublished
NotFoundError404Resource not found
RateLimitError429Rate limit exceeded
ServerError500Internal server error
💡Tip
The SDK automatically retries on 429 and 5xx errors with exponential backoff (up to 3 retries). You only need to handle errors that persist after retries.

Multi-Machine Example

# Discover available machines for a player
machines = client.machines.list(persona_id, "player-001")

for m in machines:
    status = "active" if m.has_session else "available"
    linked = " (linked)" if m.is_linked else ""
    print(f"  {m.name}: {status}{linked}")

# Start a specific machine
session = client.chat.init_session(
    persona_id=persona_id,
    user_session_id="player-001",
    player_name="Alex",
    player_gender="non-binary",
    machine_id=machines[1].machine_id,  # target a specific scenario
)