Как загрузить HTTP API в корзину AWS S3 в формате JSON с помощью Python?

#python #json #amazon-s3 #python-requests #boto3

Вопрос:

Я могу загрузить свой HTTP API в корзину S3, но без какого-либо назначенного ему формата файла. Как я могу загрузить его в виде файла JSON?

 import json
import requests
import boto3

s3 = boto3.client('s3', aws_access_key_id='***', aws_secret_access_key='***')

covid_text = requests.get('https://disease.sh/v3/covid-19/continents')

data = covid_text.json()

s3.put_object(Body=json.dumps(data), Bucket='my_bucket', Key='httpsGETdisease.sh/v3/covid-19/continents')
 

Ответ №1:

Вот фрагмент кода, который я использую внутренне для загрузки файлов (обычно JSON) в S3. Это self.client кэшированное свойство, которое эквивалентно boto3.client('s3') вашему коду выше; только я кэшировал его для возможности повторного использования, так как это немного быстрее при выполнении нескольких запросов к одному и тому же ведру, например, для чтения загруженного файла, а затем повторной загрузки.

     def upload(self, file_name, bucket, key=None, content_type='application/json'):
        """upload a file (usually a JSON file) to S3"""
        self.client.upload_file(
            file_name, bucket, key or file_name, {'ContentType': content_type})
 

Аналогичный фрагмент кода, когда я загружаю файл из S3 (обычно файл JSON). Здесь мы просто проверяем тип содержимого объекта, и если это JSON, то мы загружаем его и возвращаем данные в виде Python list или dict типа. В противном случае мы просто возвращаем данные объекта в виде открытого текста.

         content_type = res.get('ContentType', 'application/json')

        data = res['Body'].read().decode(encoding)
        if content_type.endswith('json'):
            return json.loads(data)

        return data
 

Комментарии:

1. Спасибо! Проблема в том, что у меня нет файла. У меня есть только URL API, который я предоставил.

2. Ах, я, возможно, пропустил это. Я думаю, вы могли бы продолжать использовать put_object то, что вы делали, и, возможно, возникнет content_type спор (я бы сослался на документы boto3 на S3 для уточнения).

3. Ссылаясь на документы по put_object запросу ниже, и я вижу Body=b'bytes'|file , что он ожидает, что тело будет состоять из байтов. Вы могли бы попробовать covid_text.content получить содержимое байтов, а затем передать его в качестве Body параметра? может быть, это сработало бы. boto3.amazonaws.com/v1/documentation/api/latest/reference/…

4. Кроме того, я вижу ContentType аргумент, поэтому, вероятно, это то, что вы хотите использовать, чтобы пометить файл как содержащий содержимое JSON. Поскольку это ответ API, вы можете использовать тот же заголовок из самого объекта ответа covid_text .

5. Мой код работает таким образом: import json import requests import boto3 s3 = boto3.client('s3', aws_access_key_id='***', aws_secret_access_key='***') covid_text = requests.get('https://disease.sh/v3/covid-19/continents') data = covid_text.json() s3.put_object(Body=json.dumps(data), Bucket='my_bucket', Key='httpsGETdisease.sh/v3/covid-19/continents', ContentType='application/json')