> ## 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.

# Instrumentação WSGI/ASGI

Os padrões WSGI e ASGI fornecem uma camada comum para o desenvolvimento de frameworks e servidores web em Python. A maioria dos frameworks web Python populares segue esses padrões, permitindo que qualquer aplicação web Python seja implantada com qualquer servidor web Python.

<Tip>
  O suporte a ASGI foi adicionado na versão `0.1.4` do pacote AppSignal para Python.
</Tip>

O AppSignal suporta a instrumentação para aplicações web WSGI e ASGI genéricas através do OpenTelemetry.

<Tip>
  O AppSignal também suporta frameworks web populares diretamente, como
  [Django](/python/instrumentations/django),
  [Flask](/python/instrumentations/flask),
  [FastAPI](/python/instrumentations/fastapi) ou
  [Starlette](/python/instrumentations/starlette). Se você estiver usando um framework web
  que suportamos diretamente, siga as instruções para esse framework
  em vez das instruções genéricas WSGI/ASGI desta página.
</Tip>

## Instalação

<Note>
  🐍 Não esqueça de [instalar o pacote AppSignal for Python](/python/installation) em sua aplicação primeiro.
</Note>

Primeiro, instale o pacote `opentelemetry-instrumentation-wsgi` ou `opentelemetry-instrumentation-asgi`, dependendo da interface de gateway usada na aplicação. Para adicioná-lo ao seu projeto, adicione a seguinte linha ao seu arquivo `requirements.txt`:

<CodeGroup>
  ```python Python theme={null}
  # requirements.txt
  # For a WSGI application:
  opentelemetry-instrumentation-wsgi
  # For an ASGI application:
  opentelemetry-instrumentation-asgi
  ```
</CodeGroup>

## Configuração

No ponto de entrada da sua aplicação (geralmente chamado `main.py` ou `app.py`), antes de sua aplicação ser inicializada, chame `appsignal.start()` para iniciar sua aplicação:

<CodeGroup>
  ```python Python theme={null}
  import appsignal
  appsignal.start()

  # ... the rest of your code goes here ...
  ```
</CodeGroup>

Em seguida, importe `OpenTelemetryMiddleware` da instrumentação OpenTelemetry correspondente e envolva sua aplicação com ele:

<CodeGroup>
  ```python Python theme={null}
  # For a WSGI application:
  from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware
  # For an ASGI application:
  from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware

  my_app = # ... your WSGI/ASGI application goes here ...

  my_app = OpenTelemetryMiddleware(my_app)
  ```
</CodeGroup>

## Agrupando rotas

Por padrão, uma instrumentação WSGI ou ASGI genérica não terá o contexto necessário para entender como o roteamento é estruturado na sua aplicação. Como resultado, as amostras de performance que o AppSignal recebe não serão agrupadas corretamente. Você deve adicionar informações de roteamento manualmente à span do OpenTelemetry.

Uma maneira de fazer isso é seguindo as convenções semânticas HTTP do OpenTelemetry, definindo o atributo `http.route` nos seus handlers de rota:

<CodeGroup>
  ```python Python theme={null}
  from opentelemetry.trace import get_current_span

  def get_user_route_handler():
    get_current_span().set_attribute("http.route", "/users/:user_id")
    # ... your route handler goes here ...
  ```
</CodeGroup>

O AppSignal usará automaticamente o valor desse atributo para agrupar requisições, junto com o método da requisição. Por exemplo, uma requisição GET tratada por esse método aparecerá como `GET /users/:user_id` no painel de amostras de performance do AppSignal.

Se você preferir agrupar requisições de outra maneira (por exemplo, referindo-se ao método ou classe que as implementa), pode usar o atributo `appsignal.root_name`:

<CodeGroup>
  ```python Python theme={null}
  from opentelemetry.trace import get_current_span

  class UserHandlers:
    def show():
      get_current_span().set_attribute("appsignal.root_name", "UserHandlers#show")
      # ... your route handler goes here ...
  ```
</CodeGroup>

Usando `appsignal.root_name`, o método da requisição não será usado. O valor fornecido (neste caso, `UserHandlers#show`) será usado para agrupar todas as requisições tratadas por esse método.
