Development Guide¶
This guide provides detailed information for developers who want to extend, modify, or contribute to Insight Ingenious - an enterprise-grade Python library for building AI agent APIs with Microsoft Azure integrations. The library's architecture supports extensive customization and debugging capabilities for enterprise development teams.
Development Environment Setup¶
Prerequisites¶
- Python 3.13 or higher
- Git
- uv for Python package management
Setting Up for Development¶
flowchart TD
START([Start Development Setup]) --> CLONE[Clone Repository]
CLONE --> INSTALL[Install Dependencies]
INSTALL --> HOOKS[Setup Pre-commit Hooks]
HOOKS --> INIT[Initialize Project]
INIT --> VERIFY[Verify Setup]
VERIFY --> READY([Ready for Development])
classDef start fill:#c8e6c9
classDef process fill:#e1f5fe
class START,READY start
class CLONE,INSTALL,HOOKS,INIT,VERIFY process
- Clone the repository:
- Install dependencies and set up development environment:
- Set up pre-commit hooks:
- Initialize a test project:
- Verify the setup:
Project Structure¶
ingenious/
├── ingenious/ # Main library code
│ ├── client/ # Azure client integrations
│ ├── core/ # Core framework components
│ ├── db/ # Database and storage
│ ├── models/ # Data models and schemas
│ ├── services/ # Business logic services
│ │ └── chat_services/ # Chat and agent services
│ │ └── multi_agent/ # Multi-agent conversation flows
│ ├── templates/ # Jinja2 prompt templates
│ └── utils/ # Utility functions
├── tests/ # Test suite
├── scripts/ # Development and deployment scripts
├── docs/ # Documentation source
└── pyproject.toml # Project configuration
Development Workflow¶
Code Quality Tools¶
The project uses several tools to maintain code quality:
- Ruff: Fast Python linter and formatter
- MyPy: Static type checking
- Pytest: Testing framework with async support
- Pre-commit: Git hooks for automated checks
Running Tests¶
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=ingenious
# Run specific test file
uv run pytest tests/unit/test_specific.py
# Run specific test method
uv run pytest tests/unit/test_specific.py::TestClass::test_method
Type Checking¶
# Type check the entire codebase
uv run mypy .
# Type check specific module
uv run mypy ingenious/services/
Linting and Formatting¶
# Run all pre-commit hooks
uv run pre-commit run --all-files
# Run ruff linting
uv run ruff check .
# Run ruff formatting
uv run ruff format .
Configuration Management¶
Environment Variables¶
Ingenious uses environment variables with the INGENIOUS_
prefix for configuration:
# Model configuration
INGENIOUS_MODELS__0__MODEL="gpt-4"
INGENIOUS_MODELS__0__API_KEY="your-api-key"
INGENIOUS_MODELS__0__BASE_URL="https://your-endpoint"
# Service configuration
INGENIOUS_CHAT_SERVICE__TYPE="multi_agent"
INGENIOUS_WEB_CONFIGURATION__PORT="8000"
Configuration Schema¶
All configuration is validated using Pydantic models in ingenious/models/configuration.py
.
Extending Ingenious¶
Creating Custom Conversation Flows¶
- Create a new flow module:
# ingenious_extensions/services/chat_services/multi_agent/conversation_flows/my_flow/my_flow.py
from ingenious.services.chat_services.multi_agent.conversation_flows.i_conversation_flow import IConversationFlow
class MyFlow(IConversationFlow):
def get_conversation_response(self, user_prompt: str, **kwargs) -> str:
# Implement your conversation logic
pass
- Add prompt templates:
<!-- templates/prompts/my_agent_prompt.jinja -->
You are a helpful assistant specialized in {{ domain }}.
User query: {{ user_prompt }}
- Register the flow:
The flow is automatically discovered based on the directory name matching the conversation_flow
parameter.
Testing Custom Extensions¶
# Test your custom flow
curl -X POST http://localhost:8000/api/v1/chat \
-H "Content-Type: application/json" \
-d '{
"user_prompt": "Test message",
"conversation_flow": "my_flow"
}'
Database Development¶
Supported Databases¶
- SQLite: Default for development and testing
- Azure SQL: Production deployments
- Cosmos DB: Document storage (experimental)
Migration Scripts¶
# Run database migrations
uv run python scripts/migrate_database.py
# Create new migration
uv run python scripts/create_migration.py --name "add_new_table"
API Development¶
Adding New Endpoints¶
- Create endpoint in appropriate module:
# ingenious/api/v1/my_endpoints.py
from fastapi import APIRouter
router = APIRouter(prefix="/api/v1/my-feature", tags=["my-feature"])
@router.get("/status")
async def get_status():
return {"status": "active"}
- Register in main application:
# ingenious/main/app_factory.py
from ingenious.api.v1.my_endpoints import router as my_router
app.include_router(my_router)
API Documentation¶
The API documentation is automatically generated using FastAPI's OpenAPI integration. Access it at:
- Swagger UI:
http://localhost:8000/docs
- ReDoc:
http://localhost:8000/redoc
- OpenAPI JSON:
http://localhost:8000/openapi.json
Azure Service Integration¶
Adding New Azure Services¶
- Create service client:
# ingenious/client/azure/my_service_client.py
from azure.core.credentials import AzureKeyCredential
from ingenious.client.azure.base_azure_client import BaseAzureClient
class MyServiceClient(BaseAzureClient):
def __init__(self, endpoint: str, credential: AzureKeyCredential):
super().__init__(endpoint, credential)
# Initialize your service client
- Add configuration:
# ingenious/models/configuration.py
class MyServiceConfig(BaseModel):
endpoint: str
api_key: str
# Additional configuration fields
- Register in dependency injection:
# ingenious/services/container.py
container.provide("my_service", MyServiceClient,
endpoint=config.my_service.endpoint,
credential=AzureKeyCredential(config.my_service.api_key))
Debugging and Troubleshooting¶
Logging Configuration¶
# Enable debug logging
INGENIOUS_LOG_LEVEL=DEBUG uv run ingen serve
# Enable Azure SDK logging
AZURE_LOG_LEVEL=DEBUG uv run ingen serve
Common Issues¶
- Port conflicts: Change
INGENIOUS_WEB_CONFIGURATION__PORT
- Azure authentication: Verify service principal credentials
- Database connections: Check connection strings and network access
- Token limits: Monitor usage with built-in tracking
Debug Tools¶
# Enable detailed request logging
import logging
logging.getLogger("ingenious.services").setLevel(logging.DEBUG)
# Profile performance
import cProfile
cProfile.run('your_function()', 'profile_output.prof')
Contributing¶
Pull Request Process¶
- Create feature branch:
- Make changes and test:
- Commit with conventional format:
- Push and create PR:
Code Style Guidelines¶
- Follow PEP 8 with 88-character line length
- Use type hints for all function signatures
- Document public APIs with docstrings
- Write tests for new functionality
- Keep functions focused and modular
Documentation¶
- Update relevant documentation files
- Include code examples for new features
- Add docstrings for public APIs
- Update configuration examples if needed
Release Process¶
Version Management¶
Versions follow semantic versioning (SemVer):
# Major version (breaking changes)
0.1.0 -> 1.0.0
# Minor version (new features)
1.0.0 -> 1.1.0
# Patch version (bug fixes)
1.1.0 -> 1.1.1
Release Checklist¶
- Update version in
pyproject.toml
- Update
CHANGELOG.md
- Run full test suite
- Build and test package
- Tag release and push
- Publish to PyPI
# Build package
uv build
# Test package installation
pip install dist/ingenious-*.whl
# Tag and push release
git tag v1.0.0
git push origin v1.0.0
# Publish to PyPI
uv publish
Need Help?¶
- Check existing issues on GitHub
- Review the architecture documentation
- Look at existing code examples
- Ask questions in discussions or issues