Створення API для отримання даних з погодного додатку та збереження їх у S3

python
print(“З Новим Роком!”)

Привіт усім!

Ласкаво просимо назад до ще одного челенджу з хмарних технологій / DevOps! Я ТАК радий почати цей 30-денний хмарний челендж від LinkedIn, щоб ще більше розширити свою базу знань та портфоліо.

Цей проект буде розділений на кілька частин, кожна з яких буде будуватися на попередній.

Мета: Сьогодні я створюю трекер погоди, який зберігає свої дані в S3. Для відстеження погоди я буду використовувати сайт під назвою “Openweathermap.org”.

У мене вже є обліковий запис AWS і налаштоване середовище у VsCode.

Почнемо!

Отже, перше, що я зроблю — створю файли та директорії, щоб усе було належно організовано та підписано.

Директорія, в якій я працюватиму, називатиметься GetYouAJob, а всередині цієї директорії я створю ще одну під назвою weather-dashboard-demo. Всередині цієї директорії я зроблю ще одну підкатегорію під назвою src для мого вихідного коду, tests для даних, які я тестуватиму в майбутніх частинах цього проекту, і data для даних, які будуть використовуватись як локальне сховище для тестування під час розробки.

Я також створю файл __init__.py, який зробить директорію src пакетом Python, що дозволить мені імпортувати різні файли та модулі з цієї директорії.

Файли, які я створю, це weather_dashboard.py, щоб зберігати фактичний код, та requirements.txt, щоб зберігати мої залежності. Також я створю файл .env, щоб зберігати змінні середовища для кращої безпеки моїх облікових даних.

Команди:

mkdir weather-dashboard-demo

cd weather-dashboard-demo

mkdir src tests data

touch src/__init__.py src/weather_dashboard.py

pic

Далі я додам дані в кожну директорію та файли відповідно.

Для файлу requirements.txt я додам такі залежності: boto3==1.26.137, python-dotenv==1.0.0, requests==2.28.2, використовуючи команду echo:

echo "boto3==1.26.137" >> requirements.txt

echo "python-dotenv==1.0.0" >> requirements.txt

echo "requests==2.28.2" >> requirements.txt

Boto3 — це набір інструментів для розробки, який використовується для взаємодії з ресурсами AWS. Python-dotenv використовується для зчитування змінних з файлу .env та додавання їх до середовища. В основному, він полегшує керування секретами, обліковими даними та конфігураціями без необхідності хардкодити їх у коді (робить це більш безпечним).

Залежність requests дозволяє коду виконувати HTTP-запити, обробляти дані відповіді та полегшує роботу з API та веб-сервісами.

Виправлення помилок: Коли я працював над цим проектом і намагався встановити залежності з файлу requirements.txt, у мене виникла проблема, де було написано, що "python не знайдений, запустіть без аргументів, щоб встановити з налаштувань Microsoft" (я намагався встановити pip, але не зрозумів, що Python ще не було встановлено), тому я встановив Python, а потім встановив менеджер пакетів pip:

pic

Тепер, коли Python встановлено, я можу встановити менеджер пакетів за допомогою:

python -m ensurepip --upgrade

і встановити мої залежності за допомогою:

pip install -r requirements.txt

pic

Ура, все встановлено!

pic

Менеджер пакетів pip використовується для встановлення залежностей та додавання зовнішніх бібліотек, таких як python-dotenv або requests, необхідних для мого коду.

Файл requirements.txt потрібен, щоб інші могли відтворити моє середовище за допомогою команди pip install -r requirements.txt.

Навіть із встановленим Python, pip гарантує, що я можу розширити функціональність за допомогою додаткових інструментів та бібліотек.

Далі я перенаправлю файли, які хочу ігнорувати, до файлу .gitignore.
text
Файл .gitignore вказує git ігнорувати файли або директорії, які містяться всередині, щоб все, що в ньому, залишалося приватним, безпечним, не відслідковуваним і не відправлялося в віддалений репозиторій.
text
Я поклав свій .env файл, pycache/ папку та файли з розширенням **.zip* туди.

Файл .env містить мої облікові дані для середовища, папка pycache/ зберігає скомпільовані Python файли (.pyc файли), щоб пришвидшити виконання програми, а файл з розширенням **.zip* зберігає кілька файлів і директорій в одному — стиснувши їх, щоб було зручніше зберігати... ці файли можуть бути досить великими, тому я додам їх до файлу .gitignore.

Команди:

echo ".env" >> .gitignore

echo "__pycache__/" >> .gitignore

echo "*.zip" >> gitignore

Тепер я перейду на сайт Open Weather Map, щоб створити обліковий запис і згенерувати свої облікові дані для API.

pic

Далі я додам свої облікові дані до файлу .env:

Примітка: Це чутливі дані, тому, якщо ви вирішите повторити цей проєкт, обов'язково не діліться ними у своїх скріншотах.

pic

Тепер я додам свій код до файлу weather_dashboard.py.

Ось код, який я використав:

import os  
import json  
import boto3  
import requests  
from datetime import datetime  
from dotenv import load_dotenv  

# Load environment variables  
load_dotenv()  

class WeatherDashboard:  
 def __init__(self):  
 self.api_key = os.getenv('OPEN_WEATHER_API_KEY')  
 self.bucket_name = os.getenv('AWS_BUCKET_NAME')  
 self.s3_client = boto3.client('s3')  

 def create_bucket_if_not_exists(self):  
 """Create S3 bucket if it doesn't exist"""  
 try:  
 # Simpler creation for us-east-1  
 print(f"Creating bucket {self.bucket_name}")   
 self.s3_client.create_bucket(Bucket=self.bucket_name)  
 print(f"Successfully created bucket {self.bucket_name}")  
 except NoCredentialsError:  
 print('Error: No AWS credentials found.')   
 except Exception as e:  
 print(f"Error creating bucket: {e}")   

 def fetch_weather(self, city):  
 """Fetch weather data from OpenWeather API"""  
 base_url = "http://api.openweathermap.org/data/2.5/weather"  
 params = {  
 'q': city,  
 'appid': os.getenv('OPEN_WEATHER_API_KEY')  
 }  
 try:  
 response = requests.get(base_url, params=params)  
 response.raise_for_status()  
 return response.json()  
 except requests.exceptions.RequestException as e:  
 print(f"Error fetching weather data: {e}")  
 return None  

 def save_to_s3(self, weather_data, city):  
 """Save weather data to S3 bucket"""  
 if not weather_data:  
 return False  

 timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')  
 file_name = f"weather-data/{city}-{timestamp}.json"  

 try:  
 weather_data['timestamp'] = timestamp  
 self.s3_client.put_object(  
 Bucket=self.bucket_name,  
 Key=file_name,  
 Body=json.dumps(weather_data),  
 ContentType='application/json'  
 )  
 print(f"Successfully saved data for {city} to S3")  
 return True  
 except Exception as e:  
 print(f"Error saving to S3: {e}")  
 return False  
def main():  
 dashboard = WeatherDashboard()  

 # Create bucket if one doesn't exist  
 dashboard.create_bucket_if_not_exists()  

 cities = ["Philadelphia", "Seattle", "New York"]  

 for city in cities:  
 weather_data = dashboard.fetch_weather(city)  
 if weather_data:  
 print(f"Conditions: {weather_data.get('weather', [{}])[0].get('description', 'No data')}")  

 # Saves data to S3  
 dashboard.save_to_s3(weather_data, city)  
 success = dashboard.save_to_s3(weather_data, city)  
 if success:  
 print(f"Weather data for {city} saved to S3!")  
 else:  
 print(f"Failed to fetch weather data for {city}")  

if __name__ == "__main__":  
 main()  
def save_to_s3(self, weather_data, city):  
 """Save weather data to S3 bucket"""  
 if not weather_data:  
 return False  

 # Create a timestamp for the filename  
 timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')  
 file_name = f"weather-data/{city}-{timestamp}.json"  

 try:  
 # Add timestamp to the data  
 weather_data['timestamp'] = timestamp

text
# Завантаження на S3  
 self.s3_client.put_object(  
 Bucket=self.bucket_name,  
 Key=file_name,  
 Body=json.dumps(weather_data),  
 ContentType='application/json'  
 )  
 print(f"Дані для {city} успішно збережено на S3")  
 return True  
 except Exception as e:  
 print(f"Помилка при збереженні на S3: {e}")  
 return False  
 main()

Я спробую пояснити це поступово.

Цей перший блок коду використовується для імпорту різних модулів, щоб я міг використовувати більше функціональностей Python, бібліотек та можливостей у своєму проєкті.

  • import os: Дозволяє взаємодіяти з операційною системою (наприклад, з шляхами до файлів, змінними середовища).
  • import json: Дозволяє працювати з даними у форматі JSON.
  • import boto3: Дозволяє доступ до AWS сервісів, таких як S3.
  • import requests: Допомагає надсилати HTTP запити для отримання даних з вебсайтів, таких як Weather Map.
  • from datetime import datetime: Надання інструментів для роботи з датами та часом.
  • from dotenv import load_dotenv: Завантажує змінні з файлу .env для безпечної конфігурації.

pic

Ця частина коду завантажує змінні середовища для погодного API, присвоює значення правильним атрибутам, зчитує API-ключ, зчитує назву S3 бакету, а потім створює з'єднання з S3:

pic

Це створює S3 бакет, якщо він не існує, і виводить повідомлення про успіх або помилку, залежно від того, що відбувається в блоці try:

pic

Цей код отримує погоду з вебсайту Open Weather Map, повертає дані для міст, зазначених у функції main, використовує API-ключ для авторизації запиту до вебсайту та виводить помилку, якщо виникла проблема:

pic

Цей код завантажує дані на S3 з часовою міткою, створює унікальне ім’я для файлу з часом і містом, а потім виводить результати успішного збереження, якщо немає помилок:

pic

Цей блок коду створює об'єкт WeatherDashboard, перевіряє, чи існує S3 бакет, перебирає список міст (["Philadelphia", "Seattle", "New York"]), отримує та зберігає дані про погоду, виводить поточну погоду і зберігає дані на S3 бакет — фактично викликається функція для запуску всього процесу.

pic

І останнє, але не менш важливе, name == "main" дозволяє коду виконуватись лише при безпосередньому запуску:

pic

Я виконаю команду weather_dashboard.py:

pic

Я перевіряю консоль, щоб переконатись, що все було створено правильно:

pic

pic

pic

Здається, що дані про погоду були успішно збережені в бакеті для Нью-Йорка, Філадельфії та Сіетла!

pic

pic

pic

Тепер я можу зробити коміт і відправити свій код на git:

pic

pic

pic

Успішно відправлено на git!
text
pic

Це завершення #DevOpsAllStarChallenge!

До наступного разу — залишайтеся з нами для наступної частини!!

Посилання на GitHub : https://github.com/brianarorie/30daydevopschallenge.git

Перекладено з: Creating An API To Fetch Data From A Weather App & Storing It To S3

Leave a Reply

Your email address will not be published. Required fields are marked *