> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenTelemetry Python Installation

To send OpenTelemetry data from your Python application to AppSignal, you can either use the [AppSignal for Python package](/python/installation) or install and configure OpenTelemetry manually.

## Using the AppSignal for Python package

The AppSignal for Python package can automatically configure OpenTelemetry to send data to the AppSignal collector. It can also automatically enable OpenTelemetry instrumentations for popular libraries and frameworks.

Follow the instructions in the [AppSignal for Python installation documentation](/python/installation) to install the package and set up the configuration file, then follow the instructions in the [AppSignal for Python collector configuration page](/python/configuration/collector) to use it with the AppSignal Collector.

## Installing OpenTelemetry manually

Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions.

### Install the OpenTelemetry packages

Add the OpenTelemetry SDK, OTLP exporter and instrumentation packages to your application's `requirements.txt`:

<CodeGroup>
  ```txt Text theme={null}
  opentelemetry-api
  opentelemetry-sdk
  opentelemetry-exporter-otlp-proto-http
  ```
</CodeGroup>

Also add the OpenTelemetry instrumentation packages for the libraries and frameworks that your application uses. For example, if you're using Django and Celery:

<CodeGroup>
  ```txt Text theme={null}
  opentelemetry-instrumentation-celery
  opentelemetry-instrumentation-django
  ```
</CodeGroup>

Check out [the OpenTelemetry registry for instrumentation packages](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=python\&flag=all) for most libraries and frameworks.

### Configure OpenTelemetry in your application

Add this `appsignal.py` file to your application with the OpenTelemetry exporter and AppSignal configuration. Then, import that file before your application starts.

Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed.

<CodeGroup>
  ```python Python theme={null}
  import os
  import subprocess
  import socket

  from opentelemetry import trace, metrics
  from opentelemetry.sdk.resources import Resource
  from opentelemetry.sdk.trace import TracerProvider
  from opentelemetry.sdk.trace.export import BatchSpanProcessor
  from opentelemetry.sdk.metrics.export import (
      AggregationTemporality,
      PeriodicExportingMetricReader,
  )
  from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
      OTLPSpanExporter
  )
  from opentelemetry.exporter.otlp.proto.http.metric_exporter import (
      OTLPMetricExporter
  )

  def initialize_opentelemetry(service_name):
      # Replace these values with your AppSignal application name, environment
      # and push API key. These are used by the resource attributes configuration below.
      name = "My app"
      push_api_key = "0000-0000-0000-0000"
      environment = "development"

      # Replace `http://localhost:8099` with the address of your AppSignal collector
      # if it's running on another host.
      endpoint = "http://localhost:8099"

      revision = subprocess.check_output(
          "git rev-parse --short HEAD", shell=True, text=True
      ).strip()

      resource = Resource(attributes={
          "appsignal.config.name": name,
          "appsignal.config.environment": environment,
          "appsignal.config.push_api_key": push_api_key,
          "appsignal.config.revision": revision,
          "appsignal.config.language_integration": "python",
          "appsignal.config.app_path": os.getcwd()
          "host.name": socket.gethostname(),
          # Customize the service name
          "service.name": service_name,
      })

      trace_provider = TracerProvider(resource=resource)
      span_processor = BatchSpanProcessor(
          OTLPSpanExporter(endpoint=f"{collector_host}/v1/traces")
      )
      trace_provider.add_span_processor(span_processor)
      trace.set_tracer_provider(trace_provider)

      metric_exporter = OTLPMetricExporter(
          endpoint=f"{collector_host}/v1/metrics",
      )
      metric_reader = PeriodicExportingMetricReader(
          metric_exporter,
          export_interval_millis=10000
      )
      metric_provider = MeterProvider(
          resource=resource,
          metric_readers=[metric_reader]
      )
      metrics.set_meter_provider(metric_provider)
  ```
</CodeGroup>

Then, in the same file, after the OpenTelemetry setup, initialize the OpenTelemetry instrumentations for the libraries and frameworks that your application uses. For example, if you're using the Django and Celery instrumentations:

<CodeGroup>
  ```python Python theme={null}
  # Add this below the OpenTelemetry initialization

  from opentelemetry.instrumentation.django import DjangoInstrumentor
  from opentelemetry.instrumentation.celery import CeleryInstrumentor

  DjangoInstrumentor().instrument()
  CeleryInstrumentor().instrument()
  ```
</CodeGroup>

Finally, call the `initialize_opentelemetry` function with the name of the service that is being monitored, as early as possible in your application's entry point. A common choice for the service name is the name of the framework used.

#### Usage with Django

In the `settings.py` file of your Django application, import the `appsignal.py` module at the beginning of the file and call the `initialize_opentelemetry` function:

<CodeGroup>
  ```python Python theme={null}
  from .appsignal import initialize_opentelemetry

  # Set the name of the service that is being monitored. A common choice is the
  # name of the framework used. This is used to group traces and metrics in AppSignal.
  service_name = "Django"

  initialize_opentelemetry(service_name)
  ```
</CodeGroup>

#### Usage with Celery

In the `tasks.py` file of your Celery application, add a connection callback for worker processes and import the `appsignal.py` module within it.

<CodeGroup>
  ```python Python theme={null}
  @worker_process_init.connect(weak=False)
  def init_celery_tracing(*args, **kwargs):
      from .appsignal import initialize_opentelemetry

      # Set the name of the service that is being monitored. A common choice is the
      # name of the framework used. This is used to group traces and metrics in AppSignal.
      service_name = "Celery"

      initialize_opentelemetry(service_name)
  ```
</CodeGroup>

### Test the app!

Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically.

If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation!
