Upload 2 files
Browse files- Dockerfile +2 -27
- main.py +19 -36
Dockerfile
CHANGED
|
@@ -1,38 +1,13 @@
|
|
| 1 |
FROM python:3.10-slim
|
| 2 |
-
|
| 3 |
WORKDIR /app
|
| 4 |
|
| 5 |
-
# Copy project files into the image
|
| 6 |
COPY . /app
|
| 7 |
|
| 8 |
-
|
| 9 |
-
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 10 |
-
build-essential \
|
| 11 |
-
&& rm -rf /var/lib/apt/lists/*
|
| 12 |
|
| 13 |
-
|
| 14 |
-
# NOTE: websockets version is NOT pinned to 12.0 to avoid conflict with gradio_client
|
| 15 |
-
RUN pip install --no-cache-dir \
|
| 16 |
-
fastapi==0.104.1 \
|
| 17 |
-
uvicorn[standard]==0.24.0 \
|
| 18 |
-
pydantic==2.5.0 \
|
| 19 |
-
python-multipart==0.0.6 \
|
| 20 |
-
SQLAlchemy==2.0.23 \
|
| 21 |
-
APScheduler==3.10.4 \
|
| 22 |
-
aiohttp==3.9.1 \
|
| 23 |
-
requests==2.31.0 \
|
| 24 |
-
httpx \
|
| 25 |
-
python-dotenv==1.0.0 \
|
| 26 |
-
feedparser==6.0.11 \
|
| 27 |
-
gradio==4.14.0 \
|
| 28 |
-
pandas==2.1.4 \
|
| 29 |
-
plotly==5.18.0
|
| 30 |
|
| 31 |
-
# Expose the port that Hugging Face expects (7860 by default)
|
| 32 |
EXPOSE 7860
|
| 33 |
-
|
| 34 |
-
# For HF Spaces compatibility
|
| 35 |
ENV PORT=7860
|
| 36 |
|
| 37 |
-
# Main entrypoint: use main:app (FastAPI)
|
| 38 |
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--proxy-headers", "--forwarded-allow-ips", "*"]
|
|
|
|
| 1 |
FROM python:3.10-slim
|
|
|
|
| 2 |
WORKDIR /app
|
| 3 |
|
|
|
|
| 4 |
COPY . /app
|
| 5 |
|
| 6 |
+
RUN apt-get update && apt-get install -y --no-install-recommends build-essential && rm -rf /var/lib/apt/lists/*
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
+
RUN pip install --no-cache-dir fastapi==0.104.1 uvicorn[standard]==0.24.0 pydantic==2.5.0 python-multipart==0.0.6 SQLAlchemy==2.0.23 APScheduler==3.10.4 aiohttp==3.9.1 requests==2.31.0 httpx python-dotenv==1.0.0 feedparser==6.0.11 gradio==4.14.0 pandas==2.1.4 plotly==5.18.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
|
|
|
| 10 |
EXPOSE 7860
|
|
|
|
|
|
|
| 11 |
ENV PORT=7860
|
| 12 |
|
|
|
|
| 13 |
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--proxy-headers", "--forwarded-allow-ips", "*"]
|
main.py
CHANGED
|
@@ -1,38 +1,21 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
-
|
| 9 |
-
from typing import Any
|
| 10 |
-
|
| 11 |
-
def _try_import(path: str) -> Any:
|
| 12 |
-
try:
|
| 13 |
-
module = import_module(path)
|
| 14 |
-
except Exception:
|
| 15 |
-
return None
|
| 16 |
-
return getattr(module, "app", None)
|
| 17 |
-
|
| 18 |
-
# Candidate modules (ordered)
|
| 19 |
-
_CANDIDATES = [
|
| 20 |
-
"app", # root app.py OR app/__init__.py exposes `app`
|
| 21 |
-
"app.app", # app/app.py -> app
|
| 22 |
-
"app.main", # app/main.py -> app
|
| 23 |
-
"backend.app", # backend/app.py -> app
|
| 24 |
-
"backend.main", # backend/main.py -> app
|
| 25 |
-
]
|
| 26 |
-
|
| 27 |
-
app = None
|
| 28 |
-
for candidate in _CANDIDATES:
|
| 29 |
-
app_candidate = _try_import(candidate)
|
| 30 |
-
if app_candidate is not None:
|
| 31 |
-
app = app_candidate
|
| 32 |
-
break
|
| 33 |
-
|
| 34 |
-
if app is None:
|
| 35 |
-
raise RuntimeError(
|
| 36 |
-
"Could not locate FastAPI `app` instance. "
|
| 37 |
-
"Tried modules: " + ", ".join(_CANDIDATES)
|
| 38 |
-
)
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
import importlib.util
|
| 3 |
+
from fastapi import FastAPI
|
| 4 |
|
| 5 |
+
def load_fastapi_app() -> FastAPI:
|
| 6 |
+
root = Path(__file__).resolve().parent
|
| 7 |
+
app_file = root / "app.py"
|
| 8 |
+
if not app_file.exists():
|
| 9 |
+
raise RuntimeError("app.py not found in project root; expected FastAPI app instance in app.py")
|
| 10 |
+
spec = importlib.util.spec_from_file_location("root_app_module", app_file)
|
| 11 |
+
module = importlib.util.module_from_spec(spec) # type: ignore[arg-type]
|
| 12 |
+
assert spec.loader is not None
|
| 13 |
+
spec.loader.exec_module(module) # type: ignore[call-arg]
|
| 14 |
+
if not hasattr(module, "app"):
|
| 15 |
+
raise RuntimeError("FastAPI instance `app` not found in app.py")
|
| 16 |
+
fastapi_app = getattr(module, "app")
|
| 17 |
+
if not isinstance(fastapi_app, FastAPI):
|
| 18 |
+
raise RuntimeError("`app` in app.py is not a FastAPI instance")
|
| 19 |
+
return fastapi_app
|
| 20 |
|
| 21 |
+
app = load_fastapi_app()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|