Skip to main content

Official Python SDK for the Enprompta API

Project description

enprompta

Official Python SDK for the Enprompta API.

Installation

pip install enprompta
# or
poetry add enprompta
# or
pipenv install enprompta

Requirements

  • Python 3.8+
  • httpx 0.25+
  • pydantic 2.0+

Quick Start

import asyncio
from enprompta import Enprompta

async def main():
    # Initialize with API key
    client = Enprompta(api_key="ep_your_api_key")

    # List prompts
    prompts = await client.prompts.list()
    for prompt in prompts.data:
        print(prompt.title)

    # Create a prompt
    prompt = await client.prompts.create(
        title="Email Writer",
        content="Write a professional email about {{topic}}",
        visibility="PRIVATE"
    )

    # Execute a prompt
    result = await client.prompts.execute(
        prompt.id,
        variables={"topic": "project update"},
        provider="openai",
        model="gpt-4"
    )

    print(result.output)

asyncio.run(main())

Authentication

API Key

from enprompta import Enprompta

client = Enprompta(api_key="ep_your_api_key")

OAuth2 Client Credentials

client = Enprompta(
    client_id="your_client_id",
    client_secret="your_client_secret",
    scopes=["prompts:read", "prompts:write"]
)

Environment Variables

# Set these environment variables:
# ENPROMPTA_API_KEY
# ENPROMPTA_CLIENT_ID
# ENPROMPTA_CLIENT_SECRET

client = Enprompta()  # Auto-reads from environment

Features

Prompts

# List with pagination
response = await client.prompts.list(limit=20, visibility="PRIVATE")
for prompt in response.data:
    print(prompt.title)

# Auto-pagination
async for prompt in client.prompts.list_all():
    print(prompt.title)

# Create
prompt = await client.prompts.create(
    title="My Prompt",
    content="Hello {{name}}",
    variables=[{"name": "name", "type": "text", "required": True}]
)

# Get
prompt = await client.prompts.get("prompt_id")

# Update
await client.prompts.update("prompt_id", title="New Title")

# Delete
await client.prompts.delete("prompt_id")

# Execute
result = await client.prompts.execute(
    "prompt_id",
    variables={"name": "World"},
    provider="openai",
    model="gpt-4"
)

Executions

# List executions
response = await client.executions.list(
    prompt_id="prompt_id",
    start_date="2024-01-01"
)

# Get statistics
stats = await client.executions.get_stats(group_by="day")

Teams

teams = await client.teams.list()
team = await client.teams.create(name="Engineering")
await client.teams.update("team_id", name="New Name")

Webhooks

webhook = await client.webhooks.create(
    name="My Webhook",
    url="https://example.com/webhook",
    events=["prompt.created", "execution.completed"]
)

Synchronous Client

For non-async code:

from enprompta import EnpromptaSync

client = EnpromptaSync(api_key="ep_your_api_key")

# All methods work without await
prompts = client.prompts.list()
prompt = client.prompts.create(title="My Prompt", content="Hello")

Context Manager

# Async
async with Enprompta(api_key="ep_your_api_key") as client:
    prompts = await client.prompts.list()

# Sync
with EnpromptaSync(api_key="ep_your_api_key") as client:
    prompts = client.prompts.list()

Error Handling

from enprompta.exceptions import (
    EnpromptaError,
    AuthenticationError,
    RateLimitError,
    ValidationError,
    NotFoundError
)

try:
    await client.prompts.get("invalid_id")
except NotFoundError:
    print("Prompt not found")
except RateLimitError as e:
    print(f"Retry after {e.retry_after}s")
except EnpromptaError as e:
    print(f"Error {e.code}: {e.message}")

LLM Observability & Tracing

@trace Decorator

Automatically trace any LLM function with the @trace decorator:

from enprompta import Enprompta, trace
import openai

client = Enprompta(api_key="ep_your_api_key")

@trace(client, provider="openai", model="gpt-4")
def generate_response(prompt: str) -> str:
    response = openai.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.choices[0].message.content

# Traces are automatically recorded with timing, tokens, and cost
result = generate_response("Explain quantum computing")

Async Support

@trace(client, provider="anthropic", model="claude-3-sonnet", session_id="user-123")
async def async_chat(prompt: str) -> str:
    response = await anthropic.messages.create(
        model="claude-3-sonnet-20240229",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.content[0].text

Auto-traced OpenAI Client

Wrap your OpenAI client for zero-code tracing:

from enprompta import Enprompta, traced_openai
from openai import OpenAI

enprompta = Enprompta(api_key="ep_...")
openai = traced_openai(enprompta, OpenAI())

# All calls are now automatically traced!
response = openai.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}]
)

Context Manager (Manual Tracing)

For more control, use the context manager:

with client.traces.wrap(
    provider="openai",
    model="gpt-4",
    input="Hello"
) as ctx:
    response = openai.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": "Hello"}]
    )
    ctx.set_output(
        output=response.choices[0].message.content,
        input_tokens=response.usage.prompt_tokens,
        output_tokens=response.usage.completion_tokens
    )

print(f"Trace ID: {ctx.trace_id}")

Nested Spans for Complex Pipelines

Track multi-step operations like RAG:

# Record the main trace
result = client.traces.record(
    provider="openai",
    model="gpt-4",
    input="What are our refund policies?",
    output="Based on our documentation...",
    latency_ms=2500
)

# Add spans for each step
client.traces.create_span(
    result["trace_id"],
    name="vector_search",
    span_type=SpanType.RETRIEVAL,
    input={"query": "refund policies", "top_k": 5},
    output={"document_ids": ["doc1", "doc2"]},
    duration_ms=150
)

client.traces.create_span(
    result["trace_id"],
    name="embedding",
    span_type=SpanType.EMBEDDING,
    tokens=8,
    duration_ms=50
)

Webhook Signature Verification

from enprompta.webhooks import verify_signature

# In your webhook handler (FastAPI example)
@app.post("/webhooks/enprompta")
async def handle_webhook(request: Request):
    payload = await request.body()
    signature = request.headers.get("X-Enprompta-Signature")

    if not verify_signature(payload, signature, webhook_secret):
        raise HTTPException(status_code=401)

    event = json.loads(payload)
    print(f"Received: {event['event']}")
    return {"status": "ok"}

Type Hints

Full type hint support:

from enprompta.types import (
    Prompt,
    Execution,
    Team,
    Webhook,
    CreatePromptParams,
    ExecutePromptParams
)

Documentation

Full documentation: https://enprompta.com/docs/sdk/python

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

enprompta-1.0.0.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

enprompta-1.0.0-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file enprompta-1.0.0.tar.gz.

File metadata

  • Download URL: enprompta-1.0.0.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enprompta-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2cbb6103e6f86d402744134316ddfbe0cd13af15e4eb1bdc14bf1ffba9781712
MD5 06b4a745c809d014aa57e4939e680c24
BLAKE2b-256 cdb82a963f73b4d130c5c8b9054c6f095ef78f40529d71a37b3654cffd4ff783

See more details on using hashes here.

Provenance

The following attestation bundles were made for enprompta-1.0.0.tar.gz:

Publisher: publish-sdk-python.yml on igwebupower/enprompta

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file enprompta-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: enprompta-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enprompta-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1e53c66c78ffed7132c6e3481d64aa4a5acad1b7bf81b15c220e7c0eb895dde2
MD5 e2c7fb83033d36a31761784b0ede9829
BLAKE2b-256 100dbfa6305fac5f3f1c0d5bdc4313bef25e437b80f89096ff726617f3413fca

See more details on using hashes here.

Provenance

The following attestation bundles were made for enprompta-1.0.0-py3-none-any.whl:

Publisher: publish-sdk-python.yml on igwebupower/enprompta

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page