📋 Exemplos Práticos da API
Exemplos práticos de uso da API de predição de atrasos de voos, incluindo casos de uso reais, código de exemplo e integração com diferentes linguagens de programação.
🎯 Visão Geral
Esta seção fornece exemplos concretos de como utilizar a API de predição de atrasos, desde chamadas simples até integrações complexas em sistemas de produção.
🚀 Quick Start
1. 📡 Primeiro Request
# Teste básico da API
curl -X GET "http://localhost:8000/health" \
-H "Content-Type: application/json"
# Resposta esperada
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00Z",
"version": "1.0.0"
}
2. 🎯 Predição Simples
curl -X POST "http://localhost:8000/predict" \
-H "Content-Type: application/json" \
-d '{
"airline": "TAM",
"departure_airport": "SBGR",
"arrival_airport": "SBRJ",
"departure_time": "2024-01-15T14:30:00",
"aircraft_type": "A320",
"weather_conditions": "partly_cloudy",
"temperature": 25.5,
"wind_speed": 15,
"visibility": 8.0
}'
💻 Exemplos por Linguagem
🐍 Python
Exemplo Básico
import requests
import json
from datetime import datetime
# Configuração da API
API_BASE_URL = "http://localhost:8000"
headers = {"Content-Type": "application/json"}
def predict_flight_delay(flight_data):
"""Prediz atraso de voo usando a API"""
url = f"{API_BASE_URL}/predict"
try:
response = requests.post(url, json=flight_data, headers=headers)
response.raise_for_status()
result = response.json()
return result
except requests.exceptions.RequestException as e:
print(f"Erro na requisição: {e}")
return None
# Exemplo de uso
flight_data = {
"airline": "GOL",
"departure_airport": "SBSP",
"arrival_airport": "SBGL",
"departure_time": "2024-01-15T18:45:00",
"aircraft_type": "B737",
"weather_conditions": "rain",
"temperature": 22.0,
"wind_speed": 25,
"visibility": 3.0
}
result = predict_flight_delay(flight_data)
if result:
print(f"Probabilidade de atraso: {result['delay_probability']:.2%}")
print(f"Predição: {'ATRASO' if result['is_delayed'] else 'PONTUAL'}")
print(f"Confiança: {result['confidence']:.2f}")
Cliente Python Avançado
import asyncio
import aiohttp
from typing import List, Dict, Optional
from dataclasses import dataclass
from datetime import datetime
@dataclass
class FlightPredictionResult:
is_delayed: bool
delay_probability: float
confidence: float
predicted_delay_minutes: Optional[int]
factors: Dict[str, float]
timestamp: str
class FlightDelayAPIClient:
"""Cliente avançado para API de predição de atrasos"""
def __init__(self, base_url: str = "http://localhost:8000"):
self.base_url = base_url
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.close()
async def health_check(self) -> Dict:
"""Verifica saúde da API"""
async with self.session.get(f"{self.base_url}/health") as response:
return await response.json()
async def predict_single(self, flight_data: Dict) -> FlightPredictionResult:
"""Predição para um voo"""
async with self.session.post(
f"{self.base_url}/predict",
json=flight_data
) as response:
data = await response.json()
return FlightPredictionResult(
is_delayed=data['is_delayed'],
delay_probability=data['delay_probability'],
confidence=data['confidence'],
predicted_delay_minutes=data.get('predicted_delay_minutes'),
factors=data.get('factors', {}),
timestamp=data['timestamp']
)
async def predict_batch(self, flights: List[Dict]) -> List[FlightPredictionResult]:
"""Predição em lote"""
async with self.session.post(
f"{self.base_url}/predict/batch",
json={"flights": flights}
) as response:
data = await response.json()
return [
FlightPredictionResult(**result)
for result in data['predictions']
]
# Exemplo de uso assíncrono
async def main():
flights = [
{
"airline": "TAM",
"departure_airport": "SBGR",
"arrival_airport": "SBGL",
"departure_time": "2024-01-15T08:30:00",
"aircraft_type": "A320",
"weather_conditions": "clear",
"temperature": 28.0,
"wind_speed": 10,
"visibility": 10.0
},
{
"airline": "GOL",
"departure_airport": "SBSP",
"arrival_airport": "SBRJ",
"departure_time": "2024-01-15T19:15:00",
"aircraft_type": "B737",
"weather_conditions": "thunderstorm",
"temperature": 24.0,
"wind_speed": 40,
"visibility": 1.5
}
]
async with FlightDelayAPIClient() as client:
# Verificar saúde
health = await client.health_check()
print(f"API Status: {health['status']}")
# Predição em lote
results = await client.predict_batch(flights)
for i, result in enumerate(results):
print(f"\nVoo {i+1}:")
print(f" Atraso previsto: {'SIM' if result.is_delayed else 'NÃO'}")
print(f" Probabilidade: {result.delay_probability:.2%}")
print(f" Confiança: {result.confidence:.2f}")
# Executar
# asyncio.run(main())
🟨 JavaScript/Node.js
Exemplo Básico
const axios = require('axios');
const API_BASE_URL = 'http://localhost:8000';
class FlightDelayPredictor {
constructor(baseUrl = API_BASE_URL) {
this.baseUrl = baseUrl;
this.client = axios.create({
baseURL: baseUrl,
headers: {
'Content-Type': 'application/json'
}
});
}
async healthCheck() {
try {
const response = await this.client.get('/health');
return response.data;
} catch (error) {
console.error('Health check failed:', error.message);
throw error;
}
}
async predictDelay(flightData) {
try {
const response = await this.client.post('/predict', flightData);
return response.data;
} catch (error) {
console.error('Prediction failed:', error.message);
throw error;
}
}
async predictBatch(flights) {
try {
const response = await this.client.post('/predict/batch', { flights });
return response.data;
} catch (error) {
console.error('Batch prediction failed:', error.message);
throw error;
}
}
}
// Exemplo de uso
async function main() {
const predictor = new FlightDelayPredictor();
try {
// Verificar saúde da API
const health = await predictor.healthCheck();
console.log('API Status:', health.status);
// Dados do voo
const flightData = {
airline: 'AZUL',
departure_airport: 'SBCF',
arrival_airport: 'SBGR',
departure_time: '2024-01-15T16:20:00',
aircraft_type: 'A320',
weather_conditions: 'cloudy',
temperature: 20.5,
wind_speed: 18,
visibility: 6.0
};
// Fazer predição
const result = await predictor.predictDelay(flightData);
console.log('\n=== RESULTADO DA PREDIÇÃO ===');
console.log(`Voo: ${flightData.departure_airport} → ${flightData.arrival_airport}`);
console.log(`Companhia: ${flightData.airline}`);
console.log(`Predição: ${result.is_delayed ? 'ATRASO' : 'PONTUAL'}`);
console.log(`Probabilidade: ${(result.delay_probability * 100).toFixed(1)}%`);
console.log(`Confiança: ${result.confidence.toFixed(2)}`);
} catch (error) {
console.error('Erro:', error.message);
}
}
// Executar
// main();
React Component
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const FlightDelayPredictor = () => {
const [flightData, setFlightData] = useState({
airline: '',
departure_airport: '',
arrival_airport: '',
departure_time: '',
aircraft_type: '',
weather_conditions: 'clear',
temperature: 25,
wind_speed: 10,
visibility: 10
});
const [prediction, setPrediction] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const handleInputChange = (e) => {
const { name, value } = e.target;
setFlightData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const response = await axios.post(
'http://localhost:8000/predict',
flightData
);
setPrediction(response.data);
} catch (err) {
setError(err.response?.data?.detail || 'Erro na predição');
} finally {
setLoading(false);
}
};
return (
<div className="flight-predictor">
<h2>Predição de Atrasos de Voo</h2>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label>Companhia Aérea:</label>
<select
name="airline"
value={flightData.airline}
onChange={handleInputChange}
required
>
<option value="">Selecione...</option>
<option value="TAM">TAM</option>
<option value="GOL">GOL</option>
<option value="AZUL">Azul</option>
<option value="LATAM">LATAM</option>
</select>
</div>
<div className="form-group">
<label>Aeroporto de Origem:</label>
<select
name="departure_airport"
value={flightData.departure_airport}
onChange={handleInputChange}
required
>
<option value="">Selecione...</option>
<option value="SBGR">São Paulo (Guarulhos)</option>
<option value="SBSP">São Paulo (Congonhas)</option>
<option value="SBRJ">Rio de Janeiro (Santos Dumont)</option>
<option value="SBGL">Rio de Janeiro (Galeão)</option>
</select>
</div>
<div className="form-group">
<label>Data/Hora da Partida:</label>
<input
type="datetime-local"
name="departure_time"
value={flightData.departure_time}
onChange={handleInputChange}
required
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Predizendo...' : 'Prever Atraso'}
</button>
</form>
{error && (
<div className="error">
Erro: {error}
</div>
)}
{prediction && (
<div className="prediction-result">
<h3>Resultado da Predição</h3>
<div className={`prediction ${prediction.is_delayed ? 'delayed' : 'ontime'}`}>
<span className="status">
{prediction.is_delayed ? '⚠️ ATRASO' : '✅ PONTUAL'}
</span>
<span className="probability">
Probabilidade: {(prediction.delay_probability * 100).toFixed(1)}%
</span>
<span className="confidence">
Confiança: {prediction.confidence.toFixed(2)}
</span>
</div>
</div>
)}
</div>
);
};
export default FlightDelayPredictor;
☕ Java
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
public class FlightDelayAPIClient {
private final String baseUrl;
private final ObjectMapper objectMapper;
private final CloseableHttpClient httpClient;
public FlightDelayAPIClient(String baseUrl) {
this.baseUrl = baseUrl;
this.objectMapper = new ObjectMapper();
this.httpClient = HttpClients.createDefault();
}
public class FlightData {
public String airline;
public String departureAirport;
public String arrivalAirport;
public String departureTime;
public String aircraftType;
public String weatherConditions;
public double temperature;
public int windSpeed;
public double visibility;
// Construtor e getters/setters
public FlightData(String airline, String departureAirport, String arrivalAirport,
LocalDateTime departureTime, String aircraftType,
String weatherConditions, double temperature,
int windSpeed, double visibility) {
this.airline = airline;
this.departureAirport = departureAirport;
this.arrivalAirport = arrivalAirport;
this.departureTime = departureTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
this.aircraftType = aircraftType;
this.weatherConditions = weatherConditions;
this.temperature = temperature;
this.windSpeed = windSpeed;
this.visibility = visibility;
}
}
public class PredictionResult {
public boolean isDelayed;
public double delayProbability;
public double confidence;
public String timestamp;
}
public Map<String, Object> healthCheck() throws IOException {
HttpGet request = new HttpGet(baseUrl + "/health");
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
String jsonResponse = EntityUtils.toString(entity);
return objectMapper.readValue(jsonResponse, Map.class);
}
}
public PredictionResult predictDelay(FlightData flightData) throws IOException {
HttpPost request = new HttpPost(baseUrl + "/predict");
request.setHeader("Content-Type", "application/json");
// Converter para JSON
String jsonData = objectMapper.writeValueAsString(flightData);
request.setEntity(new StringEntity(jsonData));
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
String jsonResponse = EntityUtils.toString(entity);
return objectMapper.readValue(jsonResponse, PredictionResult.class);
}
}
public static void main(String[] args) {
FlightDelayAPIClient client = new FlightDelayAPIClient("http://localhost:8000");
try {
// Verificar saúde
Map<String, Object> health = client.healthCheck();
System.out.println("API Status: " + health.get("status"));
// Criar dados do voo
FlightData flight = new FlightData(
"TAM",
"SBGR",
"SBRJ",
LocalDateTime.of(2024, 1, 15, 14, 30),
"A320",
"partly_cloudy",
25.5,
15,
8.0
);
// Fazer predição
PredictionResult result = client.predictDelay(flight);
System.out.println("\n=== RESULTADO ===");
System.out.println("Atraso previsto: " + (result.isDelayed ? "SIM" : "NÃO"));
System.out.println("Probabilidade: " + String.format("%.1f%%", result.delayProbability * 100));
System.out.println("Confiança: " + String.format("%.2f", result.confidence));
} catch (IOException e) {
System.err.println("Erro: " + e.getMessage());
}
}
}
🔄 Casos de Uso Avançados
1. 🎯 Monitoramento em Tempo Real
import asyncio
import websockets
import json
from datetime import datetime, timedelta
class RealTimeFlightMonitor:
"""Monitor de voos em tempo real"""
def __init__(self, api_client):
self.api_client = api_client
self.monitored_flights = {}
async def monitor_flight(self, flight_id, flight_data, check_interval=300):
"""Monitora um voo específico"""
while datetime.now() < datetime.fromisoformat(flight_data['departure_time']):
try:
# Atualizar dados meteorológicos (simulado)
updated_data = await self.update_weather_data(flight_data)
# Fazer nova predição
prediction = await self.api_client.predict_single(updated_data)
# Verificar mudanças significativas
await self.check_prediction_changes(flight_id, prediction)
# Aguardar próxima verificação
await asyncio.sleep(check_interval)
except Exception as e:
print(f"Erro ao monitorar voo {flight_id}: {e}")
await asyncio.sleep(60) # Retry em 1 minuto
async def update_weather_data(self, flight_data):
"""Atualiza dados meteorológicos (integração com API de clima)"""
# Implementar integração com serviço de clima
return flight_data
async def check_prediction_changes(self, flight_id, new_prediction):
"""Verifica mudanças na predição e envia alertas"""
previous = self.monitored_flights.get(flight_id)
if previous:
prob_change = abs(new_prediction.delay_probability - previous.delay_probability)
if prob_change > 0.2: # Mudança > 20%
await self.send_alert(flight_id, new_prediction, prob_change)
self.monitored_flights[flight_id] = new_prediction
async def send_alert(self, flight_id, prediction, change):
"""Envia alerta de mudança na predição"""
alert = {
'flight_id': flight_id,
'new_probability': prediction.delay_probability,
'change': change,
'timestamp': datetime.now().isoformat(),
'message': f'Mudança significativa na predição de atraso: {change:.1%}'
}
print(f"🚨 ALERTA: {alert['message']}")
# Implementar envio por webhook, email, etc.
2. 📊 Análise de Tendências
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
class FlightDelayAnalyzer:
"""Analisador de tendências de atrasos"""
def __init__(self, api_client):
self.api_client = api_client
self.predictions_history = []
async def analyze_route_trends(self, route, days_back=30):
"""Analisa tendências de uma rota específica"""
end_date = datetime.now()
start_date = end_date - timedelta(days=days_back)
# Simular dados históricos da rota
historical_data = self.generate_historical_data(route, start_date, end_date)
# Fazer predições para todos os dados
predictions = []
for data in historical_data:
pred = await self.api_client.predict_single(data)
predictions.append({
'date': data['departure_time'],
'probability': pred.delay_probability,
'weather': data['weather_conditions'],
'temperature': data['temperature']
})
# Análise estatística
df = pd.DataFrame(predictions)
df['date'] = pd.to_datetime(df['date'])
return {
'average_delay_prob': df['probability'].mean(),
'trend': self.calculate_trend(df['probability']),
'weather_impact': df.groupby('weather')['probability'].mean().to_dict(),
'daily_averages': df.groupby(df['date'].dt.date)['probability'].mean().to_dict()
}
def generate_historical_data(self, route, start_date, end_date):
"""Gera dados históricos simulados"""
# Implementar carregamento de dados reais
return []
def calculate_trend(self, probabilities):
"""Calcula tendência da série temporal"""
# Regressão linear simples
x = range(len(probabilities))
slope = np.polyfit(x, probabilities, 1)[0]
if slope > 0.01:
return "increasing"
elif slope < -0.01:
return "decreasing"
else:
return "stable"
🔧 Integração com Sistemas
1. 🎫 Sistema de Reservas
class BookingSystemIntegration:
"""Integração com sistema de reservas"""
def __init__(self, api_client, booking_db):
self.api_client = api_client
self.booking_db = booking_db
async def predict_for_booking(self, booking_id):
"""Prediz atraso para uma reserva específica"""
# Buscar dados da reserva
booking = await self.booking_db.get_booking(booking_id)
if not booking:
raise ValueError(f"Reserva {booking_id} não encontrada")
# Converter para formato da API
flight_data = {
'airline': booking['airline'],
'departure_airport': booking['departure_airport'],
'arrival_airport': booking['arrival_airport'],
'departure_time': booking['departure_time'],
'aircraft_type': booking['aircraft_type'],
# Buscar dados meteorológicos atuais
**await self.get_current_weather(booking['departure_airport'])
}
# Fazer predição
prediction = await self.api_client.predict_single(flight_data)
# Salvar resultado no banco
await self.booking_db.save_prediction(booking_id, prediction)
return prediction
async def get_current_weather(self, airport_code):
"""Busca condições meteorológicas atuais"""
# Integrar com API meteorológica
return {
'weather_conditions': 'partly_cloudy',
'temperature': 25.0,
'wind_speed': 15,
'visibility': 8.0
}
2. 📱 App Mobile
// Kotlin/Android Example
import kotlinx.coroutines.*
import retrofit2.*
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
data class FlightData(
val airline: String,
val departure_airport: String,
val arrival_airport: String,
val departure_time: String,
val aircraft_type: String,
val weather_conditions: String,
val temperature: Double,
val wind_speed: Int,
val visibility: Double
)
data class PredictionResponse(
val is_delayed: Boolean,
val delay_probability: Double,
val confidence: Double,
val timestamp: String
)
interface FlightDelayAPI {
@POST("predict")
suspend fun predictDelay(@Body flightData: FlightData): PredictionResponse
@GET("health")
suspend fun healthCheck(): Map<String, Any>
}
class FlightDelayRepository {
private val api: FlightDelayAPI
init {
val retrofit = Retrofit.Builder()
.baseUrl("http://10.0.2.2:8000/") // Android emulator
.addConverterFactory(GsonConverterFactory.create())
.build()
api = retrofit.create(FlightDelayAPI::class.java)
}
suspend fun predictFlightDelay(flightData: FlightData): Result<PredictionResponse> {
return try {
val prediction = api.predictDelay(flightData)
Result.success(prediction)
} catch (e: Exception) {
Result.failure(e)
}
}
}
// Usage in ViewModel
class FlightPredictionViewModel : ViewModel() {
private val repository = FlightDelayRepository()
fun predictDelay(flightData: FlightData) {
viewModelScope.launch {
val result = repository.predictFlightDelay(flightData)
result.onSuccess { prediction ->
// Update UI with prediction
_predictionResult.value = prediction
}.onFailure { error ->
// Handle error
_errorMessage.value = error.message
}
}
}
}
🧪 Testes de Integração
import pytest
import asyncio
from unittest.mock import AsyncMock, MagicMock
class TestAPIIntegration:
"""Testes de integração da API"""
@pytest.fixture
async def api_client(self):
"""Cliente de teste"""
return FlightDelayAPIClient("http://localhost:8000")
@pytest.mark.asyncio
async def test_health_endpoint(self, api_client):
"""Testa endpoint de saúde"""
async with api_client as client:
health = await client.health_check()
assert health['status'] == 'healthy'
assert 'timestamp' in health
assert 'version' in health
@pytest.mark.asyncio
async def test_single_prediction(self, api_client):
"""Testa predição individual"""
flight_data = {
"airline": "TAM",
"departure_airport": "SBGR",
"arrival_airport": "SBRJ",
"departure_time": "2024-01-15T14:30:00",
"aircraft_type": "A320",
"weather_conditions": "clear",
"temperature": 25.0,
"wind_speed": 10,
"visibility": 10.0
}
async with api_client as client:
result = await client.predict_single(flight_data)
assert isinstance(result.is_delayed, bool)
assert 0 <= result.delay_probability <= 1
assert 0 <= result.confidence <= 1
assert result.timestamp is not None
@pytest.mark.asyncio
async def test_batch_prediction(self, api_client):
"""Testa predição em lote"""
flights = [
{
"airline": "GOL",
"departure_airport": "SBSP",
"arrival_airport": "SBGL",
"departure_time": "2024-01-15T08:00:00",
"aircraft_type": "B737",
"weather_conditions": "cloudy",
"temperature": 20.0,
"wind_speed": 15,
"visibility": 5.0
},
{
"airline": "AZUL",
"departure_airport": "SBCF",
"arrival_airport": "SBRJ",
"departure_time": "2024-01-15T16:30:00",
"aircraft_type": "E190",
"weather_conditions": "rain",
"temperature": 18.0,
"wind_speed": 25,
"visibility": 2.0
}
]
async with api_client as client:
results = await client.predict_batch(flights)
assert len(results) == len(flights)
for result in results:
assert isinstance(result.is_delayed, bool)
assert 0 <= result.delay_probability <= 1
📋 Códigos de Erro
| Código | Descrição | Solução |
|---|---|---|
| 400 | Dados inválidos | Verificar formato dos dados de entrada |
| 401 | Não autorizado | Verificar token de autenticação |
| 404 | Endpoint não encontrado | Verificar URL da API |
| 422 | Erro de validação | Verificar tipos e valores dos campos |
| 500 | Erro interno | Verificar logs do servidor |
| 503 | Serviço indisponível | Tentar novamente mais tarde |
🔗 Próximos Passos
- 📋 Endpoints - Documentação completa da API
- 🏗️ Modelos - Schemas de dados
- 🧪 Testes - Testes de integração
📞 Suporte
- 🐛 Issues - Reportar problemas
- 📖 Documentação - Guia completo
- 🔧 Troubleshooting - Solução de problemas