AI Provider Interaction Platform - A flexible framework for interacting with various AI provider APIs.
Project description
AIPIP: AI Provider Interaction Platform
Vision
This project, AIPIP (AI Provider Interaction Platform), aims to build a flexible and extensible Python platform for interacting with various AI provider APIs. While the initial focus is on text generation using Large Language Models (LLMs), the architecture is designed to accommodate future expansion into other modalities like image generation, audio processing, streaming responses, and more complex multi-modal interactions as AI capabilities evolve.
Architecture Overview
The platform follows a modular, service-oriented architecture to promote decoupling, testability, and maintainability.
Note on Inspiration: This architecture draws inspiration from projects like aisuite, which also provide a unified interface to multiple AI providers. However, we have chosen a custom layered approach with a distinct Service Layer to better support the goal of building a broader application platform. This separation allows for more flexibility in integrating diverse functionalities (e.g., complex evaluation workflows, data analysis, problem generation) on top of the core provider interactions, leading to better separation of concerns and maintainability as the application scope grows beyond simple API calls.
-
Configuration (
config/):- Uses Pydantic models for defining structured and validated configurations.
- Centralized loading mechanism (e.g., from environment variables,
.envfiles, or dedicated config files) to manage API keys, provider settings, model parameters, etc. - Secure handling of sensitive information like API keys.
-
Provider Abstraction (
providers/interfaces/):- Defines abstract base classes (ABCs) or interfaces for different types of AI interactions (e.g.,
TextProviderInterface,ImageProviderInterface). - These interfaces enforce a common set of methods (e.g.,
generate_completion,generate_image) that specific provider implementations must adhere to.
- Defines abstract base classes (ABCs) or interfaces for different types of AI interactions (e.g.,
-
Provider Implementations (
providers/clients/):- Concrete classes implementing the provider interfaces for specific vendors (e.g.,
AnthropicClient,GoogleClient,OpenAIClientimplementingTextProviderInterface). - Each client class encapsulates the logic for interacting with a specific provider's SDK/API.
- Clients receive their necessary configuration (API key, etc.) via dependency injection during initialization, making them stateless regarding configuration loading.
- Concrete classes implementing the provider interfaces for specific vendors (e.g.,
-
Provider Registry/Factory (
providers/registry.py):- A central component responsible for instantiating and managing provider client objects based on the loaded application configuration.
- Provides a way for other parts of the application (like services) to request and obtain initialized provider instances without needing to know the instantiation details.
-
Service Layer (
services/):- Contains modules with specific business logic (e.g.,
TextGenerationService). - Services depend on the Provider Registry to get the necessary provider clients via their interfaces.
- Encapsulates workflows and orchestrates calls to providers. Services like
TextGenerationServicemay offer methods for single calls (generate) or batch/comparative calls (generate_batch).
- Contains modules with specific business logic (e.g.,
-
Application Entry Points (
cli/,api/, or separate apps):- Entry points for interacting with the
aipiplibrary (e.g., the exampleaipip.cli.run_text_generationscript). - Separate applications (like the planned
evaluation_app) can be built on top of theaipiplibrary by importing its services.
- Entry points for interacting with the
-
Utilities (
utils/):- Shared helper functions and classes used across different parts of the application.
-
Testing (
tests/):- Comprehensive unit and integration tests for all components, facilitated by the decoupled architecture and dependency injection.
-
Tool Calling / Function Calling:
- Support for provider-specific tool/function calling mechanisms will be integrated.
- The common
TextProviderInterfacewill likely include methods or parameters to pass tool schemas and receive tool invocation requests from the LLM. - Provider client implementations (
providers/clients/) will handle the specific API interactions for tool use. - Services (
services/) can then orchestrate multi-turn conversations involving tool execution, potentially drawing inspiration from patterns likeaisuite's automatic execution flow in later phases.
Proposed Directory Structure
.
├── src/
│ └── aipip/ # Main package source code
│ ├── __init__.py
│ ├── config/
│ │ ├── __init__.py
│ │ ├── models.py
│ │ └── loader.py
│ ├── providers/
│ │ ├── __init__.py
│ │ ├── interfaces/
│ │ │ ├── __init__.py
│ │ │ └── text_provider.py
│ │ ├── clients/
│ │ │ ├── __init__.py
│ │ │ ├── anthropic_client.py
│ │ │ ├── google_client.py
│ │ │ └── openai_client.py
│ │ └── registry.py
│ ├── services/
│ │ ├── __init__.py
│ │ └── text_generation_service.py # Provides core generation logic
│ ├── utils/
│ │ ├── __init__.py
│ │ └── helpers.py
│ └── cli/
│ ├── __init__.py
│ └── run_text_generation.py # Example CLI using the service
├── evaluation_app/ # Example application using the aipip library
│ ├── __init__.py
│ ├── run_evaluation.py
│ └── ... # App-specific logic, prompts, etc.
├── tests/
│ ├── integration/
│ ├── providers/
│ └── ... # Unit and integration tests
├── .gitignore
├── LICENSE
├── README.md
├── pyproject.toml # Build system & project metadata
└── main.py # Optional: Example top-level script (if needed)
Roadmap & Current Status
This README outlines the target architecture. We will migrate functionality from the old structure progressively.
Phase 1: Core Text Generation Setup (COMPLETE)
- Configuration System: Define Pydantic models (
config/models.py) and loading mechanism (config/loader.py). - Text Provider Interface: Define
TextProviderInterface(providers/interfaces/text_provider.py). - Provider Implementations:
anthropic_client.py,google_client.py,openai_client.pyclasses implementing the interface. - Provider Registry: Implement
ProviderRegistry(providers/registry.py) to instantiate and provide clients. - Text Generation Service: Create an initial
TextGenerationService(services/text_generation_service.py) using the registry. - Basic CLI Entry Point: Create a simple CLI script (
cli/run_text_generation.py) to test the structure. - Unit Tests: Add basic unit tests for config loading, registry, and provider clients (using mocks).
- Integration Tests: Add basic integration tests (
tests/integration/) for providers.
Phase 2: Enhance Core & Build Example Applications
- Evaluation Application (
evaluation_app/): Design and implement a separate application usingaipip(and potentiallygenerate_batch) to run logic problems against different providers/models, collect results, and potentially perform basic analysis. - Token Counting: Add token counting capabilities to the provider interface and clients (or use external library like
tiktoken), potentially exposing it via the service layer. - Batch Generation: Enhance
TextGenerationServicewith agenerate_batchmethod to run the same input against multiple models/configurations for a provider. - Tool Calling Support: Implement basic tool/function calling capabilities in the text provider interface and clients, and update the
TextGenerationServiceto handle them. - Refactor: Adapt prompt generation/result parsing logic into reusable utilities (
aipip/utils/) or parts of theevaluation_appas needed. - Add comprehensive tests for new core features and the evaluation application.
Phase 3: Future Enhancements & Applications (Examples)
- Logic Solution Analysis Application: A separate app using
aipipto analyze/compare the quality of solutions generated for logic problems. - Problem Generation Service/Application: Using
aipipto generate new logic problems or other evaluation data. - Image Generation Provider Interface & Implementations
- Audio Processing Provider Interface & Implementations
- Streaming Support in Providers & Services
- Advanced Error Handling, Retries, and Rate Limiting
- Adapting to Evolving Standards: Monitor and adapt provider clients and interfaces to support emerging standards for structured context communication (e.g., Anthropic's Model Context Protocol - MCP) as they gain adoption.
- Asynchronous Provider Implementations (
asyncio) - Web API (e.g., using FastAPI)
- User Interface
- Deployment Setup (Docker, CI/CD)
- Advanced Tool Calling: Implement more sophisticated tool handling (e.g., automatic execution flows).
(This list will be updated as the project progresses)
Setup & Usage
- Prerequisites: Python 3.9+
- Installation: Follow the Local Development Setup instructions to install the package editable along with development dependencies (
pip install -e '.[dev]'). - API Keys: Create a
.envfile in the project root and add your API keys:# .env (ensure this file is in .gitignore) ANTHROPIC_API_KEY="your_anthropic_key" GOOGLE_API_KEY="your_google_key" OPENAI_API_KEY="your_openai_key"
Alternatively, export these as environment variables. - Basic CLI Usage:
# Example: Anthropic (using --prompt, requires max_tokens) python -m aipip.cli.run_text_generation --provider anthropic --prompt "Haiku about clouds" --model claude-3-haiku-20240307 --max-tokens 30 # Example: Google (using --messages) python -m aipip.cli.run_text_generation --provider google --messages user "What is AGI?" # Example: OpenAI (using --prompt and --temperature) python -m aipip.cli.run_text_generation --provider openai --prompt "Tell me about the Zen of Python" --temperature 0.8 # Example: OpenAI (using --messages) python -m aipip.cli.run_text_generation --provider openai --messages user "What is the capital of France?" assistant "Paris" user "Is it sunny there?"
Local Development Setup
It is highly recommended to use a virtual environment for local development to isolate project dependencies.
-
Create a virtual environment:
python -m venv .venv
-
Activate the environment:
- macOS/Linux:
source .venv/bin/activate
- Windows (Command Prompt/PowerShell):
.\.venv\Scripts\activate
(Your terminal prompt should now show
(.venv)) - macOS/Linux:
-
Install the package in editable mode with development dependencies:
pip install -e '.[dev]'
The
-eflag installs the package in "editable" mode, meaning changes to the source code insrc/will be reflected immediately without needing to reinstall. The[dev]part installs the extra dependencies listed under[project.optional-dependencies.dev]inpyproject.toml(likepytest). -
Run tests: With the virtual environment activated, you can run tests using pytest:
pytest
-
Deactivate the environment when you're finished:
deactivate
Testing Strategy
This project uses pytest as the testing framework.
- Tests are located in the
tests/directory. - The structure of
tests/should mirror the structure ofsrc/aipip/where applicable (e.g., tests forsrc/aipip/config/go intotests/config/). - The goal is to achieve good test coverage through a combination of:
- Unit Tests: Testing individual functions, classes, or methods in isolation.
- Integration Tests: Testing the interaction between different components (e.g., a service interacting with a provider client).
- Focus on testing the core logic, public interfaces, and expected behaviors (including edge cases and error handling) of the package components.
- Tests can be run using the
pytestcommand after setting up the local development environment (see "Local Development Setup" section).
Running Tests
Tests can be run using pytest after setting up the local development environment.
- Run all tests (Unit & Integration):
pytest
- Run only unit tests: (Faster, no network/API keys needed)
pytest -m "not integration"
- Run only integration tests: (Requires network and API keys in
.envor environment)pytest -m integration
- See output during tests: To see
print()statements (like the responses from integration tests), use the-sflag:pytest -s -m integration # Run integration tests and show output pytest -s # Run all tests and show output
Integration Tests (tests/integration/)
- Integration tests verify the interaction with live provider APIs.
- They are marked with the
integrationmarker (configured inpyproject.toml). - Prerequisites: Requires valid API keys for the providers being tested. These keys should be stored in a
.envfile in the project root (and this file should be in.gitignore) or exported as environment variables (e.g.,ANTHROPIC_API_KEY,GOOGLE_API_KEY,OPENAI_API_KEY). The tests load the.envfile automatically and will skip if the required key for a specific provider test is not found. - Cost & Time: Be aware that running these tests incurs API costs and takes longer than unit tests.
- Purpose: Verify connectivity, authentication, and basic request/response compatibility with the live APIs.
Handling Upstream API Changes
This library relies on the official Python SDKs provided by the respective AI vendors (e.g., anthropic, google-generativeai, openai). Changes to these upstream SDKs or their underlying APIs can impact aipip.
Strategy:
- Dependency Management: We specify version ranges for provider SDKs in
pyproject.toml(e.g.,openai>=1.0,<2.0) to prevent automatically pulling in potentially breaking major version updates. Minor/patch updates from providers will be tested before updating the lower bound. - Interface Stability: The core
TextProviderInterfaceaims for stability. Common parameters are defined explicitly. Provider-specific parameters are handled via**kwargspassed directly to the client implementation, allowing flexibility without constant interface changes. - Client Implementation Responsibility: Each concrete client class (e.g.,
AnthropicClient,GoogleClient,OpenAIClient) is responsible for adapting to changes in its specific upstream SDK. This involves updating:- Parameter mapping (from interface calls to SDK calls).
- Method calls to the SDK.
- Response parsing.
- Testing: Our unit tests for each client (e.g.,
test_openai_client.py) use mocking to simulate the provider SDK. These tests are crucial for detecting when an SDK update breaks our client's implementation, as the mocks or the expected call signatures/responses will no longer align. - Monitoring & Maintenance: We will monitor provider announcements and SDK releases. When breaking changes occur in an upstream SDK, the corresponding
aipipclient implementation and its tests will be updated, and a new version ofaipipwill be released.
This approach allows aipip to provide a consistent interface while managing the inevitable evolution of the underlying provider APIs and SDKs.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
(Contribution guidelines will be added later)
Releasing to PyPI
This project uses PyPI's trusted publishing for automated releases.
The release process is triggered automatically by pushing a Git tag that matches the version pattern v*.*.* (e.g., v0.1.0, v1.2.3).
The .github/workflows/publish-to-pypi.yml GitHub Actions workflow handles:
- Building the source distribution and wheel.
- Uploading the package to PyPI using the trusted publisher configuration.
No manual API token configuration is required in GitHub secrets.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aipip-0.1.0.tar.gz.
File metadata
- Download URL: aipip-0.1.0.tar.gz
- Upload date:
- Size: 24.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84bff152ea2b8c8b3cc723b8a9e1ebd955d5f386f8fc7229837df9b2da20a851
|
|
| MD5 |
e9d21106207ee908b7a3100fb16b9c96
|
|
| BLAKE2b-256 |
61fe77d6f0cf8052190b8880e1604bed9ddac730c8c8778f68d7d8825db6c236
|
Provenance
The following attestation bundles were made for aipip-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on artifig/aipip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aipip-0.1.0.tar.gz -
Subject digest:
84bff152ea2b8c8b3cc723b8a9e1ebd955d5f386f8fc7229837df9b2da20a851 - Sigstore transparency entry: 200552898
- Sigstore integration time:
-
Permalink:
artifig/aipip@436a1002295730a659608e403fbc26c58deb3d12 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/artifig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@436a1002295730a659608e403fbc26c58deb3d12 -
Trigger Event:
push
-
Statement type:
File details
Details for the file aipip-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aipip-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eced1197b859edd7f9117fcd49e6b6f588ff05aaa6f3698d2a767a1d810a379f
|
|
| MD5 |
07185b084250c236555a71edd97357d4
|
|
| BLAKE2b-256 |
3eab600d2b14e0ec5f7ce7ea12cda7b812850ead71cb39fe0db1c07c9981e652
|
Provenance
The following attestation bundles were made for aipip-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on artifig/aipip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aipip-0.1.0-py3-none-any.whl -
Subject digest:
eced1197b859edd7f9117fcd49e6b6f588ff05aaa6f3698d2a767a1d810a379f - Sigstore transparency entry: 200552900
- Sigstore integration time:
-
Permalink:
artifig/aipip@436a1002295730a659608e403fbc26c58deb3d12 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/artifig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@436a1002295730a659608e403fbc26c58deb3d12 -
Trigger Event:
push
-
Statement type: