МОЙ ВОПРОС: Как запустить скрипт python для генерации / обновления файла JSON в корзине S3? Кроме того, должен ли я запускать этот скрипт каждый раз, когда файл добавляется в мое ведро, или когда кто-то посещает мою веб-страницу?
Читайте описание ...
У меня есть веб-сайт, размещенный на AWS, мои страницы c находятся в общедоступной корзине c S3. Цель - поделиться музыкой c, которую я написал, со студентами музыки c. У меня есть скрипт Python, который сканирует все объекты (листовые файлы c PDF) в папке в том же контейнере S3. Затем сценарий Python создает файл JSON, который содержит имена всех объектов s3 вместе с сгенерированными URL для каждого объекта.
Вот как отформатирован этот файл JSON :
{
"bass": [{
"bass-song1": "http://www.website.com/bass-song1.pdf"
}, {
"bass-song2": "http://www.website.com/bass-song2.pdf"
}],
"drum": [{
"drum-song1": "http://www.website.com/drum-song1.pdf"
}, {
"drum-song2": "http://www.website.com/drum-song2.pdf"
}],
"guitar": [{
"guitar-song1": "http://www.website.com/guitar-song1.pdf"
}, {
"guitar-song2": "http://www.website.com/guitar-song2.pdf"
}]
}
Мой рабочий Python скрипт, для справки:
import boto3
import json
import pprint
# This program creates a json file
# with temporary URLs for bucket objects, organized by folder
# For use with javascript that generates links to bucket objects for website
# create a session to retrieve credentials from ~/.aws/credentials
session = boto3.Session(profile_name='<MY PROFILE>')
# use your credentials to create a low-level client with the s3 service
s3 = session.client('s3')
# Store dictionary of objects from bucket that starts with the prefix '__'
response = s3.list_objects_v2(Bucket='<MY BUCKET>', Prefix='<FOLDER IN BUCKET>')
folder_list = []
url_json = {}
# (the value of 'Contents' is a list of dictionaries)
# For all the dictionaries in the 'Contents' list,
# IF they don't end with '/' (meaning, if its not a directory)...
for i in response['Contents']:
if i['Key'].endswith('/') != True:
# get the directory of the current Key, save as string in 'dir'
full_path = i['Key']
# this retrieves the folder after '__'
dir = full_path.split("/")[1]
# capitalize the directory name, update variable
dir = dir.capitalize()
# this retrieves the file name
filename = full_path.split("/")[2]
# if the name of the directory ('dir') is not in folder_list:
# add it to folder_list,
# and add an item to dictionary 'url_json' where key is current 'dir' and value is empty list
if dir not in folder_list:
folder_list.append(dir)
url_json[folder_list[-1]] = []
# generate a temporary URL for the current bucket object
url = s3.generate_presigned_url('get_object', Params={'Bucket':'<MY BUCKET>', 'Key':i['Key']}, ExpiresIn=3600)
# create a dictionary for each bucket object
# store the object's name (Key) and URL (value)
object_dict = {filename:url}
# Append the newly created URL to a list in the 'url_json' dictionary,
# whose key is the last directory in 'folder_list'
url_json[folder_list[-1]].append(object_dict)
# Dump content of 'url_json' directory to 'urls.json' file
# if it already exists, overwrite it
with open('url_list.json', mode='w') as outfile:
json.dump(url_json, outfile)
Кроме того, в теле моей веб-страницы я написал несколько встроенных JavaScript, которые загружают / читают файл JSON и использует URL-адреса и связанный с ними текст для создания ссылок для доступа пользователей к этим файлам на моей веб-странице.
Моя рабочая JavaScript, для справки:
<script type="text/javascript">
async function getData(url) {
const response = await fetch(url);
return response.json()
}
async function main() {
const data = await getData('<JSON FILE URL>');
// 'instrument' example: 'Bass'
for (var instrument in data) {
var h = document.createElement("H3"); // Create the H1 element
var t = document.createTextNode(instrument); // Create a text element
h.appendChild(t); // Append the text node to the H1 element
document.body.appendChild(h); // Append the H1 element to the document body
// store the list of bass songs
var song_list = data[instrument]
// for each song (list element),
for (var song_object of song_list) {
// for every song name in the object (in python, dictionary)
for (var song_name in song_object) {
// create a var with the name and URL of the PDF song file
var link_str = song_name;
var link_url = song_object[song_name];
// Create link to appear on website
const a = document.createElement("a");
var lineBreak = document.createElement("br");
a.href = link_url;
a.innerText = link_str;
a.style.backgroundColor="rgba(255, 255, 255, 0.7)"
document.body.appendChild(a);
document.body.append(lineBreak);
}
}
}
}
main();
</script>
Итак, моя конечная цель заключается в следующем: Я загружаю файл PDF в свое хранилище S3, мой скрипт Python выполняется для обновления файла JSON в моем хранилище S3, и когда кто-то посещает мою веб-страницу, JavaScript проанализирует файл JSON, чтобы создать ссылки на эти файлы PDF. Должен ли я сценарий python создать JSON при загрузке файлов в корзину или при посещении веб-сайта? Проблема заключается в том, что URL этих объектов имеют время истечения ... но я также не хочу запускать код каждый раз, когда кто-то загружает страницу (по соображениям $$).
Любая помощь будет принята с благодарностью. Дайте мне знать, если вам нужна дополнительная информация от меня. Спасибо, Себастьян.