Langfuse Python SDK

repository·main·Indexed 19 days ago

https://github.com/langfuse/langfuse-python

An observability and tracing library for LLM applications providing tools for OpenTelemetry-based tracing, dataset management, experimentation, prompt management, and LLM-as-a-judge evaluation. It supports various observation types including spans, generations, agents, and retrievers, and offers an @observe decorator for automatic instrumentation.

Tokens
44.6K
Snippets
110
Records
146
Agent score
65%

What's inside langfuse

  1. Best practices for API and Generated Code

    main
    The langfuse/api/ directory is managed via Fern/OpenAPI. Do not hand-edit files in langfuse/api/; instead, regenerate them from the upstream source. When making public API or serialization changes, ensure you include tests for request and response shapes, and provide backwards-compatible aliases where necessary. Always update README examples, .env.template, and generated reference documentation to prevent stale usage instructions.
  2. Quickstart: Trace observations with spans and generations

    main

    Use get_client() to initialize the Langfuse client. You can then use start_as_current_observation as a context manager to create nested traces.

    • Use as_type="span" for general processing steps.
    • Use as_type="generation" for LLM calls.
    • Use .update(output=...) to record the result of an operation.
    • Observations are automatically closed when exiting the with block.
    • Call .flush() in short-lived applications to ensure all events are sent before the process exits.
    # env: LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL
    
    from langfuse import get_client
    
    langfuse = get_client()
    
    # Create a span using a context manager
    with langfuse.start_as_current_observation(as_type="span", name="process-request") as span:
        # Your processing logic here
        span.update(output="Processing complete")
    
        # Create a nested generation for an LLM call
        with langfuse.start_as_current_observation(as_type="generation", name="llm-response", model="gpt-5.6") as generation:
            # Your LLM call logic here
            generation.update(output="Generated response")
    
    # All spans are automatically closed when exiting their context blocks
    
    # Flush events in short-lived applications
    langfuse.flush()
  3. Testing requirements for Langfuse Python SDK

    main

    To ensure reliable testing of the SDK, follow these constraints:

    • Unit Tests: Must be able to run without a live Langfuse server.
    • E2E Tests:
      • Use bounded polling helpers from tests/support/ instead of using sleep().
      • Name new E2E files using the pattern tests/e2e/test_*.py to ensure they are picked up by CI sharding.
      • Use the serial_e2e marker only for tests that are unsafe when run with shared-server concurrency.
    • Live-provider Tests: Assert stable provider-facing behavior rather than exact observation counts (unless the count itself is the specific behavior being tested).
  4. Manage blob storage integrations

    main

    The BlobStorageIntegrationsClient (and its async counterpart AsyncBlobStorageIntegrationsClient) allows you to manage data export integrations to blob storage (like S3 or Azure) for your Langfuse organization.

    Note: Most operations require an organization-scoped API key.

    Key capabilities include:

    • Listing all integrations for the organization.
    • Creating or updating (upserting) an integration for a specific project.
    • Checking the sync status of an integration.
    • Deleting an existing integration.
  5. Configure Langfuse environment variables

    main

    The SDK uses the following environment variables for authentication and connection to the Langfuse platform:

    • LANGFUSE_PUBLIC_KEY: Your Langfuse public API key.
    • LANGFUSE_SECRET_KEY: Your Langfuse secret API key.
    • LANGFUSE_BASE_URL: The base URL of your Langfuse instance.
  6. Query structure for the Metrics API

    main

    The metrics method requires a JSON string query with the following schema:

    KeyTypeDescription
    viewstringRequired. One of: observations, scores-numeric, scores-boolean, scores-categorical
    metricsarrayRequired. List of objects with measure (string) and aggregation (string)
    fromTimestampstringRequired. ISO datetime string for start of range
    toTimestampstringRequired. ISO datetime string for end of range
    dimensionsarrayOptional. List of objects with field to group by
    filtersarrayOptional. List of objects with column, operator, value, and type
    timeDimensionobjectOptional. Contains granularity (auto, minute, hour, day, week, month)
    orderByarrayOptional. List of objects with field and direction (asc, desc)
    configobjectOptional. Contains bins (1-100) and row_limit (1-1000)

    Aggregation functions: sum, avg, count, max, min, p50, p75, p90, p95, p99, histogram.

    {
      "view": "observations",
      "dimensions": [
        { "field": "type" }
      ],
      "metrics": [
        { "measure": "latency", "aggregation": "avg" }
      ],
      "fromTimestamp": "2023-01-01T00:00:00Z",
      "toTimestamp": "2023-01-02T00:00:00Z"
    }
  7. Manage Annotation Queues with AnnotationQueuesClient

    main

    The AnnotationQueuesClient (and its asynchronous counterpart AsyncAnnotationQueuesClient) provides a programmatic interface to manage annotation queues in Langfuse. You can use these clients to create, retrieve, list, and manage the lifecycle of queues and the items within them.

    from langfuse import LangfuseAPI
    
    # Synchronous usage
    client = LangfuseAPI(
        x_langfuse_sdk_name="YOUR_SDK_NAME",
        x_langfuse_sdk_version="YOUR_SDK_VERSION",
        x_langfuse_public_key="YOUR_PUBLIC_KEY",
        username="YOUR_USERNAME",
        password="YOUR_PASSWORD",
        base_url="https://yourhost.com/api",
    )
    
    # Access annotation queues
    client.annotation_queues.list_queues()
  8. Access the Langfuse REST API

    main

    The Langfuse client provides access to the full Langfuse REST API through the .api property (synchronous) and .async_api property (asynchronous). Use these to read or manage data on the Langfuse server (traces, observations, scores, datasets, prompts, etc.).

    Important Semantics:

    • Ingestion is asynchronous: langfuse.flush() only guarantees delivery to the API, not immediate read visibility. A trace might not be visible via api.trace.get(trace_id) for 15-30 seconds after ingestion. Use retries with a deadline instead of fixed sleeps.
    • List vs. Get: List endpoints (e.g., api.trace.list(...)) return lightweight views where observations and scores are lists of IDs. To get full details, use api.trace.get(trace_id) or api.observations.get_many(trace_id=...).
    • Prefer v2 Data APIs: Since SDK v4, api.observations and api.metrics map to high-performance /api/public/v2/... endpoints and are the recommended read path. Avoid api.legacy endpoints for new workflows.
    • Aggregation: For large-scale aggregation (usage/cost by model, user, etc.), use the v2 Metrics API (api.metrics.metrics(...)) instead of paginating through row-level data.
  9. Filter observations using the structured filter parameter

    main

    While get_many supports individual query parameters (like user_id or type), you can use the filter parameter for complex queries. The filter parameter accepts a JSON string containing an array of filter conditions. When provided, the filter parameter takes precedence over individual query parameter filters.

    Filter Condition Structure

    Each condition requires:

    • type: One of datetime, string, number, stringOptions, categoryOptions, arrayOptions, stringObject, numberObject, boolean, null.
    • column: The field to filter on (e.g., latency, metadata, input).
    • operator: Based on type (e.g., for string: =, contains, matches; for datetime: >, <=).
    • value: The value to compare against.
    • key: Required for stringObject, numberObject, and categoryOptions when filtering nested fields like metadata.
    [
      {
        "type": "string",
        "column": "type",
        "operator": "=",
        "value": "GENERATION"
      },
      {
        "type": "number",
        "column": "latency",
        "operator": ">=",
        "value": 2.5
      },
      {
        "type": "stringObject",
        "column": "metadata",
        "key": "environment",
        "operator": "=",
        "value": "production"
      }
    ]