{"id":149,"library":"mirascope","title":"Mirascope","description":"LLM toolkit for Python focused on type safety and developer experience. Self-described as 'the LLM anti-framework' — minimal abstractions over LLM provider APIs. Current version: 2.4.0 (Mar 2026). Three major API surfaces exist: v0 (class-based, deprecated), v1 (provider-specific decorators from mirascope.core), and v2 (unified llm module). LLMs trained before 2025 generate v1 patterns which still work but v2 is current.","status":"active","version":"2.4.0","language":"python","source_language":"en","source_url":"https://github.com/Mirascope/mirascope","tags":["mirascope","llm","python","structured-output","type-safe","decorator"],"install":[{"cmd":"pip install mirascope","lang":"bash","label":"Python (core)"},{"cmd":"pip install 'mirascope[openai]'","lang":"bash","label":"Python (with OpenAI)"},{"cmd":"pip install 'mirascope[anthropic]'","lang":"bash","label":"Python (with Anthropic)"}],"dependencies":[{"reason":"Required for structured output and type validation. Pydantic v2 required.","package":"pydantic","optional":false},{"reason":"Required for OpenAI provider. Install via mirascope[openai].","package":"openai","optional":true},{"reason":"Required for Anthropic provider. Install via mirascope[anthropic].","package":"anthropic","optional":true}],"imports":[{"note":"v1 used provider-specific imports (from mirascope.core import openai). v2 uses unified 'from mirascope import llm' with provider-prefixed model strings. v1 still works but v2 is canonical.","wrong":"from mirascope.core import openai\n\n@openai.call('gpt-4o-mini')\ndef recommend_book(genre: str):\n    \"\"\"Recommend a {genre} book.\"\"\"\n\nresponse = recommend_book('fantasy')\nprint(response.content)","symbol":"llm.call (v2 — current)","correct":"from mirascope import llm\n\n@llm.call('openai/gpt-4o-mini')\ndef recommend_book(genre: str):\n    return f'Recommend a {genre} book.'\n\nresponse = recommend_book('fantasy')\nprint(response.text())"},{"note":"v1 used response_model= parameter. v2 uses format= parameter and .parse() method. Response access changed from .content to .text().","wrong":"from mirascope.core import openai\nfrom pydantic import BaseModel\n\nclass Book(BaseModel):\n    title: str\n    author: str\n\n@openai.call('gpt-4o-mini', response_model=Book)\ndef recommend_book(genre: str):\n    \"\"\"Recommend a {genre} book.\"\"\"\n","symbol":"structured output (v2)","correct":"from pydantic import BaseModel\nfrom mirascope import llm\n\nclass Book(BaseModel):\n    title: str\n    author: str\n\n@llm.call('openai/gpt-4o-mini', format=Book)\ndef recommend_book(genre: str):\n    return f'Recommend a {genre} book.'\n\nbook = recommend_book('fantasy').parse()\nprint(f'{book.title} by {book.author}')"}],"quickstart":{"code":"# pip install 'mirascope[openai]'\nfrom mirascope import llm\nfrom pydantic import BaseModel\n\n# Simple call\n@llm.call('openai/gpt-4o-mini')\ndef recommend_book(genre: str):\n    return f'Recommend a {genre} book.'\n\nprint(recommend_book('fantasy').text())\n\n# Structured output\nclass Book(BaseModel):\n    title: str\n    author: str\n\n@llm.call('openai/gpt-4o-mini', format=Book)\ndef recommend_structured(genre: str):\n    return f'Recommend a {genre} book.'\n\nbook = recommend_structured('fantasy').parse()\nprint(f'{book.title} by {book.author}')","lang":"python","description":"Mirascope v2 unified llm module quickstart."},"warnings":[{"fix":"Replace 'from mirascope.core import openai; @openai.call(model)' with 'from mirascope import llm; @llm.call(\"openai/model\")'.","message":"v2 replaced provider-specific imports with unified 'from mirascope import llm'. Model strings now use 'provider/model' format (e.g. 'openai/gpt-4o-mini', 'anthropic/claude-sonnet-4-5').","severity":"breaking","affected_versions":">= 2.0.0"},{"fix":"response.text() not response.content. format=Book not response_model=Book. response.parse() for structured output.","message":"Response access changed in v2. v1 used response.content, v2 uses response.text(). response_model= renamed to format=. .parse() method added for structured output.","severity":"breaking","affected_versions":">= 2.0.0"},{"fix":"Use decorator-based approach. See migration guide at mirascope.com/docs/mirascope/getting-started/migration","message":"v0 class-based approach (OpenAIChat, AnthropicChat classes) completely removed in v1+. All tutorials using class instantiation are broken.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"v1 patterns work but migrate to llm module for new code.","message":"v1 (mirascope.core provider-specific imports) still works in v2 but is not the current API. LLMs trained on 2024 data will generate v1 patterns — functional but not idiomatic.","severity":"gotcha","affected_versions":">= 2.0.0"},{"fix":"pip install 'mirascope[openai]' or 'mirascope[anthropic]' etc.","message":"Provider extras must be installed separately. 'pip install mirascope' alone gives ImportError when using provider-specific features.","severity":"gotcha","affected_versions":"all"},{"fix":"Return the prompt string from the function body, or use @prompt_template decorator for docstring-style prompts.","message":"Docstring-as-prompt pattern from v1 no longer default in v2. Function return value is now the prompt. Docstring-style still works via @prompt_template decorator.","severity":"gotcha","affected_versions":">= 2.0.0"},{"fix":"Ensure the relevant API key environment variable is set before running your application (e.g., `export OPENAI_API_KEY='your_key_here'`). Alternatively, for cross-provider support, set `MIRASCOPE_API_KEY`.","message":"Mirascope requires API keys for providers to be set as environment variables (e.g., OPENAI_API_KEY for OpenAI, ANTHROPIC_API_KEY for Anthropic). Failing to set these will result in a `MissingAPIKeyError` at runtime.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T08:49:24.080Z","next_check":"2026-06-24T00:00:00.000Z","problems":[{"fix":"Set the appropriate environment variable for your provider (e.g., `export OPENAI_API_KEY='your_key_here'`, `export ANTHROPIC_API_KEY='your_key_here'`, or `export GOOGLE_API_KEY='your_key_here'`). Ensure the key is valid and has the necessary permissions.","cause":"The required API key for the specified LLM provider (e.g., OpenAI, Anthropic, Google) is either not set in the environment variables or is incorrect.","error":"llm.AuthenticationError: Invalid or missing API key"},{"fix":"Update your imports to use the v2 API, typically `from mirascope import llm` and then access provider-specific functions via `llm.call(provider='openai', ...)` or `llm.openai.call(...)`. If using a specific provider's legacy decorator, ensure `mirascope[provider]` is installed and verify the correct import path for your Mirascope version.","cause":"This error often occurs when trying to use older v1 API patterns (e.g., `from mirascope.core import openai`) while the current recommended API surface is `mirascope.llm` (v2), or when the `mirascope.core` module is not correctly installed/available in the environment.","error":"ModuleNotFoundError: No module named 'mirascope.core'"},{"fix":"Review the `response_model` or `json_mode` configuration to ensure it matches the expected output format. Adjust your prompt to guide the LLM to produce output strictly adhering to the specified schema or JSON format. You can also use `response.content` to inspect the raw output from the LLM.","cause":"Mirascope failed to parse the LLM's response into the expected structured format (e.g., a Pydantic `response_model` or JSON). This often happens when the LLM's output does not conform to the schema or expected JSON format.","error":"llm.ParseError: Failed to parse structured response"},{"fix":"Implement robust error handling using `try...except` blocks to catch Mirascope's unified `llm.Error` exceptions (e.g., `llm.ProviderError`, `llm.ConnectionError`, `llm.TimeoutError`). Inspect the raw response object before accessing attributes, or add checks for `None` to prevent attribute access on an invalid object.","cause":"This error indicates that an LLM call likely failed or returned an unexpected `None` value, and subsequent code attempted to access an attribute (like `content` or `text()`) on this `None` object. This can stem from underlying `llm.Error` exceptions (e.g., `ProviderError`, `ConnectionError`, `TimeoutError`) that were not caught or handled.","error":"AttributeError: 'NoneType' object has no attribute 'content'"}],"ecosystem":"pypi","meta_description":null,"install_score":85,"install_tag":"verified","quickstart_score":70,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.48,"mem_mb":24.9,"disk_size":"43.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.45,"mem_mb":26.6,"disk_size":"50.6M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.92,"mem_mb":14.8,"disk_size":"36.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.84,"mem_mb":24.7,"disk_size":"42M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.89,"mem_mb":26.6,"disk_size":"50M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":14.8,"disk_size":"36M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.91,"mem_mb":26.6,"disk_size":"46.9M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.04,"mem_mb":28.6,"disk_size":"54.9M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.14,"mem_mb":16.8,"disk_size":"39.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.52,"mem_mb":26.6,"disk_size":"46M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.56,"mem_mb":28.6,"disk_size":"54M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.97,"mem_mb":16.8,"disk_size":"39M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.99,"mem_mb":25.8,"disk_size":"38.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.15,"mem_mb":27.9,"disk_size":"46.0M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.46,"mem_mb":16.6,"disk_size":"31.4M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.96,"mem_mb":25.8,"disk_size":"37M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.18,"mem_mb":27.9,"disk_size":"45M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.45,"mem_mb":16.6,"disk_size":"31M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.71,"mem_mb":26.8,"disk_size":"37.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.94,"mem_mb":28.9,"disk_size":"45.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.27,"mem_mb":19.6,"disk_size":"31.1M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"anthropic","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.7,"mem_mb":26.8,"disk_size":"37M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"openai","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.91,"mem_mb":28.9,"disk_size":"45M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.23,"mem_mb":19.6,"disk_size":"30M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"anthropic","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"openai","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"anthropic","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"openai","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}