findingmodel-ai
AI-powered tools for creating and editing Open Imaging Finding Models using LLMs.
Installation
pip install findingmodel-ai
Configuration
Create a .env file with at least one AI provider:
# Choose one or more AI providers
OPENAI_API_KEY=your_key_here
ANTHROPIC_API_KEY=your_key_here
GOOGLE_API_KEY=your_key_here
# Optional: For detailed finding info with citations
TAVILY_API_KEY=your_key_here
# Optional: Override default model
DEFAULT_MODEL=anthropic:claude-sonnet-4-5
Supported AI Providers
| Provider | Example | API Key |
|---|---|---|
| OpenAI | openai:gpt-5-mini |
OPENAI_API_KEY |
| Anthropic | anthropic:claude-sonnet-4-5 |
ANTHROPIC_API_KEY |
| Google Gemini | google:gemini-3-flash-preview |
GOOGLE_API_KEY |
| Ollama (local) | ollama:llama3 |
None required |
| Gateway | gateway/openai:gpt-5-mini |
PYDANTIC_AI_GATEWAY_API_KEY |
See Configuration Guide for model tiers and per-agent overrides.
CLI (findingmodel-ai)
# Generate finding info from a name
findingmodel-ai make-info "pneumothorax"
# Create a basic model template
findingmodel-ai make-stub-model "pneumothorax"
# Convert Markdown to finding model
findingmodel-ai markdown-to-fm outline.md
Tools
Creating Finding Info
import asyncio
from findingmodel_ai.authoring import create_info_from_name, add_details_to_info
async def main():
# Generate basic info from a finding name
info = await create_info_from_name("Pneumothorax")
print(f"Name: {info.name}")
print(f"Synonyms: {info.synonyms}")
print(f"Description: {info.description}")
# Add detailed info with citations (requires TAVILY_API_KEY)
enhanced = await add_details_to_info(info)
print(f"Detail: {enhanced.detail[:200]}...")
print(f"Citations: {len(enhanced.citations)}")
asyncio.run(main())
Creating Models from Markdown
import asyncio
from findingmodel_ai.authoring import create_model_from_markdown, create_info_from_name
async def main():
info = await create_info_from_name("pneumothorax")
markdown = """
# Pneumothorax Attributes
- Size: small (<2cm), moderate (2-4cm), large (>4cm)
- Location: apical, basilar, lateral
- Tension: present, absent
"""
model = await create_model_from_markdown(info, markdown_text=markdown)
print(f"Created model with {len(model.attributes)} attributes")
asyncio.run(main())
AI-Powered Model Editing
import asyncio
from findingmodel import FindingModelFull
from findingmodel_ai.authoring import edit_model_natural_language, edit_model_markdown
async def main():
# Load existing model
with open("pneumothorax.fm.json") as f:
model = FindingModelFull.model_validate_json(f.read())
# Edit with natural language
result = await edit_model_natural_language(
model=model,
command="Add severity attribute with values mild, moderate, severe"
)
if result.rejections:
print(f"Rejected changes: {result.rejections}")
print(f"Updated model has {len(result.model.attributes)} attributes")
asyncio.run(main())
Finding Anatomic Locations
import asyncio
from findingmodel_ai.search import find_anatomic_locations
async def main():
result = await find_anatomic_locations(
finding_name="PCL tear",
description="Tear of the posterior cruciate ligament"
)
print(f"Primary: {result.primary_location.concept_text}")
print(f" ID: {result.primary_location.concept_id}")
for alt in result.alternate_locations:
print(f"Alternate: {alt.concept_text}")
asyncio.run(main())
Ontology Concept Matching
import asyncio
from findingmodel_ai.search import match_ontology_concepts
async def main():
result = await match_ontology_concepts(
finding_name="pneumonia",
finding_description="Inflammation of lung parenchyma"
)
print(f"Exact matches: {len(result.exact_matches)}")
for concept in result.exact_matches:
print(f" - {concept.code}: {concept.text}")
asyncio.run(main())
Finding Similar Models
import asyncio
from findingmodel_ai.search import find_similar_models
async def main():
analysis = await find_similar_models(
finding_name="pneumothorax",
description="Presence of air in the pleural space",
synonyms=["PTX", "collapsed lung"]
)
print(f"Recommendation: {analysis.recommendation}")
print(f"Confidence: {analysis.confidence:.2f}")
if analysis.similar_models:
for model in analysis.similar_models:
print(f" Similar: {model.name} ({model.oifm_id})")
asyncio.run(main())
Architecture
Two-Agent Patterns
Complex workflows use paired agents:
- Search agent: Generates diverse queries to find candidates
- Matching agent: Selects best options based on clinical relevance
Multi-Provider Support
All tools support multiple AI providers through Pydantic AI:
- Configure globally via
DEFAULT_MODEL - Override per-agent via
AGENT_MODEL_OVERRIDES__<tag>
Structured Outputs
All agents return typed Pydantic models for reliable downstream processing.
Related Packages
- findingmodel: Core models and Index API
- anatomic-locations: Anatomic location queries
Documentation
Metadata
Release files for findingmodel-ai 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| findingmodel_ai-0.2.1.tar.gz | 56.2 kB | Without provenance | Details for findingmodel_ai-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| findingmodel_ai-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for findingmodel_ai-0.2.1-py3-none-any.whl |
Total release size: 124.9 kB
Release files / findingmodel_ai-0.2.1.tar.gz
| Download URL | findingmodel_ai-0.2.1.tar.gz |
|---|---|
| Size | 56.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
787ae2302d96a6b13a9333433bc4402154098324fe7ed468461f102c22b0078c
|
|
BLAKE2b-256 checksum How to use checksums |
29659a48dfff8a54cd6a4e8a331fd31709bef5564ec1ae6c82c5fc246d008f28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / findingmodel_ai-0.2.1-py3-none-any.whl
| Download URL | findingmodel_ai-0.2.1-py3-none-any.whl |
|---|---|
| Size | 68.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
835c1840619d088f4dd932dd2a1158bf99fb46ebb2853dc278eb4c1144f01ef8
|
|
BLAKE2b-256 checksum How to use checksums |
a3a115adb332c9682d7c121541d50a18161066d976c74f70cfd565540b1d83c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for findingmodel-ai 0.2.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.