From 570a3eccae3d51ef2da8f90cf9ea45255ef2b2e5 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 28 Oct 2024 14:37:11 -0700 Subject: [PATCH] Python attachment documentation, plus fixed a mimetype detection bug Refs #587 --- docs/python-api.md | 28 ++++++++++++++++++++++++++++ llm/models.py | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/python-api.md b/docs/python-api.md index dccf46bf..dd553101 100644 --- a/docs/python-api.md +++ b/docs/python-api.md @@ -49,6 +49,24 @@ response = model.prompt( system="Answer like GlaDOS" ) ``` +### Attachments + +Model that accept multi-modal input (images, audio, video etc) can be passed attachments using the `attachments=` keyword argument. This accepts a list of `llm.Attachment()` instances. + +This example shows two attachments - one from a file path and one from a URL: +```python +import llm + +model = llm.get_model("gpt-4o-mini") +response = model.prompt( + "Describe these images", + attachments=[ + llm.Attachment(path="pelican.jpg"), + llm.Attachment(url="https://static.simonwillison.net/static/2024/pelicans.jpg"), + ] +) +``` +Use `llm.Attachment(content=b"binary image content here")` to pass binary content directly. ### Model options @@ -114,6 +132,16 @@ print(response2.text()) ``` You will get back five fun facts about skunks. +The `conversation.prompt()` method supports attachments as well: +```python +response = conversation.prompt( + "Describe these birds", + attachments=[ + llm.Attachment(url="https://static.simonwillison.net/static/2024/pelicans.jpg") + ] +) +``` + Access `conversation.responses` for a list of all of the responses that have so far been returned during the conversation. ## Other functions diff --git a/llm/models.py b/llm/models.py index 6364c27e..7fe54cc4 100644 --- a/llm/models.py +++ b/llm/models.py @@ -45,7 +45,9 @@ def resolve_type(self): if self.path: return puremagic.from_file(self.path, mime=True) if self.url: - return puremagic.from_url(self.url, mime=True) + response = httpx.head(self.url) + response.raise_for_status() + return response.headers.get("content-type") if self.content: return puremagic.from_string(self.content, mime=True) raise ValueError("Attachment has no type and no content to derive it from")