Почему появляется ошибка «Процесс не может получить доступ к файлу»?

Делаю бота, в которого входит функция отправки файла на определенный гугл диск. В дальнейшем планируется загрузка на хостинг. Почему файл не закрывается и выдает ошибку? Подходит ли такая реализация для деплоя на хостинг?

import os
from aiogram import types
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import time


def getCreds():
    creds = None
    SCOPES = 'https://www.googleapis.com/auth/drive'

    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('client_secrets.json', SCOPES)
            creds = flow.run_local_server(port=8080)

        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return creds


@dp.message_handler(
    content_types=types.ContentTypes.DOCUMENT, state=DDU.attach)
async def handle_DDU(message: types.Message, state: FSMContext):
    if message.document:
        try:
            logger.debug('Загрузка файла в google drive')
            file = await bot.get_file(message.document.file_id)
            filename = message.document.file_name

            await file.download(filename)

            creds = getCreds()
            service = build('drive', 'v3', credentials=creds, cache_discovery=False)
            async with state.proxy() as data:
                metadata = {'name': f'ДДУ_{data.get("client_name")}'}

            with open(filename, 'rb') as file:
                media = MediaFileUpload(
                    filename, chunksize=1024 * 1024,
                    mimetype=message.document.mime_type, resumable=True)
                request = service.files().create(
                    body=metadata, media_body=media)
                file.close()

            time.sleep(3)
            os.remove(filename)  # Удаление файла после загрузки

        except Exception as e:
            logger.info(f"Произошла ошибка: {e}")
            await message.reply(f"Произошла ошибка: {e}")
        
        finally:
            await message.answer("Успешно!")

    else:
        await message.answer("Пожалуйста, отправьте документ")
  • Вопрос задан
  • 121 просмотр
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
with open(filename, 'rb') as file:
    media = MediaFileUpload(
        filename, chunksize=1024 * 1024,
        mimetype=message.document.mime_type, resumable=True)
    request = service.files().create(
        body=metadata, media_body=media)
    file.close()

Обрати внимание, что MediaFileUpload не использует объект file.
Поэтому абсолютно не принципиально, как и когда ты закрываешь файловый объект самостоятельно.
Либо поищи способ отправить файл, используя уже заданный объект, либо читай как корректно закрыть MediaFileUpload. Можешь попробовать media.stream.close(), но я фз можно ли это делать, и если да то когда.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы