[Python] How to Modify Files Selected with Google Picker While Using drive.file Scope in...

Discussão em 'Python' iniciado por Stack, Fevereiro 4, 2025.

  1. Stack

    Stack Membro Participativo

    I’m working on a Python Flask project with Google Picker and Drive APIs, aiming to allow users to select files from their Google Drive and modify them. For security and user control reasons, I’m using the drive.file scope instead of the broader drive scope.

    What Works:


    1. Google Picker:

      • Successfully implemented the Google Picker to let users select files.


      • Picker correctly retrieves the file name and file ID.

    2. Server-Side Code:

      • When a file is selected, the file ID is sent to the Flask backend.


      • Attempt to fetch the file using the Drive API.
    The Problem:


    When trying to fetch the file content using the file ID in my backend, I get the following error

    perl Copy Edit <HttpError 404 when requesting ``https://www.googleapis.com/drive/v3/files/1olvHA_c0bzHhMg2vYli-me8I5wvdYHRV5Hl7lgyDAko?fields=id%2C+name%2C+mimeType%2C+size&supportsAllDrives=true&alt=json`` returned "File not found: 1olvHA_c0bzHhMg2vYli-me8I5wvdYHRV5Hl7lgyDAko.". Details: "[{'message': 'File not found: 1olvHA_c0bzHhMg2vYli-me8I5wvdYHRV5Hl7lgyDAko.', 'domain': 'global', 'reason': 'notFound', 'location': 'fileId', 'locationType': 'parameter'}]"> It seems like I don’t have permission to access the file, even though I’m using the drive.file scope and explicitly selecting the file through the Picker.

    Code Overview:


    HTML + JavaScript for Picker:

    <script type="text/javascript">
    function onApiLoad() {
    gapi.load('picker', { 'callback': onPickerApiLoad });
    }

    function onPickerApiLoad() {
    const oauthToken = '<YOUR_OAUTH_TOKEN>'; // Retrieved from backend securely
    const picker = new google.picker.PickerBuilder()
    .addView(google.picker.ViewId.DOCS)
    .setOAuthToken(oauthToken)
    .setDeveloperKey('<YOUR_API_KEY>')
    .setCallback(pickerCallback)
    .build();
    picker.setVisible(true);
    }

    function pickerCallback(data) {
    if (data.action === google.picker.Action.PICKED) {
    const file = data.docs[0];
    console.log('File ID:', file.id);

    // Send the file ID to the backend for further processing
    fetch('/process_file', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ fileId: file.id }),
    })
    .then(response => response.json())
    .then(data => console.log('Backend response:', data))
    .catch(error => console.error('Error:', error));
    }
    }
    </script>


    Flask Backend Code:

    from flask import Flask, request, jsonify
    from googleapiclient.discovery import build
    from google.oauth2.credentials import Credentials
    import io

    app = Flask(__name__)

    SCOPES = ['https://www.googleapis.com/auth/drive.file'] # Limited scope

    @app.route('/process_file', methods=['POST'])
    def process_file():
    data = request.json
    file_id = data.get('fileId')

    credentials = Credentials.from_authorized_user_file('credentials.json', SCOPES)
    service = build('drive', 'v3', credentials=credentials)

    try:
    # Attempting to fetch file metadata
    file_metadata = service.files().get(fileId=file_id, fields='id, name, mimeType').execute()
    print(f"File metadata: {file_metadata}")

    # Example: Modify the file's content
    request = service.files().get_media(fileId=file_id)
    file_content = request.execute()

    new_content = file_content.decode('utf-8') + '\nAppended Text.'
    media = MediaIoBaseUpload(io.BytesIO(new_content.encode()), mimetype='text/plain')

    updated_file = service.files().update(fileId=file_id, media_body=media).execute()
    return jsonify({'status': 'success', 'updatedFile': updated_file})

    except Exception as e:
    return jsonify({'status': 'error', 'message': str(e)}), 500

    My Questions:


    1. How can I ensure that the file selected with Google Picker is accessible using the drive.file scope?


    2. Is there an additional step required to link the Picker selection with the Drive API access token?


    3. Could this issue be related to how the Picker generates the file ID or how permissions are handled for the selected file?

    Any insights or suggestions on how to modify files selected with Google Picker while using drive.file scope would be greatly appreciated.

    I've tried already to find an answer but I only found one of 2011 and it doesn't give any details on how to do it.

    What I’ve Tried:

    Confirmed that the file ID is being passed correctly from the Picker to the backend.

    Verified that the OAuth token and API key work for other Drive API operations (e.g., creating files).

    Read the documentation for the Picker API and Drive API to confirm that the drive.file scope should allow access to files explicitly selected by the user.

    Continue reading...

Compartilhe esta Página