vumichien commited on
Commit
8bc50ed
·
1 Parent(s): f22e939

Upload Flask app

Browse files
Files changed (4) hide show
  1. Dockerfile +26 -0
  2. app.py +165 -0
  3. models.py +10 -0
  4. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sử dụng một image chính thức của Python 3
2
+ FROM python:3.9-slim
3
+
4
+ # Thiết lập biến môi trường để Python không tạo các file pyc
5
+ ENV PYTHONDONTWRITEBYTECODE=1
6
+
7
+ # Thiết lập biến môi trường để Python không buffer output
8
+ ENV PYTHONUNBUFFERED=1
9
+
10
+ # Tạo và đặt thư mục làm việc cho ứng dụng Flask
11
+ WORKDIR /app
12
+
13
+ # Sao chép file requirements.txt vào container
14
+ COPY requirements.txt /app/
15
+
16
+ # Cài đặt các dependencies từ requirements.txt
17
+ RUN pip install --no-cache-dir -r requirements.txt
18
+
19
+ # Sao chép toàn bộ mã nguồn ứng dụng vào container
20
+ COPY . /app/
21
+
22
+ # Expose port 5000 for Flask
23
+ EXPOSE 5000
24
+
25
+ # Chạy ứng dụng Flask bằng Gunicorn
26
+ CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
app.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, render_template
2
+ from models import db, WifiSignal
3
+ from datetime import datetime, timedelta
4
+ import random
5
+ import folium
6
+ from folium.plugins import MarkerCluster
7
+ from flasgger import Swagger
8
+
9
+ app = Flask(__name__)
10
+ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
11
+ app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
12
+
13
+ # Khởi tạo Swagger
14
+ swagger = Swagger(app)
15
+
16
+ db.init_app(app)
17
+
18
+ @app.route('/api/generate-data', methods=['POST'])
19
+ def generate_data():
20
+ """
21
+ Generate demo data.
22
+ ---
23
+ tags:
24
+ - Data Management
25
+ responses:
26
+ 201:
27
+ description: Demo data generated successfully
28
+ """
29
+ base_latitude = 35.6837
30
+ base_longitude = 139.6805
31
+ start_date = datetime(2024, 8, 1)
32
+ end_date = datetime(2024, 8, 7)
33
+ delta = end_date - start_date
34
+
35
+ for _ in range(100):
36
+ random_days = random.randint(0, delta.days)
37
+ random_seconds = random.randint(0, 86400)
38
+ random_time = start_date + timedelta(days=random_days, seconds=random_seconds)
39
+
40
+ random_latitude = base_latitude + random.uniform(-0.01, 0.01)
41
+ random_longitude = base_longitude + random.uniform(-0.01, 0.01)
42
+ random_signal_strength = random.randint(10, 50)
43
+
44
+ wifi_signal = WifiSignal(
45
+ latitude=random_latitude,
46
+ longitude=random_longitude,
47
+ timestamp=random_time,
48
+ signal_strength=random_signal_strength
49
+ )
50
+
51
+ db.session.add(wifi_signal)
52
+
53
+ db.session.commit()
54
+ return jsonify({"message": "Demo data generated successfully"}), 201
55
+
56
+ @app.route('/api/delete-data', methods=['DELETE'])
57
+ def delete_data():
58
+ """
59
+ Delete all data in the database.
60
+ ---
61
+ tags:
62
+ - Data Management
63
+ responses:
64
+ 200:
65
+ description: All data deleted successfully
66
+ 500:
67
+ description: An error occurred
68
+ """
69
+ try:
70
+ num_rows_deleted = db.session.query(WifiSignal).delete()
71
+ db.session.commit()
72
+ return jsonify({"message": f"Deleted {num_rows_deleted} rows from the database."}), 200
73
+ except Exception as e:
74
+ db.session.rollback()
75
+ return jsonify({"message": f"An error occurred: {str(e)}"}), 500
76
+
77
+ @app.route('/api/upload', methods=['POST'])
78
+ def upload_data():
79
+ """
80
+ Upload WiFi signal data.
81
+ ---
82
+ tags:
83
+ - Data Management
84
+ parameters:
85
+ - name: body
86
+ in: body
87
+ required: true
88
+ schema:
89
+ type: object
90
+ properties:
91
+ latitude:
92
+ type: number
93
+ example: 35.6895
94
+ longitude:
95
+ type: number
96
+ example: 139.6917
97
+ timestamp:
98
+ type: string
99
+ example: "2024-08-29 14:30:00"
100
+ signal_strength:
101
+ type: integer
102
+ example: 42
103
+ responses:
104
+ 201:
105
+ description: Data uploaded successfully
106
+ 400:
107
+ description: Invalid input
108
+ """
109
+ data = request.json
110
+ latitude = data.get('latitude')
111
+ longitude = data.get('longitude')
112
+ timestamp = datetime.strptime(data.get('timestamp'), '%Y-%m-%d %H:%M:%S')
113
+ signal_strength = data.get('signal_strength')
114
+
115
+ wifi_signal = WifiSignal(latitude=latitude, longitude=longitude, timestamp=timestamp, signal_strength=signal_strength)
116
+ db.session.add(wifi_signal)
117
+ db.session.commit()
118
+
119
+ return jsonify({"message": "Data uploaded successfully"}), 201
120
+
121
+ @app.route('/', methods=['GET'])
122
+ def show_map():
123
+ start_date = request.args.get('start_date')
124
+ end_date = request.args.get('end_date')
125
+
126
+ query = WifiSignal.query
127
+
128
+ if start_date and end_date:
129
+ start_datetime = datetime.strptime(start_date, '%Y-%m-%d')
130
+ end_datetime = datetime.strptime(end_date, '%Y-%m-%d')
131
+ query = query.filter(WifiSignal.timestamp >= start_datetime, WifiSignal.timestamp <= end_datetime)
132
+
133
+ signals = query.all()
134
+ signal_data = [(signal.latitude, signal.longitude, signal.signal_strength) for signal in signals]
135
+
136
+ if signal_data:
137
+ min_signal = min(s[2] for s in signal_data)
138
+ max_signal = max(s[2] for s in signal_data)
139
+ else:
140
+ min_signal = max_signal = 1
141
+
142
+ m = folium.Map(location=[35.6837, 139.6805], zoom_start=12)
143
+ marker_cluster = MarkerCluster().add_to(m)
144
+
145
+ for lat, lon, signal_strength in signal_data:
146
+ if max_signal - min_signal != 0:
147
+ radius = 5 + 10 * ((signal_strength - min_signal) / (max_signal - min_signal))
148
+ else:
149
+ radius = 15
150
+ folium.CircleMarker(
151
+ location=[lat, lon],
152
+ radius=radius,
153
+ popup=f'Signal Strength: {signal_strength}',
154
+ color='blue',
155
+ fill=True,
156
+ fill_opacity=0.6
157
+ ).add_to(marker_cluster)
158
+
159
+ map_html = m._repr_html_()
160
+ return render_template('map.html', map_html=map_html)
161
+
162
+ if __name__ == '__main__':
163
+ with app.app_context():
164
+ db.create_all()
165
+ app.run(debug=True)
models.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask_sqlalchemy import SQLAlchemy
2
+
3
+ db = SQLAlchemy()
4
+
5
+ class WifiSignal(db.Model):
6
+ id = db.Column(db.Integer, primary_key=True)
7
+ latitude = db.Column(db.Float, nullable=False)
8
+ longitude = db.Column(db.Float, nullable=False)
9
+ timestamp = db.Column(db.DateTime, nullable=False)
10
+ signal_strength = db.Column(db.Integer, nullable=False)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ Flask==2.2.5
2
+ Flask-SQLAlchemy==3.0.3
3
+ Flasgger==0.9.5
4
+ folium==0.13.0
5
+ gunicorn==20.1.0
6
+
7
+