Simplificar el intercambio de archivos

Simplificar intercambio archivos

Ejemplo de codificación para trabajar con carpetas compartidas de Google Drive en proyectos de colaboración

Recientemente, surgió nuevamente un problema de intercambio de datos, y pensé que este sería un buen momento para diseñar un método para trabajar con carpetas compartidas. Trabajo como profesional independiente de GIScience y me relaciono frecuentemente con varias organizaciones de manera simultánea. En mis proyectos, he notado que cada organización tiene su propio enfoque único para trabajar con datos, moldeado por su cultura y ética laboral distintivas, lo que resulta en una diversidad de metodologías. Afortunadamente, existen algunas prácticas que tienen en común, y una de ellas es trabajar con un sistema de gestión de datos basado en la nube, a menudo Google, pero también puede ser One-Drive (de Microsoft) o Dropbox.

En esta publicación, explicaré cómo usar Python con Carpetas Compartidas en el Ecosistema de Google.

Foto de Annie Spratt en Unsplash

Caso de uso

Cómo gestionar archivos en una máquina local es muy individual y (esperemos) estandarizado, o al menos tiene cierta estandarización, al trabajar en una organización. Compartir archivos entre sistemas puede ser complicado, pero trabajar con carpetas compartidas es una opción cuando no se tiene acceso directo a una carpeta de producción y la organización puede compartir contigo una carpeta de trabajo específicamente designada para intercambiar archivos. En este ejemplo, una organización ha otorgado acceso a una carpeta llamada DATA en su repositorio de Google Drive, y se ha acordado que podemos usar esta carpeta para intercambiar archivos.

Gestión de archivos locales

Para explicarlo rápidamente, para las personas que no están familiarizadas con el intercambio de archivos de Google Drive, el proceso comienza al recibir un correo electrónico que te invita a contribuir a una carpeta específica; ve la invitación (izquierda) a continuación. En la invitación hay un botón que abrirá un navegador web con la interfaz de Google Drive (derecha) asociada al correo electrónico de Google del receptor de la invitación.

Figura 1: Creación de una Carpeta Compartida (imagen del autor)

Hay algunas piezas de información importantes ocultas en la interfaz, y entenderlas desde el principio ayudará con el resto del proceso.

  • En la URL (parte superior de la pantalla), hay una ID enmascarada, esta es la ID que Google utiliza para rastrear todas las operaciones en esta carpeta, y esta es la ID que obtendremos en el código Python más adelante en esta publicación.
  • Luego dice: “Compartido conmigo” y el nombre de la carpeta compartida; también, esto es importante porque cuando montemos Google Drive en el cuaderno CoLab, veremos que esta categoría no está disponible.
  • Y finalmente, vemos los archivos y carpetas bajo Data; esto significa que podemos acceder a la información que necesitamos y agregar nuevos archivos a la carpeta. Sin embargo, podría haber un problema con la configuración de seguridad de la carpeta, por lo que una buena prueba en esta etapa es crear un archivo de texto pequeño y arrastrarlo y soltarlo en la carpeta “ExternalData” para verificar que tienes acceso completo.

Para hacer que la carpeta “Compartido conmigo” sea accesible, necesitamos vincular esta carpeta al disco local/personal. Podemos hacer esto creando un acceso directo, pero este es un paso manual y será diferente para cada persona. Para acceder a una carpeta o archivo compartido contigo en Google Colab, debes:

  1. Ir a “Compartido conmigo” en Google Drive.
  2. Seleccionar la carpeta o archivo al que deseas acceder.
  3. Hacer clic derecho sobre él y elegir “Agregar acceso directo al disco”, y aparecerá una ventana emergente, “Seleccionar Mi unidad”, luego haz clic en “Agregar acceso directo”.
  4. Colocar el acceso directo en una ubicación de tu disco que puedas encontrar fácilmente; en la configuración que utilizo, la ubicación para los accesos directos es “__Shared”, asegurando que la carpeta con los accesos directos esté en la parte superior de la lista de carpetas bajo “Mi unidad”, y luego un subdirectorio para la organización.
  5. Renombrar el acceso directo con un nombre significativo; en este ejemplo, uso “DataDesarrollo”. La ubicación y convenciones de nombres de archivo son muy personales y no importa para el programa dónde se almacenan los archivos o cómo se llaman, pero tener alguna estructura puede evitar algunos dolores de cabeza más adelante.
Figura 2: Creando un acceso directo (imagen del autor)

Con el sistema de archivos local organizado y la configuración del Google Drive personal, podemos intentar trabajar con esta carpeta compartida en un cuaderno de Python y automatizar el intercambio de archivos en el proyecto.

Instalación

Este proyecto se basa en un cuaderno de Google Colab, o “Collaboratory”, que compartiré al final de este artículo. La ventaja de usar este entorno es que te permite escribir y ejecutar Python en tu navegador, con

  • No se requiere configuración
  • Acceso gratuito a GPUs
  • Compartir fácilmente

Estos son puntos muy importantes cuando se trabaja con organizaciones que tienen sus procedimientos internos, porque como colaborador externo, a menudo no tienes acceso directo a la base de código (y esto puede tener muchas razones diferentes, desde preocupaciones de seguridad hasta restricciones de gestión de proyectos). El cuaderno de Colab forma parte del ecosistema de Google y (como ventaja adicional) crea un entorno de ejecución con la opción de montar unidades de Google personales (para compartir archivos).

Importar módulos y paquetes

Para este ejemplo, solo se cargan los paquetes necesarios en el tiempo de ejecución del cuaderno, y necesitamos algunas bibliotecas específicas para trabajar con la unidad compartida.

Autorización de Google

from oauth2client.client import GoogleCredentialsfrom google.colab import auth as google_authgoogle_auth.authenticate_user()from google.colab import drivedrive.mount('/content/gdrive')

Usar oauth2client y las Credenciales de Google facilitará el trabajo con los archivos. Hay alternativas, como descargar un archivo JSON con las credenciales, y habrá situaciones en las que trabajar con el archivo JSON será preferible a usar las Credenciales de Google, pero como este es un proyecto sin datos sensibles, la biblioteca oauth2client proporciona suficiente protección.

pydrive

from pydrive.auth import GoogleAuthfrom pydrive.drive import GoogleDrivegauth = GoogleAuth()gauth.credentials = GoogleCredentials.get_application_default()drive = GoogleDrive(gauth)

pydrive es una biblioteca envolvente de google-api-python-client que simplifica muchas tareas comunes de la API de Google Drive, y una de estas funcionalidades es manejar las respuestas de obtención al consultar el sistema de archivos de Google Drive. Google Drive almacena todos los objetos por ID, y los ID están vinculados por información relacional en los objetos. Es posible acceder a esta información mediante la API (ver el siguiente bloque de código), pero la biblioteca envolvente se encarga de todo el trabajo pesado por nosotros cuando creamos una instancia de GoogleDriveFileList con los parámetros de Files.list() como un dict. Llamar a GetList() obtendrá todos los archivos que coincidan con tu consulta como una lista de GoogleDriveFile.

Cliente de API de Google

# Cliente de API de Google:from googleapiclient.discovery import build# Inicializar el cliente de API de Google Drivedrive_service = build('drive', 'v3')

El Cliente de API de Google es una biblioteca grande y tiene muchas funcionalidades, pero para este proyecto, solo necesitamos un módulo: build. El módulo build construye un objeto de recurso para interactuar con una API y devuelve los métodos para interactuar con el servicio. La biblioteca pydrive manejará muy bien las funciones básicas, como crear, actualizar y eliminar archivos, pero hay algunos momentos (en este proyecto) en los que necesitamos una funcionalidad más avanzada, y tener acceso al “servicio” nos permite extraer información que no está capturada por los métodos de pydrive.

Esto concluye la configuración del cuaderno. En este ejemplo, no necesitamos más bibliotecas que las bibliotecas cargadas para la gestión de archivos, y con las bibliotecas cargadas, podemos echar un vistazo a lo que están haciendo.

Gestión de archivos en el cuaderno

Hasta este punto, han ocurrido algunas cosas:

  • Se configuró la autorización de Google,
  • Creamos acceso a la unidad (para acceso de lectura/escritura) y
  • El paquete Pydrive está disponible para navegar en la unidad

Espero que cuando estés siguiendo y ejecutando el código, veas la imagen a la derecha, después de haber actualizado el panel. Puedes ver el Acceso directo en la imagen como una carpeta debajo de “__Compartido”, y no vemos la sección “Compartido conmigo”, pero como tenemos el Acceso directo, no necesitamos ver los archivos “Compartidos conmigo”.

Figura 3: Estados sin montar vs. Montados del entorno de ejecución en la interfaz web de Google Colab (imagen del autor)

Google Drive funciona de manera diferente a la gestión de archivos en los sistemas operativos locales, la ubicación física de los archivos no es importante porque los objetos se gestionan por ID en un DataLake no estructurado, y podemos acceder a los archivos y carpetas mediante el ID.

Desafortunadamente, mientras que el módulo os.path (en Python) tiene funciones para recorrer el sistema de archivos, un método similar no existe para Google Drive (o no estoy al tanto de este método). Sin embargo, podemos utilizar la biblioteca pydrive y recorrer manualmente las carpetas en el árbol de directorios, y afortunadamente, sabemos a dónde queremos ir a partir de la ruta de la carpeta. Por lo tanto, no necesitamos recorrer toda la estructura, sino que podemos utilizar los nombres de las carpetas de la ruta de datos para adentrarnos más en el árbol de carpetas.

Así que iteramos sobre la pequeña lista (en este ejemplo, tres elementos) para encontrar el ID y usar este ID para ir al siguiente nivel. Tenga en cuenta que el cuarto nivel está comentado; llegaremos a este nivel en la segunda parte de la sección de manejo de archivos de este cuaderno.

# Pruebas de manejo de archivos:# En este ejemplo hay tres niveles de carpetas:# /content/gdrive/MyDrive/__Shared/<tu Proyecto>/DataDevelopment# Actualiza esto según tu estructura:folderList1 = ["__Shared", tu_Proyecto ,"DataDevelopment"] #, "ExternalData"]

El bucle, en el bloque de código a continuación, comienza en la raíz y cuando encuentra un elemento en la lista, el bucle utilizará el ID del objeto para ir al siguiente nivel en la lista, y si no se encuentra un elemento, el código mostrará que la carpeta no se encuentra y no buscará ninguna carpeta más profunda en la estructura. El bucle concluye con el ID de la carpeta de acceso directo o muestra que la carpeta no se encuentra.

# Intentando copiar el archivo dummy creado:boo_foundFolder = FalsefileID = "root"level = 0# Ver todas las carpetas y archivos en tu Google Drive# Primero iteramos sobre la lista:print("Estructura de archivos y carpetas - comprobar con IDs")for folderName in folderList1:  print(f"Comprobando: {folderName}")  if boo_foundFolder or fileID == "root": #primera ejecución    boo_foundFolder = False    fileList = drive.ListFile({'q': f"'{fileID}' in parents and trashed=false"}).GetList()    for file in fileList:      # Comprobando el nombre:            if(file['title'] == folderName):        fileID = file['id']        boo_foundFolder = True        level += 1       # fin if    # fin for    if boo_foundFolder == False:      print(f"carpeta no encontrada")      break    # fin if      # fin if# fin forprint(f"¿Encontramos la carpeta?: {boo_foundFolder}")if boo_foundFolder:  print(fileID)  ShortCutID = fileIDelse:  ShortCutID = 0

En este momento, tenemos el ID de archivo local para la carpeta de trabajo, pero antes de poder buscar archivos en esta ubicación, debemos relacionar este ID local con el ID objetivo de la carpeta compartida. Para encontrar esta información, debemos profundizar en la infraestructura de Google, y para hacer esto, necesitamos un ayudante: el drive_service. Activamos el ayudante mientras cargábamos el proyecto y no recibimos ninguna advertencia, lo que significa que tenemos acceso al servicio utilizando la API y solicitando información por ID.

Los detalles que necesitamos se recopilan mejor a través de una función simple, como la función findTargetID en el siguiente bloque de código. En esta función, el fileID es el ID del acceso directo que encontramos al iterar sobre los nombres de las carpetas y al llamar a drive_service.files().get y especificar los campos, obtenemos el ID objetivo de la carpeta (este será el mismo ID que en la URL de la interfaz web de Google Drive (ver Figura 1).

def findTargetID(fileID, drive_service):  # El ID del archivo compartido del que quieres obtener los detalles del acceso directo  file_id = fileID  try:      # Obtener los detalles del archivo      file = drive_service.files().get(fileId=file_id,                                       fields="id, shortcutDetails").execute()      # Comprobar si el archivo es un acceso directo      if 'shortcutDetails' in file:          shortcut_details = file['shortcutDetails']          print("Detalles del acceso directo:")          print(f"ID objetivo: {shortcut_details['targetId']}")          print(f"Tipo MIME objetivo: {shortcut_details['targetMimeType']}")      else:          print("El archivo no es un acceso directo.")      # fin if  except Exception as e:      print(f"Ocurrió un error: {e}")  return shortcut_details['targetId']if boo_foundFolder:  targetID = findTargetID(fileID, drive_service)  print(targetID)else:  print("Carpeta no encontrada")# fin if

Con este ID de destino, tenemos acceso a la carpeta compartida real en el servidor de datos de Google y ya no estamos trabajando en la carpeta de acceso directo.

Para recapitular, creamos la carpeta de acceso directo para poder ver la carpeta en nuestra lista montada de carpetas. La categoría “Compartido conmigo” no está montada, pero los accesos directos sí lo están. Por lo tanto, con este nuevo ID podemos buscar archivos.

Buscando archivos

Ahora tenemos lo que necesitamos, el ID de destino de la carpeta compartida con nosotros al comienzo del proceso, y con ese ID, todas las operaciones normales de archivos están disponibles para nosotros.

Podemos verificar que tenemos suficientes permisos en la carpeta compartida creando primero un pequeño archivo de texto en el entorno de ejecución; la creación de este archivo también confirma que tenemos acceso al entorno de ejecución porque aparecerá en el panel izquierdo de la interfaz web del cuaderno CoLab cuando el archivo se cree correctamente.

# Crear un archivo de prueba:with open('example.txt', 'w') as f:  f.write('Este es un archivo de ejemplo, para probar el intercambio de archivos de CoLab')# este archivo ahora está en el espacio de ejecución del cuaderno # (ver plano izquierdo, debajo de los archivos)

Ahora la idea es mover este archivo a la carpeta “Compartido conmigo” llamada “Data”, que hemos renombrado como “DataDevelopment” en el acceso directo, pero la función en la sección anterior proporcionó el <ID de destino>, y ahora podemos usar este ID para verificar si el archivo que acabamos de crear en el entorno de ejecución está disponible en la unidad compartida.

if boo_foundFolder:  print("carpeta encontrada")  folderID = targetID  archivo_en_unidad = False  id_archivo = 0    # verificar si el archivo está en la unidad:  listaArchivos = drive.ListFile({'q': f"'{folderID}' in parents and trashed=false"}).GetList()  for archivo in listaArchivos:    if(archivo['title'] == "example.txt"):      archivo_en_unidad = True      id_archivo = archivo['id']    # fin si  # fin para  if archivo_en_unidad:  #Sobrescribe el archivo existente en Google Drive."""    archivo1 = drive.CreateFile({'id': id_archivo})    strManejoArchivo = "Actualizado"  else:    archivo1 = drive.CreateFile({"mimeType": "text/csv",                             "parents": [{"kind": "drive#fileLink",                                         "id": folderID}]})    strManejoArchivo = "Creado"  # fin si  # creando el enlace al archivo en el entorno de ejecución:  archivo1.SetContentFile("example.txt")  # copiando el archivo a Google Drive:  archivo1.Upload()  print(f'{strManejoArchivo} archivo %s con mimeType %s' % (archivo1['title'], archivo1['mimeType']))else:  print("carpeta no encontrada")# fin si

Ejecutar el código anterior creará un nuevo archivo en la carpeta compartida o actualizará (sobrescribirá) el archivo cuando se encuentre.

Creando un espacio de trabajo

Hay una segunda razón para usar el ID de acceso directo para encontrar el ID de destino y eso es encontrar elementos en la carpeta compartida. Como se mencionó antes, Google Drive gestiona todo por ID y el ID de acceso directo no tiene ningún hijo, por lo que usar este ID para encontrar nuevos elementos dará como resultado una lista vacía. Esto se puede probar incluyendo el nombre de la carpeta “ExternalData” en la primera lista de carpetas; la primera lista no encontrará esta carpeta. Sin embargo, reiniciar el bucle con el ID de destino encontrará esta carpeta.

En el fragmento de código siguiente, se crea una nueva lista de carpetas utilizando los nombres de las carpetas debajo del nombre de la carpeta “Compartido conmigo”. La carpeta “ExternalData” está disponible (ver Figura 1), pero “NewDataFolder” aún no se ha creado.

# Actualice estos valores según su estructura:# ... DataDevelopment/ExternalData/__CoLab_Notebook # Configurando la carpeta de trabajo:listaCarpetas2 = ["ExternalData", "NewDataFolder"]

Podemos usar la misma estructura de bucle que antes, pero ahora en lugar de comenzar en la RAÍZ, comenzamos con el ID de destino y el bucle encontrará la carpeta “ExternalData”, pero no la nueva carpeta de datos.

Como la carpeta de trabajo aún no existe, podemos usar drive_service.files para crear esta nueva carpeta y, con el mismo método, todos los archivos que deben transferirse desde el entorno de ejecución a la carpeta “Compartido conmigo”.

def crear_carpeta_en_carpeta(nombre_carpeta, id_carpeta_padre, servicio_drive):
    metadatos_archivo = {
        'name' : nombre_carpeta,
        'parents' : [id_carpeta_padre],
        'mimeType' : 'application/vnd.google-apps.folder'
    }
    archivo = servicio_drive.files().create(body=metadatos_archivo, supportsAllDrives=True, fields='id').execute()
    print('ID de la carpeta: %s' % archivo.get('id'))

if IDCarpetaTrabajo == 0:  # fileID es el ID del padre obtenido de la búsqueda anterior
    crear_carpeta_en_carpeta("NuevaCarpetaDatos", fileID, servicio_drive)

Puntos clave: El sistema de archivos de Google Drive se basa en identificadores (ID), y todos los objetos tienen un ID. Los objetos “Compartidos conmigo” no están disponibles en Google Colab, pero a través de un “Acceso directo” podemos acceder a ellos, y al encontrar el ID de destino asociado, podemos trabajar directamente en la carpeta “Compartidos conmigo”, incluyendo los objetos bajo la carpeta inicialmente compartida con nosotros.

Conclusiones

En este artículo, hemos cubierto algunos aspectos esenciales de trabajar con carpetas compartidas, incluyendo:

  1. Configuración de la gestión de archivos locales: Iniciamos el proceso con la recepción de una invitación para contribuir a un directorio designado de Google Drive y mostramos cómo estructurar tu sistema de archivos local para mejorar la eficiencia colaborativa.
  2. Configuración de Google Colab para la colaboración: Discutimos las ventajas de usar Google Colab, un entorno colaborativo de Python, y cómo configurarlo para la colaboración en proyectos.
  3. Importación de módulos y paquetes necesarios: Proporcionamos ejemplos de código para importar módulos y paquetes esenciales, incluyendo la autorización de Google, pydrive para simplificar las tareas de la API de Google Drive y el cliente de la API de Google para funcionalidad avanzada.
  4. Gestión de archivos en el cuaderno: Viste cómo gestionar archivos dentro del entorno de Google Colab, incluyendo la creación y el movimiento de archivos entre tu entorno local y carpetas compartidas utilizando el ID compartido y el ID de destino.
  5. Búsqueda de archivos y creación de espacios de trabajo: Nos adentramos en el proceso de búsqueda de archivos dentro de carpetas compartidas utilizando los IDs de destino y la creación de nuevas carpetas y espacios de trabajo para tus proyectos.

Espero que esta guía sobre cómo trabajar con carpetas y archivos compartidos entre organizaciones haya sido útil y que haya brindado algunas ideas sobre cómo trabajar con archivos y carpetas en una carpeta compartida.

Gracias por leer, y espero que esta publicación te haya ayudado a resolver un problema o te haya dado una idea para el próximo proyecto.

Enlace al Cuaderno de Google CoLab: gist

Aviso legal: El código utilizado en este ejemplo no está optimizado, sino que está escrito para ilustrar el proceso (se aceptan sugerencias sobre cómo mejorar el código en las páginas de GitHub que alojan este cuaderno).

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Ciencia de Datos

PatchTST Un avance en la predicción de series temporales.

Los modelos basados en Transformer han sido aplicados con éxito en muchos campos, como el procesamiento del lenguaje ...

Inteligencia Artificial

¡Atención Industria del Gaming! No más espejos extraños con Mirror-NeRF

Las NeRF o Campos de Radiancia Neurales utilizan una combinación de RNN y CNN para capturar las características físic...

Inteligencia Artificial

Las características de IA SaaS se encuentran con aplicaciones sin fosos

Varias empresas de SaaS han anunciado recientemente características de IA generativa, lo cual representa una amenaza ...

Inteligencia Artificial

AR y AI El papel de la IA en la Realidad Aumentada

Introducción Las industrias numéricas están siendo transformadas por las tecnologías revolucionarias de la inteligenc...

Noticias de Inteligencia Artificial

Fármaco diseñado por inteligencia artificial listo para ensayos en humanos.

Una empresa biotecnológica, Insilico Medicine, respaldada por el conglomerado chino Fosun Group y el gigante de capit...