An async Python client for the PostGrid Print & Mail API, integrated into the Lead Ignite backend. Built with aiohttp and pydantic for high-performance, type-safe API interactions.
Python License Code style: black Ruff PostGrid API
- π Async-First: Built with
asynciofor non-blocking API interactions - π§ Type Safety: Full Python type hints with Pydantic models
- π‘οΈ Robust Error Handling: Comprehensive error hierarchy and validation
- β± Rate Limiting: Built-in rate limiting with configurable thresholds
- π Automatic Retries: Configurable retry logic with exponential backoff
- π Secure: Environment-based configuration and secrets management
- π¦ Modular Design: Clean separation of concerns with dedicated API modules
- β Test Coverage: Comprehensive test suite with pytest
This package is part of the Lead Ignite backend and is automatically installed as a dependency.
For development:
# Install with poetry
poetry add --group dev -e ./app/core/third_party_integrations/postgridConfiguration is managed through environment variables. Create a .env file in your project root:
# Required POSTGRID_API_KEY=your_live_or_test_api_key # Optional (with defaults shown) POSTGRID_BASE_URL=https://api.postgrid.com/print-mail/v1/ POSTGRID_TIMEOUT=30 POSTGRID_MAX_RETRIES=3 POSTGRID_RATE_LIMIT=50 # Requests per minute
import asyncio from app.core.third_party_integrations.postgrid.client import PostGridClient async def main(): # Initialize with default config (loads from environment) async with PostGridClient() as client: try: # Your code here pass except Exception as e: print(f"Error: {e}") if __name__ == "__main__": asyncio.run(main())
async def send_postcard(): async with PostGridClient() as client: try: postcard = await client.post( "/postcards", json={ "to": { "firstName": "John", "lastName": "Doe", "addressLine1": "123 Main St", "city": "Toronto", "provinceOrState": "ON", "postalOrZip": "M1M1M1", "country": "CA" }, "from": { "company": "Your Company", "addressLine1": "456 Business Ave", "city": "New York", "provinceOrState": "NY", "postalOrZip": "10001", "country": "US" }, "front": "<html>Front HTML</html>", "back": "<html>Back HTML</html>" } ) return postcard except Exception as e: logger.error(f"Failed to send postcard: {e}") raise
Main client class for interacting with the PostGrid API.
Methods:
-
get(endpoint: str, response_model: Type[T] = None, **kwargs) -> Any- Make a GET request to the specified endpoint
- Returns: Parsed response data
-
post(endpoint: str, response_model: Type[T] = None, **kwargs) -> Any- Make a POST request to the specified endpoint
- Returns: Parsed response data
-
put(endpoint: str, response_model: Type[T] = None, **kwargs) -> Any- Make a PUT request to the specified endpoint
- Returns: Parsed response data
-
delete(endpoint: str, **kwargs) -> Any- Make a DELETE request to the specified endpoint
- Returns: Parsed response data
The client supports all PostGrid API endpoints, organized into logical modules:
letters/- Create and manage physical letterspostcards/- Design and send postcardscontacts/- Manage contact informationtemplates/- Store and manage reusable templateswebhooks/- Configure and manage webhook eventstrackers/- Track mail pieces and eventsevents/- Retrieve system and mail events
The client raises specific exceptions for different error scenarios:
PostGridAuthenticationError: Invalid or missing API key (401)PostGridValidationError: Invalid request data (400)PostGridRateLimitError: Rate limit exceeded (429)PostGridAPIError: Other API errors (500+)
Run the test suite with pytest:
pytest app/core/third_party_integrations/postgrid/tests/
Tests use a mock server by default. To run against the live API:
POSTGRID_API_KEY=your_test_key POSTGRID_ENV=test pytest -v
- Follow PEP 8
- Use type hints for all function signatures
- Document all public methods with Google-style docstrings
- Keep functions small and focused
Install pre-commit hooks:
pre-commit install
This project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
For support, please open an issue in the repository or contact the maintainers.
Built with β€οΈ by the Lead Ignite Team
Part of the Lead Ignite Marketing Automation Platform
The main client class for interacting with the PostGrid API.
from postgrid_sdk import PostGridClient # With default config (loads from environment) client = PostGridClient() # Or with custom config from postgrid_sdk.config import PostGridConfig config = PostGridConfig( api_key="your_api_key_here", base_url="https://api.postgrid.com/print-mail/v1/", timeout=30, max_retries=3, rate_limit=50 ) client = PostGridClient(config=config)
get(endpoint: str, **kwargs): Make a GET requestpost(endpoint: str, **kwargs): Make a POST requestput(endpoint: str, **kwargs): Make a PUT requestdelete(endpoint: str, **kwargs): Make a DELETE requestclose(): Close the client session (automatically handled by context manager)
# Run tests pytest # With coverage pytest --cov=postgrid_sdk --cov-report=term-missing # Run with specific test pytest tests/test_client.py -v
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
TechWithTy - @techwithty
Project Link: https://github.com/techwithty/postgrid-python-sdk