Skip to content

Commit 53bacd6

Browse files
authored
Hide the not-yet-implemented file handling APIs (#81)
When the image preparation APIs were added to the server API, the general purpose file preparation APIs were also incorrectly marked as public in the client SDK API. Having those APIs available suggests that adding other file types (text files, PDFs, etc) to the chat context via the SDK is expected to work, when that simply isn't true (yet).
1 parent 1282579 commit 53bacd6

File tree

7 files changed

+30
-25
lines changed

7 files changed

+30
-25
lines changed

src/lmstudio/async_api.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,9 @@ async def _fetch_file_handle(self, file_data: _LocalFileData) -> FileHandle:
609609
handle["type"] = "file"
610610
return load_struct(handle, FileHandle)
611611

612-
@sdk_public_api_async()
613-
async def prepare_file(
612+
# Not yet implemented (server API only supports the same file types as prepare_image)
613+
# @sdk_public_api_async()
614+
async def _prepare_file(
614615
self, src: LocalFileInput, name: str | None = None
615616
) -> FileHandle:
616617
"""Add a file to the server. Returns a file handle for use in prediction requests."""
@@ -1435,12 +1436,13 @@ def repository(self) -> AsyncSessionRepository:
14351436
return self._get_session(AsyncSessionRepository)
14361437

14371438
# Convenience methods
1438-
@sdk_public_api_async()
1439-
async def prepare_file(
1439+
# Not yet implemented (server API only supports the same file types as prepare_image)
1440+
# @sdk_public_api_async()
1441+
async def _prepare_file(
14401442
self, src: LocalFileInput, name: str | None = None
14411443
) -> FileHandle:
14421444
"""Add a file to the server. Returns a file handle for use in prediction requests."""
1443-
return await self.files.prepare_file(src, name)
1445+
return await self.files._prepare_file(src, name)
14441446

14451447
@sdk_public_api_async()
14461448
async def prepare_image(

src/lmstudio/history.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,9 @@ def add_user_message(
374374
self,
375375
content: UserMessageInput | Iterable[UserMessageInput],
376376
*,
377-
files: Sequence[FileHandleInput] = (),
378377
images: Sequence[FileHandleInput] = (),
378+
# Not yet implemented (server file preparation API only supports the image file types)
379+
_files: Sequence[FileHandleInput] = (),
379380
) -> UserMessage:
380381
"""Add a new user message to the chat history."""
381382
# Accept both singular and multi-part user messages
@@ -385,8 +386,8 @@ def add_user_message(
385386
else:
386387
content_items = list(content)
387388
# Convert given local file information to file handles
388-
if files:
389-
content_items.extend(files)
389+
if _files:
390+
content_items.extend(_files)
390391
if images:
391392
content_items.extend(images)
392393
# Consecutive messages with the same role are not supported,

src/lmstudio/sync_api.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@
144144
"list_downloaded_models",
145145
"list_loaded_models",
146146
"llm",
147-
"prepare_file",
148147
"prepare_image",
149148
]
150149

@@ -586,8 +585,9 @@ def _fetch_file_handle(self, file_data: _LocalFileData) -> FileHandle:
586585
handle["type"] = "file"
587586
return load_struct(handle, FileHandle)
588587

589-
@sdk_public_api()
590-
def prepare_file(self, src: LocalFileInput, name: str | None = None) -> FileHandle:
588+
# Not yet implemented (server API only supports the same file types as prepare_image)
589+
# @sdk_public_api()
590+
def _prepare_file(self, src: LocalFileInput, name: str | None = None) -> FileHandle:
591591
"""Add a file to the server. Returns a file handle for use in prediction requests."""
592592
file_data = _LocalFileData(src, name)
593593
return self._fetch_file_handle(file_data)
@@ -1568,10 +1568,11 @@ def repository(self) -> SyncSessionRepository:
15681568
return self._get_session(SyncSessionRepository)
15691569

15701570
# Convenience methods
1571-
@sdk_public_api()
1572-
def prepare_file(self, src: LocalFileInput, name: str | None = None) -> FileHandle:
1571+
# Not yet implemented (server API only supports the same file types as prepare_image)
1572+
# @sdk_public_api()
1573+
def _prepare_file(self, src: LocalFileInput, name: str | None = None) -> FileHandle:
15731574
"""Add a file to the server. Returns a file handle for use in prediction requests."""
1574-
return self.files.prepare_file(src, name)
1575+
return self.files._prepare_file(src, name)
15751576

15761577
@sdk_public_api()
15771578
def prepare_image(self, src: LocalFileInput, name: str | None = None) -> FileHandle:
@@ -1653,10 +1654,11 @@ def embedding_model(
16531654
return get_default_client().embedding.model(model_key, ttl=ttl, config=config)
16541655

16551656

1656-
@sdk_public_api()
1657-
def prepare_file(src: LocalFileInput, name: str | None = None) -> FileHandle:
1657+
# Not yet implemented (server API only supports the same file types as prepare_image)
1658+
# @sdk_public_api()
1659+
def _prepare_file(src: LocalFileInput, name: str | None = None) -> FileHandle:
16581660
"""Add a file to the server using the default global client."""
1659-
return get_default_client().prepare_file(src, name)
1661+
return get_default_client()._prepare_file(src, name)
16601662

16611663

16621664
@sdk_public_api()

tests/async/test_images_async.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async def test_upload_from_pathlike_async(caplog: LogCap) -> None:
2424
caplog.set_level(logging.DEBUG)
2525
async with AsyncClient() as client:
2626
session = client.files
27-
file = await session.prepare_file(IMAGE_FILEPATH)
27+
file = await session._prepare_file(IMAGE_FILEPATH)
2828
assert file
2929
assert isinstance(file, FileHandle)
3030
logging.info(f"Uploaded file: {file}")
@@ -43,7 +43,7 @@ async def test_upload_from_file_obj_async(caplog: LogCap) -> None:
4343
async with AsyncClient() as client:
4444
session = client.files
4545
with open(IMAGE_FILEPATH, "rb") as f:
46-
file = await session.prepare_file(f)
46+
file = await session._prepare_file(f)
4747
assert file
4848
assert isinstance(file, FileHandle)
4949
logging.info(f"Uploaded file: {file}")
@@ -62,7 +62,7 @@ async def test_upload_from_bytesio_async(caplog: LogCap) -> None:
6262
caplog.set_level(logging.DEBUG)
6363
async with AsyncClient() as client:
6464
session = client.files
65-
file = await session.prepare_file(BytesIO(IMAGE_FILEPATH.read_bytes()))
65+
file = await session._prepare_file(BytesIO(IMAGE_FILEPATH.read_bytes()))
6666
assert file
6767
assert isinstance(file, FileHandle)
6868
logging.info(f"Uploaded file: {file}")

tests/sync/test_images_sync.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def test_upload_from_pathlike_sync(caplog: LogCap) -> None:
3030
caplog.set_level(logging.DEBUG)
3131
with Client() as client:
3232
session = client.files
33-
file = session.prepare_file(IMAGE_FILEPATH)
33+
file = session._prepare_file(IMAGE_FILEPATH)
3434
assert file
3535
assert isinstance(file, FileHandle)
3636
logging.info(f"Uploaded file: {file}")
@@ -48,7 +48,7 @@ def test_upload_from_file_obj_sync(caplog: LogCap) -> None:
4848
with Client() as client:
4949
session = client.files
5050
with open(IMAGE_FILEPATH, "rb") as f:
51-
file = session.prepare_file(f)
51+
file = session._prepare_file(f)
5252
assert file
5353
assert isinstance(file, FileHandle)
5454
logging.info(f"Uploaded file: {file}")
@@ -66,7 +66,7 @@ def test_upload_from_bytesio_sync(caplog: LogCap) -> None:
6666
caplog.set_level(logging.DEBUG)
6767
with Client() as client:
6868
session = client.files
69-
file = session.prepare_file(BytesIO(IMAGE_FILEPATH.read_bytes()))
69+
file = session._prepare_file(BytesIO(IMAGE_FILEPATH.read_bytes()))
7070
assert file
7171
assert isinstance(file, FileHandle)
7272
logging.info(f"Uploaded file: {file}")

tests/test_convenience_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def test_embedding_specific() -> None:
5151
def test_prepare_file() -> None:
5252
name = "example-file.txt"
5353
raw_data = b"raw data"
54-
file_handle = lms.prepare_file(raw_data, name)
54+
file_handle = lms.sync_api._prepare_file(raw_data, name)
5555
assert file_handle.name == name
5656
assert file_handle.size_bytes == len(raw_data)
5757
assert file_handle.file_type == "text/plain"

tests/test_history.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ def test_user_message_attachments() -> None:
624624
chat.add_user_message(
625625
"What do you make of this?",
626626
images=[INPUT_IMAGE_HANDLE],
627-
files=[INPUT_FILE_HANDLE],
627+
_files=[INPUT_FILE_HANDLE],
628628
)
629629
history = chat._get_history()
630630
assert history["messages"] == EXPECTED_USER_ATTACHMENT_MESSAGES

0 commit comments

Comments
 (0)