Spaces:
Build error
Build error
Commit
Β·
1b7ef07
1
Parent(s):
4d1b490
Refactor: Prepare for Vercel + Colab architecture
Browse files- dev_tools/colab_setup.py +50 -0
- requirements.txt +1 -0
- web_client/src/components/InteractionLab.tsx +27 -2
dev_tools/colab_setup.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import os
|
| 3 |
+
import subprocess
|
| 4 |
+
import sys
|
| 5 |
+
import time
|
| 6 |
+
import threading
|
| 7 |
+
|
| 8 |
+
def install_dependencies():
|
| 9 |
+
print("π Installing dependencies...")
|
| 10 |
+
subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
|
| 11 |
+
subprocess.check_call([sys.executable, "-m", "pip", "install", "pyngrok", "nest_asyncio", "uvicorn"])
|
| 12 |
+
|
| 13 |
+
def run_server():
|
| 14 |
+
print("π₯ Starting FastAPI Server...")
|
| 15 |
+
# Run server.py using python command to ensure it runs as a script
|
| 16 |
+
subprocess.run([sys.executable, "server.py"], check=True)
|
| 17 |
+
|
| 18 |
+
def start_ngrok():
|
| 19 |
+
from pyngrok import ngrok
|
| 20 |
+
|
| 21 |
+
token = input("π Enter your Ngrok Authtoken (from https://dashboard.ngrok.com/get-started/your-authtoken): ")
|
| 22 |
+
if not token:
|
| 23 |
+
print("β Error: Ngrok token is required.")
|
| 24 |
+
return
|
| 25 |
+
|
| 26 |
+
ngrok.set_auth_token(token)
|
| 27 |
+
|
| 28 |
+
# Start tunnel to port 8000
|
| 29 |
+
public_url = ngrok.connect(8000).public_url
|
| 30 |
+
print(f"\nβ
\033[92mPublic Backend URL: {public_url}\033[0m")
|
| 31 |
+
print("π Copy this URL and paste it into the 'Backend Connection' box on your Vercel website.\n")
|
| 32 |
+
|
| 33 |
+
# Keep functionality alive
|
| 34 |
+
try:
|
| 35 |
+
# Run server in main thread or subprocess
|
| 36 |
+
run_server()
|
| 37 |
+
except KeyboardInterrupt:
|
| 38 |
+
print("Stopping...")
|
| 39 |
+
ngrok.kill()
|
| 40 |
+
|
| 41 |
+
if __name__ == "__main__":
|
| 42 |
+
if not os.path.exists("server.py"):
|
| 43 |
+
print("β Error: server.py not found. Make sure you are in the root of the cloned repository.")
|
| 44 |
+
else:
|
| 45 |
+
try:
|
| 46 |
+
install_dependencies()
|
| 47 |
+
print("β
Dependencies installed.")
|
| 48 |
+
start_ngrok()
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"β Error: {e}")
|
requirements.txt
CHANGED
|
@@ -7,3 +7,4 @@ setuptools
|
|
| 7 |
huggingface-hub
|
| 8 |
requests
|
| 9 |
cryptography
|
|
|
|
|
|
| 7 |
huggingface-hub
|
| 8 |
requests
|
| 9 |
cryptography
|
| 10 |
+
llama-cpp-python
|
web_client/src/components/InteractionLab.tsx
CHANGED
|
@@ -12,12 +12,26 @@ export const InteractionLab = () => {
|
|
| 12 |
const [prompt, setPrompt] = useState("");
|
| 13 |
const [loading, setLoading] = useState(false);
|
| 14 |
const [result, setResult] = useState<any>(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
const handleExecute = async () => {
|
| 17 |
if (!prompt.trim()) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
setLoading(true);
|
| 19 |
try {
|
| 20 |
-
const res = await fetch(
|
| 21 |
method: 'POST',
|
| 22 |
headers: {
|
| 23 |
'Content-Type': 'application/json'
|
|
@@ -99,7 +113,18 @@ export const InteractionLab = () => {
|
|
| 99 |
))}
|
| 100 |
</div>
|
| 101 |
|
| 102 |
-
<div className="mt-6">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
<button
|
| 104 |
onClick={handleExecute}
|
| 105 |
disabled={loading}
|
|
|
|
| 12 |
const [prompt, setPrompt] = useState("");
|
| 13 |
const [loading, setLoading] = useState(false);
|
| 14 |
const [result, setResult] = useState<any>(null);
|
| 15 |
+
const [serverUrl, setServerUrl] = useState(() => localStorage.getItem("upif_server_url") || "");
|
| 16 |
+
|
| 17 |
+
const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
| 18 |
+
const url = e.target.value;
|
| 19 |
+
setServerUrl(url);
|
| 20 |
+
localStorage.setItem("upif_server_url", url);
|
| 21 |
+
};
|
| 22 |
|
| 23 |
const handleExecute = async () => {
|
| 24 |
if (!prompt.trim()) return;
|
| 25 |
+
|
| 26 |
+
let baseUrl = serverUrl.replace(/\/$/, ""); // Remove trailing slash
|
| 27 |
+
if (!baseUrl) {
|
| 28 |
+
alert("Please enter the Colab/Backend URL first.");
|
| 29 |
+
return;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
setLoading(true);
|
| 33 |
try {
|
| 34 |
+
const res = await fetch(`${baseUrl}/api/analyze`, {
|
| 35 |
method: 'POST',
|
| 36 |
headers: {
|
| 37 |
'Content-Type': 'application/json'
|
|
|
|
| 113 |
))}
|
| 114 |
</div>
|
| 115 |
|
| 116 |
+
<div className="mt-6 flex flex-col gap-4">
|
| 117 |
+
<div>
|
| 118 |
+
<label className="text-xs font-bold text-slate-500 uppercase tracking-widest mb-2 block">Backend Connection</label>
|
| 119 |
+
<input
|
| 120 |
+
type="text"
|
| 121 |
+
placeholder="Paste Colab/Ngrok URL here (e.g. https://xxxx.ngrok-free.app)"
|
| 122 |
+
className="w-full bg-slate-900 border border-slate-800 rounded-lg px-3 py-2 text-xs text-blue-400 font-mono outline-none focus:border-blue-500 transition"
|
| 123 |
+
value={serverUrl}
|
| 124 |
+
onChange={handleUrlChange}
|
| 125 |
+
/>
|
| 126 |
+
</div>
|
| 127 |
+
|
| 128 |
<button
|
| 129 |
onClick={handleExecute}
|
| 130 |
disabled={loading}
|