Spaces:
Running
Running
Commit
·
54e865e
1
Parent(s):
cb26165
Fix import and environment issues for HF Spaces
Browse files- .space/app-entrypoint.sh +0 -0
- .space/config.json +7 -4
- Dockerfile +13 -5
- app.py +28 -5
- src → src/download_model.py +56 -10
.space/app-entrypoint.sh
CHANGED
Binary files a/.space/app-entrypoint.sh and b/.space/app-entrypoint.sh differ
|
|
.space/config.json
CHANGED
@@ -2,10 +2,11 @@
|
|
2 |
"docker": {
|
3 |
"image": "Dockerfile",
|
4 |
"env": {
|
5 |
-
"PYTHONPATH": "
|
6 |
"MODEL_REVISION": "20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32",
|
7 |
"MODEL_HF_REPO": "dennisvdang/chorus-detection",
|
8 |
-
"HF_MODEL_FILENAME": "chorus_detection_crnn.h5"
|
|
|
9 |
}
|
10 |
},
|
11 |
"runtime": {
|
@@ -18,11 +19,13 @@
|
|
18 |
},
|
19 |
"app": {
|
20 |
"port": 7860,
|
21 |
-
"entrypoint": ".space/app-entrypoint.sh"
|
|
|
22 |
},
|
23 |
"app_file": "app.py",
|
24 |
"docker_build_args": {
|
25 |
-
"MODEL_HF_REPO": "dennisvdang/chorus-detection"
|
|
|
26 |
},
|
27 |
"sdk": "streamlit",
|
28 |
"python_requirements": "requirements.txt",
|
|
|
2 |
"docker": {
|
3 |
"image": "Dockerfile",
|
4 |
"env": {
|
5 |
+
"PYTHONPATH": "/app:/app/src:/home/user/app:/home/user/app/src:.",
|
6 |
"MODEL_REVISION": "20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32",
|
7 |
"MODEL_HF_REPO": "dennisvdang/chorus-detection",
|
8 |
+
"HF_MODEL_FILENAME": "chorus_detection_crnn.h5",
|
9 |
+
"PYTHONUNBUFFERED": "1"
|
10 |
}
|
11 |
},
|
12 |
"runtime": {
|
|
|
19 |
},
|
20 |
"app": {
|
21 |
"port": 7860,
|
22 |
+
"entrypoint": ".space/app-entrypoint.sh",
|
23 |
+
"working_directory": "/home/user/app"
|
24 |
},
|
25 |
"app_file": "app.py",
|
26 |
"docker_build_args": {
|
27 |
+
"MODEL_HF_REPO": "dennisvdang/chorus-detection",
|
28 |
+
"MODEL_REVISION": "20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32"
|
29 |
},
|
30 |
"sdk": "streamlit",
|
31 |
"python_requirements": "requirements.txt",
|
Dockerfile
CHANGED
@@ -3,7 +3,7 @@ FROM python:3.9-slim
|
|
3 |
# Set environment variables
|
4 |
ENV PYTHONDONTWRITEBYTECODE=1
|
5 |
ENV PYTHONUNBUFFERED=1
|
6 |
-
ENV PYTHONPATH="${PYTHONPATH}:/app:/app/src"
|
7 |
ENV MODEL_REVISION="20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32"
|
8 |
ENV MODEL_HF_REPO="dennisvdang/chorus-detection"
|
9 |
ENV HF_MODEL_FILENAME="chorus_detection_crnn.h5"
|
@@ -25,14 +25,22 @@ COPY . .
|
|
25 |
RUN pip install -e .
|
26 |
|
27 |
# Make the entry point script executable
|
28 |
-
RUN
|
29 |
|
30 |
-
#
|
31 |
-
RUN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
# Expose port for Streamlit
|
34 |
EXPOSE 7860
|
35 |
|
36 |
# Run the app
|
37 |
-
CMD ["
|
38 |
|
|
|
3 |
# Set environment variables
|
4 |
ENV PYTHONDONTWRITEBYTECODE=1
|
5 |
ENV PYTHONUNBUFFERED=1
|
6 |
+
ENV PYTHONPATH="${PYTHONPATH}:/app:/app/src:/home/user/app:/home/user/app/src:."
|
7 |
ENV MODEL_REVISION="20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32"
|
8 |
ENV MODEL_HF_REPO="dennisvdang/chorus-detection"
|
9 |
ENV HF_MODEL_FILENAME="chorus_detection_crnn.h5"
|
|
|
25 |
RUN pip install -e .
|
26 |
|
27 |
# Make the entry point script executable
|
28 |
+
RUN chmod +x .space/app-entrypoint.sh || echo "Could not chmod app-entrypoint.sh"
|
29 |
|
30 |
+
# Create symlinks to ensure proper imports
|
31 |
+
RUN ln -sf /app/src /src || echo "Could not create symlink"
|
32 |
+
|
33 |
+
# Ensure model exists and debug info
|
34 |
+
RUN echo "Debug: ls -la /app" && ls -la /app && \
|
35 |
+
echo "Debug: ls -la /app/src" && ls -la /app/src && \
|
36 |
+
echo "Debug: PYTHONPATH=$PYTHONPATH" && \
|
37 |
+
python -c "import sys; print(f'Python path: {sys.path}')" && \
|
38 |
+
python -c "import os; print(f'Working directory: {os.getcwd()}')" && \
|
39 |
+
python -c "from src.download_model import ensure_model_exists; ensure_model_exists(revision='${MODEL_REVISION}')" || echo "Warning: Model download failed during build"
|
40 |
|
41 |
# Expose port for Streamlit
|
42 |
EXPOSE 7860
|
43 |
|
44 |
# Run the app
|
45 |
+
CMD ["bash", "-c", "cd /app && ./.space/app-entrypoint.sh"]
|
46 |
|
app.py
CHANGED
@@ -22,22 +22,45 @@ if os.environ.get("SPACE_ID"):
|
|
22 |
logger.info(f"Running in Hugging Face Space: {os.environ.get('SPACE_ID')}")
|
23 |
logger.info(f"PYTHONPATH: {os.environ.get('PYTHONPATH')}")
|
24 |
logger.info(f"MODEL_REVISION: {os.environ.get('MODEL_REVISION')}")
|
|
|
|
|
25 |
|
26 |
# Add the src directory to the Python path
|
27 |
try:
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
except Exception as e:
|
31 |
logger.error(f"Error setting up Python path: {e}")
|
32 |
sys.exit(1)
|
33 |
|
34 |
# Import the app module from src
|
35 |
try:
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
except ImportError as e:
|
39 |
logger.error(f"Failed to import main from src.app: {e}")
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
if __name__ == "__main__":
|
43 |
try:
|
|
|
22 |
logger.info(f"Running in Hugging Face Space: {os.environ.get('SPACE_ID')}")
|
23 |
logger.info(f"PYTHONPATH: {os.environ.get('PYTHONPATH')}")
|
24 |
logger.info(f"MODEL_REVISION: {os.environ.get('MODEL_REVISION')}")
|
25 |
+
logger.info(f"Current working directory: {os.getcwd()}")
|
26 |
+
logger.info(f"Directory contents: {os.listdir()}")
|
27 |
|
28 |
# Add the src directory to the Python path
|
29 |
try:
|
30 |
+
app_dir = os.path.dirname(os.path.abspath(__file__))
|
31 |
+
src_dir = os.path.join(app_dir, "src")
|
32 |
+
sys.path.insert(0, app_dir)
|
33 |
+
sys.path.insert(0, src_dir)
|
34 |
+
logger.info(f"Added directories to Python path: {app_dir}, {src_dir}")
|
35 |
+
logger.info(f"Python path: {sys.path}")
|
36 |
except Exception as e:
|
37 |
logger.error(f"Error setting up Python path: {e}")
|
38 |
sys.exit(1)
|
39 |
|
40 |
# Import the app module from src
|
41 |
try:
|
42 |
+
# Try direct import first
|
43 |
+
if os.path.exists(os.path.join(src_dir, "app.py")):
|
44 |
+
import src.app as app_module
|
45 |
+
logger.info("Successfully imported app module directly")
|
46 |
+
main = app_module.main
|
47 |
+
else:
|
48 |
+
# Fall back to regular import
|
49 |
+
from src.app import main
|
50 |
+
logger.info("Successfully imported main from src.app")
|
51 |
except ImportError as e:
|
52 |
logger.error(f"Failed to import main from src.app: {e}")
|
53 |
+
logger.info(f"Trying alternative import approach...")
|
54 |
+
|
55 |
+
try:
|
56 |
+
# Try importing directly from the current directory
|
57 |
+
sys.path.append('.')
|
58 |
+
from app import main as direct_main
|
59 |
+
main = direct_main
|
60 |
+
logger.info("Successfully imported main using direct approach")
|
61 |
+
except ImportError as e2:
|
62 |
+
logger.error(f"All import attempts failed: {e2}")
|
63 |
+
sys.exit(1)
|
64 |
|
65 |
if __name__ == "__main__":
|
66 |
try:
|
src → src/download_model.py
RENAMED
@@ -12,22 +12,31 @@ import sys
|
|
12 |
from pathlib import Path
|
13 |
import logging
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
# Use huggingface_hub for better integration with HF ecosystem
|
16 |
try:
|
17 |
from huggingface_hub import hf_hub_download
|
18 |
HF_HUB_AVAILABLE = True
|
|
|
19 |
except ImportError:
|
20 |
HF_HUB_AVAILABLE = False
|
|
|
21 |
import requests
|
22 |
from tqdm import tqdm
|
23 |
|
24 |
-
# Configure logging
|
25 |
-
logging.basicConfig(
|
26 |
-
level=logging.INFO,
|
27 |
-
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
28 |
-
)
|
29 |
-
logger = logging.getLogger("model-downloader")
|
30 |
-
|
31 |
def download_file_with_progress(url: str, destination: Path) -> None:
|
32 |
"""Download a file with a progress bar.
|
33 |
|
@@ -62,7 +71,7 @@ def download_file_with_progress(url: str, destination: Path) -> None:
|
|
62 |
def ensure_model_exists(
|
63 |
model_filename: str = "best_model_V3.h5",
|
64 |
repo_id: str = None,
|
65 |
-
model_dir: Path =
|
66 |
hf_model_filename: str = None,
|
67 |
revision: str = None
|
68 |
) -> Path:
|
@@ -88,6 +97,35 @@ def ensure_model_exists(
|
|
88 |
if revision is None:
|
89 |
revision = os.environ.get("MODEL_REVISION", "20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32")
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
model_path = model_dir / model_filename
|
92 |
|
93 |
# Log environment info when running in HF Space
|
@@ -119,6 +157,8 @@ def ensure_model_exists(
|
|
119 |
revision=revision # Specify the exact revision to use
|
120 |
)
|
121 |
|
|
|
|
|
122 |
# Rename if necessary
|
123 |
if os.path.basename(downloaded_path) != model_filename:
|
124 |
downloaded_path_obj = Path(downloaded_path)
|
@@ -135,8 +175,14 @@ def ensure_model_exists(
|
|
135 |
logger.info(f"Successfully downloaded model to {model_path}")
|
136 |
return model_path
|
137 |
except Exception as e:
|
138 |
-
logger.error(f"Failed to download model: {e}")
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
if __name__ == "__main__":
|
142 |
ensure_model_exists()
|
|
|
12 |
from pathlib import Path
|
13 |
import logging
|
14 |
|
15 |
+
# Configure logging
|
16 |
+
logging.basicConfig(
|
17 |
+
level=logging.INFO,
|
18 |
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
19 |
+
)
|
20 |
+
logger = logging.getLogger("model-downloader")
|
21 |
+
|
22 |
+
# Debug environment info
|
23 |
+
logger.info(f"Current working directory: {os.getcwd()}")
|
24 |
+
logger.info(f"Python path: {sys.path}")
|
25 |
+
logger.info(f"MODEL_REVISION: {os.environ.get('MODEL_REVISION')}")
|
26 |
+
logger.info(f"MODEL_HF_REPO: {os.environ.get('MODEL_HF_REPO')}")
|
27 |
+
logger.info(f"HF_MODEL_FILENAME: {os.environ.get('HF_MODEL_FILENAME')}")
|
28 |
+
|
29 |
# Use huggingface_hub for better integration with HF ecosystem
|
30 |
try:
|
31 |
from huggingface_hub import hf_hub_download
|
32 |
HF_HUB_AVAILABLE = True
|
33 |
+
logger.info("huggingface_hub is available")
|
34 |
except ImportError:
|
35 |
HF_HUB_AVAILABLE = False
|
36 |
+
logger.warning("huggingface_hub is not available, falling back to direct download")
|
37 |
import requests
|
38 |
from tqdm import tqdm
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
def download_file_with_progress(url: str, destination: Path) -> None:
|
41 |
"""Download a file with a progress bar.
|
42 |
|
|
|
71 |
def ensure_model_exists(
|
72 |
model_filename: str = "best_model_V3.h5",
|
73 |
repo_id: str = None,
|
74 |
+
model_dir: Path = None,
|
75 |
hf_model_filename: str = None,
|
76 |
revision: str = None
|
77 |
) -> Path:
|
|
|
97 |
if revision is None:
|
98 |
revision = os.environ.get("MODEL_REVISION", "20e66eb3d0788373c3bdc5b28fa2f2587b0e475f3bbc47e8ab9ff0dbdbb2df32")
|
99 |
|
100 |
+
# Handle model directory paths for different environments
|
101 |
+
if model_dir is None:
|
102 |
+
# Check if we're in HF Spaces
|
103 |
+
if os.environ.get("SPACE_ID"):
|
104 |
+
# Try several possible locations
|
105 |
+
possible_dirs = [
|
106 |
+
Path("models/CRNN"),
|
107 |
+
Path("/home/user/app/models/CRNN"),
|
108 |
+
Path("/app/models/CRNN"),
|
109 |
+
Path(os.getcwd()) / "models" / "CRNN"
|
110 |
+
]
|
111 |
+
|
112 |
+
for directory in possible_dirs:
|
113 |
+
if directory.exists() or directory.parent.exists():
|
114 |
+
model_dir = directory
|
115 |
+
break
|
116 |
+
|
117 |
+
# If none exist, use the first option and create it
|
118 |
+
if model_dir is None:
|
119 |
+
model_dir = possible_dirs[0]
|
120 |
+
else:
|
121 |
+
model_dir = Path("models/CRNN")
|
122 |
+
|
123 |
+
# Make sure model_dir is a Path object
|
124 |
+
if isinstance(model_dir, str):
|
125 |
+
model_dir = Path(model_dir)
|
126 |
+
|
127 |
+
logger.info(f"Using model directory: {model_dir}")
|
128 |
+
|
129 |
model_path = model_dir / model_filename
|
130 |
|
131 |
# Log environment info when running in HF Space
|
|
|
157 |
revision=revision # Specify the exact revision to use
|
158 |
)
|
159 |
|
160 |
+
logger.info(f"Downloaded to: {downloaded_path}")
|
161 |
+
|
162 |
# Rename if necessary
|
163 |
if os.path.basename(downloaded_path) != model_filename:
|
164 |
downloaded_path_obj = Path(downloaded_path)
|
|
|
175 |
logger.info(f"Successfully downloaded model to {model_path}")
|
176 |
return model_path
|
177 |
except Exception as e:
|
178 |
+
logger.error(f"Failed to download model: {e}", exc_info=True)
|
179 |
+
|
180 |
+
# Handle error more gracefully in production environment
|
181 |
+
if os.environ.get("SPACE_ID"):
|
182 |
+
logger.warning("Continuing despite model download failure")
|
183 |
+
return model_path
|
184 |
+
else:
|
185 |
+
sys.exit(1)
|
186 |
|
187 |
if __name__ == "__main__":
|
188 |
ensure_model_exists()
|