flashstudio 0.1.8__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flashstudio might be problematic. Click here for more details.
- {flashstudio-0.1.8 → flashstudio-0.2.0}/PKG-INFO +4 -6
- {flashstudio-0.1.8 → flashstudio-0.2.0}/README.md +50 -54
- flashstudio-0.2.0/flashstudio/launcher.py +183 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/PKG-INFO +4 -6
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/requires.txt +4 -6
- {flashstudio-0.1.8 → flashstudio-0.2.0}/pyproject.toml +3 -5
- flashstudio-0.1.8/flashstudio/launcher.py +0 -104
- {flashstudio-0.1.8 → flashstudio-0.2.0}/README_PYPI.md +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/app.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/cli.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/project_manager.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/sidebar.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/styles.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/wizard.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/components/zone_drawer/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/constants.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/core/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/core/constants.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/_common.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/metrics.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/pipeline_status.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/project_banner.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/quick_actions.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/recent_runs.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/_common.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/download/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/download/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/helpers.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/preview/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/preview/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/upload/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/upload/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/verify/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/data/verify/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/export/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/export/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/export/weights/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/export/weights/exporter.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/export/weights/settings.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/_common.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/data/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/data/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/model/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/model/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/run/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/run/detection.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/run/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/run/video.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/solution/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/inference/solution/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/_common.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/advanced/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/advanced/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/architecture/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/architecture/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/augment/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/augment/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/hyperparams/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/hyperparams/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/utils/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/model/utils/config.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/_common.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/controls.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/dialogs.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/preflight.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/runner.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/launch/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/checkpoints.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/curves.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/dashboard.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/gt_verification.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/log_viewer.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/parsers.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/run_meta.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/tab.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/visualizations.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/page.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/__init__.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/config.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/device.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/filesystem.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/jobs.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/utils/training_hooks.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/SOURCES.txt +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/dependency_links.txt +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/entry_points.txt +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio.egg-info/top_level.txt +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/setup.cfg +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_app.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_cli.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_constants.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_launcher.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_pipeline_flow.py +0 -0
- {flashstudio-0.1.8 → flashstudio-0.2.0}/tests/test_save_dir_compat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flashstudio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Interactive Training & Inference UI for FlashDet — runs on Google Colab
|
|
5
5
|
Author: FlashVision
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,17 +19,15 @@ Requires-Dist: plotly>=5.0
|
|
|
19
19
|
Requires-Dist: pandas>=1.5
|
|
20
20
|
Requires-Dist: pillow>=9.0
|
|
21
21
|
Requires-Dist: numpy>=1.21
|
|
22
|
-
Requires-Dist: pyngrok>=6.0
|
|
23
22
|
Requires-Dist: opencv-python>=4.5
|
|
24
23
|
Requires-Dist: pyyaml>=6.0
|
|
25
24
|
Requires-Dist: flashdet
|
|
26
25
|
Provides-Extra: full
|
|
27
|
-
Requires-Dist: pyngrok>=6.0; extra == "full"
|
|
28
26
|
Requires-Dist: torch>=2.0; extra == "full"
|
|
29
|
-
Requires-Dist: opencv-python>=4.5; extra == "full"
|
|
30
27
|
Requires-Dist: flashdet[export]; extra == "full"
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
Requires-Dist: pyngrok>=6.0; extra == "full"
|
|
29
|
+
Provides-Extra: ngrok
|
|
30
|
+
Requires-Dist: pyngrok>=6.0; extra == "ngrok"
|
|
33
31
|
Provides-Extra: dev
|
|
34
32
|
Requires-Dist: ruff; extra == "dev"
|
|
35
33
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
- 📤 **Export** — ONNX export with FP16 auto-generated weights
|
|
29
29
|
- 📦 **Data** — Native `flashdet download` datasets + custom upload (COCO/VOC/YOLO formats)
|
|
30
30
|
- 📊 **Dashboard** — Overview with recent training runs from workspace
|
|
31
|
-
- 🚀 **Colab Support** —
|
|
31
|
+
- 🚀 **Colab Support** — Works out-of-the-box, no token or signup needed
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -80,19 +80,14 @@ Full inference pipeline with 17 built-in solutions (object counting, speed estim
|
|
|
80
80
|
|
|
81
81
|
## Installation
|
|
82
82
|
|
|
83
|
-
### Step 1: Install FlashStudio
|
|
84
|
-
|
|
85
83
|
```bash
|
|
86
84
|
pip install flashstudio
|
|
87
85
|
```
|
|
88
86
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
pip install git+https://github.com/FlashVision/FlashDet.git
|
|
93
|
-
```
|
|
87
|
+
This automatically installs FlashDet and all other dependencies.
|
|
94
88
|
|
|
95
|
-
|
|
89
|
+
<details>
|
|
90
|
+
<summary><b>Development install (from source)</b></summary>
|
|
96
91
|
|
|
97
92
|
```bash
|
|
98
93
|
git clone https://github.com/FlashVision/FlashStudio.git
|
|
@@ -100,6 +95,8 @@ cd FlashStudio
|
|
|
100
95
|
pip install -e .
|
|
101
96
|
```
|
|
102
97
|
|
|
98
|
+
</details>
|
|
99
|
+
|
|
103
100
|
---
|
|
104
101
|
|
|
105
102
|
## Usage — Local Machine
|
|
@@ -123,53 +120,46 @@ Then open **http://localhost:8501** in your browser.
|
|
|
123
120
|
|
|
124
121
|
## Usage — Google Colab
|
|
125
122
|
|
|
126
|
-
|
|
123
|
+
No signup or token needed. Just 2 steps:
|
|
124
|
+
|
|
125
|
+
### Step 1: Install
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
!pip install -q flashstudio
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Step 2: Launch
|
|
127
132
|
|
|
128
133
|
```python
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
from flashstudio import launch
|
|
135
|
+
launch()
|
|
131
136
|
```
|
|
132
137
|
|
|
133
|
-
|
|
138
|
+
A clickable **"Open FlashStudio"** button appears in the cell output. Click it to open the UI.
|
|
134
139
|
|
|
135
|
-
FlashStudio uses
|
|
140
|
+
FlashStudio auto-detects Colab and uses the built-in proxy to create a working URL — no `localhost`, no ngrok, no token.
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
3. Copy the token (looks like `2xAbC1234_something...`)
|
|
142
|
+
<details>
|
|
143
|
+
<summary><b>Optional: ngrok for a stable public URL</b></summary>
|
|
140
144
|
|
|
141
|
-
|
|
145
|
+
If the built-in proxy doesn't work for your setup, you can use ngrok as a fallback:
|
|
142
146
|
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
1. Get a free token at https://dashboard.ngrok.com/get-started/your-authtoken
|
|
148
|
+
2. Pass it when launching:
|
|
145
149
|
|
|
146
|
-
|
|
147
|
-
launch(ngrok_token="
|
|
150
|
+
```python
|
|
151
|
+
launch(ngrok_token="YOUR_TOKEN")
|
|
148
152
|
```
|
|
149
153
|
|
|
150
154
|
Or set it as an environment variable:
|
|
151
155
|
|
|
152
156
|
```python
|
|
153
157
|
import os
|
|
154
|
-
os.environ["NGROK_TOKEN"] = "
|
|
155
|
-
|
|
156
|
-
from flashstudio import launch
|
|
158
|
+
os.environ["NGROK_TOKEN"] = "YOUR_TOKEN"
|
|
157
159
|
launch()
|
|
158
160
|
```
|
|
159
161
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
After launching, you'll see output like:
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
============================================================
|
|
166
|
-
FlashStudio is running!
|
|
167
|
-
Local: http://localhost:8501
|
|
168
|
-
Public: https://abc123.ngrok-free.app
|
|
169
|
-
============================================================
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Click the **Public URL** to open FlashStudio in a new tab.
|
|
162
|
+
</details>
|
|
173
163
|
|
|
174
164
|
---
|
|
175
165
|
|
|
@@ -203,7 +193,7 @@ FlashStudio/
|
|
|
203
193
|
├── flashstudio/
|
|
204
194
|
│ ├── __init__.py # Package init + launch() export
|
|
205
195
|
│ ├── app.py # Main Streamlit app (wizard flow)
|
|
206
|
-
│ ├── launcher.py # Colab/local launcher
|
|
196
|
+
│ ├── launcher.py # Colab/local launcher (auto-tunnel)
|
|
207
197
|
│ ├── cli.py # CLI entrypoint
|
|
208
198
|
│ ├── constants.py # Centralized constants (paths, defaults, models)
|
|
209
199
|
│ │
|
|
@@ -297,26 +287,32 @@ FlashStudio/
|
|
|
297
287
|
|
|
298
288
|
## Troubleshooting
|
|
299
289
|
|
|
300
|
-
###
|
|
301
|
-
|
|
302
|
-
```bash
|
|
303
|
-
pip install --upgrade flashstudio
|
|
304
|
-
```
|
|
290
|
+
### Colab: "localhost can't be reached" or ngrok error
|
|
305
291
|
|
|
306
|
-
|
|
292
|
+
`launch()` uses Colab's built-in proxy automatically. If it doesn't work, run this in a **new cell**:
|
|
307
293
|
|
|
308
|
-
|
|
309
|
-
|
|
294
|
+
```python
|
|
295
|
+
import subprocess, sys, time
|
|
296
|
+
|
|
297
|
+
proc = subprocess.Popen(
|
|
298
|
+
[sys.executable, "-m", "streamlit", "run",
|
|
299
|
+
__import__('flashstudio.launcher', fromlist=['_get_app_path'])._get_app_path(),
|
|
300
|
+
"--server.port", "8501", "--server.headless", "true",
|
|
301
|
+
"--server.enableCORS", "false", "--server.enableXsrfProtection", "false"],
|
|
302
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
303
|
+
)
|
|
304
|
+
time.sleep(5)
|
|
305
|
+
|
|
306
|
+
from google.colab.output import eval_js
|
|
307
|
+
print(eval_js("google.colab.kernel.proxyPort(8501)"))
|
|
308
|
+
```
|
|
310
309
|
|
|
311
|
-
|
|
310
|
+
Open the printed URL in a new tab. No token or signup needed.
|
|
312
311
|
|
|
313
312
|
### Streamlit port already in use
|
|
314
313
|
|
|
315
314
|
```bash
|
|
316
|
-
# Kill existing Streamlit processes
|
|
317
315
|
pkill -f "streamlit run"
|
|
318
|
-
|
|
319
|
-
# Then restart
|
|
320
316
|
flashstudio --port 8501
|
|
321
317
|
```
|
|
322
318
|
|
|
@@ -324,10 +320,10 @@ flashstudio --port 8501
|
|
|
324
320
|
|
|
325
321
|
## Requirements
|
|
326
322
|
|
|
327
|
-
- Python >= 3.
|
|
328
|
-
- FlashDet (`pip install git+https://github.com/FlashVision/FlashDet.git`)
|
|
329
|
-
- ngrok account (free) for Google Colab usage
|
|
323
|
+
- Python >= 3.10
|
|
330
324
|
- GPU recommended for training (T4 or better)
|
|
325
|
+
- Google Colab works out-of-the-box (no extra accounts needed)
|
|
326
|
+
- FlashDet installs automatically with `pip install flashstudio`
|
|
331
327
|
|
|
332
328
|
## License
|
|
333
329
|
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""Launch FlashStudio UI — works locally and inside Google Colab."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from flashstudio.utils.device import is_colab
|
|
9
|
+
|
|
10
|
+
_STREAMLIT_CONFIG = """\
|
|
11
|
+
[theme]
|
|
12
|
+
primaryColor = "#7C3AED"
|
|
13
|
+
backgroundColor = "#FFFFFF"
|
|
14
|
+
secondaryBackgroundColor = "#F8F9FB"
|
|
15
|
+
textColor = "#1A1A2E"
|
|
16
|
+
font = "sans serif"
|
|
17
|
+
|
|
18
|
+
[server]
|
|
19
|
+
headless = true
|
|
20
|
+
port = 8501
|
|
21
|
+
enableCORS = false
|
|
22
|
+
enableXsrfProtection = false
|
|
23
|
+
|
|
24
|
+
[client]
|
|
25
|
+
showSidebarNavigation = false
|
|
26
|
+
|
|
27
|
+
[browser]
|
|
28
|
+
gatherUsageStats = false
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _get_app_path() -> str:
|
|
33
|
+
return str(Path(__file__).parent / "app.py")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _ensure_streamlit_config():
|
|
37
|
+
"""Write the default Streamlit config if one doesn't already exist."""
|
|
38
|
+
config_dir = Path.home() / ".streamlit"
|
|
39
|
+
config_file = config_dir / "config.toml"
|
|
40
|
+
if config_file.exists():
|
|
41
|
+
return
|
|
42
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
43
|
+
config_file.write_text(_STREAMLIT_CONFIG)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def launch(port: int = 8501, share: bool = True, ngrok_token: str | None = None):
|
|
47
|
+
"""Launch FlashStudio Streamlit app.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
port: Port to run the Streamlit server on.
|
|
51
|
+
share: If True and running in Colab, creates a public ngrok tunnel.
|
|
52
|
+
ngrok_token: Optional ngrok auth token. If not provided, uses NGROK_TOKEN env var.
|
|
53
|
+
"""
|
|
54
|
+
_ensure_streamlit_config()
|
|
55
|
+
app_path = _get_app_path()
|
|
56
|
+
|
|
57
|
+
if is_colab():
|
|
58
|
+
return _launch_colab(app_path, port, share, ngrok_token)
|
|
59
|
+
else:
|
|
60
|
+
_launch_local(app_path, port)
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _launch_colab(app_path: str, port: int, share: bool, ngrok_token: str | None):
|
|
65
|
+
"""Launch in Google Colab with automatic tunnel detection."""
|
|
66
|
+
import time as _time
|
|
67
|
+
import urllib.request
|
|
68
|
+
import urllib.error
|
|
69
|
+
|
|
70
|
+
print(" Starting FlashStudio...", end="", flush=True)
|
|
71
|
+
|
|
72
|
+
proc = subprocess.Popen(
|
|
73
|
+
[sys.executable, "-m", "streamlit", "run", app_path,
|
|
74
|
+
"--server.port", str(port),
|
|
75
|
+
"--server.headless", "true",
|
|
76
|
+
"--server.enableCORS", "false",
|
|
77
|
+
"--server.enableXsrfProtection", "false"],
|
|
78
|
+
stdout=subprocess.PIPE,
|
|
79
|
+
stderr=subprocess.PIPE,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Wait until Streamlit is actually responding (up to 30s)
|
|
83
|
+
ready = False
|
|
84
|
+
for i in range(30):
|
|
85
|
+
_time.sleep(1)
|
|
86
|
+
if proc.poll() is not None:
|
|
87
|
+
_, stderr = proc.communicate()
|
|
88
|
+
err_msg = stderr.decode("utf-8", errors="replace")[-500:] if stderr else "Unknown error"
|
|
89
|
+
print(f"\n\n FlashStudio failed to start:\n {err_msg}")
|
|
90
|
+
return proc
|
|
91
|
+
try:
|
|
92
|
+
urllib.request.urlopen(f"http://localhost:{port}/_stcore/health", timeout=2)
|
|
93
|
+
ready = True
|
|
94
|
+
break
|
|
95
|
+
except Exception:
|
|
96
|
+
print(".", end="", flush=True)
|
|
97
|
+
|
|
98
|
+
if ready:
|
|
99
|
+
print(" Ready!")
|
|
100
|
+
else:
|
|
101
|
+
print(" (still loading, URL may take a moment)")
|
|
102
|
+
|
|
103
|
+
public_url = None
|
|
104
|
+
|
|
105
|
+
# Method 1: Colab's built-in proxy (simplest, no install needed)
|
|
106
|
+
try:
|
|
107
|
+
from google.colab.output import eval_js
|
|
108
|
+
result = eval_js(f"google.colab.kernel.proxyPort({port})")
|
|
109
|
+
if result and str(result).startswith("http"):
|
|
110
|
+
public_url = str(result)
|
|
111
|
+
except Exception:
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
# Method 2: ngrok (only if token is provided)
|
|
115
|
+
if not public_url:
|
|
116
|
+
token = ngrok_token or os.environ.get("NGROK_TOKEN", "")
|
|
117
|
+
if token:
|
|
118
|
+
try:
|
|
119
|
+
from pyngrok import ngrok, conf
|
|
120
|
+
conf.get_default().auth_token = token
|
|
121
|
+
public_url = str(ngrok.connect(port, "http"))
|
|
122
|
+
except ImportError:
|
|
123
|
+
try:
|
|
124
|
+
subprocess.check_call(
|
|
125
|
+
[sys.executable, "-m", "pip", "install", "-q", "pyngrok"],
|
|
126
|
+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
|
127
|
+
)
|
|
128
|
+
from pyngrok import ngrok, conf
|
|
129
|
+
conf.get_default().auth_token = token
|
|
130
|
+
public_url = str(ngrok.connect(port, "http"))
|
|
131
|
+
except Exception:
|
|
132
|
+
pass
|
|
133
|
+
except Exception:
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
print(f"\n{'=' * 60}")
|
|
137
|
+
print(" FlashStudio is running!")
|
|
138
|
+
if public_url:
|
|
139
|
+
print(f" Open: {public_url}")
|
|
140
|
+
else:
|
|
141
|
+
print(f" Port: {port}")
|
|
142
|
+
print("")
|
|
143
|
+
print(" Run this in a new cell to get the URL:")
|
|
144
|
+
print(f" from google.colab.output import eval_js")
|
|
145
|
+
print(f" print(eval_js('google.colab.kernel.proxyPort({port})'))")
|
|
146
|
+
print(f"{'=' * 60}\n")
|
|
147
|
+
|
|
148
|
+
if public_url:
|
|
149
|
+
try:
|
|
150
|
+
from IPython.display import display, HTML
|
|
151
|
+
display(HTML(
|
|
152
|
+
f'<a href="{public_url}" target="_blank" '
|
|
153
|
+
f'style="display:inline-block;font-size:16px;padding:10px 24px;'
|
|
154
|
+
f'background:#7C3AED;color:white;border-radius:8px;'
|
|
155
|
+
f'text-decoration:none;font-weight:600;margin:8px 0;">'
|
|
156
|
+
f'Open FlashStudio</a>'
|
|
157
|
+
))
|
|
158
|
+
except Exception:
|
|
159
|
+
pass
|
|
160
|
+
else:
|
|
161
|
+
try:
|
|
162
|
+
from IPython.display import display, HTML
|
|
163
|
+
display(HTML(
|
|
164
|
+
f'<div style="padding:12px;background:#FEF3C7;border-radius:8px;'
|
|
165
|
+
f'margin:8px 0;font-size:14px;">'
|
|
166
|
+
f'Run in a <b>new cell</b>:<br>'
|
|
167
|
+
f'<code style="background:#F3F4F6;padding:4px 8px;border-radius:4px;">'
|
|
168
|
+
f'from google.colab.output import eval_js; '
|
|
169
|
+
f'print(eval_js("google.colab.kernel.proxyPort({port})"))</code>'
|
|
170
|
+
f'</div>'
|
|
171
|
+
))
|
|
172
|
+
except Exception:
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
return proc
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _launch_local(app_path: str, port: int):
|
|
179
|
+
"""Launch locally with streamlit."""
|
|
180
|
+
subprocess.run(
|
|
181
|
+
[sys.executable, "-m", "streamlit", "run", app_path,
|
|
182
|
+
"--server.port", str(port)],
|
|
183
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flashstudio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Interactive Training & Inference UI for FlashDet — runs on Google Colab
|
|
5
5
|
Author: FlashVision
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,17 +19,15 @@ Requires-Dist: plotly>=5.0
|
|
|
19
19
|
Requires-Dist: pandas>=1.5
|
|
20
20
|
Requires-Dist: pillow>=9.0
|
|
21
21
|
Requires-Dist: numpy>=1.21
|
|
22
|
-
Requires-Dist: pyngrok>=6.0
|
|
23
22
|
Requires-Dist: opencv-python>=4.5
|
|
24
23
|
Requires-Dist: pyyaml>=6.0
|
|
25
24
|
Requires-Dist: flashdet
|
|
26
25
|
Provides-Extra: full
|
|
27
|
-
Requires-Dist: pyngrok>=6.0; extra == "full"
|
|
28
26
|
Requires-Dist: torch>=2.0; extra == "full"
|
|
29
|
-
Requires-Dist: opencv-python>=4.5; extra == "full"
|
|
30
27
|
Requires-Dist: flashdet[export]; extra == "full"
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
Requires-Dist: pyngrok>=6.0; extra == "full"
|
|
29
|
+
Provides-Extra: ngrok
|
|
30
|
+
Requires-Dist: pyngrok>=6.0; extra == "ngrok"
|
|
33
31
|
Provides-Extra: dev
|
|
34
32
|
Requires-Dist: ruff; extra == "dev"
|
|
35
33
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -3,21 +3,19 @@ plotly>=5.0
|
|
|
3
3
|
pandas>=1.5
|
|
4
4
|
pillow>=9.0
|
|
5
5
|
numpy>=1.21
|
|
6
|
-
pyngrok>=6.0
|
|
7
6
|
opencv-python>=4.5
|
|
8
7
|
pyyaml>=6.0
|
|
9
8
|
flashdet
|
|
10
9
|
|
|
11
|
-
[colab]
|
|
12
|
-
pyngrok>=6.0
|
|
13
|
-
|
|
14
10
|
[dev]
|
|
15
11
|
ruff
|
|
16
12
|
pytest
|
|
17
13
|
pytest-cov
|
|
18
14
|
|
|
19
15
|
[full]
|
|
20
|
-
pyngrok>=6.0
|
|
21
16
|
torch>=2.0
|
|
22
|
-
opencv-python>=4.5
|
|
23
17
|
flashdet[export]
|
|
18
|
+
pyngrok>=6.0
|
|
19
|
+
|
|
20
|
+
[ngrok]
|
|
21
|
+
pyngrok>=6.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "flashstudio"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Interactive Training & Inference UI for FlashDet — runs on Google Colab"
|
|
9
9
|
readme = "README_PYPI.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -25,7 +25,6 @@ dependencies = [
|
|
|
25
25
|
"pandas>=1.5",
|
|
26
26
|
"pillow>=9.0",
|
|
27
27
|
"numpy>=1.21",
|
|
28
|
-
"pyngrok>=6.0",
|
|
29
28
|
"opencv-python>=4.5",
|
|
30
29
|
"pyyaml>=6.0",
|
|
31
30
|
"flashdet",
|
|
@@ -33,12 +32,11 @@ dependencies = [
|
|
|
33
32
|
|
|
34
33
|
[project.optional-dependencies]
|
|
35
34
|
full = [
|
|
36
|
-
"pyngrok>=6.0",
|
|
37
35
|
"torch>=2.0",
|
|
38
|
-
"opencv-python>=4.5",
|
|
39
36
|
"flashdet[export]",
|
|
37
|
+
"pyngrok>=6.0",
|
|
40
38
|
]
|
|
41
|
-
|
|
39
|
+
ngrok = ["pyngrok>=6.0"]
|
|
42
40
|
dev = ["ruff", "pytest", "pytest-cov"]
|
|
43
41
|
|
|
44
42
|
[project.scripts]
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
"""Launch FlashStudio UI — works locally and inside Google Colab."""
|
|
2
|
-
|
|
3
|
-
import subprocess
|
|
4
|
-
import sys
|
|
5
|
-
import os
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
from flashstudio.utils.device import is_colab
|
|
9
|
-
|
|
10
|
-
_STREAMLIT_CONFIG = """\
|
|
11
|
-
[theme]
|
|
12
|
-
primaryColor = "#7C3AED"
|
|
13
|
-
backgroundColor = "#FFFFFF"
|
|
14
|
-
secondaryBackgroundColor = "#F8F9FB"
|
|
15
|
-
textColor = "#1A1A2E"
|
|
16
|
-
font = "sans serif"
|
|
17
|
-
|
|
18
|
-
[server]
|
|
19
|
-
headless = true
|
|
20
|
-
port = 8501
|
|
21
|
-
enableCORS = false
|
|
22
|
-
enableXsrfProtection = false
|
|
23
|
-
|
|
24
|
-
[client]
|
|
25
|
-
showSidebarNavigation = false
|
|
26
|
-
|
|
27
|
-
[browser]
|
|
28
|
-
gatherUsageStats = false
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def _get_app_path() -> str:
|
|
33
|
-
return str(Path(__file__).parent / "app.py")
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _ensure_streamlit_config():
|
|
37
|
-
"""Write the default Streamlit config if one doesn't already exist."""
|
|
38
|
-
config_dir = Path.home() / ".streamlit"
|
|
39
|
-
config_file = config_dir / "config.toml"
|
|
40
|
-
if config_file.exists():
|
|
41
|
-
return
|
|
42
|
-
config_dir.mkdir(parents=True, exist_ok=True)
|
|
43
|
-
config_file.write_text(_STREAMLIT_CONFIG)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def launch(port: int = 8501, share: bool = True, ngrok_token: str | None = None):
|
|
47
|
-
"""Launch FlashStudio Streamlit app.
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
port: Port to run the Streamlit server on.
|
|
51
|
-
share: If True and running in Colab, creates a public ngrok tunnel.
|
|
52
|
-
ngrok_token: Optional ngrok auth token. If not provided, uses NGROK_TOKEN env var.
|
|
53
|
-
"""
|
|
54
|
-
_ensure_streamlit_config()
|
|
55
|
-
app_path = _get_app_path()
|
|
56
|
-
|
|
57
|
-
if is_colab():
|
|
58
|
-
_launch_colab(app_path, port, share, ngrok_token)
|
|
59
|
-
else:
|
|
60
|
-
_launch_local(app_path, port)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def _launch_colab(app_path: str, port: int, share: bool, ngrok_token: str | None):
|
|
64
|
-
"""Launch in Google Colab with ngrok tunnel."""
|
|
65
|
-
try:
|
|
66
|
-
from pyngrok import ngrok, conf
|
|
67
|
-
except ImportError:
|
|
68
|
-
print("Installing pyngrok...")
|
|
69
|
-
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "pyngrok"])
|
|
70
|
-
from pyngrok import ngrok, conf
|
|
71
|
-
|
|
72
|
-
token = ngrok_token or os.environ.get("NGROK_TOKEN", "")
|
|
73
|
-
if token:
|
|
74
|
-
conf.get_default().auth_token = token
|
|
75
|
-
|
|
76
|
-
proc = subprocess.Popen(
|
|
77
|
-
[sys.executable, "-m", "streamlit", "run", app_path,
|
|
78
|
-
"--server.port", str(port),
|
|
79
|
-
"--server.headless", "true",
|
|
80
|
-
"--server.enableCORS", "false",
|
|
81
|
-
"--server.enableXsrfProtection", "false"],
|
|
82
|
-
stdout=subprocess.PIPE,
|
|
83
|
-
stderr=subprocess.PIPE,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
if share:
|
|
87
|
-
public_url = ngrok.connect(port, "http")
|
|
88
|
-
print(f"\n{'=' * 60}")
|
|
89
|
-
print(" FlashStudio is running!")
|
|
90
|
-
print(f" Local: http://localhost:{port}")
|
|
91
|
-
print(f" Public: {public_url}")
|
|
92
|
-
print(f"{'=' * 60}\n")
|
|
93
|
-
else:
|
|
94
|
-
print(f"\n FlashStudio running at http://localhost:{port}\n")
|
|
95
|
-
|
|
96
|
-
return proc
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def _launch_local(app_path: str, port: int):
|
|
100
|
-
"""Launch locally with streamlit."""
|
|
101
|
-
subprocess.run(
|
|
102
|
-
[sys.executable, "-m", "streamlit", "run", app_path,
|
|
103
|
-
"--server.port", str(port)],
|
|
104
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/pipeline_status.py
RENAMED
|
File without changes
|
{flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/project_banner.py
RENAMED
|
File without changes
|
{flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/dashboard/overview/quick_actions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/gt_verification.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flashstudio-0.1.8 → flashstudio-0.2.0}/flashstudio/pages/training/monitor/visualizations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|