AB498 commited on
Commit
a4af9c5
·
1 Parent(s): 88d99d1
Files changed (6) hide show
  1. Dockerfile +2 -2
  2. README.md +27 -19
  3. requirements.txt +1 -1
  4. src/app.py +52 -0
  5. src/streamlit_app.py +0 -40
  6. src/templates/index.html +128 -0
Dockerfile CHANGED
@@ -15,6 +15,6 @@ RUN pip3 install -r requirements.txt
15
 
16
  EXPOSE 8501
17
 
18
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
 
20
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
15
 
16
  EXPOSE 8501
17
 
18
+ HEALTHCHECK CMD curl --fail http://localhost:8501/health
19
 
20
+ ENTRYPOINT ["python", "src/app.py"]
README.md CHANGED
@@ -1,19 +1,27 @@
1
- ---
2
- title: Docker
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- ---
13
-
14
- # Welcome to Streamlit!
15
-
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
-
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
1
+ # Flask Spiral Visualization
2
+
3
+ This is a Flask application that visualizes spiral patterns using Altair charts.
4
+
5
+ ## Features
6
+
7
+ - Interactive sliders to control the number of points and turns in the spiral
8
+ - Real-time visualization updates
9
+ - Responsive web design
10
+
11
+ ## Usage
12
+
13
+ 1. Adjust the sliders to change the spiral parameters
14
+ 2. Click "Update Chart" to regenerate the visualization
15
+
16
+ ## Endpoints
17
+
18
+ - `/` - Main application page
19
+ - `/generate_chart` - API endpoint for generating charts
20
+ - `/health` - Health check endpoint
21
+
22
+ ## Dependencies
23
+
24
+ - Flask
25
+ - Altair
26
+ - Pandas
27
+ - Vega-Lite (frontend)
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
  altair
2
  pandas
3
- streamlit
 
1
  altair
2
  pandas
3
+ flask
src/app.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ import altair as alt
3
+ import numpy as np
4
+ import pandas as pd
5
+ import json
6
+
7
+ app = Flask(__name__)
8
+
9
+ @app.route('/')
10
+ def index():
11
+ return render_template('index.html')
12
+
13
+ @app.route('/health')
14
+ def health():
15
+ return {'status': 'healthy'}
16
+
17
+ @app.route('/generate_chart', methods=['POST'])
18
+ def generate_chart():
19
+ data = request.get_json()
20
+ num_points = data.get('num_points', 1100)
21
+ num_turns = data.get('num_turns', 31)
22
+
23
+ # Generate spiral data
24
+ indices = np.linspace(0, 1, num_points)
25
+ theta = 2 * np.pi * num_turns * indices
26
+ radius = indices
27
+
28
+ x = radius * np.cos(theta)
29
+ y = radius * np.sin(theta)
30
+
31
+ df = pd.DataFrame({
32
+ "x": x,
33
+ "y": y,
34
+ "idx": indices,
35
+ "rand": np.random.randn(num_points),
36
+ })
37
+
38
+ # Create Altair chart
39
+ chart = alt.Chart(df, height=700, width=700).mark_point(filled=True).encode(
40
+ x=alt.X("x", axis=None),
41
+ y=alt.Y("y", axis=None),
42
+ color=alt.Color("idx", legend=None, scale=alt.Scale()),
43
+ size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
44
+ )
45
+
46
+ # Convert chart to JSON
47
+ chart_json = chart.to_json()
48
+
49
+ return jsonify({'chart': chart_json})
50
+
51
+ if __name__ == '__main__':
52
+ app.run(host='0.0.0.0', port=8501, debug=True)
src/streamlit_app.py DELETED
@@ -1,40 +0,0 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/templates/index.html ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Spiral Visualization with Flask</title>
5
+ <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
6
+ <script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ margin: 20px;
12
+ background-color: #f5f5f5;
13
+ }
14
+ .container {
15
+ max-width: 1200px;
16
+ margin: 0 auto;
17
+ background-color: white;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
21
+ }
22
+ h1 {
23
+ color: #333;
24
+ text-align: center;
25
+ }
26
+ .controls {
27
+ margin: 20px 0;
28
+ padding: 20px;
29
+ background-color: #f8f9fa;
30
+ border-radius: 5px;
31
+ }
32
+ .slider-container {
33
+ margin: 15px 0;
34
+ }
35
+ label {
36
+ display: block;
37
+ margin-bottom: 5px;
38
+ font-weight: bold;
39
+ }
40
+ input[type="range"] {
41
+ width: 100%;
42
+ }
43
+ .value-display {
44
+ display: inline-block;
45
+ width: 50px;
46
+ text-align: right;
47
+ }
48
+ #vis {
49
+ width: 700px;
50
+ height: 700px;
51
+ margin: 20px auto;
52
+ }
53
+ button {
54
+ background-color: #007bff;
55
+ color: white;
56
+ border: none;
57
+ padding: 10px 20px;
58
+ border-radius: 5px;
59
+ cursor: pointer;
60
+ font-size: 16px;
61
+ }
62
+ button:hover {
63
+ background-color: #0056b3;
64
+ }
65
+ </style>
66
+ </head>
67
+ <body>
68
+ <div class="container">
69
+ <h1>Welcome to Flask Spiral Visualization!</h1>
70
+
71
+ <div class="controls">
72
+ <div class="slider-container">
73
+ <label for="points">Number of points in spiral: <span id="points-value" class="value-display">1100</span></label>
74
+ <input type="range" id="points" name="points" min="1" max="10000" value="1100">
75
+ </div>
76
+
77
+ <div class="slider-container">
78
+ <label for="turns">Number of turns in spiral: <span id="turns-value" class="value-display">31</span></label>
79
+ <input type="range" id="turns" name="turns" min="1" max="300" value="31">
80
+ </div>
81
+
82
+ <button onclick="updateChart()">Update Chart</button>
83
+ </div>
84
+
85
+ <div id="vis"></div>
86
+ </div>
87
+
88
+ <script>
89
+ // Initialize slider value displays
90
+ document.getElementById('points').addEventListener('input', function() {
91
+ document.getElementById('points-value').textContent = this.value;
92
+ });
93
+
94
+ document.getElementById('turns').addEventListener('input', function() {
95
+ document.getElementById('turns-value').textContent = this.value;
96
+ });
97
+
98
+ // Function to update the chart
99
+ function updateChart() {
100
+ const numPoints = document.getElementById('points').value;
101
+ const numTurns = document.getElementById('turns').value;
102
+
103
+ fetch('/generate_chart', {
104
+ method: 'POST',
105
+ headers: {
106
+ 'Content-Type': 'application/json',
107
+ },
108
+ body: JSON.stringify({
109
+ num_points: parseInt(numPoints),
110
+ num_turns: parseInt(numTurns)
111
+ })
112
+ })
113
+ .then(response => response.json())
114
+ .then(data => {
115
+ vegaEmbed('#vis', JSON.parse(data.chart));
116
+ })
117
+ .catch(error => {
118
+ console.error('Error:', error);
119
+ });
120
+ }
121
+
122
+ // Load initial chart
123
+ document.addEventListener('DOMContentLoaded', function() {
124
+ updateChart();
125
+ });
126
+ </script>
127
+ </body>
128
+ </html>