A powerful open-source Python framework that simplifies the development of artificial intelligence software.
Everything you need to build, maintain and scale amazing AI software
Integrate AI logic into your codebase with zero context-switching, feels like native Python.
Auto-recovers from 90% of common errors including API failures, rate limits, and malformed responses.
Pre-wired for common AI providers (OpenAI/Ollama) and connectors for custom API's.
Add AI features to live apps in hours, not weeks, with less downtime and project refactoring.
Optimized for performance, in most cases adding less than 1ms to any runtime.
Detailed interaction recording for building robust safety and governance.
See how simple it is to build AI applications with Dandy
# dandy_settings.py
import os
from pathlib import Path
ALLOW_DEBUG_RECORDING = True
BASE_PATH = Path.resolve(Path(__file__)).parent
LLM_CONFIGS = {
'DEFAULT': {
'TYPE': 'openai',
'HOST': 'https://api.openai.com',
'PORT': 443,
'API_KEY': os.getenv('OPENAI_API_KEY'),
'MODEL': 'gpt-4o-mini',
}
}
# main.py
from dandy import Bot
response = Bot().process('What is the capital of Canada?')
print(response.content)
# Output: The capital of Canada is Ottawa
from dandy import Bot, Prompt
class AssistantBot(Bot):
def process(self, user_prompt: Prompt | str):
default_intel = self.llm.prompt_to_intel(
prompt=user_prompt,
)
return default_intel
intel = AssistantBot().process('Can you give me an idea for a book?')
print(intel.content)
# Output: Here's an idea for a book: 'The Memory Thief's Daughter' - A mystery thriller ...
from dandy import BaseIntel, Bot
class ClownIntel(BaseIntel):
clown_name: str
can_juggle: bool
real_name: str | None = None
bozo = ClownIntel(
clown_name='Bozo',
can_juggle=True
)
print(bozo.can_juggle)
# True
class FakeClownBot(Bot):
def process(self, clown_description: str) -> ClownIntel:
return self.llm.prompt_to_intel(
prompt=clown_description,
intel_class=ClownIntel,
exclude_fields={'real_name'},
)
another_clown = FakeClownBot().process(
clown_description='I am a big fan of juggling, can you please create me a clown!',
)
print(another_clown)
# Output: clown_name='Bouncing Buddy' can_juggle=True real_name=None
from dandy import BaseIntel, Bot, Prompt
class CandyIntel(BaseIntel):
short_name: str
long_name: str
description: str
class CandyDesignBot(Bot):
llm_config = 'LLAMA_3_2_3B'
instructions_prompt = (
Prompt()
.text('You are a candy design bot and will be given a request to make a new type of candy.')
.line_break()
.heading('Rules')
.list([
'Make sure you response is sugar based not chocolate based.',
'Do not include any chocolate based words or phrases in the response.',
'Incorporate the theme of the request into the response.',
])
)
intel_class = CandyIntel
def process(self, user_prompt: Prompt | str, candy_theme: str) -> CandyIntel:
prompt = (
Prompt()
.heading('Request')
.prompt(user_prompt)
.line_break()
.heading('Theme')
.prompt(candy_theme)
)
return self.llm.prompt_to_intel(
prompt=prompt,
)
candy_intel = CandyDesignBot().process(
user_prompt='Strawberries and Cookie Dough',
candy_theme='Medieval Times'
)
print(candy_intel.short_name)
# Output: Cinnamon Lances
from dandy import Map
class AnimalFamilyMap(Map):
mapping_keys_description = 'Animal Sounds'
mapping = {
'barking': 'dog',
'meowing': 'cat',
'quacking': 'duck'
}
animal_families = AnimalFamilyMap().process(
'I was out on a walk and heard some barking',
max_return_values=1
)
print(animal_families[0])
# Output: dog
from dandy import Agent, Bot
class AssistantAgent(Agent):
# This attribute is required and determines which other processors you want this agent to have access to using.
processors = (
Bot,
)
intel = AssistantAgent().process('Can you give me an idea for a drawing?')
print(intel.content)
# Output: Here's a creative drawing idea for you: A steampunk robot cat ...
Proven performance and developer satisfaction
Real feedback from engineers using Dandy in production
"Dandy cut our prototyping time from weeks to days. The Pythonic API made adoption effortless."
"We shipped AI features to production with almost no downtime. The self-healing behavior is fantastic."
"The tutorial took me just under an hour and with in another hour I had integrated a working feature into our client's project."