Created
December 18, 2024 23:25
-
-
Save pietrocaselani/713f97cfb1b5daf4de14983e7ebc3415 to your computer and use it in GitHub Desktop.
Get pedal activities from Strava
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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