Skip to main content
BAML generates client libraries for Python, TypeScript, Ruby, and Go that expose your BAML functions as type-safe methods. After running baml-cli generate, you can call your BAML functions directly from your application code.

Basic Function Calls

Async Client

The async client is recommended for most use cases as it doesn’t block your application while waiting for LLM responses.
from baml_client.async_client import b

async def example():
    # Call a BAML function with no arguments
    story = await b.TellMeAStory()
    
    # Call a BAML function with arguments
    poem = await b.WriteAPoemAbout("Roses")
    
    # Call with multiple arguments
    result = await b.ExtractResume(
        resume_text="...",
        extract_skills=True
    )

Sync Client

The sync client blocks execution until the LLM response is received. Use this when you need synchronous behavior or don’t have an async runtime.
from baml_client.sync_client import b

def example():
    # Sync calls block until completion
    story = b.TellMeAStory()
    poem = b.WriteAPoemAbout("Roses")

Function Signature

Given a BAML function:
function ExtractResume(resume_text: string, extract_skills: bool) -> Resume {
    client "openai/gpt-4o"
    prompt #"
        Extract information from this resume:
        {{ resume_text }}
        
        {% if extract_skills %}
        Make sure to extract skills.
        {% endif %}
    "#
}
The generated client signatures are:
# Async
async def ExtractResume(
    resume_text: str,
    extract_skills: bool,
    baml_options: BamlCallOptions = {}
) -> Resume:
    ...

# Sync
def ExtractResume(
    resume_text: str,
    extract_skills: bool,
    baml_options: BamlCallOptions = {}
) -> Resume:
    ...

Advanced Call Patterns

Request Inspection

The .request object returns the raw HTTP request without sending it. Useful for debugging or custom request handling.
from baml_client.async_client import b

async def example():
    request = await b.request.TellMeAStory()
    print(request.url)
    print(request.headers)
    print(request.body.json())

Response Parsing

The .parse object parses LLM responses without making the actual API call. Use this with .request for full control.
import requests
from baml_client.sync_client import b

def example():
    # Get the HTTP request
    request = b.request.ExtractResume(resume_text)
    
    # Send the HTTP request yourself
    response = requests.post(
        request.url,
        headers=request.headers,
        json=request.body.json()
    )
    
    # Parse the LLM response
    parsed = b.parse.ExtractResume(
        response.json()["choices"][0]["message"]["content"]
    )
    
    print(parsed)

Type Safety

All generated functions are fully type-safe:
from baml_client import b, types

async def example():
    # TypeScript/IDE will know the return type
    resume: types.Resume = await b.ExtractResume(resume_text, True)
    
    # Access typed fields
    print(resume.name)  # string
    print(resume.skills)  # list[string]
    print(resume.experience)  # list[Experience]

Error Handling

All BAML function calls can throw errors. See the Error Types page for details.
from baml_client import b
from baml_py import BamlValidationError, BamlClientFinishReasonError

async def example():
    try:
        result = await b.ExtractResume(resume_text, True)
    except BamlValidationError as e:
        # LLM output couldn't be parsed
        print(f"Validation error: {e.message}")
        print(f"Raw output: {e.raw_output}")
    except BamlClientFinishReasonError as e:
        # LLM stopped with unexpected finish reason
        print(f"Finish reason error: {e.message}")
    except Exception as e:
        # Other errors
        print(f"Error: {e}")

Build docs developers (and LLMs) love