Skip to content
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

Feat: multiple endpoints using a list of LitServer #276

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1ec0782
Adds initial function definition
bhimrazy Sep 11, 2024
88b6b2f
adds run all method
bhimrazy Sep 12, 2024
30d2c35
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 12, 2024
266b271
adding a test for multi endpoint servers
bhimrazy Sep 12, 2024
3cf17a0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 12, 2024
f4b4715
fixes multi client generation
bhimrazy Sep 12, 2024
ab90959
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 12, 2024
e3ee2b9
testing mounting of apps
bhimrazy Sep 13, 2024
e1865df
mounted on root
bhimrazy Sep 13, 2024
faea18a
Merge branch 'main' into feat/multi-endpoints
bhimrazy Sep 14, 2024
49865f2
Refactor run_all function to support multiple LitServers
bhimrazy Sep 15, 2024
368f91c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 15, 2024
885ab06
adds test for the manage_lifespan
bhimrazy Sep 15, 2024
7ba3ab7
ref: format imports
bhimrazy Sep 15, 2024
fe8f82c
Merge branch 'feat/multi-endpoints' of github.com:bhimrazy/LitServe i…
bhimrazy Sep 15, 2024
d7cb562
removed the extra test file
bhimrazy Sep 15, 2024
d502af4
adds simple server with multi endpoints
bhimrazy Sep 15, 2024
17a37cc
adds e2e test for multi endpoints
bhimrazy Sep 15, 2024
452a509
Refactor run_all function to remove unnecessary check for empty litse…
bhimrazy Sep 15, 2024
391cefd
adds test to runnall litservers
bhimrazy Sep 15, 2024
ea0ac77
Refactor test_e2e_with_multi_endpoints function name
bhimrazy Sep 15, 2024
b82733e
Refactor test_e2e_with_multi_endpoints function name
bhimrazy Sep 15, 2024
f8491a1
update tests to include more litservers
bhimrazy Sep 15, 2024
ec46b14
Merge branch 'main' into feat/multi-endpoints
bhimrazy Sep 17, 2024
e061c88
Refactor manage_lifespan to multi_server_lifespan
bhimrazy Sep 17, 2024
1de6935
Refactor test multi_server_lifespan
bhimrazy Sep 17, 2024
0697222
refactor classnames
bhimrazy Sep 17, 2024
4ac180d
Refactor test_e2e_combined_multiple_litserver to use multiple_litserv…
bhimrazy Sep 17, 2024
3e9dc6e
adds default queue id for the main app
bhimrazy Sep 17, 2024
def24f8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 17, 2024
d19e1ae
rm num api server
bhimrazy Sep 17, 2024
3705505
Update server.py
aniketmaurya Sep 17, 2024
fa8dd7d
fix
aniketmaurya Sep 17, 2024
724d80b
Refactor server.py to use 'servers' instead of 'litservers' for consi…
bhimrazy Sep 17, 2024
2ac6388
added more test cases to increase the coverage
bhimrazy Sep 17, 2024
a09f540
updated test
bhimrazy Sep 17, 2024
e5db967
Refactor server.py to use 'servers' instead of 'litservers' for consi…
bhimrazy Sep 18, 2024
efb838c
Merge branch 'main' into feat/multi-endpoints
bhimrazy Sep 18, 2024
33e3b12
update
bhimrazy Sep 18, 2024
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
67 changes: 66 additions & 1 deletion src/litserve/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from concurrent.futures import ThreadPoolExecutor
from contextlib import asynccontextmanager
from queue import Empty
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
from typing import Callable, Dict, List, Optional, Sequence, Tuple, Union

import uvicorn
from fastapi import Depends, FastAPI, HTTPException, Request, Response
Expand Down Expand Up @@ -472,3 +472,68 @@ def setup_auth(self):
if LIT_SERVER_API_KEY:
return api_key_auth
return no_auth


def run_all(
servers: List[LitServer],
port: Union[str, int] = 8000,
num_api_servers: Optional[int] = None,
log_level: str = "info",
generate_client_file: bool = True,
api_server_worker_type: Optional[str] = None,
**kwargs,
):
"""Run multiple LitServers on the same port."""
if not servers:
raise ValueError("No servers provided to run_all")

if any(not isinstance(server, LitServer) for server in servers):
raise ValueError("All elements in the servers list must be instances of LitServer")

if generate_client_file:
for server in servers:
server.generate_client_file()
bhimrazy marked this conversation as resolved.
Show resolved Hide resolved

port_msg = f"port must be a value from 1024 to 65535 but got {port}"
try:
port = int(port)
except ValueError:
raise ValueError(port_msg)
if not (1024 <= port <= 65535):
raise ValueError(port_msg)

if num_api_servers is None:
num_api_servers = sum(len(server.workers) for server in servers)
if num_api_servers < 1:
raise ValueError("num_api_servers must be greater than 0")

if sys.platform == "win32":
print("Windows does not support forking. Using threads api_server_worker_type will be set to 'thread'")
api_server_worker_type = "thread"
elif api_server_worker_type is None:
api_server_worker_type = "process"

app = servers[0].app
config = uvicorn.Config(app=app, host="0.0.0.0", port=port, log_level=log_level, **kwargs)
sockets = [config.bind_socket()]

managers, all_workers = [], []
try:
all_servers = []
for server in servers:
manager, litserve_workers = server.launch_inference_worker(num_api_servers)
managers.append(manager)
all_workers.extend(litserve_workers)

_servers = server._start_server(port, num_api_servers, log_level, sockets, api_server_worker_type, **kwargs)
all_servers.extend(_servers)
print(f"Swagger UI is available at http://0.0.0.0:{port}/docs")
for s in all_servers:
s.join()
finally:
bhimrazy marked this conversation as resolved.
Show resolved Hide resolved
print("Shutting down LitServe")
for w in all_workers:
w.terminate()
w.join()
for manager in managers:
manager.shutdown()
28 changes: 28 additions & 0 deletions tests/test_lit_server_multi_endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@


from litserve.server import LitServer


async def test_lit_server_with_multi_endpoints(simple_litapi):
server1 = LitServer(simple_litapi, api_path="/predict-1", timeout=10)
server2 = LitServer(simple_litapi, api_path="/predict-2", timeout=10)
servers = [server1, server2]
# TODO: update test to use run_all

# Run the servers in a separate thread
port = 8000
# server_thread = threading.Thread(
# target=run_all, args=(servers,), kwargs={"port": port, "num_api_servers": 2, "log_level": "debug"}
# )
# server_thread.start()

# async with AsyncClient(base_url=f"http://localhost:{port}") as client:
# # Test server1 endpoint
# response1 = await client.post("/predict-1", json={"input": 1})
# assert response1.status_code == 200
# assert response1.json() == {"output": 1}

# # Test server2 endpoint
# response2 = await client.post("/predict-2", json={"input": 2})
# assert response2.status_code == 200
# assert response2.json() == {"output": 2}
Loading