Skip to content

feat: Add Programmatic Configuration Support for Tracing Decorators #495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 31, 2025

Conversation

viniciusdsmello
Copy link
Contributor

Add Programmatic Configuration Support for Tracing Decorators

🚀 Overview

This PR adds the ability to programmatically configure API keys and pipeline IDs for Openlayer tracing decorators, providing an alternative to environment variables for more flexible runtime configuration.

🎯 Problem

Previously, users could only configure tracing through environment variables:

# Only option before this PR
os.environ["OPENLAYER_API_KEY"] = "your_api_key_here"
os.environ["OPENLAYER_INFERENCE_PIPELINE_ID"] = "your_pipeline_id_here"

@trace()
def my_function():
    return "result"

This approach had limitations:

  • No runtime flexibility - configuration must be set before application startup
  • Multi-environment challenges - difficult to switch between different API keys/pipeline IDs
  • Docker/containerization issues - requires environment variable management in deployment
  • Testing complexity - harder to mock or override configuration in tests

✨ Solution

Added a new configure() function that allows programmatic configuration with a clear precedence chain:

🔧 New configure() Function

from openlayer.lib import configure, trace

# Configure once at application startup
configure(
    api_key="your_api_key_here",
    inference_pipeline_id="your_pipeline_id_here",
    base_url="https://custom.api.com/v1"  # Optional
)

# Use decorators normally - no environment variables needed
@trace()
def my_function():
    return "result"

📋 Configuration Precedence

  1. Highest: Values passed directly to decorators (@trace(inference_pipeline_id="specific"))
  2. Medium: Values set via configure() function
  3. Lowest: Environment variables (maintains backward compatibility)

🎨 Key Features

Flexible Configuration Options

# Basic programmatic configuration
configure(
    api_key="your_api_key",
    inference_pipeline_id="your_pipeline_id"
)

# Per-decorator override
@trace()  # Uses configured default
def func1():
    pass

@trace(inference_pipeline_id="override_pipeline")  # Overrides default
def func2():
    pass

# Mixed approach (environment + programmatic)
os.environ["OPENLAYER_API_KEY"] = "env_key"
configure(inference_pipeline_id="programmatic_pipeline")

Runtime Configuration Changes

# Switch configurations at runtime
configure(api_key="dev_key", inference_pipeline_id="dev_pipeline")
run_development_tests()

configure(api_key="prod_key", inference_pipeline_id="prod_pipeline")  
run_production_workload()

Testing Support

# Easy mocking in tests
def test_my_function():
    configure(
        api_key="test_key",
        inference_pipeline_id="test_pipeline"
    )
    # Test with known configuration
    result = my_traced_function()
    assert result == expected_value

🛠 Technical Implementation

Enhanced Client Initialization

  • Modified _get_client() to use configured values with fallback to environment variables
  • Client recreation when configuration changes (lazy initialization)
  • Support for custom base URLs and SSL configuration

Pipeline ID Precedence Chain

  • Updated _handle_trace_completion() to implement proper precedence logic
  • Maintained all existing functionality while adding new configuration options

Public API Integration

  • Added configure to public exports in src/openlayer/lib/__init__.py
  • Comprehensive docstrings with usage examples

📝 Usage Examples

Multi-Environment Application

from openlayer.lib import configure

class MyApp:
    def __init__(self, environment: str):
        if environment == "development":
            configure(
                api_key=dev_config.openlayer_key,
                inference_pipeline_id=dev_config.pipeline_id
            )
        elif environment == "production":
            configure(
                api_key=prod_config.openlayer_key,
                inference_pipeline_id=prod_config.pipeline_id
            )

Dynamic Configuration

# Load from database, secrets manager, etc.
config = load_config_from_database()
configure(
    api_key=config.get("openlayer_api_key"),
    inference_pipeline_id=config.get("pipeline_id")
)

⚠️ Breaking Changes

None - This is a purely additive change that maintains full backward compatibility with existing environment variable usage.

🧪 Testing

  • 9 new comprehensive tests covering all configuration scenarios
  • Backward compatibility verified - existing environment variable behavior unchanged
  • Integration tests - verified existing tracing functionality still works
  • Precedence testing - confirmed proper fallback chain behavior

Test Coverage

python -m pytest tests/test_tracer_configuration.py -v
# ============================================ 9 passed in 7.78s ============================================

📁 Files Changed

  • src/openlayer/lib/tracing/tracer.py - Added configure() function and enhanced client initialization
  • src/openlayer/lib/__init__.py - Exported configure to public API
  • examples/tracing/programmatic_configuration.py - Comprehensive usage examples
  • tests/test_tracer_configuration.py - Full test suite covering all scenarios

🎉 Benefits

  1. 🔄 Runtime Flexibility - Change configuration without restarting applications
  2. 🏗️ Better Architecture - Cleaner separation of configuration from deployment
  3. 🧪 Enhanced Testing - Easier to mock and test different configurations
  4. 📦 Container-Friendly - Reduces dependency on environment variable management
  5. 🔒 Security - Enables integration with secrets management systems
  6. ⚡ Zero Disruption - Existing code continues to work unchanged

📖 Documentation

Added comprehensive examples in examples/tracing/programmatic_configuration.py demonstrating:

  • Environment variable approach (existing)
  • Programmatic configuration (new)
  • Per-decorator overrides
  • Mixed configuration strategies

All functions include detailed docstrings with usage examples and parameter descriptions.

…acer functionality

- Introduced a new example script demonstrating programmatic configuration for Openlayer tracing, allowing users to set API keys and pipeline IDs without relying on environment variables.
- Added a `configure` function to the tracer module for programmatic setup of API key, inference pipeline ID, and base URL.
- Enhanced the tracer to support mixed configuration approaches, allowing both environment variables and programmatic settings.
- Implemented comprehensive unit tests for the new configuration functionality, ensuring correct behavior and precedence of settings.
@viniciusdsmello viniciusdsmello self-assigned this Jul 30, 2025
- Removed unnecessary blank lines and improved code formatting for better readability in the programmatic configuration examples.
- Streamlined the `configure` function and related methods to ensure consistent style and clarity.
- Updated unit tests to reflect the new formatting and maintain consistency across the codebase.
- Ensured that all functions and methods adhere to the established coding guidelines for type annotations and docstring standards.
@viniciusdsmello viniciusdsmello added the enhancement New feature or request label Jul 30, 2025
@viniciusdsmello viniciusdsmello changed the title feat: Adds feat: Add Programmatic Configuration Support for Tracing Decorators Jul 30, 2025
@viniciusdsmello viniciusdsmello merged commit 12b0f28 into main Jul 31, 2025
5 checks passed
@viniciusdsmello viniciusdsmello deleted the vini/adds-tracer-configure branch July 31, 2025 00:26
@stainless-app stainless-app bot mentioned this pull request Jul 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy