3
votes

Google Drive API v3 Modifier les autorisations de fichier et obtenir un lien partageable publiquement (Python)

J'essaie d'utiliser l'API Google Drive v3 avec Python 3 pour télécharger automatiquement des fichiers, les rendre `` publics '' et obtenir un lien partageable que n'importe qui, connecté ou non à un compte Google, peut voir et télécharger (mais pas modifier).

Je suis proche, mais je n'arrive pas à comprendre! Observez mon code. Il nécessite qu'un fichier texte nommé "testing.txt" se trouve dans le même répertoire que le script:

1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH
01486072639937946874
An error occurred: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH/permissions/01486072639937946874?alt=json returned "The resource body includes fields which are not directly writable.">
https://drive.google.com/file/d/1quyzYHc0uCQIEt88gqd4h_jWtlBaoHHH/view?usp=drivesdk

Lorsque j'exécute ce code, je reçois ce qui suit: p >

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

from apiclient.http import MediaFileUpload
from apiclient import errors

# https://developers.google.com/drive/api/v2/about-auth#requesting_full_drive_scope_during_app_development
SCOPES = 'https://www.googleapis.com/auth/drive' # https://stackoverflow.com/a/32309750

# https://developers.google.com/drive/api/v2/reference/permissions/update
def update_permission(service, file_id, permission_id, new_role, type):
  """Update a permission's role.

  Args:
    service: Drive API service instance.
    file_id: ID of the file to update permission for.
    permission_id: ID of the permission to update.
    new_role: The value 'owner', 'writer' or 'reader'.

  Returns:
    The updated permission if successful, None otherwise.
  """
  try:
    # First retrieve the permission from the API.
    permission = service.permissions().get(fileId=file_id, permissionId=permission_id).execute()
    permission['role'] = new_role
    permission['type'] = type
    return service.permissions().update(fileId=file_id, permissionId=permission_id, body=permission).execute()
  except errors.HttpError as error:
    print('An error occurred:', error)
  return None

if __name__ == '__main__':
    # credential things
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    drive_service = build('drive', 'v3', http=creds.authorize(Http()))

    # create and upload file
    file_metadata = {'name': 'testing.txt'}
    media = MediaFileUpload('testing.txt',
                            mimetype='text/txt')
    file = drive_service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id, webViewLink, permissions').execute()

    # get information needed to update permissions
    file_id = file['id']
    permission_id = file['permissions'][0]['id']

    print(file_id)
    print(permission_id)

    # update permissions?  It doesn't work!
    update_permission(drive_service, file_id, permission_id, 'reader', 'anyone') # https://stackoverflow.com/a/11669565

    print(file.get('webViewLink'))

Lorsque je copie et colle le lien final dans un autre navigateur, il n'est pas disponible, donc clairement il n'a pas réussi à changer les permissions du fichier. Mais je ne comprends pas pourquoi cela a échoué. Il mentionne que Le corps de la ressource comprend des champs qui ne sont pas directement inscriptibles , mais je ne sais pas ce que cela signifie.

Quelqu'un peut-il m'aider à comprendre ce que je fais mal et que dois-je changer pour y remédier? Merci.


2 commentaires

Ma réponse vous a-t-elle montré le résultat souhaité? Pouvez-vous m'en parler? Cela m'est également utile d'étudier. Si cela fonctionne, d'autres personnes qui ont le même problème avec vous peuvent également baser votre question comme une question qui peut être résolue. Si vous avez encore des problèmes pour ma réponse, je vous présente mes excuses. À ce moment-là, puis-je vous interroger sur votre situation actuelle? Je voudrais étudier pour résoudre vos problèmes.


Y a-t-il quelque chose que je puisse faire pour votre question? Si ma réponse n'était pas utile pour votre situation. Je dois m'excuser et le modifier. Si vous pouvez coopérer pour résoudre votre problème, je suis heureux. Je voudrais réfléchir à la solution.


3 Réponses :


1
votes

Et cette modification? Je pense que vous avez déjà pu télécharger le fichier. Je voudrais donc proposer la modification de la fonction de update_permission () .

Point de modification:

  • Je pense que dans votre situation, il est nécessaire d'ajouter l'autorisation en créant.
    • Vous pouvez donc utiliser service.permissions (). create () .
    • Lorsque vous souhaitez mettre à jour l'autorisation créée, veuillez utiliser l'identifiant récupéré lors de la création de l'autorisation.

Script modifié:

Veuillez modifier update_permission () comme suit.

De:

try:
  permission = {
      "role": new_role,
      "type": types,
  }
  return service.permissions().create(fileId=file_id, body=permission).execute()
except errors.HttpError as error:
  print('An error occurred:', error)
return None

À:

try:
  # First retrieve the permission from the API.
  permission = service.permissions().get(fileId=file_id, permissionId=permission_id).execute()
  permission['role'] = new_role
  permission['type'] = type
  return service.permissions().update(fileId=file_id, permissionId=permission_id, body=permission).execute()
except errors.HttpError as error:
  print('An error occurred:', error)
return None

Remarque :

  • Ce script modifié suppose que votre environnement peut utiliser l'API Drive.

Référence :

Si je comprends mal votre question, je suis désolé.


4 commentaires

Existe-t-il un moyen d'obtenir un lien pour un document lisible (document Word) sans permettre à l'utilisateur de le télécharger?


@Tejas Gaykar Merci pour votre commentaire. Malheureusement, je ne peux pas comprendre votre objectif à partir de votre commentaire. Cela est dû à ma mauvaise maîtrise de l'anglais. Je m'excuse profondément pour cela. Alors, pouvez-vous la poster comme nouvelle question en incluant les informations détaillées? Cela aidera les utilisateurs à réfléchir au problème et à la solution. Si vous pouvez coopérer pour résoudre votre problème, je suis heureux.


Où et comment permissionId entre en service.permissions (). Get ()


@Tanaike Savez-vous pourquoi je ne peux pas définir d'autorisations pour un fichier téléchargé? stackoverflow .com / questions / 62699404 /…



0
votes

Typo: Veuillez noter que dans le code initial, il est dit "type" dans l'en-tête de la fonction de update_permission mais ensuite dans l'extrait corrigé, la réponse utilise "types".


0 commentaires

1
votes

La réponse sélectionnée n'était pas suffisamment précise (rien sur la valeur de type et le rôle) donc j'ai dû lire un peu plus la documentation, voici un exemple de travail, il vous suffit de donner le file_id:

def set_permission(service, file_id):
    print(file_id)
    try:
        permission = {'type': 'anyone',
                      'value': 'anyone',
                      'role': 'reader'}
        return service.permissions().create(fileId=file_id,body=permission).execute()
    except errors.HttpError as error:
        return print('Error while setting permission:', error)


0 commentaires