Облачная функция GCP Python: чтение простого текстового файла из облачного хранилища

Облачная функция запускается после загрузки файла в хранилище My File Name: PubSubMessage. Внутри текста: Привет, это первое сообщение

from google.cloud import storage
storage_client = storage.Client()

def hello_gcs(event, context):
file = event

bucket = storage_client.get_bucket(file['bucket'])

blob = bucket.blob(file['name'])

contents = blob.download_as_string()
print('contents: {}'.format(contents))

decodedstring = contents.decode(encoding="utf-8", errors="ignore")
print('decodedstring: \n{}'.format(decodedstring))

print ('decodedstring: \ n {}'. format (decodedstring))

------WebKitFormBoundaryAWAKqDaYZB3fJBhx
Content-Disposition: form-data; name="file"; filename="PubSubMessage.txt"
Content-Type: text/plain

Hi, this this the first line.
Hi ,this is the second line. 

hi this is the space after.
------WebKitFormBoundaryAWAKqDaYZB3fJBhx--

Мой файл Requirements.txt

google-cloud-storage
requests==2.20.0
requests-toolbelt==0.9.1

Как мне получить фактическую строку внутри файла Привет, я первое сообщение .....?

Как лучше всего получить текст из файла? TIA


person Kamal Garg    schedule 24.06.2020    source источник
comment
Я вижу, вы отредактировали свое сообщение, чтобы включить в него дальнейшие действия, которые вы хотите сделать после прочтения строки внутри файла, но я думаю, что было бы лучше разделите их на один или несколько отдельных вопросов.   -  person Rafael Almeida    schedule 24.06.2020
comment
@RafaelAlmeida, я не пробовал эти две вещи, так как я застрял с получением текстовой части.   -  person Kamal Garg    schedule 24.06.2020
comment
@RafaelAlmeida Я пробовал этот код, но его не удалось. Я обновил свой вопрос кодом. пожалуйста помоги. не уверен, что он не работает   -  person Kamal Garg    schedule 24.06.2020
comment
На первый взгляд кажется, что проблема с отступом, вам не хватает трех пробелов перед print в последних двух строках. Если это не решит проблему, включите полученное сообщение об ошибке.   -  person Rafael Almeida    schedule 24.06.2020
comment
@RafaelAlmeida, если проблема с отступом, облачные функции выдают ошибку компиляции. Более серьезная проблема заключается в том, что в журналах нет правильной ошибки. просто говорится, что произошел сбой без другой информации, но я уверен, что это не проблема с отступом   -  person Kamal Garg    schedule 24.06.2020
comment
Тогда это немного сложнее отладить. Вы можете попробовать увеличить выделение памяти, если оно в настоящее время достаточно мало, чтобы добавление и использование дополнительной библиотеки вызывало нехватку памяти. В противном случае попробуйте выполнить отладку локально и / или отладить разделением пополам: попробуйте удалить (или закомментировать) большие части кода, пока вы найдете точную линию, вызвавшую аварию. Поскольку ваш код невелик, вы можете даже просто создать новую функцию и тестировать построчно с последовательными развертываниями.   -  person Rafael Almeida    schedule 24.06.2020
comment
@RafaelAlmeida печатает `` содержимое '', если я удалю код под ним, но он не работает после multipart_data   -  person Kamal Garg    schedule 24.06.2020
comment
Это может быть связано с кодировкой, поскольку кодировка по умолчанию в from_response - utf-8, и вы, похоже, передаете байтовую строку. Может быть, сначала попробуйте преобразовать его в строку UTF-8 с contents.decode('utf-8')? Я по-прежнему рекомендую вам попытаться увеличить объем памяти и отладить локально, чтобы вы могли, по крайней мере, получить лучшее сообщение об ошибке, которое вы можете добавить в вопрос.   -  person Rafael Almeida    schedule 24.06.2020
comment
@RafaelAlmeida Я пробовал, не работает. from_response требуется объект ответа для доступа к response.content, но наш - это просто строка. Ошибка говорит о том, что объект str не имеет содержимого атрибута. Вот ссылка, которую я ищу, но это AWS Lambda. они жестко кодируют его в какой-то части или получают что-то из объекта контекста aws lamba, который не является частью функций gcp: ------- stackoverflow.com/questions/50925083/   -  person Kamal Garg    schedule 25.06.2020
comment
Не могли бы вы рассказать нам больше о контексте? Функция запускается из загрузки в хранилище, хорошо, но есть ли у вас какой-либо контроль над самой загрузкой? Похоже, что тело составной формы было загружено без заголовков, вы должны сохранить оба, если можете. Если это не вариант, вы можете предположить, что структура остается той же, и первая строка всегда содержит границу, но затем она попадает дальше на территорию ручного парсера.   -  person Rafael Almeida    schedule 25.06.2020
comment
На самом деле у нас есть разные типы файлов из разных источников, и мы должны их обрабатывать и помещать в базу данных. Какое решение для этого лучше всего подходит? Какие дополнительные метаданные или информацию я передаю, чтобы упростить и упростить работу, а также как я могу их проанализировать? Я много пробовал, но у меня ничего не получилось. Пожалуйста, помогите   -  person Kamal Garg    schedule 25.06.2020


Ответы (2)


Строка, которую вы читаете из Google Storage, представляет собой строковое представление составного форма. Он содержит не только содержимое загруженного файла, но и некоторые метаданные. Один и тот же тип запроса может использоваться для представления более одного файла и / или полей формы вместе с файлом.

Чтобы получить доступ к желаемому содержимому файла, вы можете использовать поддерживающую его библиотеку, например requests-toolbelt. Посмотрите пример этого SO-ответа. Вам понадобится заголовок Content-Type, который включает границу, или для ручного анализа границы только из содержимого, если вам это абсолютно необходимо.

РЕДАКТИРОВАТЬ: из вашего ответа кажется, что заголовок Content-Type был доступен в метаданных хранилища в хранилище Google, что является распространенным сценарием. Для будущих читателей этого ответа особенности того, где читать этот заголовок, будет зависеть от вашего конкретного случая.

Поскольку эта библиотека присутствует в PyPI (индекс пакета Python), вы можете использовать ее даже в облачных функциях , указав его как зависимость в requirements.txt файле.

person Rafael Almeida    schedule 24.06.2020
comment
Я хочу достичь этого с помощью облачных функций, поэтому я не уверен, поддерживается ли этот набор инструментов и как я могу заставить его работать там. есть ли другой способ, с помощью которого я могу получить доступ к данным файла и обработать их в той же функции? - person Kamal Garg; 24.06.2020
comment
Вы можете использовать его в облачных функциях, я добавил редактирование в ответ со ссылкой, объясняющей процесс. - person Rafael Almeida; 24.06.2020
comment
Я пробовал, не работает. from_response требуется объект ответа для доступа к response.content, но наш - это просто строка. Ошибка говорит о том, что объект str не имеет содержимого атрибута. Вот ссылка, которую я ищу, но это AWS Lambda. они жестко кодируют его в какой-то части или получают что-то из объекта контекста aws lamba, который не является частью функций gcp: ------- stackoverflow.com/questions/50925083/ - person Kamal Garg; 25.06.2020

Код ниже распечатает фактический текст, присутствующий внутри файла.

from requests_toolbelt.multipart import decoder
from google.cloud import storage
storage_client = storage.Client()

def hello_gcs(event, context):
    file = event
    
    bucket = storage_client.bucket(file['bucket'])
    #print('Bucket Name :  {}'.format(file['bucket']))
    #print('Object Name :  {}'.format(file['name']))
    #print('Bucket Object :  {}'.format(bucket))
    
    blob = bucket.get_blob(file['name'])
    #print('Blob Object :  {}'.format(blob))
    
    contentType = blob.content_type
    print('Blob ContentType: {}'.format(contentType))

    #To download the file as byte object
    content = blob.download_as_string()
    print('content: {}'.format(content))

    for part in decoder.MultipartDecoder(content, contentType).parts:
         print(part.text)
person Kamal Garg    schedule 26.06.2020