Official Python SDK for the Ziptax API
Project description
Ziptax Python SDK
Official Python SDK for the Ziptax API - Get accurate sales and use tax rates for any US or Canadian address.
Features
- 🚀 Simple and intuitive API
- 🔄 Automatic retry logic with exponential backoff
- ✅ Input validation
- 🔍 Type hints for better IDE support
- 📦 Pydantic models for response validation
- 🔒 Comprehensive error handling
- ⚡ Support for concurrent operations
- 🧪 Well-tested with high code coverage
Installation
pip install ziptax-sdk
Quick Start
from ziptax import ZipTaxClient
# Initialize the client with your API key
client = ZipTaxClient.api_key("your-api-key-here")
# Get sales tax by address
response = client.request.GetSalesTaxByAddress(
"200 Spectrum Center Drive, Irvine, CA 92618"
)
print(f"Address: {response.addressDetail.normalizedAddress}")
if response.tax_summaries:
for summary in response.tax_summaries:
print(f"{summary.summary_name}: {summary.rate * 100:.2f}%")
# Always close the client when done
client.close()
Usage
Initialize the Client
from ziptax import ZiptaxClient
# Basic initialization
client = ZiptaxClient.api_key("your-api-key-here")
# With custom configuration
client = ZiptaxClient.api_key(
"your-api-key-here",
timeout=60, # Request timeout in seconds
max_retries=5, # Maximum retry attempts
retry_delay=2.0, # Base delay between retries
)
# Using as a context manager (recommended)
with ZiptaxClient.api_key("your-api-key-here") as client:
response = client.request.GetSalesTaxByAddress("123 Main St")
Get Sales Tax by Address
response = client.request.GetSalesTaxByAddress(
address="200 Spectrum Center Drive, Irvine, CA 92618",
country_code="USA", # Optional: "USA" or "CAN" (default: "USA")
historical="2024-01", # Optional: Historical date (YYYY-MM format)
format="json", # Optional: "json" or "xml" (default: "json")
)
# Access response data
print(response.addressDetail.normalizedAddress)
print(response.addressDetail.geoLat)
print(response.addressDetail.geoLng)
# Response code
print(f"Response: {response.metadata.response.code} - {response.metadata.response.message}")
# Tax summaries with display rates
if response.tax_summaries:
for summary in response.tax_summaries:
print(f"{summary.summary_name}: {summary.rate}")
for display_rate in summary.display_rates:
print(f" {display_rate.name}: {display_rate.rate}")
# Base rates by jurisdiction
if response.base_rates:
for rate in response.base_rates:
print(f"{rate.jur_name} ({rate.jur_type}): {rate.rate}")
# Sourcing rules
if response.sourcing_rules:
print(f"Sourcing: {response.sourcing_rules.value}")
Get Sales Tax by Geolocation
response = client.request.GetSalesTaxByGeoLocation(
lat="33.6489",
lng="-117.8386",
country_code="USA",
format="json",
)
print(response.addressDetail.normalizedAddress)
Get Account Metrics
metrics = client.request.GetAccountMetrics()
print(f"Core Requests: {metrics.core_request_count:,} / {metrics.core_request_limit:,}")
print(f"Core Usage: {metrics.core_usage_percent:.2f}%")
print(f"Geo Requests: {metrics.geo_request_count:,} / {metrics.geo_request_limit:,}")
print(f"Geo Usage: {metrics.geo_usage_percent:.2f}%")
print(f"Account Active: {metrics.is_active}")
Configuration
You can configure the client using dict-style access:
client = ZiptaxClient.api_key("your-api-key-here")
# Set configuration options
client.config["format"] = "json"
client.config["timeout"] = 60
# Get configuration options
timeout = client.config["timeout"]
Error Handling
The SDK provides comprehensive error handling with specific exception types:
from ziptax import (
ZipTaxClient,
ZipTaxValidationError,
ZipTaxAuthenticationError,
ZipTaxRateLimitError,
ZipTaxServerError,
ZipTaxError,
)
client = ZipTaxClient.api_key("your-api-key-here")
try:
response = client.request.GetSalesTaxByAddress("123 Main St")
except ZipTaxValidationError as e:
# Input validation errors
print(f"Validation error: {e.message}")
except ZipTaxAuthenticationError as e:
# Authentication failures (401)
print(f"Authentication error: {e.message}")
except ZipTaxRateLimitError as e:
# Rate limit exceeded (429)
print(f"Rate limit error: {e.message}")
if e.retry_after:
print(f"Retry after {e.retry_after} seconds")
except ZipTaxServerError as e:
# Server errors (5xx)
print(f"Server error: {e.message}")
except ZipTaxError as e:
# General Ziptax errors
print(f"Ziptax error: {e.message}")
Exception Hierarchy
ZipTaxError
├── ZipTaxAPIError
│ ├── ZipTaxAuthenticationError (401)
│ ├── ZipTaxAuthorizationError (403)
│ ├── ZipTaxNotFoundError (404)
│ ├── ZipTaxRateLimitError (429)
│ └── ZipTaxServerError (5xx)
├── ZipTaxValidationError
├── ZipTaxConnectionError
├── ZipTaxTimeoutError
└── ZipTaxRetryError
Async Operations
For concurrent operations, you can use asyncio with the SDK:
import asyncio
from concurrent.futures import ThreadPoolExecutor
from ziptax import ZipTaxClient
async def get_tax_rates_async(client, addresses):
loop = asyncio.get_event_loop()
with ThreadPoolExecutor() as executor:
tasks = [
loop.run_in_executor(
executor,
client.request.GetSalesTaxByAddress,
address
)
for address in addresses
]
return await asyncio.gather(*tasks)
# Usage
client = ZipTaxClient.api_key("your-api-key-here")
addresses = ["123 Main St, CA", "456 Oak Ave, NY"]
responses = asyncio.run(get_tax_rates_async(client, addresses))
See examples/async_usage.py for more examples.
Response Models
All API responses are validated using Pydantic models:
V60Response
class V60Response:
metadata: V60Metadata # Response metadata with code/message
base_rates: Optional[List[V60BaseRate]] # Tax rates by jurisdiction
service: V60Service # Service taxability
shipping: V60Shipping # Shipping taxability
sourcing_rules: Optional[V60SourcingRules] # Origin/Destination rules
tax_summaries: Optional[List[V60TaxSummary]] # Tax summaries with display rates
addressDetail: V60AddressDetail # Address details
V60Metadata
class V60Metadata:
version: str # API version (e.g., "v60")
response: V60ResponseInfo # Response info object
class V60ResponseInfo:
code: int # Response code (100 = success)
name: str # Response code name
message: str # Response message
definition: str # Schema definition URL
V60TaxSummary
class V60TaxSummary:
rate: float # Summary tax rate
tax_type: str # Tax type (e.g., "SALES_TAX")
summary_name: str # Summary description
display_rates: List[V60DisplayRate] # Display rates breakdown
class V60DisplayRate:
name: str # Display rate name
rate: float # Display rate value
V60AccountMetrics
class V60AccountMetrics:
core_request_count: int
core_request_limit: int
core_usage_percent: float
geo_enabled: bool
geo_request_count: int
geo_request_limit: int
geo_usage_percent: float
is_active: bool
message: str
See the models documentation for complete model definitions.
Development
Setup
# Clone the repository
git clone https://github.com/ziptax/ziptax-python.git
cd ziptax-python
# Install dependencies
pip install -e ".[dev]"
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=src/ziptax --cov-report=html
# Run specific test file
pytest tests/test_client.py
Code Quality
# Format code
black src/ tests/
# Lint code
ruff src/ tests/
# Type checking
mypy src/
Examples
See the examples/ directory for complete examples:
- basic_usage.py - Basic SDK usage
- async_usage.py - Concurrent operations
- error_handling.py - Error handling patterns
API Reference
ZipTaxClient
Main client for interacting with the Ziptax API.
Methods
api_key(api_key, **kwargs)- Create a client instance with an API keyclose()- Close the HTTP client session
Properties
config- Configuration object (dict-like access)request- Functions object for making API requests
Functions
API endpoint functions accessible via client.request.
Methods
GetSalesTaxByAddress(address, **kwargs)- Get tax rates by addressGetSalesTaxByGeoLocation(lat, lng, **kwargs)- Get tax rates by coordinatesGetAccountMetrics(**kwargs)- Get account usage metrics
Requirements
- Python 3.8+
- requests >= 2.28.0
- pydantic >= 2.0.0
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Documentation: https://github.com/ziptax/ziptax-python#readme
- Issues: https://github.com/ziptax/ziptax-python/issues
- Email: support@zip.tax
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your 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
Changelog
See CHANGELOG.md for version history and changes.
Made with ❤️ by the Ziptax Team
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 ziptax_sdk-0.1.3b0.tar.gz.
File metadata
- Download URL: ziptax_sdk-0.1.3b0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbd4db5861d748c0e9d0044d944a2863ba24bdec03f32a0d4450208b363f6872
|
|
| MD5 |
0d7bcb9cea6bc4798f94d5c4949559de
|
|
| BLAKE2b-256 |
632e29ee3231e4e11a8e3703c4b5a754e7ae8334f3599ff32b66b7c659ed1bf7
|
Provenance
The following attestation bundles were made for ziptax_sdk-0.1.3b0.tar.gz:
Publisher:
publish.yml on ZipTax/ziptax-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ziptax_sdk-0.1.3b0.tar.gz -
Subject digest:
cbd4db5861d748c0e9d0044d944a2863ba24bdec03f32a0d4450208b363f6872 - Sigstore transparency entry: 869012750
- Sigstore integration time:
-
Permalink:
ZipTax/ziptax-python@de6684ee9bb5fb694ef4935d640466e4fbfc090f -
Branch / Tag:
refs/tags/v0.1.3-beta - Owner: https://github.com/ZipTax
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de6684ee9bb5fb694ef4935d640466e4fbfc090f -
Trigger Event:
release
-
Statement type:
File details
Details for the file ziptax_sdk-0.1.3b0-py3-none-any.whl.
File metadata
- Download URL: ziptax_sdk-0.1.3b0-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
006c5623b48e6e9f0e08c4bbb4ea065b15bf9c22b5484e23b40edc4a61a1a64b
|
|
| MD5 |
1732015d8de9b114d479e19c5bd11cbf
|
|
| BLAKE2b-256 |
1a4b47590346b96362b64b775857112797b1a0996dfdc5822edb7acaafd7b579
|
Provenance
The following attestation bundles were made for ziptax_sdk-0.1.3b0-py3-none-any.whl:
Publisher:
publish.yml on ZipTax/ziptax-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ziptax_sdk-0.1.3b0-py3-none-any.whl -
Subject digest:
006c5623b48e6e9f0e08c4bbb4ea065b15bf9c22b5484e23b40edc4a61a1a64b - Sigstore transparency entry: 869012751
- Sigstore integration time:
-
Permalink:
ZipTax/ziptax-python@de6684ee9bb5fb694ef4935d640466e4fbfc090f -
Branch / Tag:
refs/tags/v0.1.3-beta - Owner: https://github.com/ZipTax
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de6684ee9bb5fb694ef4935d640466e4fbfc090f -
Trigger Event:
release
-
Statement type: