Como exportar um CSV com dados dos meus posts no DEV usando sua API
Tags: api, python, braziliandevs, beginners
Published: 2024-05-19 11:39:29

Neste post mostramos um passo a passo rápido para coletar dados de "minhas" publicações no DEV ([dev.to](dev.to)) utilizando sua API versão beta. Usamos bibliotecas do Python 3.9+ (Requests, Json e Pandas) para realizar requisições a endpoints da API DEV, então passar para o formato `DataFrame` e, em seguida, exportar como um arquivo `.CSV`. Esse `CSV` terá os dados dos posts que foram publicados pelo usuário `msc2020` até o momento.

---

<a id="conteudo"></a>

## Conteúdo ☕

  - [API DEV, versões v0 e v1 ](#versoes_api)

  - [Alguns endpoints da API ](#endpoints)

  - [Obtendo dados da API via Python](#api)

  - [Exportando os dados para CSV](#csv)

  - [Testes usando outro nome de usuário](#testes)

  - [Possibilidades de uso](#possibilidades_uso)

  - [Conclusão](#conclusao)

---

🎶 **[Wayne Shorter (Featuring Milton Nascimento) - Native Dancer (1975) full album](https://www.youtube.com/watch?v=vu8nNJVX0hs)**

---

<a id='versoes_api'></a>

## API DEV, versões v0 e v1 [<a href="#conteudo">^</A>]


O DEV dispensa apresentações, mas vale mencionar que ele é feito sobre o Forem, uma "[ferramenta _open source_ para construir comunidades](https://github.com/forem/forem)" 👊🏼. Ao visitar a [homepage](https://forem.dev/) da comunidade Forem notamos as várias semelhanças entre ambas.

Atualmente, o DEV possui uma API (versão beta 0.9.7) com documentação em [https://developers.forem.com/api](https://developers.forem.com/api). Há algumas diferenças entre as duas versões disponíveis. A principal delas é que alguns endpoints da versão **v0** podem ser acessados sem token de acesso (`API_TOKEN`). Já a **v1** usa token em todos seus endpoints. Segundo a documentação, os endpoints que não exigem autenticação com o token usam o [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) (_Cross-origin resource sharing_) para controlar o acesso.

<a id='endpoints'></a>

## Alguns endpoints da API [<a href="#conteudo">^</A>]

A tabela abaixo mostra alguns endpoints da API (https://dev.to/api/) acompanhados de informações que podem ser úteis.


| <small>Versão</small>| <small>Endpoint</small> | <small>Método</small> | <small>API_KEY</small>| <small>Descrição</small> | <small>Exemplo</small> |
|:-:|:----------:|:------------------:|:-----------:|:---|:---|
| <small>v0</small> | <small>/articles</small> | <small>GET</small> | <small>Não</small> | <small>Retorna todos os posts (artigos, dúvidas, divulgações, etc) publicados, sendo 30 por página </small> |<small>`curl https://dev.to/api/articles` <small>|
| <small>v0</small> | <small>/articles</small> | <small>POST</small> | <small>Sim</small> | <small>Cria um artigo</small> | <small>`curl -X POST -H "Content-Type: application/json" -H "api-key: API_KEY" -d '{"article": "title":"Title","body_markdown":"Body","published":false,"tags":["discuss", "javascript"]}}' https://dev.to/api/articles` </small>|
| <small>v0</small> | <small><small>/comments</small></small> | <small>GET</small> | <small>Não</small> | <small>Retorna todos os comentários de um artigo ou comentários de um podcast, sendo 30 por página</small> | <small> `curl https://dev.to/api/comments?a_id=270180` <small> |


As documentações dos endpoints da API na versão v0 e v1 podem ser encontradas, respectivamente, em: 

- [https://developers.forem.com/api/v0](https://developers.forem.com/api/v0)

- [https://developers.forem.com/api/v1](https://developers.forem.com/api/v1)

**🙈 Atenção:**  Embora para alguns endpoints da versão v0 não seja exigido um token, no site da API recomendam o uso dessa autenticação.

<a id='api'></a>
## Obtendo dados da API via Python [<a href="#conteudo">^</A>]

O código abaixo realiza a captura, via API DEV, dos dados referentes as minhas (`username = msc2020`) postagens:

```Python
import requests # instalação: pip install requests

url = 'https://dev.to/api/articles'
querystring = {'username': 'msc2020'}
headers = requests.utils.default_headers()

response = requests.request('GET', url, headers=headers, params=querystring)

print(response.text)

'''
saída esperada:

[{
  "type_of":"article","id":1850779,"title":"Raspagem de dados de um site de notícias em pt-BR","description": ...
  ...
}]
'''
```
O retorno da chamada `GET` usada no código acima, é um objeto (`response`) da biblioteca `Requests`. Para converter/_parsear_ o conteúdo de `response.text` (`str`) em uma lista de dicionários (`dict`) usamos:

```Python
import json # biblioteca padrão do Python

res_json = json.loads(response.text)
```
**🗒️ Nota:** No _script_  da requisição passamos o parâmetro `username` na chamada `GET`. Para ver outros parâmetros disponíveis no endpoint `/articles` acesse este [link](https://developers.forem.com/api/v0#tag/articles/operation/getArticles) da documentação da API.

A fim de facilitar uma futura análise dos dados coletado, estaremos convertendo esse `JSON` em um `CSV`. Para quem optar em trabalhar com o `Pandas` nas análises, o formato `CSV` poderá ajudar muito.

<a id='csv'></a>
## Exportando os dados para CSV [<a href="#conteudo">^</A>]

Após coletar o `JSON` dos dados via API, utilizamos o `to_csv` do Pandas para exportar os dados para o formato `CSV`.

Incluindo essa etapa, obtemos o código completo `exporta_posts.py`: <a id="codigo_completo"></a>

```Python
# exporta_posts.py

import requests # instalação: pip install requests
import pandas as pd # instalação: pip install pandas
import json # biblioteca padrão do Python

# define nome do usuário
USER_NAME = 'msc2020'

# faz requisição GET
url = 'https://dev.to/api/articles'
querystring = {'username': USER_NAME}
headers = requests.utils.default_headers()
response = requests.request('GET', url, headers=headers, params=querystring)
# print(response.text)

# converte resposta da requisição em uma lista de dict
res_json = json.loads(response.text)

# converte o JSON para Pandas DataFrame
df_posts = pd.DataFrame(res_json)

# exporta os dados do posts para CSV
df_posts.to_csv('dataset_articles_published_msc2020.csv', index=None)

# exibe as 3 primeiras linhas do dataset
print(df_posts.head(3))

'''saídas esperadas:
. 1) 3 primeiras linhas do CSV:
>>>
type_of       id  ...                                               tags                                               user
0  article  1850779  ...         tutorial, braziliandevs, python, beginners  {'name': 'msc2020', 'username': 'msc2020', 'tw...
1  article  1842575  ...  deeplearning, machinelearning, python, brazili...  {'name': 'msc2020', 'username': 'msc2020', 'tw...
2  article  1835701  ...                    python, tutorial, braziliandevs  {'name': 'msc2020', 'username': 'msc2020', 'tw...

[3 rows x 25 columns]

. 2) criação de um arquivo CSV no diretório local: `dataset_articles_published_msc2020.csv`
'''
```

![df_posts.head(3) no jupyter notebook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06ufyqey87tmh58ro6d5.png "Print da saída no Jupyter notebook")

<center><small><small>Print da saída de df_posts.head(3) no Jupyter notebook</small></small></center>

<a id='testes'></a>
## Testes usando outro nome de usuário [<a href="#conteudo">^</A>]

Atualmente, também é possível obter dados sobre os posts de outros usuários usando o endpoint `articles` da API DEV. Por exemplo, usando agora `USER_NAME = 'anuragrana'` e mudando o nome da saída para `dataset_articles_published_user.csv` no código completo [`exporta_posts.py`](#codigo_completo) é esperado que o retorno seja o seguinte:

```yaml
   type_of       id  ...                                               user flare_tag
0  article  1855307  ...  {'name': 'Anurag Rana', 'username': 'anuragran...       NaN
1  article  1276096  ...  {'name': 'Anurag Rana', 'username': 'anuragran...       NaN
2  article   262178  ...  {'name': 'Anurag Rana', 'username': 'anuragran...       NaN

[3 rows x 26 columns]
```


![head jupyter notebook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8jwl4lpwjkznvjmxhe2a.png)

<center><small><small>Print da saída de df_posts.head(3) do código exporta_posts.py no Jupyter notebook</small></small></center>

<a id='possibilidades_uso'></a>

## Possibilidades de uso [<a href="#conteudo">^</A>]

É possível explorar os dados coletados de várias maneiras. A seguir listamos algumas:

1. Usar o <u>Insomnia</u> (https://insomnia.rest/download) ou <u>Postman</u>
(https://www.postman.com/downloads/) para acessar outros endpoints da [v1](https://developers.forem.com/api/v1) da API DEV. Por exemplo, os endpoints `display_ads/`, `follows/tags/`, `reactions/` e `readinglist`.

2. Realizar uma <u>análise exploratória</u> do `CSV` construído, usando bibliotecas como [Pandas](https://pandas.pydata.org/), [Scikit-learn](https://scikit-learn.org/stable/index.html), [Seaborn](https://seaborn.pydata.org/) e [Plotly](https://plotly.com/python/).

3. Aplicar um modelo de LLM como o [_Social-LLM: Modeling User Behavior at Scale using Language Models and Social Network Data_](Social-LLM: Modeling User Behavior at Scale using Language Models and Social Network Data) para analisar um _dataset_ formado com dados de vários endpoints selecionados da API DEV.

4. Contribuir para evolução do projeto Forem, colaborando em [seu Github](https://github.com/forem/forem).

---

<a id='conclusao'></a>

## Conclusão [<a href="#conteudo">^</A>]

O `CSV` obtido neste post pode ajudar nas análises de dados com bibliotecas Python. Com poucas adaptações no código criado, é possível obter dados de outros endpoints da API DEV. Se vc tem alguma ideia para usarmos os dados coletados da API, compartilhe.

***<center>Agradecemos a leitura!</center>***<center>☕ 🧘‍♂️ 💻 ☯️ 🪬</center>