# Python Examples

Esta prática mostra como escrever um programa simples que baixa e analisa algum conteúdo usando o [snapshots](https://github.com/decentraland/docs/blob/main/contributor/practice/snapshots/README.md) fornecido pelos servidores de conteúdo.

{% hint style="info" %}
Você pode encontrar o [script completo](https://github.com/decentraland/documentation/blob/main/content/contributor/content/practice/snapshots_mini.py) no GitHub, junto com um [exemplo mais avançado](https://github.com/decentraland/documentation/blob/main/content/contributor/content/practice/snapshots.py).
{% endhint %}

Usaremos o servidor da Decentraland Foundation em `peer.decentraland.org`, e Python 3 como nossa linguagem de escolha.

Isto é o que faremos:

1. Consultar o status do servidor de conteúdo.
2. Selecionar e baixar um [snapshot](https://github.com/decentraland/docs/blob/main/contributor/practice/snapshots/README.md) com uma lista de entidades.
3. Imprimir o tipo e o ID de todas as entidades referenciadas.

Vamos começar nosso script com algumas preparações. Usaremos apenas módulos da biblioteca padrão, mas no código real você provavelmente vai querer um cliente HTTP mais confortável (como a [requests](https://github.com/psf/requests) library).

```py
# Fazer uma requisição HTTP GET, retornar uma resposta HTTP parecida com um arquivo.
def fetch(path):
    url = f"https://peer.decentraland.org/{path}"
    headers = { "User-Agent": "urllib" } # importante em alguns servidores (se vazio, 403 Forbidden)

    request = urllib.request.Request(url, headers=headers)
    response = urllib.request.urlopen(request)

    return response
```

Nosso simples auxiliar faz um `GET` request, e retorna o objeto de resposta parecida com um arquivo. Nada sofisticado. Vamos usá-lo para acessar o `/about` endpoint e verificar o status do servidor:

```py
# Verificar o status do servidor:
about = json.load(fetch('about'))

if not about['healthy']:
    print("Servidor não saudável!")
    sys.exit(1)
```

Se chegarmos além deste ponto, o servidor está ativo e funcionando (recebemos uma `200` response) e reporta estar operacional. Podemos solicitar o conjunto atual de snapshots (que chega no formato de array JSON):

```py
# Obter a lista de snapshots:
all_snapshots = json.load(fetch('content/snapshots'))
```

Arquivos de snapshot (especialmente para intervalos de tempo maiores) podem ser muito grandes. Para um experimento rápido, vamos pegar o menor da lista por `numberOfEntities`:

```py
# Pegar o menor snapshot, em termos de entidades incluídas:
snapshot = min(all_snapshots, key=lambda s: s['numberOfEntities'])
```

Para baixar o conteúdo, precisamos do `hash` campo de `snapshot`. Obtemos a URL do arquivo anexando-o à raiz de conteúdo:

```py
# Solicitar o arquivo da API de conteúdo:
response = fetch('content/contents/' + snapshot['hash'])
```

O arquivo que selecionamos é pequeno o suficiente para ser armazenado em memória, mas vamos fingir que não sabemos disso e transmiti-lo em streaming. A primeira linha é o cabeçalho do snapshot, e cada linha depois disso contém um objeto JSON.

Vamos verificar o cabeçalho, sempre uma boa ideia:

```py
# Verificar o cabeçalho do snapshot:
header = response.readline().decode('utf-8').strip()

if header != '### Decentraland json snapshot':
    print("Cabeçalho de snapshot inválido: " + header)
    sys.exit(1)
```

Agora podemos processar todas as entidades no snapshot, lendo a resposta linha por linha. Para nossos humildes propósitos, *process* significa imprimir o tipo e o ID da entidade:

```py
# Ler e decodificar todos os itens, um JSON por linha:
for line in response:
    item = json.loads(line)
    print(item['entityType'], item['entityId'])
```

Este loop começará a transmitir, analisar e imprimir linhas como estas até terminar o snapshot:

```
profile bafkreic36qmzyprs6whkpuxbeiif4no6kvdrr2tfpichbx2fzfz5py6eyv
scene bafkreibr5xfujqrp5q3o4s73vm2yljlcp7cucqgugssnarsuclxv4emlmy
profile bafkreid7khr5wnkialba44rsslffi633rh3lvctad5oa5vjoe6wa7s4c5a
wearable bafkreihlqcb7jgubomyidikpwpqhgzbagltk5m4rgbjdvzydxmoka7bg4i
```

Saúde! Usamos o sistema de snapshot para explorar parte do conteúdo disponível na Decentraland.

Lembre-se que você pode encontrar o [script completo](https://github.com/decentraland/documentation/blob/main/content/contributor/content/practice/snapshots_mini.py) no GitHub, junto com um [exemplo mais avançado](https://github.com/decentraland/documentation/blob/main/content/contributor/content/practice/snapshots.py).
