ckharche commited on
Commit
f113ec9
·
verified ·
1 Parent(s): c3046af

Upload rebuilt Space (research showcase + labelled demo)

Browse files
Files changed (2) hide show
  1. Dockerfile +4 -2
  2. run.sh +64 -64
Dockerfile CHANGED
@@ -16,8 +16,10 @@ RUN pip install --no-cache-dir -r requirements.txt
16
  # Copy ALL your files (including run.sh, streamlit_app.py, etc.) into the container
17
  COPY . .
18
 
19
- # NOW that run.sh is copied, make it executable
20
- RUN chmod +x ./run.sh
 
 
21
 
22
  # This is the command that will run when the Space starts
23
  CMD ["./run.sh"]
 
16
  # Copy ALL your files (including run.sh, streamlit_app.py, etc.) into the container
17
  COPY . .
18
 
19
+ # NOW that run.sh is copied, strip Windows line endings (a CRLF shebang makes the
20
+ # container die with "exec ./run.sh: no such file or directory", 2026-10-31) and make
21
+ # it executable.
22
+ RUN sed -i 's/\r$//' ./run.sh && chmod +x ./run.sh
23
 
24
  # This is the command that will run when the Space starts
25
  CMD ["./run.sh"]
run.sh CHANGED
@@ -1,64 +1,64 @@
1
- #!/bin/bash
2
- # Space entrypoint: FastAPI on :7860 (internal) + Streamlit on :8501 (the exposed port).
3
- #
4
- # The old version was two lines -- background uvicorn with `&`, then start Streamlit -- and
5
- # never checked whether the API came up. That matters because config.py raises ImportError
6
- # when FINNHUB_KEY or REDDIT_CLIENT_ID is unset, which kills uvicorn instantly. Streamlit
7
- # then starts fine, the Space reports "Running" in green, and every click returns
8
- # "Failed to connect to the API" with no indication that the actual cause is a missing
9
- # secret. Same failure shape as every other bug in this codebase: a real error absorbed by
10
- # the layer above and re-presented as something vague.
11
- #
12
- # So: wait for the API to actually answer, and if it does not, write the reason somewhere
13
- # the UI can read and display. Streamlit still starts either way -- a Space that boots and
14
- # explains itself is far more useful than one that exits.
15
- set -u
16
-
17
- STATUS_FILE=/tmp/api_status
18
- API_LOG=/tmp/api.log
19
- : > "$STATUS_FILE"
20
-
21
- echo "[run.sh] starting FastAPI on :7860 ..."
22
- uvicorn trade_analysis.enhanced_api:app --host 0.0.0.0 --port 7860 > "$API_LOG" 2>&1 &
23
- API_PID=$!
24
-
25
- # python, not curl -- python:3.12-slim ships no curl and adding it just for a health check
26
- # is a layer nobody needs.
27
- ready=0
28
- for _ in $(seq 1 45); do
29
- if ! kill -0 "$API_PID" 2>/dev/null; then
30
- {
31
- echo "The analysis API exited while starting up."
32
- echo
33
- echo "Most common cause: a required Space secret is not set."
34
- echo "Settings -> Variables and secrets: FINNHUB_KEY, REDDIT_CLIENT_ID,"
35
- echo "REDDIT_CLIENT_SECRET, REDDIT_USER_AGENT."
36
- echo
37
- echo "--- last lines of the API log ---"
38
- tail -n 25 "$API_LOG"
39
- } > "$STATUS_FILE"
40
- echo "[run.sh] API process died during startup; see $STATUS_FILE"
41
- break
42
- fi
43
- if python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/', timeout=2)" 2>/dev/null; then
44
- echo "ready" > "$STATUS_FILE"
45
- ready=1
46
- echo "[run.sh] API is answering."
47
- break
48
- fi
49
- sleep 2
50
- done
51
-
52
- if [ "$ready" -eq 0 ] && [ ! -s "$STATUS_FILE" ]; then
53
- {
54
- echo "The analysis API did not answer within 90 seconds of starting."
55
- echo "It may still be loading the sentiment models on first boot -- reload shortly."
56
- echo
57
- echo "--- last lines of the API log ---"
58
- tail -n 25 "$API_LOG"
59
- } > "$STATUS_FILE"
60
- echo "[run.sh] API health check timed out; starting the UI anyway."
61
- fi
62
-
63
- echo "[run.sh] starting Streamlit on :8501 ..."
64
- exec streamlit run streamlit_app.py --server.port 8501 --server.address 0.0.0.0
 
1
+ #!/bin/bash
2
+ # Space entrypoint: FastAPI on :7860 (internal) + Streamlit on :8501 (the exposed port).
3
+ #
4
+ # The old version was two lines -- background uvicorn with `&`, then start Streamlit -- and
5
+ # never checked whether the API came up. That matters because config.py raises ImportError
6
+ # when FINNHUB_KEY or REDDIT_CLIENT_ID is unset, which kills uvicorn instantly. Streamlit
7
+ # then starts fine, the Space reports "Running" in green, and every click returns
8
+ # "Failed to connect to the API" with no indication that the actual cause is a missing
9
+ # secret. Same failure shape as every other bug in this codebase: a real error absorbed by
10
+ # the layer above and re-presented as something vague.
11
+ #
12
+ # So: wait for the API to actually answer, and if it does not, write the reason somewhere
13
+ # the UI can read and display. Streamlit still starts either way -- a Space that boots and
14
+ # explains itself is far more useful than one that exits.
15
+ set -u
16
+
17
+ STATUS_FILE=/tmp/api_status
18
+ API_LOG=/tmp/api.log
19
+ : > "$STATUS_FILE"
20
+
21
+ echo "[run.sh] starting FastAPI on :7860 ..."
22
+ uvicorn trade_analysis.enhanced_api:app --host 0.0.0.0 --port 7860 > "$API_LOG" 2>&1 &
23
+ API_PID=$!
24
+
25
+ # python, not curl -- python:3.12-slim ships no curl and adding it just for a health check
26
+ # is a layer nobody needs.
27
+ ready=0
28
+ for _ in $(seq 1 45); do
29
+ if ! kill -0 "$API_PID" 2>/dev/null; then
30
+ {
31
+ echo "The analysis API exited while starting up."
32
+ echo
33
+ echo "Most common cause: a required Space secret is not set."
34
+ echo "Settings -> Variables and secrets: FINNHUB_KEY, REDDIT_CLIENT_ID,"
35
+ echo "REDDIT_CLIENT_SECRET, REDDIT_USER_AGENT."
36
+ echo
37
+ echo "--- last lines of the API log ---"
38
+ tail -n 25 "$API_LOG"
39
+ } > "$STATUS_FILE"
40
+ echo "[run.sh] API process died during startup; see $STATUS_FILE"
41
+ break
42
+ fi
43
+ if python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/', timeout=2)" 2>/dev/null; then
44
+ echo "ready" > "$STATUS_FILE"
45
+ ready=1
46
+ echo "[run.sh] API is answering."
47
+ break
48
+ fi
49
+ sleep 2
50
+ done
51
+
52
+ if [ "$ready" -eq 0 ] && [ ! -s "$STATUS_FILE" ]; then
53
+ {
54
+ echo "The analysis API did not answer within 90 seconds of starting."
55
+ echo "It may still be loading the sentiment models on first boot -- reload shortly."
56
+ echo
57
+ echo "--- last lines of the API log ---"
58
+ tail -n 25 "$API_LOG"
59
+ } > "$STATUS_FILE"
60
+ echo "[run.sh] API health check timed out; starting the UI anyway."
61
+ fi
62
+
63
+ echo "[run.sh] starting Streamlit on :8501 ..."
64
+ exec streamlit run streamlit_app.py --server.port 8501 --server.address 0.0.0.0