1
votes

Obtention d'un jeton d'accès Google Cloud pour l'API Cloud SQL afin d'importer un CSV dans une fonction Cloud

Je recherche un exemple python 3 sur la façon dont j'obtiendrais un jeton d'accès afin que je puisse importer un fichier csv de GCS dans Cloud SQL à partir d'une fonction Google Cloud.

Il s'agit d'une fonction Cloud, donc l'attente est que le compte de service sous lequel il s'exécute ou le compte de service de l'instance Cloud SQL y aurait accès s'il y avait accès, mais ce n'est pas le cas.

response = requests.post(
            url="https://www.googleapis.com/sql/v1beta4/projects/redacted-project/instances/redacted-instance/import",
            headers={"Content-Type": "application/json; charset=utf-8"
            },
            data=json.dumps({
                "importContext": {
                    "fileType": "CSV",
                    "csvImportOptions": {
                        "table": "service_data"
                    },
                    "uri": "gs://redacted-bucket/log/" + blob.name + "",
                    "database": "redacted-db"
                }
            })
        )
        print('Response HTTP Status Code: {status_code}'.format(status_code=response.status_code))
        print('Response HTTP Response Body: {content}'.format(content=response.content))

Voici le code, je curieux de savoir si quelqu'un a un exemple de code sur la façon dont je peux le faire authentifier.

Response HTTP Response Body: {
 "error": {
 "code": 401,
 "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
 "errors": [
 {
 "message": "Login Required.",
 "domain": "global",
 "reason": "required",
 "location": "Authorization",
 "locationType": "header"
 }
 ],
 "status": "UNAUTHENTICATED"
 }
}


0 commentaires

3 Réponses :


1
votes

Vous devez utiliser le google-api-python-client code> pour construire un service pour cette API au lieu d'essayer de faire une demande directement. Cela lui permettra de récupérer le compte de service par défaut pour la fonction Cloud:

from googleapiclient.discovery import build
service = build('sql', 'v1beta4')
...

Plus de détails ici: https://github.com/googleapis/google-api-python-client/blob/master/docs/start.md a>


1 commentaires

Merci, ce lien m'a aidé à m'orienter dans la bonne direction. Le seul petit problème que j'essaie de comprendre est l'erreur. `` `` sqladmin.googleapis .com / sql / v1beta4 / projects / reddated-projec‌ t /… a renvoyé "Charge utile JSON non valide reçue. Nom inconnu" ": L'élément racine doit être un message."> `` `



0
votes

À partir de Google Cloud Functions, vous pouvez obtenir des jetons d'authentification par interrogation du serveur de métadonnées .

Il existe une option plus simple, cependant: utilisez Bibliothèque cliente Cloud SQL . Cela obtiendra automatiquement des jetons d'authentification pour vous.

Ces deux options s'authentifieront avec PROJECT_ID@appspot.gserviceaccount.com compte de service. Vous devrez peut-être accorder des autorisations à ce compte si vous effectuez des appels entre projets, etc.


0 commentaires

0
votes

1 À partir de vos fonctions Google Cloud, obtenez des jetons d'authentification en interrogeant le serveur de métadonnées en supposant que votre fonction cloud s'exécute sous le compte de service par défaut, qui est le compte de service par défaut App Engine et a le rôle Editor .

{'kind': 'sql#operation',
 'targetLink': 'https://sqladmin.googleapis.com/sql/v1beta4/projects/your-project/instances/instance',
 'status': 'PENDING',
 'user': 'youraccount,
 'insertTime': '2020-03-18T09:02:55.437Z',
 'operationType': 'IMPORT',
 'importContext': {'uri': 'gs://yourbucket/dumpfile',
  'database': 'yourdatabase',
  'kind': 'sql#importContext',
  'fileType': 'CSV',
  'csvImportOptions': {'table': 'sql-table}},
 'name': 'cdcd53d4-96fe-41cf-aee4-12cf6ec6394e',
 'targetId': 'instance_name',
 'selfLink': 'https://sqladmin.googleapis.com/sql/v1beta4/projects/project/operations/cdcd53d4-96fe-41cf-aee4-12cf6ec6394e',
 'targetProject': 'your-project'}

2.Utilisation des bibliothèques clientes google-api-python-client:

def import_table(request):

    from googleapiclient.discovery import build
    service = build('sqladmin', 'v1beta4')

    body = {'importContext': {'fileType': 'CSV',
        'csvImportOptions': {'table': 'your_table'},
        'uri': 'gs://temprun/your_dump_file',
        'database': 'your_database'}}

    service.instances().import_(project='your_project', instance='your_instance', body=body).execute()

    return "Table was imported"

En cas de succès, le Le corps de la réponse contient une instance d'Opération.

import requests
import json

METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/'
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
SERVICE_ACCOUNT = 'default'


def import_table(request):
    url = '{}instance/service-accounts/{}/token'.format(
        METADATA_URL, SERVICE_ACCOUNT)

    # Request an access token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    r.raise_for_status()

    # Extract the access token from the response.
    access_token = r.json()["access_token"]


    body = json.dumps({'importContext': {'fileType': 'CSV',
        'csvImportOptions': {'table': 'your_table'},
        'uri': 'gs://temprun/your_dump_file',
        'database': 'your_database'}})

    response = requests.post(
            url="https://www.googleapis.com/sql/v1beta4/projects/your_project/instances/your_sql_instance/import",
            headers={"Content-Type": "application/json; charset=utf-8",
                     "Authorization": "Bearer {}".format(access_token)
            },
            data=body)    

    return  str(response)




3 commentaires

L'utilisation des bibliothèques clientes a aidé, même si je reçois un message googleapiclient.errors.HttpError: sqladmin.googleapis.com/sql/v1beta4/projects/redoted-projec‌ t /… a renvoyé" Charge utile JSON non valide reçue. Nom inconnu "": L'élément racine doit être un message. ">


J'ai eu recours à l'option 1 ci-dessus et tout a fonctionné. Appréciez l'exemple.


ok, j'ai aussi corrigé l'option 2, il faut que body soit un dict, et l'option 1 nécessite que body soit une chaîne