fm-rs - Python bindings for Apple FoundationModels
Python bindings for fm-rs, enabling on-device AI via Apple Intelligence.
Requirements
- macOS 26.0+ (Tahoe) on Apple Silicon (ARM64)
- Apple Intelligence enabled in System Settings
- Python 3.10+
Installation
pip install fm-rs
From Source
# Requires Rust toolchain
cd bindings/python
uv sync
uv run maturin develop
Quick Start
import fm
# Create the default system language model
model = fm.SystemLanguageModel()
# Check availability
if not model.is_available:
print("Apple Intelligence is not available")
exit(1)
# Create a session
session = fm.Session(model, instructions="You are a helpful assistant.")
# Send a prompt
response = session.respond("What is the capital of France?")
print(response.content)
Streaming
import fm
model = fm.SystemLanguageModel()
session = fm.Session(model)
# Stream the response
session.stream_response(
"Tell me a short story",
lambda chunk: print(chunk, end="", flush=True)
)
print() # newline at end
Structured Generation
import fm
model = fm.SystemLanguageModel()
session = fm.Session(model)
# Using a dict schema
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"]
}
person = session.respond_structured("Generate a fictional person", schema)
print(f"Name: {person['name']}, Age: {person['age']}")
# Using the Schema builder
schema = (fm.Schema.object()
.property("name", fm.Schema.string(), required=True)
.property("age", fm.Schema.integer().minimum(0), required=True))
person = session.respond_structured("Generate a fictional person", schema.to_dict())
Tool Calling
Tools allow the model to call external functions during generation.
import fm
class WeatherTool:
name = "get_weather"
description = "Gets the current weather for a location"
arguments_schema = {
"type": "object",
"properties": {
"city": {"type": "string", "description": "The city name"}
},
"required": ["city"]
}
def call(self, args):
city = args.get("city", "Unknown")
return f"Sunny, 72°F in {city}"
model = fm.SystemLanguageModel()
session = fm.Session(model, tools=[WeatherTool()])
response = session.respond("What's the weather in Paris?")
print(response.content)
Context Management
import fm
model = fm.SystemLanguageModel()
session = fm.Session(model)
# After some conversation...
limit = fm.ContextLimit.default_on_device()
usage = session.context_usage(limit)
print(f"Tokens used: {usage.estimated_tokens}/{usage.max_tokens}")
print(f"Utilization: {usage.utilization:.1%}")
if usage.over_limit:
# Compact the conversation
transcript = session.transcript_json
summary = fm.compact_transcript(model, transcript)
print(f"Summary: {summary}")
macOS 27 Capabilities
On macOS/iOS 27+, sessions support image attachments, Apple's built-in
tools, exact token accounting, and transcript controls. These raise
UnsupportedPlatformError on older build SDKs or runtimes.
import fm
model = fm.SystemLanguageModel()
print(model.context_size()) # model-reported context window (26.4+ SDK)
session = fm.Session(
model,
instructions="Describe images and read any text in them.",
system_tools=["ocr"], # also: "barcode_reader", "spotlight_search"
)
response = session.respond_with_attachments(
"What does this receipt say?",
[fm.Attachment.file("receipt.png", label="receipt")],
fm.GenerationOptions(tool_calling_mode="allowed"),
)
print(response.content)
print(response.usage) # per-response token usage, or None
usage = session.usage() # exact cumulative session usage
print(usage.input_tokens, usage.cached_input_tokens,
usage.output_tokens, usage.reasoning_tokens)
session.set_transcript_error_handling_policy("revert") # or "preserve", None
Failures surface as typed exceptions on macOS 26 and 27 runtimes alike:
ContextSizeExceededError, RateLimitedError, GuardrailViolationError,
RefusalError, AssetsUnavailableError, ConcurrentRequestsError, and the
Unsupported*Error family. Private Cloud Compute is currently Rust-only.
Error Handling
import fm
try:
model = fm.SystemLanguageModel()
model.ensure_available()
except fm.DeviceNotEligibleError:
print("This device doesn't support Apple Intelligence")
except fm.AppleIntelligenceNotEnabledError:
print("Please enable Apple Intelligence in Settings")
except fm.ModelNotReadyError:
print("Model is still downloading, try again later")
except fm.ModelNotAvailableError:
print("Model not available for unknown reason")
API Reference
Classes
SystemLanguageModel- Entry point for on-device AISession- Maintains conversation contextGenerationOptions- Controls generation (temperature, max_tokens, tool_calling_mode, etc.)Response- Model output, with per-responseusageon macOS/iOS 27+SessionUsage- Exact token usage counters (macOS/iOS 27+)Attachment- Image input for multimodal prompting (macOS/iOS 27+)ToolOutput- Tool invocation resultContextLimit- Context window configurationContextUsage- Estimated token usageSchema- JSON Schema builder
Enums
Sampling-GreedyorRandomModelAvailability-Available,DeviceNotEligible,AppleIntelligenceNotEnabled,ModelNotReady,Unknown
Functions
estimate_tokens(text, chars_per_token=4)- Estimate token countcontext_usage_from_transcript(json, limit)- Get context usagetranscript_to_text(json)- Extract text from transcriptcompact_transcript(model, json)- Summarize conversation
Exceptions
FmError- Base exceptionModelNotAvailableErrorDeviceNotEligibleErrorAppleIntelligenceNotEnabledErrorModelNotReadyErrorGenerationErrorToolCallErrorJsonErrorUnsupportedPlatformError- API needs a newer Apple platform or SDKContextSizeExceededError,RateLimitedError,GuardrailViolationError,RefusalError,AssetsUnavailableError,ConcurrentRequestsErrorUnsupportedCapabilityError,UnsupportedTranscriptContentError,UnsupportedGenerationGuideError,UnsupportedLanguageOrLocaleErrorNetworkFailureError,QuotaLimitReachedError,ServiceUnavailableError(Private Cloud Compute)
Notes
- Apple Silicon only: Wheels are built for macOS ARM64 only (Apple Silicon Macs)
- Tool callbacks: May be invoked from non-main threads; avoid UI work in callbacks
- Blocking calls: All calls block until completion; use streaming for long responses
- GIL: Callbacks run under the GIL; keep them short
Development
cd bindings/python
uv sync
uv run maturin develop
uv run pytest tests/
License
MIT
Metadata
Release files for fm-rs 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fm_rs-0.3.0.tar.gz | 130.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fm_rs-0.3.0-cp310-abi3-macosx_26_0_arm64.whl | CPython 3.10 | abi3 | macOS 26.0+ ARM64 | Details |
Total release size: 724.1 kB
Release files / fm_rs-0.3.0.tar.gz
| Download URL | fm_rs-0.3.0.tar.gz |
|---|---|
| Size | 130.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0f913c54e922e5d35cb6f1112b775284f7005dba160fc23e98491f1f79a7fdb5
|
|
BLAKE2b-256 checksum How to use checksums |
5946508c0e075d7351912f8023c62d81939101de8fe27ea8f92222e16c10c0b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.
Transparency logRelease files / fm_rs-0.3.0-cp310-abi3-macosx_26_0_arm64.whl
| Download URL | fm_rs-0.3.0-cp310-abi3-macosx_26_0_arm64.whl |
|---|---|
| Size | 594.0 kB |
| Tags | CPython 3.10 abi3 macOS 26.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
638b4e344ae788fa014e455eacd3749ed3c7d77624213e079893cc7ea013f788
|
|
BLAKE2b-256 checksum How to use checksums |
930293ac34040b89d013a0d397777fd2ef60bd6e7e8ec5188db302ca24a54d1c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.
Transparency log