Skip to content

Commit e5e53da

Browse files
bump linting to min python version py3.9 (#597)
* bump linting to min python version py3.9 * fixing --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 3a2410c commit e5e53da

32 files changed

+396
-318
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ repos:
4747
- repo: https://github.com/astral-sh/ruff-pre-commit
4848
rev: v0.12.2
4949
hooks:
50-
- id: ruff-format
51-
args: ["--preview"]
5250
- id: ruff
5351
args: ["--fix"]
52+
- id: ruff-format
53+
- id: ruff-check

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ blank = true
110110

111111
[tool.ruff]
112112
line-length = 120
113-
target-version = "py38"
113+
target-version = "py39"
114114
# Enable Pyflakes `E` and `F` codes by default.
115115
lint.select = [
116116
"E", "W", # see: https://pypi.org/project/pycodestyle

src/litserve/callbacks/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
from abc import ABC
33
from enum import Enum
4-
from typing import List, Union
4+
from typing import Union
55

66
logger = logging.getLogger(__name__)
77

@@ -62,12 +62,12 @@ def on_response(self, *args, **kwargs):
6262

6363

6464
class CallbackRunner:
65-
def __init__(self, callbacks: Union[Callback, List[Callback]] = None):
65+
def __init__(self, callbacks: Union[Callback, list[Callback]] = None):
6666
self._callbacks = []
6767
if callbacks:
6868
self._add_callbacks(callbacks)
6969

70-
def _add_callbacks(self, callbacks: Union[Callback, List[Callback]]):
70+
def _add_callbacks(self, callbacks: Union[Callback, list[Callback]]):
7171
if not isinstance(callbacks, list):
7272
callbacks = [callbacks]
7373
for callback in callbacks:

src/litserve/connector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
import subprocess
1717
import sys
1818
from functools import lru_cache
19-
from typing import List, Optional, Union
19+
from typing import Optional, Union
2020

2121

2222
class _Connector:
23-
def __init__(self, accelerator: str = "auto", devices: Union[List[int], int, str] = "auto"):
23+
def __init__(self, accelerator: str = "auto", devices: Union[list[int], int, str] = "auto"):
2424
accelerator = self._sanitize_accelerator(accelerator)
2525
if accelerator in ("cpu", "cuda", "mps"):
2626
self._accelerator = accelerator

src/litserve/loggers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import multiprocessing as mp
1717
import pickle
1818
from abc import ABC, abstractmethod
19-
from typing import TYPE_CHECKING, List, Optional, Union
19+
from typing import TYPE_CHECKING, Optional, Union
2020

2121
from starlette.types import ASGIApp
2222

@@ -93,7 +93,7 @@ class _LoggerConnector:
9393
9494
"""
9595

96-
def __init__(self, lit_server: "LitServer", loggers: Optional[Union[List[Logger], Logger]] = None):
96+
def __init__(self, lit_server: "LitServer", loggers: Optional[Union[list[Logger], Logger]] = None):
9797
self._loggers = []
9898
self._lit_server = lit_server
9999
if loggers is None:
@@ -126,7 +126,7 @@ def _is_picklable(obj):
126126
return False
127127

128128
@staticmethod
129-
def _process_logger_queue(logger_proxies: List[_LoggerProxy], queue):
129+
def _process_logger_queue(logger_proxies: list[_LoggerProxy], queue):
130130
loggers = [proxy if isinstance(proxy, Logger) else proxy.create_logger() for proxy in logger_proxies]
131131
while True:
132132
key, value = queue.get()

src/litserve/loops/base.py

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import time
2222
from abc import ABC
2323
from queue import Empty, Queue
24-
from typing import Any, Dict, List, Optional, Tuple, Union
24+
from typing import Any, Optional, Union
2525

2626
from starlette.formparsers import MultiPartParser
2727

@@ -41,7 +41,7 @@
4141
_SENTINEL_VALUE = (None, None, None, None)
4242

4343

44-
def _inject_context(context: Union[List[dict], dict], func, *args, **kwargs):
44+
def _inject_context(context: Union[list[dict], dict], func, *args, **kwargs):
4545
sig = inspect.signature(func)
4646
if "context" in sig.parameters:
4747
return func(*args, **kwargs, context=context)
@@ -80,7 +80,7 @@ async def _handle_async_function(func, *args, **kwargs):
8080
return result
8181

8282

83-
async def _async_inject_context(context: Union[List[dict], dict], func, *args, **kwargs):
83+
async def _async_inject_context(context: Union[list[dict], dict], func, *args, **kwargs):
8484
sig = inspect.signature(func)
8585

8686
# Determine if we need to inject context
@@ -99,7 +99,7 @@ def __init__(self, message: str = _DEFAULT_STOP_LOOP_MESSAGE):
9999
def collate_requests(
100100
lit_api: LitAPI,
101101
request_queue: Queue,
102-
) -> Tuple[List, List]:
102+
) -> tuple[list, list]:
103103
payloads = []
104104
timed_out_uids = []
105105
entered_at = time.monotonic()
@@ -170,9 +170,9 @@ def run(
170170
device: str,
171171
worker_id: int,
172172
request_queue: Queue,
173-
response_queues: List[Queue],
173+
response_queues: list[Queue],
174174
stream: bool,
175-
workers_setup_status: Dict[int, str],
175+
workers_setup_status: dict[int, str],
176176
callback_runner: CallbackRunner,
177177
):
178178
item = request_queue.get()
@@ -198,7 +198,7 @@ async def schedule_task(
198198
lit_api: LitAPI,
199199
lit_spec: Optional[LitSpec],
200200
request_queue: Queue,
201-
response_queues: List[Queue],
201+
response_queues: list[Queue],
202202
):
203203
pass
204204

@@ -209,7 +209,7 @@ def __call__(
209209
worker_id: int,
210210
request_queue: Queue,
211211
transport: MessageTransport,
212-
workers_setup_status: Dict[int, str],
212+
workers_setup_status: dict[int, str],
213213
callback_runner: CallbackRunner,
214214
):
215215
lit_spec = lit_api.spec
@@ -255,7 +255,7 @@ def run(
255255
worker_id: int,
256256
request_queue: Queue,
257257
transport: MessageTransport,
258-
workers_setup_status: Dict[int, str],
258+
workers_setup_status: dict[int, str],
259259
callback_runner: CallbackRunner,
260260
):
261261
raise NotImplementedError
@@ -279,7 +279,7 @@ def get_batch_requests(
279279
self,
280280
lit_api: LitAPI,
281281
request_queue: Queue,
282-
) -> Tuple[List, List]:
282+
) -> tuple[list, list]:
283283
batches, timed_out_uids = collate_requests(
284284
lit_api,
285285
request_queue,
@@ -330,10 +330,13 @@ def pre_setup(self, lit_api: LitAPI, spec: Optional[LitSpec] = None):
330330
return
331331

332332
original = lit_api.unbatch.__code__ is LitAPI.unbatch.__code__
333-
if not lit_api.stream and any([
334-
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
335-
inspect.isgeneratorfunction(lit_api.encode_response) or inspect.isasyncgenfunction(lit_api.encode_response),
336-
]):
333+
if not lit_api.stream and any(
334+
[
335+
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
336+
inspect.isgeneratorfunction(lit_api.encode_response)
337+
or inspect.isasyncgenfunction(lit_api.encode_response),
338+
]
339+
):
337340
raise ValueError(
338341
"""When `stream=False`, `lit_api.predict`, `lit_api.encode_response` must not be
339342
generator or async generator functions.
@@ -366,16 +369,18 @@ async def predict(self, inputs):
366369
if (
367370
lit_api.stream
368371
and lit_api.max_batch_size > 1
369-
and not all([
370-
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
371-
inspect.isgeneratorfunction(lit_api.encode_response)
372-
or inspect.isasyncgenfunction(lit_api.encode_response),
373-
(
374-
original
375-
or inspect.isgeneratorfunction(lit_api.unbatch)
376-
or inspect.isasyncgenfunction(lit_api.unbatch)
377-
),
378-
])
372+
and not all(
373+
[
374+
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
375+
inspect.isgeneratorfunction(lit_api.encode_response)
376+
or inspect.isasyncgenfunction(lit_api.encode_response),
377+
(
378+
original
379+
or inspect.isgeneratorfunction(lit_api.unbatch)
380+
or inspect.isasyncgenfunction(lit_api.unbatch)
381+
),
382+
]
383+
)
379384
):
380385
raise ValueError(
381386
"""When `stream=True` with max_batch_size > 1, `lit_api.predict`, `lit_api.encode_response` and
@@ -407,10 +412,13 @@ async def predict(self, inputs):
407412
"""
408413
)
409414

410-
if lit_api.stream and not all([
411-
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
412-
inspect.isgeneratorfunction(lit_api.encode_response) or inspect.isasyncgenfunction(lit_api.encode_response),
413-
]):
415+
if lit_api.stream and not all(
416+
[
417+
inspect.isgeneratorfunction(lit_api.predict) or inspect.isasyncgenfunction(lit_api.predict),
418+
inspect.isgeneratorfunction(lit_api.encode_response)
419+
or inspect.isasyncgenfunction(lit_api.encode_response),
420+
]
421+
):
414422
raise ValueError(
415423
"""When `stream=True` both `lit_api.predict` and
416424
`lit_api.encode_response` must generate values using `yield` (can be regular or async generators).

src/litserve/loops/continuous_batching_loop.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import logging
1616
from dataclasses import dataclass
1717
from queue import Queue
18-
from typing import Any, Dict, List, Optional, Tuple
18+
from typing import Any, Optional
1919

2020
from fastapi import HTTPException
2121

@@ -30,15 +30,17 @@
3030

3131

3232
def notify_timed_out_requests(
33-
response_queues: List[Queue],
34-
timed_out_uids: List[Tuple[int, str]],
33+
response_queues: list[Queue],
34+
timed_out_uids: list[tuple[int, str]],
3535
):
3636
for response_queue_id, uid in timed_out_uids:
3737
logger.error(f"Request {uid} was waiting in the queue for too long and has been timed out.")
38-
response_queues[response_queue_id].put((
39-
uid,
40-
(HTTPException(504, "Request timed out"), LitAPIStatus.ERROR, LoopResponseType.STREAMING),
41-
))
38+
response_queues[response_queue_id].put(
39+
(
40+
uid,
41+
(HTTPException(504, "Request timed out"), LitAPIStatus.ERROR, LoopResponseType.STREAMING),
42+
)
43+
)
4244

4345

4446
@dataclass
@@ -67,9 +69,9 @@ def __init__(self, max_sequence_length: int = 2048):
6769
6870
"""
6971
super().__init__()
70-
self.active_sequences: Dict[str, Dict] = {} # uid -> {input, current_length, generated_sequence}
72+
self.active_sequences: dict[str, dict] = {} # uid -> {input, current_length, generated_sequence}
7173
self.max_sequence_length = max_sequence_length
72-
self.response_queue_ids: Dict[str, int] = {} # uid -> response_queue_id
74+
self.response_queue_ids: dict[str, int] = {} # uid -> response_queue_id
7375

7476
def pre_setup(self, lit_api: LitAPI, spec: Optional[LitSpec] = None):
7577
"""Check if the lit_api has the necessary methods and if streaming is enabled."""
@@ -119,14 +121,14 @@ def has_capacity(self, lit_api: LitAPI) -> bool:
119121

120122
async def prefill(
121123
self,
122-
pending_requests: List[Tuple[str, Any]],
124+
pending_requests: list[tuple[str, Any]],
123125
lit_api: LitAPI,
124126
lit_spec: Optional[LitSpec],
125127
request_queue: Queue,
126-
response_queues: List[Queue] = None,
128+
response_queues: list[Queue] = None,
127129
max_batch_size: Optional[int] = None,
128130
batch_timeout: Optional[float] = None,
129-
) -> List[Tuple[str, Any]]:
131+
) -> list[tuple[str, Any]]:
130132
"""Fill available capacity with pending and new requests."""
131133
# First process existing pending requests
132134
while pending_requests and self.has_capacity(lit_api):
@@ -154,7 +156,7 @@ async def schedule_task(
154156
lit_api: LitAPI,
155157
lit_spec: Optional[LitSpec],
156158
request_queue: Queue,
157-
response_queues: List[Queue],
159+
response_queues: list[Queue],
158160
):
159161
logger.info("Running prefill in background")
160162
try:
@@ -176,8 +178,8 @@ async def schedule_task(
176178
logger.info("Exiting run_in_background in continuous_batching_loop")
177179

178180
async def step(
179-
self, prev_outputs: Optional[List[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]
180-
) -> List[Output]:
181+
self, prev_outputs: Optional[list[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]
182+
) -> list[Output]:
181183
return await asyncio.to_thread(lit_api.step, prev_outputs)
182184

183185
async def run(
@@ -187,7 +189,7 @@ async def run(
187189
worker_id: int,
188190
request_queue: Queue,
189191
transport: MessageTransport,
190-
workers_setup_status: Dict[int, str],
192+
workers_setup_status: dict[int, str],
191193
callback_runner: CallbackRunner,
192194
):
193195
"""Main loop that processes batches of requests."""
@@ -243,8 +245,8 @@ def add_request(self, uid: str, request: Any, lit_api: LitAPI, lit_spec: Optiona
243245
self.active_sequences[uid] = {"input": decoded_request, "current_length": 0, "generated_sequence": []}
244246

245247
async def step(
246-
self, prev_outputs: Optional[List[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]
247-
) -> List[Output]:
248+
self, prev_outputs: Optional[list[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]
249+
) -> list[Output]:
248250
"""Process one token generation step for all active sequences."""
249251
if not self.active_sequences:
250252
return []
@@ -255,9 +257,9 @@ async def step(
255257

256258
try:
257259
# Assume lit_api.predict handles batched token generation
258-
new_tokens: List[Any] = lit_api.predict(inputs, generated)
260+
new_tokens: list[Any] = lit_api.predict(inputs, generated)
259261

260-
responses: List[Output] = []
262+
responses: list[Output] = []
261263

262264
# Process each sequence's new token
263265
for uid, token in zip(self.active_sequences.keys(), new_tokens):

src/litserve/loops/loops.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414
import logging
1515
from queue import Queue
16-
from typing import Dict
1716

1817
from litserve import LitAPI
1918
from litserve.callbacks import CallbackRunner, EventTypes
@@ -64,7 +63,7 @@ def inference_worker(
6463
worker_id: int,
6564
request_queue: Queue,
6665
transport: MessageTransport,
67-
workers_setup_status: Dict[int, str],
66+
workers_setup_status: dict[int, str],
6867
callback_runner: CallbackRunner,
6968
):
7069
lit_spec = lit_api.spec

src/litserve/loops/simple_loops.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import logging
1616
import time
1717
from queue import Empty, Queue
18-
from typing import Dict, Optional
18+
from typing import Optional
1919

2020
from fastapi import HTTPException
2121

@@ -275,7 +275,7 @@ def __call__(
275275
worker_id: int,
276276
request_queue: Queue,
277277
transport: MessageTransport,
278-
workers_setup_status: Dict[int, str],
278+
workers_setup_status: dict[int, str],
279279
callback_runner: CallbackRunner,
280280
lit_spec: Optional[LitSpec] = None,
281281
stream: bool = False,
@@ -401,7 +401,7 @@ def __call__(
401401
worker_id: int,
402402
request_queue: Queue,
403403
transport: MessageTransport,
404-
workers_setup_status: Dict[int, str],
404+
workers_setup_status: dict[int, str],
405405
callback_runner: CallbackRunner,
406406
lit_spec: Optional[LitSpec] = None,
407407
stream: bool = False,

0 commit comments

Comments
 (0)