|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +Example showing how to use Laminar's Exa search API instrumentation. |
| 4 | +
|
| 5 | +This example demonstrates how to automatically instrument Exa API calls |
| 6 | +with comprehensive input/output tracing using Laminar. |
| 7 | +
|
| 8 | +The instrumentation captures: |
| 9 | +- All input parameters via lmnr.span.input |
| 10 | +- Complete response data via lmnr.span.output |
| 11 | +- Service-specific metadata as JSON (search params, results, etc.) |
| 12 | +- Cost tracking with actual costs from Exa API responses |
| 13 | +- Performance metrics (response size, status, duration) |
| 14 | +- Streaming response chunks with aggregated final content |
| 15 | +
|
| 16 | +Uses unified service instrumentation specification: |
| 17 | +- service.name: "exa" |
| 18 | +- service.operation: "search" | "answer" | "research" |
| 19 | +- service.cost.*: Cost tracking attributes |
| 20 | +- service.metadata: Exa-specific parameters as JSON string |
| 21 | +""" |
| 22 | + |
| 23 | +import os |
| 24 | +from lmnr import Laminar |
| 25 | + |
| 26 | +# Initialize Laminar with Exa instrumentation |
| 27 | +# This will automatically instrument all Exa API calls with comprehensive tracing |
| 28 | +Laminar.initialize( |
| 29 | + project_api_key="your-laminar-api-key", # Replace with your actual API key |
| 30 | + # EXA instrumentation is included by default, but you can explicitly specify it: |
| 31 | + # instruments={"EXA"} |
| 32 | +) |
| 33 | + |
| 34 | +# Content tracing is always enabled - all inputs and outputs are captured automatically |
| 35 | + |
| 36 | +# Now you can use Exa normally, and all calls will be automatically traced |
| 37 | +try: |
| 38 | + from exa_py import Exa |
| 39 | + |
| 40 | + # Initialize Exa client |
| 41 | + exa = Exa(os.getenv('EXA_API_KEY')) # Set your EXA_API_KEY environment variable |
| 42 | + |
| 43 | + # All of these calls will be automatically instrumented: |
| 44 | + |
| 45 | + # Basic search |
| 46 | + print("Performing basic search...") |
| 47 | + results = exa.search("hottest AI startups", num_results=2) |
| 48 | + print(f"Found {len(results.results)} results") |
| 49 | + |
| 50 | + # Search with content |
| 51 | + print("\nPerforming search with content...") |
| 52 | + results_with_content = exa.search_and_contents( |
| 53 | + "AI in healthcare", |
| 54 | + text=True, |
| 55 | + num_results=2 |
| 56 | + ) |
| 57 | + print(f"Found {len(results_with_content.results)} results with content") |
| 58 | + |
| 59 | + # Find similar content |
| 60 | + print("\nFinding similar content...") |
| 61 | + similar_results = exa.find_similar( |
| 62 | + "https://www.adept.ai/", |
| 63 | + num_results=2 |
| 64 | + ) |
| 65 | + print(f"Found {len(similar_results.results)} similar results") |
| 66 | + |
| 67 | + # Generate answer |
| 68 | + print("\nGenerating answer...") |
| 69 | + answer = exa.answer("What is the capital of France?") |
| 70 | + print(f"Answer: {answer}") |
| 71 | + |
| 72 | + # Research task (if available) |
| 73 | + print("\nCreating research task...") |
| 74 | + try: |
| 75 | + task = exa.research.create_task( |
| 76 | + instructions="What are the main benefits of meditation?", |
| 77 | + infer_schema=True |
| 78 | + ) |
| 79 | + print(f"Created research task with ID: {task.id}") |
| 80 | + |
| 81 | + # Poll for completion |
| 82 | + result = exa.research.poll_task(task.id) |
| 83 | + print(f"Research completed with status: {result.status}") |
| 84 | + |
| 85 | + except AttributeError: |
| 86 | + print("Research methods not available in this version of exa_py") |
| 87 | + |
| 88 | + print("\n✓ All Exa API calls have been automatically instrumented!") |
| 89 | + print("Check your Laminar dashboard to see:") |
| 90 | + print(" - lmnr.span.input: Complete input parameters") |
| 91 | + print(" - lmnr.span.output: Full response data (no truncation)") |
| 92 | + print(" - service.name: 'exa'") |
| 93 | + print(" - service.cost.amount: Actual costs from Exa API (fallback to estimates)") |
| 94 | + print(" - service.metadata: Exa-specific parameters as JSON") |
| 95 | + print(" - service.response.status: 'success' or 'error'") |
| 96 | + print(" - Regular CLIENT spans following unified service spec") |
| 97 | + |
| 98 | +except ImportError: |
| 99 | + print("exa_py not installed. Install it with: pip install exa_py") |
| 100 | + print("The instrumentation is still ready and will work once exa_py is installed.") |
| 101 | + |
| 102 | +except Exception as e: |
| 103 | + print(f"Error: {e}") |
| 104 | + print("Make sure to set your EXA_API_KEY environment variable.") |
| 105 | + print("The instrumentation is working - this is just an API key issue.") |
0 commit comments