Skip to main content

Lamia - AI Native language

Write AI-powered scripts in plain English.

Lamia

Lamia extends Python with human-readable syntax for AI commands, web automation, and file operations. Write what you want in plain English - Lamia handles the LLM calls, validates the output, and returns structured data.

How it guarantees results: every command runs through a built-in validator. If the output doesn't match the expected format or schema, Lamia retries automatically across a configurable model chain — escalating to the next model until it passes or the chain is exhausted. You define the contract once; Lamia enforces it on every run.

  • Get your expected results in HTML, JSON, CSV, XML, YAML Markdown formats back
  • Web automation with automatic data extraction into Pydantic models
  • Multi-model support: OpenAI, Anthropic, Ollama (and extensible)
  • Model evaluation to find the cheapest model that still passes validation

Installation

pip install lamia-lang

Quick Start

Create a .lm file and run it with lamia your_script.lm:

# Ask AI and create a login from using our model
page = "Create a login form" -> HTML[LoginForm]

# Read a local file as typed JSON
config = "./config.json" -> JSON[OnlyTheConfigsWeNeed]

# Scrape a website into a Pydantic model
quote = "https://finance.yahoo.com/quote/AAPL" -> HTML[StockQuote]

A minimal real-world example - extract stock quotes from Yahoo Finance into a CSV:

class StockQuote(BaseModel):
    ticker: str = Field(description="Stock ticker symbol, e.g. AAPL")
    open: float = Field(description="Open price from the Quote Summary section")
    bid: str = Field(description="Bid price from the Quote Summary section")
    ask: str = Field(description="Ask price from the Quote Summary section")
    bid_size: int = Field(description="Bid size (number of lots) from the Quote Summary")
    ask_size: int = Field(description="Ask size (number of lots) from the Quote Summary")

for ticker in ["QQQ", "VOO", "VGT"]:
    "extract the stock quote data from https://finance.yahoo.com/quote/{ticker}" -> File(CSV[StockQuote], "stocks.csv", append=True)

For more real-world examples, you can check the Lamia Examples repository.

Running from Python

Lamia can be used as a Python library as well.

from lamia import Lamia

lamia = Lamia()

ai_response = lamia.run(
    "Create a login form",
    "openai:gpt4o",
    "anthropic:claude",
    return_type=HTML[LoginForm]
)

Using Lamia Claude Pro or Max Subscription

Currently, Lamia supports only 3 LLM providers: OpenAI, Anthropic, and Ollama (local models). But you can easily extend it to support other providers by creating a new adapter by extending the BaseLLMAdapter class and placing it in the extensions/adapters directory in the root of the project.

For more information see the Implementing a new Adapter section of the Lamia LLM Adapters documentation.

Here is a ready to use adapter for Claude Pro or Max subscriptions. Just place it in the extensions/adapters/llm directory in the root of your Lamia project.

IMPORTANT: Using this llm adapter might result your account being banned by Anthropic. This is just an example showing how you can have your own LLM adapter (not supported by Lamia).

and add the following to your config.yaml file:

model_chain:
  - name: "claude-max:claude-sonnet-4"
    max_retries: 3
"""
Adapter for anthropic-max-router local proxy.

Routes requests through anthropic-max-router
(https://github.com/nsxdavid/anthropic-max-router) — an OpenAI-compatible
endpoint backed by Anthropic's Claude API via OAuth.
Works with Claude Pro ($20/mo) and Max ($100/$200/mo) subscriptions
for flat-rate billing instead of pay-per-token.

The router stores its OAuth tokens in .oauth-tokens.json relative to the
working directory, so all commands below use ~ as a stable anchor.
"""

import asyncio
import logging
from typing import Optional, Type

import aiohttp

from lamia.adapters.llm.base import BaseLLMAdapter, LLMResponse, raise_for_status, raise_for_connection_error
from lamia import LLMModel
from pydantic import BaseModel

logger = logging.getLogger(__name__)

DEFAULT_BASE_URL = "http://127.0.0.1:3000"


class ClaudeMaxAdapter(BaseLLMAdapter):
    """Adapter for a local claude-max-api proxy (OpenAI-compatible, no streaming)."""

    @classmethod
    def name(cls) -> str:
        return "claude-max"

    @classmethod
    def env_var_names(cls) -> list[str]:
        return [] # No env variables like API key names needed

    @classmethod
    def is_remote(cls) -> bool:
        return False

    def __init__(self, base_url: str = DEFAULT_BASE_URL):
        self.base_url = base_url.rstrip("/")
        self.session: Optional[aiohttp.ClientSession] = None

    async def async_initialize(self) -> None:
        if self.session is None:
            self.session = aiohttp.ClientSession(
                headers={"Content-Type": "application/json"},
                timeout=aiohttp.ClientTimeout(total=600),
            )

    async def generate(
        self,
        prompt: str,
        model: LLMModel,
        response_model: Optional[Type[BaseModel]] = None,
    ) -> LLMResponse:
        if self.session is None:
            await self.async_initialize()
        assert self.session is not None

        model_name = model.get_model_name_without_provider() or "claude-sonnet-4"

        payload: dict = {
            "model": model_name,
            "messages": [{"role": "user", "content": prompt}],
            "stream": False,
        }

        if model.temperature is not None:
            payload["temperature"] = model.temperature
        if model.max_tokens is not None:
            payload["max_tokens"] = model.max_tokens
        if model.top_p is not None:
            payload["top_p"] = model.top_p
        if response_model is not None:
            payload["response_format"] = {
                "type": "json_schema",
                "json_schema": {
                    "name": response_model.__name__,
                    "schema": response_model.model_json_schema(),
                    "strict": True,
                },
            }

        url = f"{self.base_url}/v1/chat/completions"
        logger.debug("Requesting %s with model=%s", url, model_name)

        try:
            async with self.session.post(url, json=payload) as response:
                if response.status != 200:
                    error_text = await response.text()
                    raise_for_status(response.status, error_text, "claude-max-api error")
                data = await response.json()
        except (aiohttp.ClientError, asyncio.TimeoutError) as e:
            raise_for_connection_error(e, "claude-max-api connection error")

        usage_data = data.get("usage", {})

        return LLMResponse(
            text=data["choices"][0]["message"]["content"],
            raw_response=data,
            usage={
                "prompt_tokens": usage_data.get("prompt_tokens", 0),
                "completion_tokens": usage_data.get("completion_tokens", 0),
                "total_tokens": usage_data.get("total_tokens", 0),
            },
            model=model_name,
        )

    async def close(self) -> None:
        if self.session:
            await self.session.close()
            self.session = None

Module Documentation

Module Description
Hybrid Syntax .lm file syntax: LLM commands, file operations, web actions, sessions, -> File(...) write syntax
Validation Validators for HTML, JSON, YAML, XML, Markdown, CSV, Pydantic models
Web Adapters Browser automation (Selenium, Playwright) and HTTP clients
LLM Adapters Implementing new LLM provider adapters
Engine Core engine, LLM manager, configuration
Selector Resolution CSS/XPath and AI-powered natural language selectors
Evaluation Model evaluation to find cost-effective models

Documentation

Full documentation: lamia-lang.github.io/lamia

Development

See CONTRIBUTING.md for development setup, doc building, and code style guidelines.

License

MIT

Metadata

Release files for lamia-lang 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lamia-lang 0.2.2
File Size Uploaded Provenance
lamia_lang-0.2.2.tar.gz 6.9 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lamia-lang 0.2.2
File Interpreter ABI Platform
lamia_lang-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 7.4 MB

Release files / lamia_lang-0.2.2.tar.gz

Download URL lamia_lang-0.2.2.tar.gz
Size 6.9 MB
Tags Source
SHA-256 checksum
How to use checksums
2e412409a55a49021e61e6001c85c2ef0f3b0371adf485017d8635d4f2fab668
BLAKE2b-256 checksum
How to use checksums
0d6072da411630c4d77c00e2149969ba616d03fb40a8ed67edcfb4b406b559a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 5, 2026.

Transparency log

Release files / lamia_lang-0.2.2-py3-none-any.whl

Download URL lamia_lang-0.2.2-py3-none-any.whl
Size 591.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9771dddccf4062e998cb8b640635e421c8c7af102e2517ab5ff9acef5054cf41
BLAKE2b-256 checksum
How to use checksums
5a325cb8016e14e6f13ce0e43176c3d55781d190b4f6e94a4d1e8aeacf5660c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 5, 2026.

Transparency log

Security for lamia-lang 0.2.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for lamia_lang-0.2.2.tar.gz

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 Sep 5, 2026.

Transparency log

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page