- Overview
- Choosing the Right Client
- Installation
- Asynchronous Client Example
- Synchronous Client Example
- Context Manager Support
- How the Synchronous Client Works
- Performance Considerations
- Best Practices
- Migrating Between Clients
- Conclusion
The LocalLab Python client (locallab-client package) provides two different client classes to interact with the LocalLab server:
LocalLabClient- An asynchronous client that usesasync/awaitsyntaxSyncLocalLabClient- A synchronous client that doesn't requireasync/await
This guide explains when and how to use each client, with practical examples and best practices.
- You're already using async/await in your application
- You need to handle many concurrent operations efficiently
- You're building a high-performance web application
- You want to avoid blocking the main thread during long operations
- You're writing a script or application that doesn't use async/await elsewhere
- You want simpler code without async/await boilerplate
- You're integrating with synchronous frameworks or libraries
- You're new to Python and not familiar with async programming
First, install the client package:
pip install locallab-clientimport asyncio
from locallab_client import LocalLabClient
async def main():
# Initialize client
client = LocalLabClient("http://localhost:8000")
try:
# Basic text generation
response = await client.generate("Write a story about a robot")
print(response)
# Streaming text generation
print("Streaming response: ", end="")
async for chunk in client.stream_generate("Write a haiku about nature"):
print(chunk, end="", flush=True)
print()
# Chat completion
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
response = await client.chat(messages)
print(response["choices"][0]["message"]["content"])
finally:
# Always close the client
await client.close()
# Run the async function
asyncio.run(main())from locallab_client import SyncLocalLabClient
# Initialize client
client = SyncLocalLabClient("http://localhost:8000")
try:
# Basic text generation
response = client.generate("Write a story about a robot")
print(response)
# Streaming text generation
print("Streaming response: ", end="")
for chunk in client.stream_generate("Write a haiku about nature"):
print(chunk, end="", flush=True)
print()
# Chat completion
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
response = client.chat(messages)
print(response["choices"][0]["message"]["content"])
finally:
# Always close the client
client.close()Both clients support context managers for automatic resource cleanup:
import asyncio
from locallab_client import LocalLabClient
async def main():
# Use the client as an async context manager
async with LocalLabClient("http://localhost:8000") as client:
response = await client.generate("Write a story about a robot")
print(response)
# Client is automatically closed when exiting the context
asyncio.run(main())from locallab_client import SyncLocalLabClient
# Use the client as a sync context manager
with SyncLocalLabClient("http://localhost:8000") as client:
response = client.generate("Write a story about a robot")
print(response)
# Client is automatically closed when exiting the contextThe SyncLocalLabClient is a wrapper around the asynchronous LocalLabClient. It handles all the async/await details internally by:
- Running a dedicated event loop in a background thread
- Converting async calls to synchronous calls by running them in the background thread
- Providing a synchronous API that matches the asynchronous API
This allows you to use the same functionality without having to deal with async/await syntax.
- Asynchronous Client: More efficient for concurrent operations, as it doesn't block the main thread
- Synchronous Client: Slightly higher overhead due to thread management, but simpler to use
- Be Consistent: Choose one client type and stick with it in a single module or application
- Close Explicitly: Always close the client when you're done with it, or use a context manager
- Error Handling: Always use try/except blocks to handle errors properly
- Resource Management: Be mindful of resource usage, especially when creating multiple clients
If you need to migrate from one client to the other:
- Remove
async/awaitkeywords - Replace
LocalLabClientwithSyncLocalLabClient - Replace
async forwithforin streaming operations - Remove
asyncio.run()calls
- Add
async/awaitkeywords - Replace
SyncLocalLabClientwithLocalLabClient - Replace
forwithasync forin streaming operations - Wrap your code in an async function and use
asyncio.run()
Both clients provide the same functionality with different programming styles. Choose the one that best fits your application's needs and your programming preferences.