#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')