-
Notifications
You must be signed in to change notification settings - Fork 846
π¦ feat(inspect): Add docker build #3136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/geti-inspect
Are you sure you want to change the base?
Changes from all commits
5bdd704
918ba83
82dd6b0
1588d72
22f8f8f
978a895
cbb0a46
644f594
072ef38
0614756
e07a955
61d2481
e04ef66
3489422
4e160a1
7437855
590ece3
d9a613d
6d51c68
1baa2eb
0a2af70
8f1ef19
f0339cd
237731d
2a4f257
7653915
f0a7643
df8eb42
9fc19c1
3a446de
a2df1cb
dc08cf0
b84f44c
d63f53d
fed89a3
390f97f
f6ae55f
3da55dd
42c5541
4339b78
931af9c
cdeeaff
6ddb323
be6fe07
31c3d2f
701aca5
6bf1e55
71ca2c1
1d14bf1
dace0f0
cf91762
9096eb7
87a1efe
19a3461
64fe8ea
32f527a
1d7b9c7
1a08bee
22aa6df
5008712
0500abf
48365ba
ab12f0e
12fa1a4
e8476dc
0202e60
80e459a
bdad999
0b08527
8adc3a1
0773110
9990aca
5cb2bc6
a9c5f70
09d9f27
40c5e5a
4d09a21
0a232b8
c7ebce5
ef63ed2
f0ef85b
c0d3c78
438a499
70f05fa
39209fc
5cf0ad6
83a7c16
85d4860
54501fb
5d3a63c
bdac68a
3af24ca
0e450d1
86e137a
0740a18
be206fe
9ae1a10
bada298
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| # Git | ||
| .git | ||
| .gitignore | ||
| .gitattributes | ||
|
|
||
| # Python | ||
| __pycache__/ | ||
| *.py[cod] | ||
| *$py.class | ||
| *.so | ||
| .Python | ||
| build/ | ||
| develop-eggs/ | ||
| dist/ | ||
| downloads/ | ||
| eggs/ | ||
| .eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
| var/ | ||
| wheels/ | ||
| *.egg-info/ | ||
| .installed.cfg | ||
| *.egg | ||
| .pytest_cache/ | ||
| .coverage | ||
| htmlcov/ | ||
| .tox/ | ||
| .nox/ | ||
| .hypothesis/ | ||
|
|
||
| # Virtual environments | ||
| venv/ | ||
| env/ | ||
| ENV/ | ||
| .venv | ||
|
|
||
| # IDEs | ||
| .vscode/ | ||
| .idea/ | ||
| *.swp | ||
| *.swo | ||
| *~ | ||
| .DS_Store | ||
|
|
||
| # Node | ||
| node_modules/ | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
|
|
||
| # Application data (will be mounted as volumes) | ||
| application/backend/data/** | ||
| application/backend/logs/** | ||
| application/backend/openvino_cache/** | ||
| application/backend/tests/** | ||
| application/backend/**/__pycache__/** | ||
| application/backend/.*_cache/** | ||
| application/backend/.tmp/** | ||
| application/backend/.venv/** | ||
| application/ui/dist/ | ||
| application/ui/build/ | ||
| application/ui/node_modules/ | ||
| data/ | ||
|
|
||
| # Documentation and examples | ||
| docs/ | ||
| examples/ | ||
| *.md | ||
| !README.md | ||
|
|
||
| # CI/CD | ||
| .github/ | ||
| .gitlab-ci.yml | ||
| .travis.yml | ||
|
|
||
| # Testing | ||
| tests/ | ||
| *.test.js | ||
| *.spec.js | ||
| coverage/ | ||
|
|
||
| # Temporary files | ||
| tmp/ | ||
| temp/ | ||
| *.tmp | ||
| *.log | ||
|
|
||
| # Datasets and model artifacts | ||
| datasets/ | ||
| pre_trained/ | ||
| results/ | ||
| openvino_cache/ | ||
|
|
||
| # Experiment tracking and logs | ||
| wandb/ | ||
| lightning_logs/ | ||
| mlruns/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -176,3 +176,7 @@ docs/source/_build/ | |
| wandb/ | ||
| lightning_logs/ | ||
| mlruns | ||
|
|
||
| # application data | ||
| data/ | ||
| logs/ | ||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||||||
| # Copyright (C) 2025 Intel Corporation | ||||||||||||
| # SPDX-License-Identifier: Apache-2.0 | ||||||||||||
|
|
||||||||||||
| from pathlib import Path | ||||||||||||
|
|
||||||||||||
| from fastapi import APIRouter, HTTPException | ||||||||||||
| from fastapi.responses import FileResponse | ||||||||||||
|
|
||||||||||||
| from settings import get_settings | ||||||||||||
|
|
||||||||||||
| settings = get_settings() | ||||||||||||
| webui_router = APIRouter(tags=["Webui"]) | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| @webui_router.get("/", include_in_schema=False) | ||||||||||||
| async def get_webui(full_path: str = "") -> FileResponse: # noqa: ARG001 | ||||||||||||
| """Get the webui index.html file.""" | ||||||||||||
| if settings.static_files_dir and not (file_path := Path(settings.static_files_dir) / "index.html").exists(): | ||||||||||||
|
||||||||||||
| if settings.static_files_dir and not (file_path := Path(settings.static_files_dir) / "index.html").exists(): | |
| if not settings.static_files_dir: | |
| raise HTTPException(status_code=500, detail="Static files directory is not configured") | |
| file_path = Path(settings.static_files_dir) / "index.html" | |
| if not file_path.exists(): |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,12 @@ | |
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import os | ||
| from pathlib import Path | ||
|
|
||
| import uvicorn | ||
| from fastapi import FastAPI | ||
| from fastapi.middleware.cors import CORSMiddleware | ||
| from fastapi.staticfiles import StaticFiles | ||
|
|
||
| from api.endpoints.active_pipeline_endpoints import router as active_pipeline_router | ||
| from api.endpoints.capture_endpoints import router as capture_router | ||
|
|
@@ -20,6 +22,7 @@ | |
| from api.endpoints.source_endpoints import router as source_router | ||
| from api.endpoints.trainable_models_endpoints import router as trainable_model_router | ||
| from api.endpoints.webrtc import router as webrtc_router | ||
| from api.endpoints.webui_endpoints import webui_router | ||
| from core.lifecycle import lifespan | ||
| from settings import get_settings | ||
|
|
||
|
|
@@ -34,15 +37,11 @@ | |
|
|
||
| _ = exception_handlers # to avoid import being removed by linters | ||
|
|
||
| # TODO: check if middleware is required | ||
| # Enable CORS for local test UI | ||
| app.add_middleware( | ||
| CORSMiddleware, | ||
| allow_origins=[ | ||
| "http://localhost:3000", | ||
| "http://localhost:9000", | ||
| "http://127.0.0.1:9000", | ||
| ], | ||
| allow_origins=["*"], | ||
ashwinvaidya17 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| allow_credentials=True, | ||
| allow_methods=["*"], | ||
| allow_headers=["*"], | ||
|
|
@@ -61,8 +60,24 @@ | |
| app.include_router(capture_router) | ||
| app.include_router(snapshot_router) | ||
|
|
||
| settings = get_settings() | ||
|
|
||
| if __name__ == "__main__": | ||
| settings = get_settings() | ||
| # In docker deployment, the UI is built and served statically | ||
| if ( | ||
| settings.static_files_dir | ||
| and Path(settings.static_files_dir).is_dir() | ||
| and (Path(settings.static_files_dir) / "index.html").exists() | ||
| ): | ||
| static_dir = Path(settings.static_files_dir) | ||
| app.mount("/static", StaticFiles(directory=static_dir / "static"), name="static") | ||
| app.include_router(webui_router) | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Main function to run the Geti Inspect server""" | ||
| uvicorn_port = int(os.environ.get("HTTP_SERVER_PORT", settings.port)) | ||
| uvicorn.run("main:app", loop="uvloop", host=settings.host, port=uvicorn_port, log_config=None) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,9 @@ | |
| from pydantic import Field | ||
| from pydantic_settings import BaseSettings, SettingsConfigDict | ||
|
|
||
| # Get the directory where this settings module is located | ||
| _MODULE_DIR = Path(__file__).parent | ||
|
|
||
|
|
||
| class Settings(BaseSettings): | ||
| """Application settings with environment variable support""" | ||
|
|
@@ -26,6 +29,7 @@ class Settings(BaseSettings): | |
| environment: Literal["dev", "prod"] = "dev" | ||
| data_dir: Path = Field(default=Path("data"), alias="DATA_DIR") | ||
| log_dir: Path = Field(default=Path("logs"), alias="LOG_DIR") | ||
| static_files_dir: str | None = Field(default=None, alias="STATIC_FILES_DIR") | ||
|
|
||
| # Server | ||
| host: str = Field(default="0.0.0.0", alias="HOST") # noqa: S104 | ||
|
|
@@ -36,16 +40,16 @@ class Settings(BaseSettings): | |
| db_echo: bool = Field(default=False, alias="DB_ECHO") | ||
|
|
||
| # Alembic | ||
| alembic_config_path: str = "src/alembic.ini" | ||
| alembic_script_location: str = "src/alembic" | ||
| alembic_config_path: str = str(_MODULE_DIR / "alembic.ini") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be adjusted further when we introduce Pyinstaller |
||
| alembic_script_location: str = str(_MODULE_DIR / "alembic") | ||
|
|
||
| # Proxy settings | ||
| no_proxy: str = Field(default="localhost,127.0.0.1,::1", alias="no_proxy") | ||
|
|
||
| @property | ||
| def database_url(self) -> str: | ||
| """Get database URL""" | ||
| return f"sqlite+aiosqlite:///./{self.data_dir / self.database_file}?journal_mode=WAL" | ||
| return f"sqlite+aiosqlite:///{self.data_dir / self.database_file}?journal_mode=WAL" | ||
|
|
||
| @property | ||
| def sync_database_url(self) -> str: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function parameter
full_pathis declared but never used, and there's no logic to prevent potential path traversal attacks or handle different routes. If this endpoint is meant to handle multiple paths, the implementation should usefull_pathto serve the appropriate files. If it only serves index.html, the parameter should be removed.