{"slug": "the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider", "title": "The Requests library for AI one Unified Python SDK for every LLM provider", "summary": "UniversalAI, a new open-source Python SDK, provides a unified interface for interacting with nine major LLM providers, including OpenAI, Anthropic, Gemini, and Ollama. The SDK supports async-first operations, streaming, tool calling, middleware, routing, vision, audio, image generation, embeddings, RAG, agents, context safety, cost tracking, and a CLI, aiming to simplify AI application development.", "body_md": "**The Requests library for AI** — one unified SDK for every LLM provider. Write once, run anywhere.\n\n```\npip install universal-ai\npython\nfrom universal_ai import AI\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\nresponse = await ai.chat(\"What is quantum computing?\")\nprint(response.content)\n```\n\nBuilding AI applications today means juggling multiple provider SDKs, each with different APIs, error handling, and quirks. UniversalAI gives you **one clean interface** that works across all major providers:\n\n| Feature | Description |\n|---|---|\n9 Providers |\nOpenAI, Anthropic, Gemini, Ollama, Groq, Mistral, OpenRouter, HuggingFace, Azure OpenAI |\nAsync-first |\nFull `async` /`await` with synchronous wrappers for scripts and notebooks |\nStreaming |\nReal-time token streaming from any provider |\nTool Calling |\n`@tool` decorator with automatic execution loop |\nMiddleware |\nRetry, cache, rate limit, circuit breaker, cost tracking, logging |\nRouting |\nFallback, round-robin, lowest latency, lowest cost strategies |\nVision |\nImage-aware chat with OpenAI, Anthropic, Gemini |\nAudio |\nTranscription (Whisper) and TTS with OpenAI |\nImage Generation |\nDALL-E 3 support |\nEmbeddings |\nOpenAI, Gemini, Mistral, HuggingFace, Azure, OpenRouter |\nRAG |\nBuilt-in retrieval-augmented generation with chunking and vector store |\nAgents |\nMulti-agent orchestration with coordinator pattern |\nContext Safety |\nAutomatic validation and optional truncation |\nCost Tracking |\nPer-request and cumulative cost estimation |\nCLI |\nFull-featured `uai` command-line tool |\n\n```\n# Core SDK (auto-detects available providers)\npip install universal-ai\n\n# With specific provider support\npip install universal-ai[openai]\npip install universal-ai[anthropic]\npip install universal-ai[gemini]\npip install universal-ai[ollama]\n\n# Everything\npip install universal-ai[all]\npython\nimport asyncio\nfrom universal_ai import AI\n\nasync def main():\n    # Auto-detect provider from environment\n    ai = AI()\n\n    # Chat\n    response = await ai.chat(\"Explain quantum computing in one sentence\")\n    print(response.content)\n\n    # Streaming\n    async for chunk in ai.stream(\"Write a haiku about programming\"):\n        print(chunk.delta, end=\"\", flush=True)\n\n    # Embeddings\n    embed_response = await ai.embed(\"Hello, world!\")\n    print(f\"Embedding dimensions: {len(embed_response.vector)}\")\n\nasyncio.run(main())\npython\nfrom universal_ai import AI\n\n# OpenAI\nai = AI(provider=\"openai\", model=\"gpt-4o\")\nresponse = await ai.chat(\"Hello!\")\n\n# Anthropic\nai = AI(provider=\"anthropic\", model=\"claude-sonnet-4-20250514\")\nresponse = await ai.chat(\"Hello!\")\n\n# Local Ollama\nai = AI(provider=\"ollama\", model=\"llama3\")\nresponse = await ai.chat(\"Hello!\")\npython\nfrom universal_ai import AI\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Synchronous wrappers for scripts/notebooks\nresponse = ai.chat_sync(\"Hello!\")\nprint(response.content)\n\n# Sync streaming (returns full text)\ntext = ai.stream_sync(\"Tell me a joke\")\nprint(text)\n```\n\nDefine tools with the `@tool`\n\ndecorator and let the AI use them:\n\n``` python\nfrom universal_ai import AI, tool\n\n@tool\ndef get_weather(city: str, unit: str = \"celsius\") -> str:\n    \"\"\"Get current weather for a city.\"\"\"\n    # In a real app, call a weather API\n    return f\"Weather in {city}: 22°{unit[0].upper()}, sunny\"\n\n@tool\ndef calculate(expression: str) -> str:\n    \"\"\"Evaluate a mathematical expression.\"\"\"\n    return str(eval(expression))\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# The AI will automatically call your tools\nresponse = await ai.chat(\n    \"What's the weather in Paris? Also calculate 15 * 23.\",\n    tools=[get_weather, calculate]\n)\nprint(response.content)\nphp\nfrom universal_ai import AI, tool\n\n@tool\ndef search(query: str) -> str:\n    \"\"\"Search the web.\"\"\"\n    return f\"Results for: {query}\"\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\nai.register_tool(search)\n\n# Tools are auto-executed in the tool loop\nresponse = await ai.chat(\"Search for Python tutorials\")\n```\n\nMulti-turn conversations with automatic history management:\n\n``` python\nfrom universal_ai import AI\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Create a conversation\nconv = ai.conversation(\n    system_prompt=\"You are a helpful cooking assistant.\",\n    max_turns=20\n)\n\n# Send messages\nresponse = await conv.send(message=\"What should I cook for dinner?\")\nprint(response.content)\n\nresponse = await conv.send(message=\"Can you give me a recipe?\")\nprint(response.content)\n\n# Access history\nprint(f\"Turn count: {conv.turn_count}\")\nprint(f\"Messages: {len(conv.history)}\")\n\n# Reset\nconv.reset()\n# Provider selection\nexport UNIVERSALAI_PROVIDER=openai\nexport UNIVERSALAI_MODEL=gpt-4o\n\n# API keys (provider-specific)\nexport OPENAI_API_KEY=sk-...\nexport ANTHROPIC_API_KEY=sk-ant-...\nexport GEMINI_API_KEY=...\nexport GROQ_API_KEY=gsk_...\nexport MISTRAL_API_KEY=...\nexport OPENROUTER_API_KEY=sk-or-...\nexport HF_API_KEY=hf_...\n\n# Azure OpenAI\nexport AZURE_OPENAI_API_KEY=...\nexport AZURE_OPENAI_API_BASE=https://your-resource.openai.azure.com\nexport AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o\n\n# Ollama (local)\nexport OLLAMA_HOST=http://localhost:11434\n# ~/.config/universalai/config.yaml\nprovider: openai\nmodel: gpt-4o\ntemperature: 0.7\nmax_tokens: 4096\ntimeout: 30\nmax_retries: 3\nauto_truncate: true\n\nfallback_providers:\n  - anthropic\n  - gemini\n\nprovider_api_keys:\n  openai: sk-...\n  anthropic: sk-ant-...\npython\nfrom universal_ai import AI, Config\n\nconfig = Config(\n    provider=\"openai\",\n    model=\"gpt-4o\",\n    temperature=0.7,\n    max_tokens=4096,\n    timeout=30,\n    max_retries=3,\n    auto_truncate=True,\n    provider_api_keys={\n        \"openai\": \"sk-...\",\n        \"anthropic\": \"sk-ant-...\",\n    }\n)\n\nai = AI(config=config)\n```\n\nAdd resilience and observability to your requests:\n\n``` python\nfrom universal_ai import AI\nfrom universal_ai.middleware import (\n    RetryMiddleware,\n    CacheMiddleware,\n    RateLimitMiddleware,\n    CircuitBreakerMiddleware,\n    CostTrackingMiddleware,\n    LoggingMiddleware,\n)\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Add middleware in order (executed top to bottom)\nai.add_middleware(LoggingMiddleware())\nai.add_middleware(CostTrackingMiddleware())\nai.add_middleware(RetryMiddleware(max_retries=3, base_delay=1.0))\nai.add_middleware(CacheMiddleware(ttl=300))\nai.add_middleware(RateLimitMiddleware(requests_per_minute=60))\nai.add_middleware(CircuitBreakerMiddleware(failure_threshold=5))\n\n# All requests now go through the middleware pipeline\nresponse = await ai.chat(\"Hello!\")\n```\n\n| Middleware | Purpose | Key Options |\n|---|---|---|\n`RetryMiddleware` |\nRetry failed requests |\n`max_retries` , `base_delay` , `max_delay` , `jitter`\n|\n`CacheMiddleware` |\nCache responses |\n`ttl` , `backend` (memory/sqlite/redis) |\n`RateLimitMiddleware` |\nLimit request rate |\n`requests_per_minute` , `burst`\n|\n`CircuitBreakerMiddleware` |\nStop cascading failures |\n`failure_threshold` , `recovery_timeout`\n|\n`CostTrackingMiddleware` |\nTrack API costs | — |\n`LoggingMiddleware` |\nLog requests/responses | `log_level` |\n\nAutomatically select the best provider:\n\n``` python\nfrom universal_ai import AI\nfrom universal_ai.router import (\n    Router,\n    FallbackStrategy,\n    RoundRobinStrategy,\n    LowestLatencyStrategy,\n    LowestCostStrategy,\n)\n\n# Configure fallback in config\nconfig = Config(\n    provider=\"openai\",\n    fallback_providers=[\"anthropic\", \"gemini\"]\n)\n\nai = AI(config=config)\n\n# Or use router directly\nrouter = Router(\n    providers=[\"openai\", \"anthropic\", \"gemini\"],\n    strategy=FallbackStrategy()\n)\n```\n\n| Strategy | Behavior |\n|---|---|\n`FallbackStrategy` |\nTry first provider, failover to next on error |\n`RoundRobinStrategy` |\nDistribute requests evenly across providers |\n`LowestLatencyStrategy` |\nAlways use the fastest responding provider |\n`LowestCostStrategy` |\nAlways use the cheapest provider |\n\nBuild knowledge-base powered chat:\n\n``` python\nfrom universal_ai import AI\nfrom universal_ai.rag import RAG, TextLoader, DirectoryLoader\n\n# Initialize RAG\nrag = RAG(chunk_size=500, chunk_overlap=50, top_k=3)\n\n# Add content\nrag.add_text(\"Python is a high-level programming language...\")\nrag.add_document(Document(content=\"...\", source=\"docs.txt\"))\nrag.add_folder(\"./knowledge_base\")\nrag.add_url(\"https://example.com/article.txt\")\nrag.add_github(\"owner/repo\")\n\n# Search\nchunks = await rag.search(\"What is Python?\")\nfor chunk in chunks:\n    print(f\"Score: {chunk.content[:50]}...\")\n\n# Use with AI\nai = AI(provider=\"openai\", model=\"gpt-4o\")\naugmented_request = await rag.augment_request(chat_request)\nresponse = await ai.chat(augmented_request)\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Transcribe audio file\ntext = await ai.transcribe(\"audio.mp3\")\nprint(text)\n\n# Transcribe from bytes\ntext = await ai.transcribe(audio_bytes)\n# Generate speech\naudio_bytes = await ai.speak(\"Hello, world!\", voice=\"alloy\")\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n# Generate image\nurls = await ai.image(\"A sunset over mountains\", size=\"1024x1024\")\nprint(urls[0])  # URL to generated image\n```\n\nUniversalAI includes a full-featured command-line tool:\n\n```\n# Chat interactively\nuai chat\n\n# Chat with specific provider\nuai chat -p openai -m gpt-4o\n\n# Send a single message\nuai chat \"What is machine learning?\"\n\n# List available providers\nuai providers\n\n# Run diagnostics\nuai doctor\n\n# Manage configuration\nuai config show\nuai config set provider openai\nuai config set-api-key openai\n\n# Benchmark providers\nuai benchmark --iterations 10\n\n# Start local API server\nuai serve --port 8000\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Features: Chat, Streaming, Vision, Tools, Embeddings, Audio, Image Gen\n# Requires: OPENAI_API_KEY\nai = AI(provider=\"anthropic\", model=\"claude-sonnet-4-20250514\")\n\n# Features: Chat, Streaming, Vision, Tools\n# Requires: ANTHROPIC_API_KEY\nai = AI(provider=\"gemini\", model=\"gemini-2.0-flash\")\n\n# Features: Chat, Streaming, Vision, Tools, Embeddings\n# Requires: GEMINI_API_KEY\nai = AI(provider=\"ollama\", model=\"llama3\")\n\n# Features: Chat, Streaming, Embeddings\n# Requires: Ollama running locally\n# Install: https://ollama.ai\nai = AI(provider=\"groq\", model=\"llama-3.1-70b-versatile\")\n\n# Features: Chat, Streaming, Tools\n# Requires: GROQ_API_KEY\nai = AI(provider=\"mistral\", model=\"mistral-large-latest\")\n\n# Features: Chat, Streaming, Tools, Embeddings\n# Requires: MISTRAL_API_KEY\nai = AI(provider=\"openrouter\", model=\"openai/gpt-4o\")\n\n# Features: Chat, Streaming, Vision, Tools, Embeddings\n# Requires: OPENROUTER_API_KEY\nai = AI(provider=\"huggingface\", model=\"meta-llama/Llama-2-7b-chat-hf\")\n\n# Features: Chat, Streaming, Embeddings\n# Requires: HF_API_KEY\nai = AI(provider=\"azure\", model=\"gpt-4o\")\n\n# Features: Chat, Streaming, Vision, Tools, Embeddings\n# Requires: AZURE_OPENAI_API_KEY, AZURE_OPENAI_API_BASE\npython\nfrom universal_ai import AI\nfrom universal_ai.exceptions import (\n    AuthenticationError,\n    RateLimitError,\n    ContextWindowExceededError,\n    ProviderError,\n    TimeoutError,\n)\n\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\ntry:\n    response = await ai.chat(\"Hello!\")\nexcept AuthenticationError as e:\n    print(f\"Invalid API key: {e}\")\nexcept RateLimitError as e:\n    print(f\"Rate limited, retry after: {e.retry_after}s\")\nexcept ContextWindowExceededError as e:\n    print(f\"Context too long: {e.estimated_tokens} > {e.context_window}\")\nexcept ProviderError as e:\n    print(f\"Provider error: {e}\")\nexcept TimeoutError:\n    print(\"Request timed out\")\n```\n\nUniversalAI validates that messages fit within the provider's context window:\n\n``` python\nfrom universal_ai import AI, Config\n\n# Option 1: Raise error if too long (default)\nconfig = Config(auto_truncate=False)\nai = AI(config=config)\n\n# Option 2: Auto-truncate to fit\nconfig = Config(auto_truncate=True)\nai = AI(config=config)\nai = AI(provider=\"openai\", model=\"gpt-4o\")\n\n# Estimate cost before sending\nestimated_cost = ai.estimate_cost(\"Hello, world!\")\nprint(f\"Estimated cost: ${estimated_cost:.6f}\")\n\n# Track actual costs with middleware\nfrom universal_ai.middleware import CostTrackingMiddleware\n\ncost_middleware = CostTrackingMiddleware()\nai.add_middleware(cost_middleware)\n\nresponse = await ai.chat(\"Hello!\")\nprint(f\"Actual cost: ${response.usage.estimated_cost:.6f}\")\nprint(f\"Total cost: ${cost_middleware.total_cost:.6f}\")\n```\n\nFor scripts and notebooks where you can't use `async`\n\n:\n\n| Async Method | Sync Wrapper |\n|---|---|\n`await ai.chat(...)` |\n`ai.chat_sync(...)` |\n`async for chunk in ai.stream(...)` |\n`ai.stream_sync(...)` |\n`await ai.embed(...)` |\n`ai.embed_sync(...)` |\n`await ai.chat_with_tools(...)` |\n`ai.chat_with_tools_sync(...)` |\n`await ai.chat_json(...)` |\n`ai.chat_json_sync(...)` |\n\nSee the [ examples/](https://dev.toexamples/) directory for complete working examples:\n\n`basic_chat.py`\n\n- Simple chat usage`streaming.py`\n\n- Real-time streaming`tool_calling.py`\n\n- Tool definition and execution`middleware_demo.py`\n\n- Middleware configuration`rag_demo.py`\n\n- RAG with document loading`multi_provider.py`\n\n- Provider switchingWe welcome contributions! Please see [CONTRIBUTING.md](https://CONTRIBUTING.md) for guidelines.\n\n```\n# Clone the repo\ngit clone https://github.com/6t9xstar/universal-ai.git\ncd universal-ai\n\n# Install dev dependencies\npip install -e \".[dev]\"\n\n# Run tests\npytest\n\n# Run linting\nruff check .\n\n# Run type checking\nmypy .\n```\n\nMIT License - see [LICENSE](https://dev.toLICENSE) for details.", "url": "https://wpnews.pro/news/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider", "canonical_source": "https://dev.to/6t9/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider-3job", "published_at": "2026-07-31 20:19:48+00:00", "updated_at": "2026-07-31 20:43:17.311877+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "large-language-models", "artificial-intelligence"], "entities": ["UniversalAI", "OpenAI", "Anthropic", "Gemini", "Ollama", "Groq", "Mistral", "OpenRouter"], "alternates": {"html": "https://wpnews.pro/news/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider", "markdown": "https://wpnews.pro/news/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider.md", "text": "https://wpnews.pro/news/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider.txt", "jsonld": "https://wpnews.pro/news/the-requests-library-for-ai-one-unified-python-sdk-for-every-llm-provider.jsonld"}}