Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lightly_studio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ start-e2e: build
@echo "Starting server for e2e tests..."
uv run e2e-tests/index_dataset_for_end2end_ui_tests.py

.PHONY: start-coco-10k
start-coco-10k: build
@echo "Starting server for e2e tests with COCO 10k dataset..."
uv run e2e-tests/index_coco_10k.py

.PHONY: start-e2e-with-captions
start-e2e-with-captions: build
@echo "Starting server for e2e tests with captions..."
Expand Down
25 changes: 25 additions & 0 deletions lightly_studio/e2e-tests/index_coco_10k.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""End-to-end demonstration of the lightly_studio dataset loading and UI.
This module provides a simple example of how to load a COCO instance
segmentation dataset and launch the UI application for exploration and
visualization.
"""

from lightly_studio import AnnotationType, Dataset, db_manager, start_gui

# Clean up an existing database
db_manager.connect(cleanup_existing=True)

# Create a Dataset instance
dataset = Dataset.create()

# We point to the annotations json file and the input images folder.
# Defined dataset is processed here to be available for the UI application.
dataset.add_samples_from_coco(
annotations_json="datasets/coco-10k/annotations/instances_train2017.json",
images_path="datasets/coco-10k/images",
annotation_type=AnnotationType.INSTANCE_SEGMENTATION,
)

# We start the UI application on port 8001
start_gui()
15 changes: 13 additions & 2 deletions lightly_studio/src/lightly_studio/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,19 @@ def __init__(self, host: str, port: int) -> None:

def start(self) -> None:
"""Start the API server using Uvicorn."""
# start the app
uvicorn.run(app, host=self.host, port=self.port, http="h11")
# start the app with connection limits and timeouts
uvicorn.run(
app,
host=self.host,
port=self.port,
http="h11",
# https://uvicorn.dev/settings/#resource-limits
limit_concurrency=1000, # Max concurrent connections
limit_max_requests=10000, # Max requests before worker restart
# https://uvicorn.dev/settings/#timeouts
timeout_keep_alive=5, # Keep-alive timeout in seconds
timeout_graceful_shutdown=30, # Graceful shutdown timeout
)


def _get_available_port(host: str, preferred_port: int, max_tries: int = 50) -> int:
Expand Down
9 changes: 8 additions & 1 deletion lightly_studio/src/lightly_studio/db_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ def __init__(
self._engine_url = engine_url if engine_url else "duckdb:///lightly_studio.db"
if cleanup_existing:
_cleanup_database_file(engine_url=self._engine_url)
self._engine = create_engine(url=self._engine_url, poolclass=poolclass)
# Total available connections = pool_size + max_overflow = 20 + 40 = 60
# (default is (pool_size=5, max_overflow=10))
self._engine = create_engine(
url=self._engine_url,
poolclass=poolclass,
pool_size=20,
max_overflow=40,
)
SQLModel.metadata.create_all(self._engine)

@contextmanager
Expand Down
Loading