Ferramenta genérica e extensível para extração massiva de dados de APIs (com suporte a paginação, rate-limit, retries e salvamento em CSV/Parquet/Postgres).
O projeto é assíncrono e inclui presets para a API de Tênis (api.api-tennis.com).
- 🔄 Requisições assíncronas com
aiohttp - 🕓 Rate-limit e concorrência configuráveis
- 💥 Retries automáticos com backoff exponencial
- 📄 Modos:
single— chamadas diretas (ex.:get_players?player_key=...)page— paginação page/limitcursor— paginação por cursor/token (cursor/next)players_harvest— varredura de jogadores (torneios → fixtures → players)odds_harvest— varredura de odds por fixture
- 📊 Normalização JSON → DataFrame (
pandas.json_normalize) - 💾 Parquet (com fallback automático para CSV)
- 🗄️ Postgres opcional via
SQLAlchemy - 🧩
state.jsonpara incremental/cobertura - 🧠 Logs ricos com métricas de cobertura
Api-data-extractor/
├── src/
│ ├── __init__.py
│ ├── async_client.py # HTTP assíncrono (aiohttp)
│ ├── config.py # Carrega .env → AppConfig
│ ├── extractor.py # Padrões de paginação (sync)
│ ├── logger.py # Logging central
│ ├── normalizer.py # JSON → tabela
│ ├── storage.py # CSV/Parquet/Postgres
│ ├── incremental.py # state.json (incremental)
│ ├── run_async.py # Runner principal (async)
│ └── run_sync.py # Runner síncrono (debug)
│
├── .env
├── requirements.txt
└── README.md
# 1) Clonar git clone https://github.com/seuuser/api-data-extractor.git cd api-data-extractorpy -3.13 -m venv .venv ..venv\Scripts\Activate.ps1
pip install -r requirements.txt
pip install pyarrow
Nota: Em Python 3.14, use OUTPUT_FORMAT=csv (pyarrow pode não ter wheel).
API_BASE_URL=https://api.api-tennis.com/tennis API_KEY=SEU_API_KEY_AQUI API_AUTH_TYPE=api_key ENDPOINT_PATH=/ ITEM_KEY=resultPAGINATION_MODE=single TENNIS_METHOD=get_players TENNIS_PLAYER_KEY=137
OUTPUT_FORMAT=csv OUTPUT_DIR=./data RATE_LIMIT_PER_MINUTE=60 CONCURRENCY=5 REQUEST_TIMEOUT_SEC=30 LOG_LEVEL=INFO
API_BASE_URL=https://api.api-tennis.com/tennis API_KEY=SEU_API_KEY_AQUI ENDPOINT_PATH=/ ITEM_KEY=resultPAGINATION_MODE=players_harvest TENNIS_SEASONS=2025,2024,2023 HARVEST_MAX_TOURNAMENTS=0 HARVEST_CONCURRENCY=6
OUTPUT_FORMAT=csv OUTPUT_DIR=./data LOG_LEVEL=INFO
API_BASE_URL=https://api.api-tennis.com/tennis API_KEY=SEU_API_KEY_AQUI ENDPOINT_PATH=/ ITEM_KEY=resultPAGINATION_MODE=odds_harvest TENNIS_SEASONS=2025,2024 HARVEST_CONCURRENCY=6
OUTPUT_FORMAT=csv OUTPUT_DIR=./data LOG_LEVEL=INFO
# com a venv ativa, a partir da raiz do projeto
python -m src.run_async
Saídas padrão (em ./data):
resources_async.csv— single/page/cursorplayers_harvest.csv— players_harvestodds_harvest.csv— odds_harveststate.json— histórico incremental/coverage
2025-10-16 14:26:12 | INFO | api_extractor.async | Iniciando HARVEST ...
2025-10-16 14:26:35 | INFO | api_extractor.async | Torneios considerados: 48
2025-10-16 14:26:58 | INFO | api_extractor.async | Player keys únicos encontrados: 566
2025-10-16 14:27:01 | INFO | api_extractor.async | Perfis coletados: 566. Normalizando...
2025-10-16 14:27:02 | INFO | api_extractor.async | Arquivo salvo (csv) em: ./data/players_harvest.csv
[COVERAGE] previous_keys=566 new_keys_this_run=0 total_unique=566
Defina no .env:
POSTGRES_URL=postgresql+psycopg2://user:senha@localhost:5432/api_data
O script cria/alimenta as tabelas (resources, players, odds). Para UPSERT real (chave primária/merge), ajuste o schema/constraints conforme sua necessidade.
| Ação | Onde mudar |
|---|---|
Header de auth (ex.: X-API-Key) | função _auth_headers() em run_async.py |
Chave de lista (result / data / items) | .env → ITEM_KEY |
| Nome de tabela no Postgres | chamadas upsert_postgres(...) |
| Fallback para CSV | já implementado em storage.py |
| Escopo do harvest | .env → TENNIS_SEASONS, HARVEST_MAX_TOURNAMENTS |
- Harvest de rankings, head-to-head e detalhes de torneios
- Agendador (cron/Airflow) e pipelines
- BigQuery/S3
- Exports incrementais diários