Updating Files
نجحت جميع الفحوصات
CI/CD Pipeline - Weather App 🌤️ / test (push) Successful in 41s
CI/CD Pipeline - Weather App 🌤️ / build_and_push_image (push) Successful in 46s
CI/CD Pipeline - Weather App 🌤️ / deploy (push) Successful in 7m15s

هذا الالتزام موجود في:
ahmedgamalyousef
2025-10-20 14:08:01 +03:00
الأصل d88db9e8e3
التزام feb25052b0
6 ملفات معدلة مع 145 إضافات و137 حذوفات

عرض الملف

@@ -75,3 +75,4 @@ jobs:
- name: 🚀 Deploy Application - name: 🚀 Deploy Application
run: $HOME/ghaymah/bin/gy resource app launch run: $HOME/ghaymah/bin/gy resource app launch

عرض الملف

@@ -16,4 +16,3 @@ RUN echo '<!DOCTYPE html><html><head><title>Weather App</title></head><body><h1>
EXPOSE 5000 EXPOSE 5000
CMD ["python", "app.py"] CMD ["python", "app.py"]

عرض الملف

@@ -180,5 +180,3 @@ https://<your-app-name>.hosted.ghaymah.systems
## 🎥 Project Record ## 🎥 Project Record
[Watch the Demo](https://app.gitpasha.com/AhmedGamalYousef/Complete-CI-CD-Project-pipeline-on-Ghaymah-Cloud/src/branch/main/demo/CICDonGhaymahCloud.mp4) [Watch the Demo](https://app.gitpasha.com/AhmedGamalYousef/Complete-CI-CD-Project-pipeline-on-Ghaymah-Cloud/src/branch/main/demo/CICDonGhaymahCloud.mp4)

74
app.py
عرض الملف

@@ -1,13 +1,14 @@
from flask import Flask, request, jsonify, render_template_string
import requests
import os import os
from datetime import datetime from datetime import datetime
import requests
from flask import Flask, jsonify, render_template_string, request
app = Flask(__name__) app = Flask(__name__)
# Get API key from environment variable (preferred) or use demo key # Get API key from environment variable (preferred) or use demo key
API_KEY = os.getenv('API_KEY', '6cf356ceb2ec0ff941855d4a43144e0e') API_KEY = os.getenv("API_KEY", "6cf356ceb2ec0ff941855d4a43144e0e")
BASE_URL = 'https://api.openweathermap.org/data/2.5/weather' BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
# HTML Template with embedded CSS and JavaScript - MUST BE DEFINED BEFORE ROUTES # HTML Template with embedded CSS and JavaScript - MUST BE DEFINED BEFORE ROUTES
HTML_TEMPLATE = """ HTML_TEMPLATE = """
@@ -378,6 +379,7 @@ HTML_TEMPLATE = """
</html> </html>
""" """
def get_weather(city): def get_weather(city):
"""Fetch weather data from OpenWeatherMap API""" """Fetch weather data from OpenWeatherMap API"""
try: try:
@@ -386,25 +388,29 @@ def get_weather(city):
response.raise_for_status() # Raises an HTTPError for bad responses response.raise_for_status() # Raises an HTTPError for bad responses
data = response.json() data = response.json()
main = data['main'] main = data["main"]
weather = data['weather'][0] weather = data["weather"][0]
sys = data.get('sys', {}) sys = data.get("sys", {})
return { return {
'city': data['name'], "city": data["name"],
'country': sys.get('country', ''), "country": sys.get("country", ""),
'temperature': round(main['temp']), "temperature": round(main["temp"]),
'feels_like': round(main['feels_like']), "feels_like": round(main["feels_like"]),
'description': weather['description'].title(), "description": weather["description"].title(),
'humidity': main['humidity'], "humidity": main["humidity"],
'pressure': main['pressure'], "pressure": main["pressure"],
'wind_speed': round(data['wind']['speed'], 1), "wind_speed": round(data["wind"]["speed"], 1),
'wind_deg': data['wind'].get('deg', 0), "wind_deg": data["wind"].get("deg", 0),
'visibility': data.get('visibility', 0), "visibility": data.get("visibility", 0),
'icon': weather['icon'], "icon": weather["icon"],
'sunrise': datetime.fromtimestamp(sys.get('sunrise', 0)).strftime('%H:%M') if sys.get('sunrise') else 'N/A', "sunrise": datetime.fromtimestamp(sys.get("sunrise", 0)).strftime("%H:%M")
'sunset': datetime.fromtimestamp(sys.get('sunset', 0)).strftime('%H:%M') if sys.get('sunset') else 'N/A', if sys.get("sunrise")
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S') else "N/A",
"sunset": datetime.fromtimestamp(sys.get("sunset", 0)).strftime("%H:%M")
if sys.get("sunset")
else "N/A",
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
} }
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
print(f"API request failed: {e}") print(f"API request failed: {e}")
@@ -413,29 +419,33 @@ def get_weather(city):
print(f"Error parsing weather data: {e}") print(f"Error parsing weather data: {e}")
return None return None
@app.route('/')
@app.route("/")
def home(): def home():
return render_template_string(HTML_TEMPLATE) return render_template_string(HTML_TEMPLATE)
@app.route('/weather', methods=['GET', 'POST'])
@app.route("/weather", methods=["GET", "POST"])
def weather(): def weather():
if request.method == 'POST': if request.method == "POST":
city = request.form.get('city') city = request.form.get("city")
else: else:
city = request.args.get('city') city = request.args.get("city")
if not city: if not city:
return jsonify({'error': 'City parameter is required'}), 400 return jsonify({"error": "City parameter is required"}), 400
weather_data = get_weather(city) weather_data = get_weather(city)
if weather_data: if weather_data:
return jsonify(weather_data) return jsonify(weather_data)
else: else:
return jsonify({'error': 'City not found or API request failed'}), 404 return jsonify({"error": "City not found or API request failed"}), 404
@app.route('/health')
@app.route("/health")
def health(): def health():
return jsonify({'status': 'healthy', 'timestamp': datetime.now().isoformat()}) return jsonify({"status": "healthy", "timestamp": datetime.now().isoformat()})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False) if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False)