Skip to content

Instantly share code, notes, and snippets.

@pietrocaselani
Created December 18, 2024 23:25
Show Gist options
  • Save pietrocaselani/713f97cfb1b5daf4de14983e7ebc3415 to your computer and use it in GitHub Desktop.
Save pietrocaselani/713f97cfb1b5daf4de14983e7ebc3415 to your computer and use it in GitHub Desktop.
Get pedal activities from Strava
import requests
import os
from datetime import datetime, timezone
from dotenv import load_dotenv
from strava_oauth import get_tokens
# Carrega as variáveis do arquivo .env
load_dotenv()
# Lê os dados de configuração do app Strava do arquivo .env
CLIENT_ID = os.getenv("CLIENT_ID")
CLIENT_SECRET = os.getenv("CLIENT_SECRET")
REDIRECT_URI = os.getenv("CALLBACK_URL")
if not all([CLIENT_ID, CLIENT_SECRET, REDIRECT_URI]):
print("Erro: Variáveis de configuração não encontradas no arquivo .env")
exit(1)
# Configurações da API
BASE_URL = "https://www.strava.com/api/v3"
# Obtém o ano atual
current_year = datetime.now().year
# Datas do período (início e fim do ano atual)
inicio_ano = int(datetime(current_year, 1, 1, tzinfo=timezone.utc).timestamp())
fim_ano = int(datetime(current_year, 12, 31, 23, 59, 59, tzinfo=timezone.utc).timestamp())
def get_pedal_activities(access_token):
url = f"{BASE_URL}/athlete/activities"
headers = {"Authorization": f"Bearer {access_token}"}
params = {
"after": inicio_ano,
"before": fim_ano,
"per_page": 200,
}
print(f"Buscando atividades de {current_year}...")
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
atividades = response.json()
print(f"Total de atividades encontradas: {len(atividades)}")
pedal_activities = [a for a in atividades if a.get("type") == "Ride"]
print(f"Total de pedaladas encontradas: {len(pedal_activities)}")
total_km = sum(a.get("distance", 0) for a in pedal_activities) / 1000
print(f"Distância total pedalada em 2024: {total_km:.2f} km")
for i, atividade in enumerate(pedal_activities, 1):
nome = atividade.get("name", "Atividade sem nome")
distancia = atividade.get("distance", 0) / 1000
data = atividade.get("start_date_local", "Data desconhecida")
print(f"{i}. {nome} - {distancia:.2f} km - {data}")
else:
print(f"Erro ao buscar atividades: {response.status_code} - {response.text}")
if __name__ == "__main__":
tokens = get_tokens(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
if tokens:
access_token = tokens["access_token"]
get_pedal_activities(access_token)
else:
print("Nao foi possivel obter o Access Token.")
import webbrowser
import requests
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.parse
AUTH_URL = "https://www.strava.com/oauth/authorize"
TOKEN_URL = "https://www.strava.com/oauth/token"
# Servidor HTTP para capturar o callback
class OAuthHandler(BaseHTTPRequestHandler):
def do_GET(self):
global authorization_code
query = urllib.parse.urlparse(self.path).query
params = urllib.parse.parse_qs(query)
if "code" in params:
authorization_code = params["code"][0]
self.send_response(200)
self.end_headers()
self.wfile.write(b"Autenticacao bem-sucedida! Pode fechar esta janela.")
else:
self.send_response(400)
self.end_headers()
self.wfile.write(b"Erro ao capturar o codigo de autorizacao.")
# Sobrescreve o método log_message para suprimir o log de requisições
def log_message(self, format, *args):
return # Não faz nada com a mensagem de log
def start_server_and_get_code():
"""
Inicia o servidor HTTP local para capturar o código de autorização
enviado pelo Strava após o usuário autenticar.
Retorna:
str: O código de autorização obtido do callback da Strava.
"""
global authorization_code
server_address = ("localhost", 8080)
httpd = HTTPServer(server_address, OAuthHandler)
print("Aguardando callback da autorizacao...")
httpd.handle_request()
# Após capturar o código, retorná-lo
return authorization_code
def get_tokens(client_id, client_secret, callback_url):
"""
Obtém o access_token e refresh_token do Strava.
Parâmetros:
client_id (str): Client ID do aplicativo Strava.
client_secret (str): Client Secret do aplicativo Strava.
callback_url (str): URL de redirecionamento configurada.
Retorna:
dict: Contém o access_token, refresh_token e expires_at.
"""
# Montar e abrir a URL de autorização
params = {
"client_id": client_id,
"redirect_uri": callback_url,
"response_type": "code",
"scope": "activity:read",
"approval_prompt": "force",
}
url = f"{AUTH_URL}?{urllib.parse.urlencode(params)}"
print("Abrindo navegador para autenticacao...")
webbrowser.open(url)
# Iniciar servidor para capturar o código
authorization_code = start_server_and_get_code()
# Trocar código por tokens
if authorization_code:
payload = {
"client_id": client_id,
"client_secret": client_secret,
"code": authorization_code,
"grant_type": "authorization_code",
}
response = requests.post(TOKEN_URL, data=payload)
if response.status_code == 200:
tokens = response.json()
return tokens # Retorna o access token e refresh token
else:
print(f"Erro ao trocar código por token: {response.text}")
return None
else:
print("Não foi possível capturar o código de autorização.")
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment