[PYTHON] L'histoire de la copie de données de S3 vers TeamDrive de Google

Contexte

Je ne pense pas qu'il y ait beaucoup de besoin, mais j'ai facilité le partage de fichiers tout en enregistrant les fichiers dans S3 sur le stockage d'un autre Vender. Ce n'était pas difficile si j'utilisais GoogleDriveApi pour suivre la documentation, mais il y avait des moments où la taille du fichier était importante. Je pense qu'il y a encore une implémentation similaire, je la laisserai comme note de service au cas où.

Que veux-tu faire

Transférez automatiquement les données S3 vers Google Drive.

Ce que j'ai fait

Migrer le contenu du compartiment S3 avec Python vers le lecteur d'équipe spécifié.

Détails d'implémentation

  1. Téléchargez le fichier de S3 vers tmp.
  2. Vérifiez si le fichier existe déjà dans Gdrive
  3. Écraser s'il existe
  4. S'il n'existe pas, ajoutez-le comme nouveau

Préparation préalable

C'est la source que j'ai réellement implémentée.

# Download File from S3 to Local tmp Dir
# Upload a file to Google Drive

import os
import boto3
import json
import requests
import magic



## setting info
CONTENT_BUCKET_NAME = 'MY_S3_BUCKET_NAME'
CONTENT_BACKUP_KEY = 'MY_S3_BUCKET_KEY'
GOOGLE_CLIENT_ID = "XXXXXXXXXXXX.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET = "XXXXXXXXXXXX"
GOOGLE_REFRESH_TOKEN = "XXXXXXXXXXXX"
GOOGLE_FOLDER_ID = 'GOOGLE_FOLDER_ID'


s3 = boto3.resource('s3')
 
# Get the object from the event and show its content type
bucket = CONTENT_BUCKET_NAME
key = CONTENT_BACKUP_KEY
file_name = key.split("/")[1]
file_path = os.path.join("/tmp/"+ file_name)
s3.Object(bucket, key).download_file(file_path)
filesize = os.path.getsize(file_path)
fname, extension = os.path.splitext(file_name)

# refresh token
access_token_url = 'https://accounts.google.com/o/oauth2/token'
headers = {"Content-Type":"application/json","X-Accept":"application/json"}
refresh_token_request = {"grant_type":"refresh_token", "client_id": GOOGLE_CLIENT_ID, "client_secret": GOOGLE_CLIENT_SECRET, "refresh_token": GOOGLE_REFRESH_TOKEN}
access_token_request = requests.post(access_token_url,headers=headers,data=json.dumps(refresh_token_request))
access_token = access_token_request.json()['access_token']
print(access_token)

# check file already exist 
downloadUrl = "https://www.googleapis.com/drive/v3/files"
headers = {
    'Host':'www.googleapis.com',
    'Authorization': 'Bearer ' + access_token,
    'Content-Type':'application/json; charset=UTF-8',
    "X-Accept":"application/json"
}
qs= { "q": "'" + GOOGLE_FOLDER_ID + "' in parents and name='" + file_name + "' and trashed=false",
      "supportsAllDrives": True,
      "includeItemsFromAllDrives": True
    }

fileExistCheck = requests.get(downloadUrl, params=qs, headers=headers)
responseJsonFiles = fileExistCheck.json()['files']
searchResponseLength = len(responseJsonFiles)

#upload_file()
mime = magic.Magic(mime=True)
mimeType = mime.from_file(file_path) 

#folder_id = GOOGLE_FOLDER_ID
headers = {
    'Host':'www.googleapis.com',
    'Content-Length': str(filesize),
    'Authorization': 'Bearer ' + access_token,
    'Content-Type':'application/json; charset=UTF-8',
    'X-Upload-Content-Type': mimeType,
    'X-Upload-Content-Length': str(filesize)
}

with open(file_path, 'rb') as data:
  file_name= os.path.basename(file_path)
  metadata = {
    "name": file_name,
    "title": file_name,
    "parents": [GOOGLE_FOLDER_ID],
    'kind': 'drive#permission',
    "permissionDetails": [
      {
        "permissionType": "file",
        "role": "organizer"
      }
    ],
  }
 
 # No file exist. Post new one.
  if searchResponseLength < 1:
    postUrl = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true"
    r = requests.post(postUrl, data=json.dumps(metadata), headers=headers)
    # data upload url
    uploadUrl = r.headers['Location']

    r2 = requests.post(uploadUrl, data=data, headers=headers)
  
  # file exist. Put to override
  else:
    fileId = responseJsonFiles[0]['id']
    metadata = {
      "filename": file_name,
      "name": file_name,
      "title": file_name,
      'kind': 'drive#permission',
      "permissionDetails": [
        {
          "permissionType": "file",
          "role": "organizer"
        }
      ]
    }
    
    putUrl = "https://www.googleapis.com/upload/drive/v3/files/" + fileId + "?uploadType=resumable&supportsAllDrives=true"
    r = requests.patch(putUrl, data=json.dumps(metadata), headers=headers)
    uploadUrl = r.headers['Location']
    r2 = requests.patch(uploadUrl, data=data, headers=headers)

À la fin

Je pense qu'il y a d'autres améliorations, mais s'il existe un moyen plus simple de le mettre en œuvre, veuillez commenter.

Recommended Posts

L'histoire de la copie de données de S3 vers TeamDrive de Google
Histoire de passer de Pipenv à la poésie
Après tout, l'histoire du retour de Linux à Windows
L'histoire d'essayer de reconnecter le client
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
L'histoire du changement de pep8 en pycodestyle
Modifiez le point décimal de la journalisation de, à.
L'histoire de la lecture des données HSPICE en Python
De l'introduction de pyethapp à l'exécution du contrat
Transition du baseball vue à partir des données
L'histoire du passage du système Web Azure App Service de Windows à Linux
Extraction de données depuis S3
L'histoire de sys.path.append ()
Le mur lors du passage du service Django de Python 2.7 à la série Python 3
Envoyer les données du journal du serveur vers Splunk Cloud
DataNitro, implémentation de la fonction de lecture des données de feuille
L'histoire de vouloir acheter une aventure en forme de bague
L'histoire de l'utilisation de Circleci pour construire des roues Manylinux
L'histoire du passage de WoSign à Let's Encrypt pour un certificat SSL gratuit
L'histoire du portage du code de C vers Go (et vers la spécification du langage)
L'histoire de la construction de Zabbix 4.4
SIGNATURE Quête ② De la création du modèle de ciblage à la création des données soumises
[Introduction au graphique logarithmique] Prédire l'heure de fin de chaque pays à partir du graphique logarithmique des données sur le nombre d'infections ♬
L'histoire du champ de modèle Django disparaissant de la classe
Comment calculer la quantité de calcul appris de ABC134-D
L'histoire du rubyiste aux prises avec Python :: Dict data with pycall
[Introduction à matplotlib] Lire l'heure de fin à partir des données COVID-19 ♬
Comment représenter la distribution de la composition bactérienne à partir des données d'analyse Qiime2 dans un diagramme de moustaches
Transmettez les données OpenCV de la bibliothèque C ++ d'origine à Python
J'ai envoyé les données de Raspberry Pi à GCP (gratuit)
Essayez d'extraire les caractéristiques des données de capteur avec CNN
Apprenez les données comptables et essayez de prédire les comptes à partir du contenu de la description lors de la saisie des journaux
Porté du langage R de "Sazae-san's Janken Data Analysis" vers Python
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
L'histoire de ne pas pouvoir exécuter pygame avec pycharm
Enregistrez le résultat de l'exploration avec Scrapy dans Google Data Store
Lire tout le contenu de proc / [pid] ~ De setgroups à wchan ~
Etudier le web scraping dans le but d'extraire des données de Filmarks # 2
Comment éviter la duplication des données lors de la saisie de Python vers SQLite.
Lire tout le contenu de proc / [pid] ~ De cwd à loginuid ~
Lire tout le contenu de proc / [pid] ~ De map_files à numa_maps ~
[Pythonista] L'histoire de la réalisation d'une action pour copier le texte sélectionné
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
Lire tout le contenu de proc / [pid] ~ De attr à cpuset ~
L'histoire de l'échec de la mise à jour de "calendar.day_abbr" sur l'écran d'administration de django
De l'installation d'Elasticsearch à la saisie des données
L'histoire de Python et l'histoire de NaN
Existence du point de vue de Python
L'histoire du "trou" dans le fichier
L'histoire du remontage du serveur d'application
Supplément à l'explication de vscode
L'histoire de l'exportation d'un programme
Une histoire sur la création d'un programme qui augmentera le nombre d'abonnés Instagram de 0 à 700 en une semaine
Mettez à jour les données en les téléchargeant sur s3 d'aws avec une commande, et supprimez les données utilisées (en chemin)
De l'introduction de l'API GoogleCloudPlatform Natural Language à son utilisation
À propos de l'ordre d'apprentissage des langages de programmation (de débutant à intermédiaire) Partie 2
Comparaison de R, Python, SAS, SPSS du point de vue des data scientists européens