{"id":191,"library":"opentelemetry-api","title":"OpenTelemetry Python API","description":"OpenTelemetry Python API package. Current version: 1.40.0 (Mar 2026). TWO separate packages: 'opentelemetry-api' (interfaces + no-op implementations) and 'opentelemetry-sdk' (actual implementation). Installing only opentelemetry-api produces silent no-ops — all tracing calls succeed but nothing is recorded or exported. Must also install opentelemetry-sdk AND configure a TracerProvider AND call trace.set_tracer_provider(). Exporters (OTLP, Jaeger, Zipkin) are separate packages. All packages must be the same version.","status":"active","version":"1.40.0","language":"python","source_language":"en","source_url":"https://github.com/open-telemetry/opentelemetry-python","tags":["opentelemetry","otel","tracing","observability","python","apm"],"install":[{"cmd":"pip install opentelemetry-api opentelemetry-sdk","lang":"bash","label":"Python (both required for actual tracing)"},{"cmd":"pip install opentelemetry-exporter-otlp","lang":"bash","label":"OTLP exporter (for Grafana, Datadog, Honeycomb, etc.)"},{"cmd":"pip install opentelemetry-instrumentation-fastapi opentelemetry-instrumentation-sqlalchemy","lang":"bash","label":"Auto-instrumentation packages (from contrib repo)"}],"dependencies":[{"reason":"Required for actual telemetry. API alone gives no-ops.","package":"opentelemetry-sdk","optional":false},{"reason":"Required by SDK. Installed automatically.","package":"opentelemetry-semantic-conventions","optional":false}],"imports":[{"note":"trace.get_tracer() returns a NoopTracer unless trace.set_tracer_provider() has been called with a real TracerProvider. No error is raised — spans are silently discarded.","wrong":"# Wrong: API only — all no-ops, nothing exported\nfrom opentelemetry import trace\ntracer = trace.get_tracer(__name__)  # returns NoopTracer\n\n# Wrong: forgot to call set_tracer_provider — still no-op\nfrom opentelemetry.sdk.trace import TracerProvider\nprovider = TracerProvider()\ntracer = trace.get_tracer(__name__)  # still NoopTracer — provider not registered","symbol":"TracerProvider setup","correct":"from opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter\nfrom opentelemetry.sdk.resources import Resource\n\n# Configure provider with resource and exporter\nresource = Resource.create({'service.name': 'my-service'})\nprovider = TracerProvider(resource=resource)\n\nexporter = OTLPSpanExporter(endpoint='http://localhost:4317')\nprocessor = BatchSpanProcessor(exporter)\nprovider.add_span_processor(processor)\n\n# MUST register globally before any tracing\ntrace.set_tracer_provider(provider)\n\n# Get tracer\ntracer = trace.get_tracer(__name__)\n\n# Use tracer\nwith tracer.start_as_current_span('my-operation') as span:\n    span.set_attribute('user.id', '42')\n    # do work"}],"quickstart":{"code":"# pip install opentelemetry-api opentelemetry-sdk\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter\nfrom opentelemetry.sdk.resources import Resource\n\n# Setup — do this once at app startup\nresource = Resource.create({'service.name': 'my-service', 'service.version': '1.0.0'})\nprovider = TracerProvider(resource=resource)\n\n# ConsoleSpanExporter for local dev — replace with OTLPSpanExporter in production\nprovider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))\n\n# Register globally — MUST be before any trace.get_tracer() calls\ntrace.set_tracer_provider(provider)\n\n# Get tracer\ntracer = trace.get_tracer(__name__)\n\n# Create spans\nwith tracer.start_as_current_span('main-operation') as span:\n    span.set_attribute('env', 'production')\n\n    with tracer.start_as_current_span('db-query') as child:\n        child.set_attribute('db.system', 'postgresql')\n        child.set_attribute('db.statement', 'SELECT * FROM users')\n        # do DB work\n\n# Flush remaining spans on shutdown\nprovider.shutdown()","lang":"python","description":"OpenTelemetry Python — TracerProvider setup with ConsoleSpanExporter."},"warnings":[{"fix":"pip install opentelemetry-api opentelemetry-sdk","message":"Installing only 'opentelemetry-api' gives silent no-ops. All tracing calls succeed without errors but nothing is recorded. Must also install 'opentelemetry-sdk'.","severity":"breaking","affected_versions":"all"},{"fix":"Always call trace.set_tracer_provider(provider) after creating TracerProvider, before any trace.get_tracer() calls.","message":"trace.get_tracer() returns NoopTracer until trace.set_tracer_provider() is called. Forgetting this line means all spans are silently discarded. Warning: 'No TracerProvider configured, using NoopTracerProvider' only shows with debug logging enabled.","severity":"breaking","affected_versions":"all"},{"fix":"pip install opentelemetry-exporter-otlp for production. Use ConsoleSpanExporter for local development.","message":"Exporters are separate packages not included in opentelemetry-sdk. OTLP requires 'opentelemetry-exporter-otlp'. Jaeger requires 'opentelemetry-exporter-jaeger'. ConsoleSpanExporter is included in SDK.","severity":"breaking","affected_versions":"all"},{"fix":"Pin all packages to same version: pip install 'opentelemetry-api==1.40.0' 'opentelemetry-sdk==1.40.0' 'opentelemetry-exporter-otlp==1.40.0'","message":"All opentelemetry-* packages must be the same version. Mixing versions (e.g. api=1.20, sdk=1.25) causes ImportError or unexpected behavior.","severity":"breaking","affected_versions":"all"},{"fix":"pip install opentelemetry-instrumentation-fastapi opentelemetry-instrumentation-sqlalchemy etc.","message":"Auto-instrumentation packages (opentelemetry-instrumentation-fastapi etc.) are in the separate 'opentelemetry-python-contrib' repo — not in the main SDK. Must be installed separately.","severity":"gotcha","affected_versions":"all"},{"fix":"Call provider.shutdown() in app shutdown handler or use atexit.register(provider.shutdown).","message":"provider.shutdown() must be called on app exit to flush buffered spans. Without it, spans in the BatchSpanProcessor queue are lost on process exit.","severity":"gotcha","affected_versions":"all"},{"fix":"Resource.create({'service.name': 'my-service'}) or set OTEL_SERVICE_NAME env var.","message":"service.name resource attribute is not set by default. Without it, traces appear as 'unknown_service' in your backend.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:55:58.406Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Install `opentelemetry-sdk` and configure a `TracerProvider` with a `SpanProcessor` and `SpanExporter`, then set it as the global provider early in your application's lifecycle.\n\n```python\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor\n\n# 1. Create a TracerProvider\nprovider = TracerProvider()\n\n# 2. Configure an exporter and processor (e.g., ConsoleSpanExporter for testing)\nspan_processor = SimpleSpanProcessor(ConsoleSpanExporter())\nprovider.add_span_processor(span_processor)\n\n# 3. Set the global TracerProvider (MUST be done before getting a tracer)\ntrace.set_tracer_provider(provider)\n\n# Now get a tracer and create spans as normal\ntracer = trace.get_tracer(__name__)\nwith tracer.start_as_current_span(\"my-operation\"):\n    print(\"This span will be recorded and exported!\")\n```","cause":"The opentelemetry-sdk package is not installed, or a TracerProvider from opentelemetry.sdk.trace has not been created and globally registered using trace.set_tracer_provider() before any tracing occurs. The opentelemetry-api package alone provides no-op implementations.","error":"Warning: No TracerProvider configured, using NoopTracerProvider. All tracing operations will be no-ops."},{"fix":"Ensure all necessary OpenTelemetry packages are installed in the active Python environment. For example, use `pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http`. Verify the correct Python environment is active if the issue persists.\n\n```bash\npip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http\n# If using auto-instrumentation, also install the distro and specific instrumentations:\npip install opentelemetry-distro opentelemetry-instrumentation-requests # Example for requests library\n```","cause":"The required OpenTelemetry SDK package has not been installed in the current Python environment, or there's a Python environment mismatch or namespace package conflict. This error also appears for other missing OpenTelemetry-related modules, such as specific instrumentation libraries or exporters.","error":"ModuleNotFoundError: No module named 'opentelemetry.sdk'"},{"fix":"Ensure `trace.set_tracer_provider()` is called only once, typically at the very beginning of your application's startup. Centralize OpenTelemetry initialization to prevent multiple components from trying to set the global provider.\n\n```python\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor\n\ndef initialize_telemetry():\n    provider = TracerProvider()\n    span_processor = SimpleSpanProcessor(ConsoleSpanExporter())\n    provider.add_span_processor(span_processor)\n    trace.set_tracer_provider(provider)\n\n# Call this once, e.g., in your main application file or entry point\ninitialize_telemetry()\n\n# Subsequent calls to trace.set_tracer_provider() will result in the warning.\n```","cause":"The `trace.set_tracer_provider()` function has been called more than once in the application's lifecycle. This often happens when multiple parts of an application or different libraries attempt to initialize and set the global `TracerProvider` independently.","error":"WARNING: opentelemetry.trace:Overriding of current TracerProvider is not allowed."},{"fix":"Always ensure `trace.set_tracer_provider()` is called with an instance of `opentelemetry.sdk.trace.TracerProvider` *before* attempting to call SDK-specific methods like `add_span_processor` on the globally retrieved `TracerProvider`.\n\n```python\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor\n\n# Correct order: Set the concrete provider first\nprovider = TracerProvider()\ntrace.set_tracer_provider(provider)\n\n# Now, when you get the provider, it will be the actual SDK provider\n# (or a proxy that correctly delegates to it if using newer SDK versions)\nactual_provider = trace.get_tracer_provider()\nspan_processor = SimpleSpanProcessor(ConsoleSpanExporter())\nactual_provider.add_span_processor(span_processor) # This will now work\n```","cause":"This error occurs when `trace.get_tracer_provider()` is called before a concrete `TracerProvider` from `opentelemetry.sdk.trace` has been set using `trace.set_tracer_provider()`. In such cases, `get_tracer_provider()` returns a `NoopTracerProvider` or `ProxyTracerProvider`, which does not have SDK-specific methods like `add_span_processor`.","error":"AttributeError: 'ProxyTracerProvider' object has no attribute 'add_span_processor'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":4.4,"disk_size":"22.1M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":4.4,"disk_size":"50.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":4.4,"disk_size":"22.6M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":4.4,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":4.4,"disk_size":"48M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":4.4,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.19,"mem_mb":4.9,"disk_size":"24.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":4.9,"disk_size":"53.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":4.9,"disk_size":"24.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.16,"mem_mb":4.9,"disk_size":"25M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.9,"disk_size":"51M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.9,"disk_size":"25M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"16.1M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":4.8,"disk_size":"44.8M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"16.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"43M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"15.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.9,"disk_size":"44.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"16.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"16M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"42M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":4.9,"disk_size":"17M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"21.6M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"49.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":4.3,"disk_size":"22.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"22M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"47M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.3,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}