From 6483c9a304fad2212fcaf1c833ec0ccfa74c0e7b Mon Sep 17 00:00:00 2001 From: Mila Date: Tue, 30 Jan 2024 22:13:35 -0300 Subject: [PATCH] newdata --- ArchivosBucket.py | 173 ++++++++++++++++++ .../agency_20231007.csv} | 0 .../calendar_20231007.csv} | 0 .../calendar_dates_20231007.csv} | 0 .../feed_info_20231007.csv} | 0 .../frequencies_20231007.csv} | 0 .../routes_20231007.csv} | 0 .../shapes_20231007.csv} | 0 .../stop_times_20231007.csv} | 0 .../stops_20231007.csv} | 0 .../trips_20231007.csv} | 0 .../agency_20231007.txt" | 0 .../calendar_20231007.txt" | 0 .../calendar_dates_20231007.txt" | 0 .../feed_info_20231007.txt" | 0 .../frequencies_20231007.txt" | 0 .../routes_20231007.txt" | 0 .../shapes_20231007.txt" | 0 .../stop_times_20231007.txt" | 0 .../stops_20231007.txt" | 0 .../trips_20231007.txt" | 0 ...icos_20240127.zip => datos_historicos.zip} | Bin DatosHistoricos.py | 81 +++++--- 23 files changed, 233 insertions(+), 21 deletions(-) create mode 100644 ArchivosBucket.py rename BigData/{agency_20240127.csv => Archivos CSV/agency_20231007.csv} (100%) rename BigData/{calendar_20240127.csv => Archivos CSV/calendar_20231007.csv} (100%) rename BigData/{calendar_dates_20240127.csv => Archivos CSV/calendar_dates_20231007.csv} (100%) rename BigData/{feed_info_20240127.csv => Archivos CSV/feed_info_20231007.csv} (100%) rename BigData/{frequencies_20240127.csv => Archivos CSV/frequencies_20231007.csv} (100%) rename BigData/{routes_20240127.csv => Archivos CSV/routes_20231007.csv} (100%) rename BigData/{shapes_20240127.csv => Archivos CSV/shapes_20231007.csv} (100%) rename BigData/{stop_times_20240127.csv => Archivos CSV/stop_times_20231007.csv} (100%) rename BigData/{stops_20240127.csv => Archivos CSV/stops_20231007.csv} (100%) rename BigData/{trips_20240127.csv => Archivos CSV/trips_20231007.csv} (100%) rename BigData/agency.txt => "BigData/Hist\303\263ricos originales/agency_20231007.txt" (100%) rename BigData/calendar.txt => "BigData/Hist\303\263ricos originales/calendar_20231007.txt" (100%) rename BigData/calendar_dates.txt => "BigData/Hist\303\263ricos originales/calendar_dates_20231007.txt" (100%) rename BigData/feed_info.txt => "BigData/Hist\303\263ricos originales/feed_info_20231007.txt" (100%) rename BigData/frequencies.txt => "BigData/Hist\303\263ricos originales/frequencies_20231007.txt" (100%) rename BigData/routes.txt => "BigData/Hist\303\263ricos originales/routes_20231007.txt" (100%) rename BigData/shapes.txt => "BigData/Hist\303\263ricos originales/shapes_20231007.txt" (100%) rename BigData/stop_times.txt => "BigData/Hist\303\263ricos originales/stop_times_20231007.txt" (100%) rename BigData/stops.txt => "BigData/Hist\303\263ricos originales/stops_20231007.txt" (100%) rename BigData/trips.txt => "BigData/Hist\303\263ricos originales/trips_20231007.txt" (100%) rename BigData/{datos_historicos_20240127.zip => datos_historicos.zip} (100%) diff --git a/ArchivosBucket.py b/ArchivosBucket.py new file mode 100644 index 0000000..95129ce --- /dev/null +++ b/ArchivosBucket.py @@ -0,0 +1,173 @@ +import aiohttp +import os +import zipfile +import pandas as pd +import requests +from aiohttp import ClientConnectorError, TCPConnector +from google.cloud import storage +from google.oauth2 import service_account +from datetime import datetime + +# Configuración +package_id_historicos = "5e8bb1f8-f0a5-4719-a877-38543545505b" +package_id_diarios = "ID_DEL_PAQUETE_PARA_DATOS_DIARIOS" +url_diarios_base = "https://www.red.cl/restservice_v2/rest/conocerecorrido?codsint={}" + +async def obtener_url_descarga(request): + try: + package_id = request.args.get('package_id', default=package_id_historicos, type=str) + url_api = f"https://datos.gob.cl/api/action/package_show?id={package_id}" + response = requests.get(url_api) + response.raise_for_status() + data = response.json() + if data["success"]: + return data["result"]["resources"][0]["url"] + else: + raise ValueError(f"Error en la solicitud API: {data}") + except requests.exceptions.RequestException as e: + return str(e) + +async def descargar_y_descomprimir(request): + try: + url_descarga = await obtener_url_descarga(request) + destino = "/tmp/datos_historicos.zip" + response = requests.get(url_descarga) + response.raise_for_status() + + with open(destino, 'wb') as archivo: + archivo.write(response.content) + + fecha_str = url_descarga.split('/')[-1].split('.')[0][-8:] + + with zipfile.ZipFile(destino, 'r') as zip_ref: + csv_folder = f"/tmp/Archivos_CSV/{fecha_str}" + diarios_folder = os.path.join(csv_folder, 'Diarios') + os.makedirs(diarios_folder, exist_ok=True) + originales_folder = f"/tmp/Historicos_originales/{fecha_str}" + os.makedirs(originales_folder, exist_ok=True) + + for archivo in zip_ref.namelist(): + ruta_archivo = os.path.join(os.path.dirname(destino), archivo) + + if archivo.endswith('.txt'): + destino_txt = os.path.join(originales_folder, f'{os.path.splitext(archivo)[0]}_{fecha_str}.txt') + with open(destino_txt, 'wb') as f: + f.write(zip_ref.read(archivo)) + elif archivo.endswith('.csv'): + destino_csv = os.path.join(csv_folder, f'{os.path.splitext(archivo)[0]}_{fecha_str}.csv') + with open(destino_csv, 'wb') as f: + f.write(zip_ref.read(archivo)) + + convertir_a_csv(originales_folder, csv_folder, fecha_str) + convertir_a_csv(diarios_folder, csv_folder, fecha_str) + + return f'Descarga y descompresión exitosas para fecha: {fecha_str}' + + except requests.exceptions.RequestException as e: + return f'Error en la descarga y descompresión: {e}' + except zipfile.BadZipFile: + return 'Error: El archivo descargado no es un archivo ZIP válido.' + +def convertir_a_csv(directorio_originales, directorio_csv, fecha_str): + archivos_txt = [archivo for archivo in os.listdir(directorio_originales) if archivo.endswith('.txt')] + + for archivo in archivos_txt: + ruta_archivo_txt = os.path.join(directorio_originales, archivo) + dataframe = pd.read_csv(ruta_archivo_txt, delimiter='\t') + ruta_csv = os.path.join(directorio_csv, f'{os.path.splitext(archivo)[0]}.csv') + dataframe.to_csv(ruta_csv, index=False) + +async def obtener_codigos_servicio(request): + try: + url = "https://www.red.cl/restservice_v2/rest/getservicios/all" + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + response.raise_for_status() + return await response.json() + except aiohttp.ClientError as e: + return None + +async def descargar_json_y_convertir_a_csv(request): + try: + codigos_servicio = await obtener_codigos_servicio(request) + + if codigos_servicio: + códigos_fallidos = set(codigos_servicio) + + while códigos_fallidos: + codigo = códigos_fallidos.pop() + url = f"https://www.red.cl/restservice_v2/rest/conocerecorrido?codsint={codigo}" + + connector = TCPConnector(limit_per_host=10) + async with aiohttp.ClientSession(connector=connector) as session: + async with session.get(url) as response: + response.raise_for_status() + dataframe = pd.json_normalize(await response.json()) + diarios_folder = f"/tmp/Archivos_CSV/Diarios" + os.makedirs(diarios_folder, exist_ok=True) + ruta_csv = os.path.join(diarios_folder, f'datos_diarios_{codigo}.csv') + dataframe.to_csv(ruta_csv, index=False) + + return 'Proceso de descarga y conversión de datos diarios completado' + + except (aiohttp.ClientError, ClientConnectorError) as e: + return f'Error en la descarga de datos diarios: {e}' + +def subir_datos_a_bucket(local_folder, bucket): + archivos_nuevos = 0 + archivos_actualizados = 0 + + def upload_file(local_file, blob_name): + nonlocal archivos_nuevos, archivos_actualizados + blob = bucket.blob(blob_name) + + if blob.exists(): + archivos_actualizados += 1 + accion = "actualizado" + else: + archivos_nuevos += 1 + accion = "agregado" + + blob.upload_from_filename(local_file) + print(f"Archivo {local_file} {accion} en {blob_name}.") + + for root, dirs, files in os.walk(local_folder): + for filename in files: + local_file_path = os.path.join(root, filename) + upload_file(local_file_path, filename) + + print(f"Total de archivos nuevos agregados: {archivos_nuevos}") + print(f"Total de archivos actualizados: {archivos_actualizados}") + +def cloud_function_handler(request): + try: + # Descargar y procesar datos históricos + response_historicos = asyncio.run(descargar_y_descomprimir(request)) + print(response_historicos) + + # Configuración de la autenticación + credentials_path = os.path.join(os.getcwd(), 'tav2024-411600-905e9a2544f7.json') + credentials = service_account.Credentials.from_service_account_file( + credentials_path, + scopes=["https://www.googleapis.com/auth/cloud-platform"], + ) + storage_client = storage.Client(credentials=credentials) + + # Obtener el bucket + bucket_name = 'tavbucket2024' + bucket = storage_client.get_bucket(bucket_name) + + # Subir datos históricos al bucket + subir_datos_a_bucket("/tmp", bucket) + + # Descargar y procesar datos diarios + response_diarios = asyncio.run(descargar_json_y_convertir_a_csv(request)) + print(response_diarios) + + # Subir datos diarios al bucket + subir_datos_a_bucket("/tmp/Archivos_CSV/Diarios", bucket) + + return 'Proceso completo' + + except Exception as e: + return f'Error en la ejecución principal: {e}' diff --git a/BigData/agency_20240127.csv b/BigData/Archivos CSV/agency_20231007.csv similarity index 100% rename from BigData/agency_20240127.csv rename to BigData/Archivos CSV/agency_20231007.csv diff --git a/BigData/calendar_20240127.csv b/BigData/Archivos CSV/calendar_20231007.csv similarity index 100% rename from BigData/calendar_20240127.csv rename to BigData/Archivos CSV/calendar_20231007.csv diff --git a/BigData/calendar_dates_20240127.csv b/BigData/Archivos CSV/calendar_dates_20231007.csv similarity index 100% rename from BigData/calendar_dates_20240127.csv rename to BigData/Archivos CSV/calendar_dates_20231007.csv diff --git a/BigData/feed_info_20240127.csv b/BigData/Archivos CSV/feed_info_20231007.csv similarity index 100% rename from BigData/feed_info_20240127.csv rename to BigData/Archivos CSV/feed_info_20231007.csv diff --git a/BigData/frequencies_20240127.csv b/BigData/Archivos CSV/frequencies_20231007.csv similarity index 100% rename from BigData/frequencies_20240127.csv rename to BigData/Archivos CSV/frequencies_20231007.csv diff --git a/BigData/routes_20240127.csv b/BigData/Archivos CSV/routes_20231007.csv similarity index 100% rename from BigData/routes_20240127.csv rename to BigData/Archivos CSV/routes_20231007.csv diff --git a/BigData/shapes_20240127.csv b/BigData/Archivos CSV/shapes_20231007.csv similarity index 100% rename from BigData/shapes_20240127.csv rename to BigData/Archivos CSV/shapes_20231007.csv diff --git a/BigData/stop_times_20240127.csv b/BigData/Archivos CSV/stop_times_20231007.csv similarity index 100% rename from BigData/stop_times_20240127.csv rename to BigData/Archivos CSV/stop_times_20231007.csv diff --git a/BigData/stops_20240127.csv b/BigData/Archivos CSV/stops_20231007.csv similarity index 100% rename from BigData/stops_20240127.csv rename to BigData/Archivos CSV/stops_20231007.csv diff --git a/BigData/trips_20240127.csv b/BigData/Archivos CSV/trips_20231007.csv similarity index 100% rename from BigData/trips_20240127.csv rename to BigData/Archivos CSV/trips_20231007.csv diff --git a/BigData/agency.txt "b/BigData/Hist\303\263ricos originales/agency_20231007.txt" similarity index 100% rename from BigData/agency.txt rename to "BigData/Hist\303\263ricos originales/agency_20231007.txt" diff --git a/BigData/calendar.txt "b/BigData/Hist\303\263ricos originales/calendar_20231007.txt" similarity index 100% rename from BigData/calendar.txt rename to "BigData/Hist\303\263ricos originales/calendar_20231007.txt" diff --git a/BigData/calendar_dates.txt "b/BigData/Hist\303\263ricos originales/calendar_dates_20231007.txt" similarity index 100% rename from BigData/calendar_dates.txt rename to "BigData/Hist\303\263ricos originales/calendar_dates_20231007.txt" diff --git a/BigData/feed_info.txt "b/BigData/Hist\303\263ricos originales/feed_info_20231007.txt" similarity index 100% rename from BigData/feed_info.txt rename to "BigData/Hist\303\263ricos originales/feed_info_20231007.txt" diff --git a/BigData/frequencies.txt "b/BigData/Hist\303\263ricos originales/frequencies_20231007.txt" similarity index 100% rename from BigData/frequencies.txt rename to "BigData/Hist\303\263ricos originales/frequencies_20231007.txt" diff --git a/BigData/routes.txt "b/BigData/Hist\303\263ricos originales/routes_20231007.txt" similarity index 100% rename from BigData/routes.txt rename to "BigData/Hist\303\263ricos originales/routes_20231007.txt" diff --git a/BigData/shapes.txt "b/BigData/Hist\303\263ricos originales/shapes_20231007.txt" similarity index 100% rename from BigData/shapes.txt rename to "BigData/Hist\303\263ricos originales/shapes_20231007.txt" diff --git a/BigData/stop_times.txt "b/BigData/Hist\303\263ricos originales/stop_times_20231007.txt" similarity index 100% rename from BigData/stop_times.txt rename to "BigData/Hist\303\263ricos originales/stop_times_20231007.txt" diff --git a/BigData/stops.txt "b/BigData/Hist\303\263ricos originales/stops_20231007.txt" similarity index 100% rename from BigData/stops.txt rename to "BigData/Hist\303\263ricos originales/stops_20231007.txt" diff --git a/BigData/trips.txt "b/BigData/Hist\303\263ricos originales/trips_20231007.txt" similarity index 100% rename from BigData/trips.txt rename to "BigData/Hist\303\263ricos originales/trips_20231007.txt" diff --git a/BigData/datos_historicos_20240127.zip b/BigData/datos_historicos.zip similarity index 100% rename from BigData/datos_historicos_20240127.zip rename to BigData/datos_historicos.zip diff --git a/DatosHistoricos.py b/DatosHistoricos.py index 3923092..302f7ac 100644 --- a/DatosHistoricos.py +++ b/DatosHistoricos.py @@ -2,54 +2,93 @@ import os import zipfile import pandas as pd -from datetime import datetime -def descargar_y_descomprimir(url, directorio_destino): +def obtener_url_descarga(package_id): + url_api = f"https://datos.gob.cl/api/action/package_show?id={package_id}" + response = requests.get(url_api) + response.raise_for_status() + data = response.json() - fecha_actual = datetime.now().strftime("%Y%m%d") + # Verificar si la solicitud fue exitosa + if data["success"]: + # Obtener la URL de descarga del primer recurso (asumimos que hay al menos uno) + return data["result"]["resources"][0]["url"] + else: + raise ValueError(f"Error en la solicitud API: {data}") +def descargar_y_descomprimir(url, destino): try: + # Realizar solicitud HTTP GET response = requests.get(url) - response.raise_for_status() + response.raise_for_status() # Verificar si la solicitud fue exitosa - nombre_archivo = f'datos_historicos_{fecha_actual}.zip' - ruta_archivo = os.path.join(directorio_destino, nombre_archivo) - with open(ruta_archivo, 'wb') as archivo: + with open(destino, 'wb') as archivo: archivo.write(response.content) - print(f'Descarga exitosa. Archivo guardado en: {ruta_archivo}') + print(f'Descarga exitosa. Archivo guardado en: {destino}') + # Extraer la fecha de la URL + fecha_str = url.split('/')[-1].split('.')[0][-8:] - with zipfile.ZipFile(ruta_archivo, 'r') as zip_ref: - zip_ref.extractall(directorio_destino) + # Descomprimir el archivo ZIP + with zipfile.ZipFile(destino, 'r') as zip_ref: + # Crear la carpeta "Archivos CSV" dentro del directorio de destino + csv_folder = os.path.join(os.path.dirname(destino), 'Archivos CSV') + os.makedirs(csv_folder, exist_ok=True) - print(f'Descompresión exitosa.') + # Crear la carpeta "Históricos originales" dentro del directorio de destino + originales_folder = os.path.join(os.path.dirname(destino), 'Históricos originales') + os.makedirs(originales_folder, exist_ok=True) + + # Extraer archivos y organizar según su extensión + for archivo in zip_ref.namelist(): + ruta_archivo = os.path.join(os.path.dirname(destino), archivo) + if archivo.endswith('.txt'): + # Mover archivos TXT a la carpeta "Históricos originales" + destino_txt = os.path.join(originales_folder, f'{os.path.splitext(archivo)[0]}_{fecha_str}.txt') + with open(destino_txt, 'wb') as f: + f.write(zip_ref.read(archivo)) + elif archivo.endswith('.csv'): + # Mover archivos CSV a la carpeta "Archivos CSV" y agregar fecha al nombre + destino_csv = os.path.join(csv_folder, f'{os.path.splitext(archivo)[0]}_{fecha_str}.csv') + with open(destino_csv, 'wb') as f: + f.write(zip_ref.read(archivo)) + + print(f'Descompresión exitosa.') - convertir_a_csv(directorio_destino, fecha_actual) + # Convertir archivos TXT a CSV + convertir_a_csv(originales_folder, csv_folder, fecha_str) except requests.exceptions.RequestException as e: print(f'Error en la descarga: {e}') except zipfile.BadZipFile: print(f'Error: El archivo descargado no es un archivo ZIP válido.') -def convertir_a_csv(directorio_destino, fecha_actual): +def convertir_a_csv(directorio_originales, directorio_csv, fecha_str): + archivos_txt = [archivo for archivo in os.listdir(directorio_originales) if archivo.endswith('.txt')] - archivos_extraidos = [f for f in os.listdir(directorio_destino) if f.endswith('.txt')] - - # Recorrer los archivos y convertirlos a CSV - for archivo in archivos_extraidos: - ruta_archivo_txt = os.path.join(directorio_destino, archivo) + # Recorrer los archivos TXT y convertirlos a CSV + for archivo in archivos_txt: + ruta_archivo_txt = os.path.join(directorio_originales, archivo) dataframe = pd.read_csv(ruta_archivo_txt, delimiter='\t') - ruta_csv = os.path.join(directorio_destino, f'{os.path.splitext(archivo)[0]}_{fecha_actual}.csv') + + # Crear la ruta para guardar el archivo CSV dentro de la carpeta "Archivos CSV" con la fecha + ruta_csv = os.path.join(directorio_csv, f'{os.path.splitext(archivo)[0]}.csv') + dataframe.to_csv(ruta_csv, index=False) print(f'Archivo convertido a CSV: {ruta_csv}') if __name__ == "__main__": - url_descarga = "https://datos.gob.cl/dataset/5e8bb1f8-f0a5-4719-a877-38543545505b/resource/e4cd8abb-4ac3-4754-9e9c-29be83abad39/download/gtfs-v104-po20231007.zip" + # Obtener la URL de descarga desde la API usando el package_id + package_id = "5e8bb1f8-f0a5-4719-a877-38543545505b" + url_descarga = obtener_url_descarga(package_id) + directorio_destino = "./BigData" + nombre_archivo = "datos_historicos.zip" + ruta_archivo = os.path.join(directorio_destino, nombre_archivo) if not os.path.exists(directorio_destino): os.makedirs(directorio_destino) - descargar_y_descomprimir(url_descarga, directorio_destino) + descargar_y_descomprimir(url_descarga, ruta_archivo) \ No newline at end of file