Skip to content

Commit 84566bf

Browse files
committed
Updated LocalLab v0.2.3
1 parent 1015fe6 commit 84566bf

File tree

4 files changed

+27
-7
lines changed

4 files changed

+27
-7
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
All notable changes for version updates.
44

5+
## [0.2.3] - 2025-03-03
6+
7+
### Fixed
8+
9+
- Fixed critical server startup error in Google Colab environment with uvicorn callback configuration
10+
- Resolved "'list' object is not callable" error by properly implementing the callback_notify as an async function
11+
- Enhanced server startup sequence for better compatibility with both local and Colab environments
12+
- Improved custom server implementation to handle callbacks more robustly
13+
514
## [0.2.2] - 2025-03-03
615

716
### Fixed

locallab/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
LocalLab - A lightweight AI inference server
33
"""
44

5-
__version__ = "0.2.2"
5+
__version__ = "0.2.3"
66

77
from typing import Dict, Any, Optional
88

locallab/server.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,19 @@ def on_startup():
253253
import nest_asyncio
254254
nest_asyncio.apply()
255255
logger.info(f"Starting server on port {port} (Colab mode)")
256+
257+
# Define the callback for Colab
258+
async def on_startup_async():
259+
on_startup()
260+
256261
config = uvicorn.Config(
257262
app,
258263
host="0.0.0.0",
259264
port=port,
260265
reload=False,
261266
log_level="info",
262-
# Add callback to print the RUNNING banner when server starts
263-
callback_notify=[on_startup]
267+
# Use an async callback function, not a list
268+
callback_notify=on_startup_async
264269
)
265270
server = uvicorn.Server(config)
266271
asyncio.get_event_loop().run_until_complete(server.serve())
@@ -278,8 +283,13 @@ async def serve(self, sockets=None):
278283
self.config.setup_event_loop()
279284
await self.startup(sockets=sockets)
280285
# Call our callback before processing requests
281-
for callback in self.config.callback_notify:
282-
callback()
286+
if callable(self.config.callback_notify):
287+
await self.config.callback_notify()
288+
elif isinstance(self.config.callback_notify, list):
289+
for callback in self.config.callback_notify:
290+
if callable(callback):
291+
callback()
292+
on_startup() # Always ensure our startup function is called
283293
await self.main_loop()
284294
await self.shutdown()
285295

@@ -290,7 +300,8 @@ async def serve(self, sockets=None):
290300
reload=False,
291301
workers=1,
292302
log_level="info",
293-
callback_notify=[on_startup]
303+
# This won't be used directly, as we call on_startup in the ServerWithCallback class
304+
callback_notify=None
294305
)
295306
server = ServerWithCallback(config)
296307
asyncio.run(server.serve())

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="locallab",
8-
version="0.2.2",
8+
version="0.2.3",
99
packages=find_packages(include=["locallab", "locallab.*"]),
1010
install_requires=[
1111
"fastapi>=0.68.0,<1.0.0",

0 commit comments

Comments
 (0)