Laden Sie Dateien mit Lambda (Python) auf Google Drive hoch.

Laden Sie Dateien mit Lambda (Python) auf Google Drive hoch.

Dieser Artikel ist ein praktischer Artikel zum Überprüfen und Korrigieren der durch die Entwicklung von Serverless Web App Mosaic gewonnenen Erkenntnisse. Es ist eines von w2or3w / items / 87b57dfdbcf218de91e2).

Es wäre schön, diesen Artikel zu lesen, nachdem man sich Folgendes angesehen hat.

Einführung

S3 ist gut, wenn Sie nur die Datei speichern, aber es ist nicht geeignet, dass Personen auf diese Datei verweisen. Selbst wenn es sich um ein Bild handelt, kann es nicht wie in einem Webbrowser angezeigt werden. Es muss einmal heruntergeladen und anschließend angezeigt werden. Es ist ein bisschen mühsam. In dieser Hinsicht ist Google Drive nett, da Sie Bilder mit einem Browser oder einer Anwendung gut durchsuchen können, egal ob es sich um einen PC oder ein Smartphone handelt.

Inhalt

Erstellen eines Google Developers Console-Projekts

Gehen Sie zur Entwicklerkonsole von Google. https://console.developers.google.com

Wenn Sie kein Projekt haben, erstellen Sie eines. Screenshot 2020-01-06 at 22.43.06.png

Aktivieren Sie die Google Drive-API

Klicken Sie oben im Bildschirm "APIs und Dienste" in der Konsole auf "+ APIs und Dienste aktivieren", um Google Drive zu aktivieren. Screenshot 2020-01-06 at 22.45.12.png Screenshot 2020-01-06 at 22.47.53.png Screenshot 2020-01-06 at 22.48.10.png

Anmeldeinformationen erstellen

Erstellen Sie nach dem Aktivieren der Google Drive-API die Anmeldeinformationen unter "Anmeldeinformationen" im linken Bereich des Bildschirms "APIs und Dienste" der Konsole. Wählen Sie "Dienstkonto" aus dem Dropdown-Menü, das angezeigt wird, wenn Sie oben auf der Seite "Anmeldeinformationen" auf "+ Anmeldeinformationen erstellen" klicken. Screenshot 2020-01-06 at 22.56.00.png

Bitte geben Sie den Namen des Dienstkontos ein, um ihn zu erstellen. Die Dienstkonto-ID unter dem Namen des Dienstkontos ist eine wichtige Information. Verwalten Sie sie daher so, dass sie nicht durchgesickert ist. ink (1).png

Bestätigung des Dienstkontos

Durchsuchen Sie nach dem Erstellen des Dienstkontos die Details des erstellten Dienstkontos unter "Dienstkonto" im linken Bereich des Bildschirms "IAM und Administration" der Konsole. ink (2).png

Erstellen eines privaten Schlüssels für ein Dienstkonto

Klicken Sie in den Dienstkontodetails auf die Schaltflächen "Bearbeiten" und "Erstellen + Schlüssel", um den privaten Schlüssel im JSON-Format zu erstellen und die JSON-Datei herunterzuladen. ink (4).png

Erstellen Sie einen Ordner in Google Drive und geben Sie ihn für Ihr Dienstkonto frei

Erstellen Sie einen Ordner zum Hochladen von Dateien auf Google Drive. Hier lautet der Ordnername "sample-drive". Geben Sie dann diesen Ordner für das zuvor erstellte Dienstkonto (E-Mail-Adresse) frei. Screenshot 2020-01-06 at 23.11.04.png ink (3).png

Die Zeichenfolge nach der URL dieses Ordners wird später im Programm verwendet. (Versteckter Teil der Aufnahme unten) ink (5).png

Damit sind die Einstellungen auf der Google-Seite abgeschlossen. Laden Sie als Nächstes die Datei programmgesteuert mit der Google-API hoch.

Fordern Sie die Google API von Lambda (Python) mit Dienstkonto an

Benennen Sie zunächst die JSON-Datei mit privatem Schlüssel des zuvor heruntergeladenen Dienstkontos in einen geeigneten Namen um und platzieren Sie sie am selben Speicherort wie lambda_function.py. Ich habe es hier "service-account-key.json" genannt.

Installieren Sie dann die erforderlichen Bibliotheken.

$ pip install google-api-python-client -t .
$ pip install oauth2client -t .

Importieren Sie dann das, was Sie benötigen.

lambda_function.py


  :
from googleapiclient.discovery import build 
from googleapiclient.http import MediaFileUpload 
from oauth2client.service_account import ServiceAccountCredentials 
  :

Laden Sie dann die Datei mit der folgenden Implementierung hoch.

lambda_function.py


  :
def uploadFileToGoogleDrive(fileName, localFilePath):
    try:
        ext = os.path.splitext(localFilePath.lower())[1][1:]
        if ext == "jpg":
            ext = "jpeg"
        mimeType = "image/" + ext

        service = getGoogleService()
        file_metadata = {"name": fileName, "mimeType": mimeType, "parents": ["*********************************"] } 
        media = MediaFileUpload(localFilePath, mimetype=mimeType, resumable=True) 
        file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

    except Exception as e:
        logger.exception(e)

def getGoogleService():
    scope = ['https://www.googleapis.com/auth/drive.file'] 
    keyFile = 'service-account-key.json'
    credentials = ServiceAccountCredentials.from_json_keyfile_name(keyFile, scopes=scope)
    
    return build("drive", "v3", credentials=credentials, cache_discovery=False) 

"Eltern": ["*************************************"] Dieser Teil ist ein Ordner, der in Google Drive erstellt wurde Ersetzen Sie es durch die Zeichenfolge nach der URL in.

Zum Schluss werde ich für alle Fälle das gesamte Programm veröffentlichen.

lambda_function.py


# coding: UTF-8
import boto3
import os
import json
from urllib.parse import unquote_plus
import numpy as np
import cv2
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.client("s3")
rekognition = boto3.client('rekognition')

from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
ENDPOINT = "https://**************************.appsync-api.ap-northeast-1.amazonaws.com/graphql"
API_KEY = "da2-**************************"
_headers = {
    "Content-Type": "application/graphql",
    "x-api-key": API_KEY,
}
_transport = RequestsHTTPTransport(
    headers = _headers,
    url = ENDPOINT,
    use_json = True,
)
_client = Client(
    transport = _transport,
    fetch_schema_from_transport = True,
)

from googleapiclient.discovery import build 
from googleapiclient.http import MediaFileUpload 
from oauth2client.service_account import ServiceAccountCredentials 

def lambda_handler(event, context):
    bucket = event["Records"][0]["s3"]["bucket"]["name"]
    key = unquote_plus(event["Records"][0]["s3"]["object"]["key"], encoding="utf-8")
    logger.info("Function Start (deploy from S3) : Bucket={0}, Key={1}" .format(bucket, key))

    fileName = os.path.basename(key)
    dirPath = os.path.dirname(key)
    dirName = os.path.basename(dirPath)
    
    orgFilePath = "/tmp/" + fileName
    
    if (not key.startswith("public") or key.startswith("public/processed/")):
        logger.info("don't process.")
        return
    
    apiCreateTable(dirName, key)

    keyOut = key.replace("public", "public/processed", 1)
    dirPathOut = os.path.dirname(keyOut)

    try:
        s3.download_file(Bucket=bucket, Key=key, Filename=orgFilePath)

        orgImage = cv2.imread(orgFilePath)
        grayImage = cv2.cvtColor(orgImage, cv2.COLOR_RGB2GRAY)
        processedFileName = "gray-" + fileName
        processedFilePath = "/tmp/" + processedFileName
        uploadImage(grayImage, processedFilePath, bucket, os.path.join(dirPathOut, processedFileName), dirName, False)

        uploadFileToGoogleDrive(key, orgFilePath)
        detectFaces(bucket, key, fileName, orgImage, dirName, dirPathOut)

    except Exception as e:
        logger.exception(e)
        raise e
        
    finally:
        if os.path.exists(orgFilePath):
            os.remove(orgFilePath)

def uploadImage(image, localFilePath, bucket, s3Key, group, isUploadGoogleDrive):
    logger.info("start uploadImage({0}, {1}, {2}, {3})".format(localFilePath, bucket, s3Key, group))
    try:
        cv2.imwrite(localFilePath, image)
        s3.upload_file(Filename=localFilePath, Bucket=bucket, Key=s3Key)
        apiCreateTable(group, s3Key)
        if isUploadGoogleDrive:
            uploadFileToGoogleDrive(s3Key, localFilePath)
    except Exception as e:
        logger.exception(e)
        raise e
    finally:
        if os.path.exists(localFilePath):
            os.remove(localFilePath)

def apiCreateTable(group, path):
    logger.info("start apiCreateTable({0}, {1})".format(group, path))
    try:
        query = gql("""
            mutation create {{
                createSampleAppsyncTable(input:{{
                group: \"{0}\"
                path: \"{1}\"
              }}){{
                group path
              }}
            }}
            """.format(group, path))
        _client.execute(query)
    except Exception as e:
        logger.exception(e)
        raise e

def detectFaces(bucket, key, fileName, image, group, dirPathOut):
    logger.info("start detectFaces ({0}, {1}, {2}, {3}, {4})".format(bucket, key, fileName, group, dirPathOut))
    try:
        response = rekognition.detect_faces(
            Image={
                "S3Object": {
                    "Bucket": bucket,
                    "Name": key,
                }
            },
            Attributes=[
                "ALL",
            ]
        )

        name, ext = os.path.splitext(fileName)
        
        jsonFileName = name + ".json"
        localPathJSON = "/tmp/" + jsonFileName
        with open(localPathJSON, 'w') as f:
            json.dump(response, f, ensure_ascii=False)
        s3.upload_file(Filename=localPathJSON, Bucket=bucket, Key=os.path.join(dirPathOut, jsonFileName))
        if os.path.exists(localPathJSON):
            os.remove(localPathJSON)
        
        imgHeight = image.shape[0]
        imgWidth = image.shape[1]
        index = 0
        for faceDetail in response["FaceDetails"]:
            index += 1
            faceFileName = "face_{0:03d}".format(index) + ext
            box = faceDetail["BoundingBox"]
            x = max(int(imgWidth * box["Left"]), 0)
            y = max(int(imgHeight * box["Top"]), 0)
            w = int(imgWidth * box["Width"])
            h = int(imgHeight * box["Height"])
            logger.info("BoundingBox({0},{1},{2},{3})".format(x, y, w, h))
            
            faceImage = image[y:min(y+h, imgHeight-1), x:min(x+w, imgWidth)]
            
            localFaceFilePath = os.path.join("/tmp/", faceFileName)
            uploadImage(faceImage, localFaceFilePath, bucket, os.path.join(dirPathOut, faceFileName), group, False)
            cv2.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 3)

        processedFileName = "faces-" + fileName
        processedFilePath = "/tmp/" + processedFileName
        uploadImage(image, processedFilePath, bucket, os.path.join(dirPathOut, processedFileName), group, True)
    except Exception as e:
        logger.exception(e)
        raise e


def uploadFileToGoogleDrive(fileName, localFilePath):
    try:
        ext = os.path.splitext(localFilePath.lower())[1][1:]
        if ext == "jpg":
            ext = "jpeg"
        mimeType = "image/" + ext

        service = getGoogleService()
        file_metadata = {"name": fileName, "mimeType": mimeType, "parents": ["*********************************"] } 
        media = MediaFileUpload(localFilePath, mimetype=mimeType, resumable=True) 
        file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

    except Exception as e:
        logger.exception(e)

def getGoogleService():
    scope = ['https://www.googleapis.com/auth/drive.file'] 
    keyFile = 'service-account-key.json'
    credentials = ServiceAccountCredentials.from_json_keyfile_name(keyFile, scopes=scope)
    
    return build("drive", "v3", credentials=credentials, cache_discovery=False) 

Funktionsprüfung

Wenn Sie ein Bild von einer Web-App hochladen, wird Lambdas Python ausgeführt, um das Bild zu verarbeiten. Anschließend laden Sie das Originalbild und das Bild mit dem auf der Vorderseite markierten ROI auf Google Drive hoch. Im Gegensatz zu S3 sehe ich es gerne als Bild. Screenshot 2020-01-08 at 22.51.30.png

Nachwort

Ich möchte auch den Cloud-Service von Google berühren. Ich mag Google. Dies ist eines der Ziele für 2020.

Übrigens gibt es viele Google-Produkte um mich herum, wie Pixel 3a, Chromebook, Google Home Mini, Chromecast und Google Wifi. Für den Dienst verwende ich täglich Google Fit mit Mi Band sowie Google Mail, Kalender, Laufwerk, Foto usw. und poste Google Map gerne in einem lokalen Leitfaden. Google One wurde ebenfalls auf 2 TB (13.000 Yen pro Jahr) aktualisiert.

OK Google, ich liebe dich!

Recommended Posts

Laden Sie Dateien mit Lambda (Python) auf Google Drive hoch.
Laden Sie Bilder mit Python auf Google Drive hoch
Greifen Sie mit Python auf Google Drive zu
So laden Sie Dateien in Google Drive mit Google Colaboratory
Hochladen auf ein freigegebenes Laufwerk mit Google Drive API V3
Laden Sie Google Drive-Dateien in Python herunter
Hochladen von Dateien in den Cloud-Speicher mit dem Python-SDK von Firebase
Laden Sie Dateien mit Django-Speicher in Google Cloud Storages hoch und löschen Sie sie
So suchen Sie in Google Colaboratory nach Google Drive
Stellen Sie mit AWS Lambda Python eine Verbindung zu s3 her
Hochladen mit Heroku, Flask, Python, Git (4)
Laden Sie Dateien mit Django hoch
Fahren Sie WebDriver mit Python
Beispiel für eine Slack-Benachrichtigung mit Python Lambda
Laden Sie Dateien direkt auf Google Drive herunter (mithilfe von Google Colaboratory).
Exportieren Sie den RDS-Snapshot mit Lambda (Python) nach S3.
Laden Sie das, was Sie angefordert haben, mit AWS Lambda Python in S3 hoch
Hochladen mit Heroku, Flask, Python, Git (Teil 3)
Einfache Möglichkeit, mit Google Colab mit Python zu kratzen
Schreiben Sie mit Lambda (Python, JavaScript) mehrere Datensätze in DynamoDB.
Hochladen mit Heroku, Flask, Python, Git (Teil 1)
Hochladen mit Heroku, Flask, Python, Git (Teil 2)
Stellen Sie mit Python eine Verbindung zu BigQuery her
Betreiben Sie TwitterBot mit Lambda, Python
Stellen Sie mit Python eine Verbindung zu Wikipedia her
Post to Slack mit Python 3
Lernen Sie Python mit Google Colaboratory
Sortieren von Bilddateien mit Python (2)
Sortieren Sie große Dateien mit Python
Sortieren von Bilddateien mit Python (3)
Bilddateien mit Python sortieren
Integrieren Sie PDF-Dateien in Python
TXT-Dateien mit Python lesen
Schalten Sie Python mit Alternativen auf 2.7 um
Schreiben Sie mit Python in csv
Hängen Sie Google Drive mit google-drive-ocamlfuse ein
Google Drive API-Tipps (Python)
Wie benutzt man Python Lambda?
So extrahieren Sie einen Termin in Google Kalender mit Python
[AWS] Versuchen Sie, die Python-Bibliothek mit SAM + Lambda (Python) zur Ebene hinzuzufügen.
Herausforderung Problem 5 mit Python: Lambda ... Ich habe mich entschieden, ohne zu kopieren
Senden Sie eine Nachricht an Google Hangouts Chat mit einem Thread (Python)
Speichern Sie Bilder im Web mit Python (Colab) auf einem Laufwerk.
[Python] Exportieren Sie regelmäßig mit Lambda aus CloudWatch-Protokollen nach S3
Betreiben Sie die eingeschränkte Freigabe von Google Kalender mit Lambda (Python) [Cloudpack Osaka]
Bis wir einen Mechanismus zum Hochladen von Dateien, die für Slack freigegeben wurden, ohne Server auf Google Drive erstellt haben
[Einführung in die Udemy Python3 + -Anwendung] 58. Lambda
Laden wir S3-Dateien mit CLI hoch
Python: So verwenden Sie Async mit
Link, um mit Python zu beginnen
[Python] Mit Python in eine CSV-Datei schreiben
Bearbeiten von EAGLE .brd-Dateien mit Python
Schön dich mit Python zu treffen
Versuchen Sie, Facebook mit Python zu betreiben
Gesichtserkennung mit Lambda (Python) + Erkennung
Ausgabe in eine CSV-Datei mit Python
[Lambda] [Python] Von Lambda auf Twitter posten!