# Source: https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/migrate/python/v4.md

---
title: Migrate to dd-trace-py v4
description: Upgrade your Python tracer from v3 to v4.
breadcrumbs: Docs > APM > Application Instrumentation > Migrate to dd-trace-py v4
---

# Migrate to dd-trace-py v4

## Overview{% #overview %}

Version 4.0.0 of `dd-trace-py` drops support for older Python versions, removes deprecated APIs, and creates new default behaviors for frameworks such as Django.

The `3.x` release line is now in maintenance mode; only critical bug fixes are backported.

## Prerequisites{% #prerequisites %}

Ensure your environment meets the following requirements:

- **Python Version:** Python 3.9 or newer (Python 3.8 support is removed).
- **Datadog Agent:** v7.63.0 or newer.
- **OS:** 64-bit Linux (32-bit Linux support is removed).

## Step 1: Detect deprecations{% #step-1-detect-deprecations %}

To ensure a smooth transition, upgrade to the latest v3 release (`3.19.0`) and use the following tools to detect deprecated code.

### In tests{% #in-tests %}

Run `pytest` with warnings enabled as errors to identify necessary updates in your test suite:

```bash
pytest -W "error::ddtrace.DDTraceDeprecationWarning" tests.py
```

### In applications{% #in-applications %}

Set the `PYTHONWARNINGS` environment variable to surface deprecation warnings when running your application:

```bash
PYTHONWARNINGS=error::ddtrace.DDTraceDeprecationWarning python app.py
```

## Step 2: Address breaking changes{% #step-2-address-breaking-changes %}

Review the following changes and update your code before installing v4.

### Configuration and environment variables{% #configuration-and-environment-variables %}

The `ddtrace.settings` package is removed. Use environment variables to configure settings.

The following environment variables are removed:

- `DD_DYNAMIC_INSTRUMENTATION_UPLOAD_FLUSH_INTERVAL`
- `DD_EXCEPTION_DEBUGGING_ENABLED`
- `DD_PROFILING_STACK_V2_ENABLED`
- `DEFAULT_RUNTIME_METRICS_INTERVAL`

Use `git grep` to find occurrences in your codebase:

```bash
git grep -P -e "DD_DYNAMIC_INSTRUMENTATION_UPLOAD_FLUSH_INTERVAL" \
-e "DD_EXCEPTION_DEBUGGING_ENABLED" \
-e "DD_PROFILING_STACK_V2_ENABLED" \
-e "DEFAULT_RUNTIME_METRICS_INTERVAL"
```

### Tracing API changes{% #tracing-api-changes %}

The following methods on `Span` and `Tracer` objects are removed or have updated type signatures.

#### Removed methods{% #removed-methods %}

| Class           | Method                     | Replacement          |
| --------------- | -------------------------- | -------------------- |
| `Span`          | `set_tag_str`              | Use `Span.set_tag`.  |
| `Span`          | `finished` (setter)        | Use `Span.finish()`. |
| `Span`          | `finish_with_ancestors`    | None.                |
| `Span`          | `set_struct_tag`           | None.                |
| `Span`          | `get_struct_tag`           | None.                |
| `Span`          | `_pprint`                  | None.                |
| `Tracer`        | `on_start_span`            | None.                |
| `Tracer`        | `deregister_on_start_span` | None.                |
| `ddtrace.trace` | `Pin`                      | None.                |

#### Updated type signatures{% #updated-type-signatures %}

The following methods enforce stricter typing:

- `Span.set_tag`: `(key: str, value: Optional[str] = None) -> None`
- `Span.get_tag`: `(key: str) -> Optional[str]`
- `Span.set_tags`: `(tags: dict[str, str]) -> None`
- `Span.get_tags`: `() -> dict[str, str]`
- `Span.set_metric`: `(key: str, value: int | float) -> None`
- `Span.get_metric`: `(key: str) -> Optional[int | float]`
- `Span.set_metrics`: `(metrics: Dict[str, int | float]) -> None`
- `Span.get_metrics`: `() -> dict[str, int | float]`

#### Parameter changes{% #parameter-changes %}

- `Span.record_exception`: The `timestamp` and `escaped` parameters are removed.

### Framework and Integration changes{% #framework-and-integration-changes %}

#### Django{% #django %}

`DD_DJANGO_TRACING_MINIMAL` defaults to `true`.

- **Impact:** Django ORM, cache, and template instrumentation are disabled by default. This reduces performance overhead and eliminates duplicate spans, as underlying libraries (such as `psycopg`, `redis`, `jinja2`) are instrumented by their own integrations.
- **Database Spans:** When `DD_DJANGO_INSTRUMENT_DATABASES=true` (default `false`), the tracer merges Django-specific tags into the driver spans rather than creating separate spans.
- **Restoration:** To restore full Django instrumentation, set `DD_DJANGO_TRACING_MINIMAL=false`.

#### OpenAI{% #openai %}

Streamed chat/completions do not use `tiktoken` to compute token counts.

- **Action:** To guarantee accurate streamed token metrics, set `stream_options={"include_usage": True}` in your OpenAI request.

#### LLM Observability{% #llm-observability %}

- **Manual Instrumentation:** The following methods raise exceptions instead of logging errors: `LLMObs.annotate()`, `LLMObs.export_span()`, `LLMObs.submit_evaluation()`, `LLMObs.inject_distributed_headers()`, and `LLMObs.activate_distributed_headers()`.
- **Renaming:** `LLMObs.submit_evaluation_for()` is removed. Use `LLMObs.submit_evaluation()` and rename the `span_context` argument to `span`.

#### Removed integrations{% #removed-integrations %}

The following libraries are no longer supported:

- `google_generativeai`: Use the `google_genai` library and integration.
- `Mongoengine:** Support for`ddtrace.Pin`is removed. Use the`pymongo` integration.
- `Aioredis`
- `Freezegun`
- `Opentracer`

### Profiling{% #profiling %}

- The V1 stack profiler is removed. V2 is the default.
- `echion` (Python stack sampler) includes an experimental faster memory copy function.

### CI Visibility{% #ci-visibility %}

- **Pytest:** Deprecated entry points for `pytest_benchmark` and `pytest_bdd` are removed. The standard `pytest` integration supports these plugins.
- **Propagation:** The deprecated `non_active_span` parameter is removed from `HttpPropagator.inject`.

## Step 3: Upgrade the library{% #step-3-upgrade-the-library %}

After addressing breaking changes, install the new version:

```bash
pip install --upgrade ddtrace
```

## Further reading{% #further-reading %}

- [Release Notes](https://github.com/DataDog/dd-trace-py/releases)
- [Python Tracing Setup](https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/python)