somya-27-04-03 commited on
Commit
fc8f5a2
·
verified ·
1 Parent(s): e5dc87d

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +32 -0
  2. index.html +23 -19
  3. requirements.txt +3 -0
  4. script.js +79 -0
  5. style.css +57 -28
app.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ from flask_cors import CORS
3
+ import requests
4
+ app = Flask(__name__)
5
+ CORS(app)
6
+ API_KEY = "8b578569eecee3ba36ea02c94b036ebc"
7
+ @app.route("/", methods=["GET"])
8
+ def home():
9
+ return "🌦️ Weather Backend is running!"
10
+ @app.route("/get_weather", methods=["POST"])
11
+ def get_weather():
12
+ data = request.get_json()
13
+ city = data.get("city")
14
+ if not city:
15
+ return jsonify({"error": "No city provided"}), 400
16
+ url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
17
+ response = requests.get(url)
18
+
19
+ if response.status_code != 200:
20
+ return jsonify({"error": "City not found"}), 404
21
+ weather_data = response.json()
22
+ result = {
23
+ "city": weather_data["name"],
24
+ "country": weather_data["sys"]["country"],
25
+ "temperature": weather_data["main"]["temp"],
26
+ "humidity": weather_data["main"]["humidity"],
27
+ "description": weather_data["weather"][0]["description"],
28
+ "icon": weather_data["weather"][0]["icon"]
29
+ }
30
+ return jsonify(result)
31
+ if __name__ == "__main__":
32
+ app.run(host="0.0.0.0", port=7860)
index.html CHANGED
@@ -1,19 +1,23 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>Weather App</title>
7
+ <link rel="stylesheet" href="style.css" />
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <h1>🌦️ Weather App</h1>
12
+
13
+ <!-- 🌓 Theme Toggle Button -->
14
+ <button id="toggleTheme">Toggle Theme</button>
15
+
16
+ <input type="text" id="cityInput" placeholder="Enter city name">
17
+ <button onclick="getWeatherByCity()">Get Weather</button>
18
+ <div id="weatherResult"></div>
19
+ </div>
20
+
21
+ <script src="script.js"></script>
22
+ </body>
23
+ </html>
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ flask
2
+ flask-cors
3
+ gunicorn
script.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function displayWeather(data) {
2
+ const weatherDiv = document.getElementById("weatherResult");
3
+ const rain = data.rain ? data.rain["1h"] || data.rain["3h"] || 0 : 0;
4
+
5
+ weatherDiv.innerHTML = `
6
+ <h3>${data.name}, ${data.sys.country}</h3>
7
+ <p>Temperature: ${data.main.temp} °C</p>
8
+ <p>Humidity: ${data.main.humidity} %</p>
9
+ <p>Weather: ${data.weather[0].description}</p>
10
+ <p>Rain (last hour): ${rain} mm</p>
11
+ <img src="https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png" alt="weather icon">
12
+ `;
13
+ }
14
+
15
+ function getWeather(city = null, lat = null, lon = null) {
16
+ const apiKey = "8b578569eecee3ba36ea02c94b036ebc";
17
+ let url = "";
18
+
19
+ if (city) {
20
+ url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`;
21
+ } else if (lat && lon) {
22
+ url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric`;
23
+ } else {
24
+ document.getElementById("weatherResult").innerText = "No city or coordinates provided";
25
+ return;
26
+ }
27
+
28
+ fetch(url)
29
+ .then(response => {
30
+ if (!response.ok) throw new Error("City not found");
31
+ return response.json();
32
+ })
33
+ .then(displayWeather)
34
+ .catch(error => {
35
+ document.getElementById("weatherResult").innerText = error.message;
36
+ });
37
+ }
38
+
39
+ function getWeatherByCity() {
40
+ const city = document.getElementById("cityInput").value;
41
+ if (city.trim() !== "") {
42
+ getWeather(city);
43
+ } else {
44
+ document.getElementById("weatherResult").innerText = "Please enter a city name.";
45
+ }
46
+ }
47
+
48
+ // Auto-detect on page load
49
+ window.onload = function() {
50
+ if (navigator.geolocation) {
51
+ navigator.geolocation.getCurrentPosition(
52
+ position => {
53
+ getWeather(null, position.coords.latitude, position.coords.longitude);
54
+ },
55
+ () => {
56
+ document.getElementById("weatherResult").innerText = "Geolocation permission denied.";
57
+ }
58
+ );
59
+ } else {
60
+ document.getElementById("weatherResult").innerText = "Geolocation not supported.";
61
+ }
62
+
63
+ // 🌓 Load saved theme preference
64
+ const savedTheme = localStorage.getItem("theme") || "light";
65
+ document.body.classList.add(savedTheme);
66
+ };
67
+
68
+ // 🌓 Theme toggle functionality
69
+ document.getElementById("toggleTheme").addEventListener("click", () => {
70
+ if (document.body.classList.contains("light")) {
71
+ document.body.classList.remove("light");
72
+ document.body.classList.add("dark");
73
+ localStorage.setItem("theme", "dark");
74
+ } else {
75
+ document.body.classList.remove("dark");
76
+ document.body.classList.add("light");
77
+ localStorage.setItem("theme", "light");
78
+ }
79
+ });
style.css CHANGED
@@ -1,28 +1,57 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ font-family: Arial, sans-serif;
4
+ display: flex;
5
+ justify-content: center;
6
+ align-items: center;
7
+ height: 100vh;
8
+ transition: background 0.3s, color 0.3s;
9
+ }
10
+
11
+ /* Light Theme */
12
+ body.light {
13
+ background: linear-gradient(to right, #83a4d4, #b6fbff);
14
+ color: #333;
15
+ }
16
+
17
+ /* Dark Theme */
18
+ body.dark {
19
+ background: linear-gradient(to right, #0f2027, #203a43, #2c5364);
20
+ color: #f0f0f0;
21
+ }
22
+
23
+ .container {
24
+ background: rgba(255,255,255,0.8);
25
+ padding: 30px;
26
+ border-radius: 10px;
27
+ text-align: center;
28
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
29
+ }
30
+
31
+ body.dark .container {
32
+ background: rgba(0,0,0,0.5);
33
+ }
34
+
35
+ input {
36
+ padding: 10px;
37
+ width: 200px;
38
+ margin-right: 10px;
39
+ }
40
+
41
+ button {
42
+ padding: 10px 20px;
43
+ background-color: #4CAF50;
44
+ border: none;
45
+ color: white;
46
+ border-radius: 5px;
47
+ cursor: pointer;
48
+ }
49
+
50
+ button:hover {
51
+ background-color: #45a049;
52
+ }
53
+
54
+ #weatherResult {
55
+ margin-top: 20px;
56
+ font-size: 18px;
57
+ }