# radar-mapping-api
A Python client library for the [Radar.io](https://radar.com) geocoding, mapping, and geolocation API.
> [!CAUTION]
> **Pricing Alert for Startups**: While Radar offers an excellent free tier and well-designed APIs, their pricing model has a significant gap that may not work for growing startups. Pricing jumps from free to $20,000/year with no incremental pricing options in between, even when working directly with their startup sales team. If you're building a startup that expects to scale beyond the free tier limits, consider whether this pricing structure fits your growth trajectory.
This library provides a type-safe, production-ready client for interacting with Radar.io's APIs, including:
- Forward and reverse geocoding
- Place search
- Address autocomplete
- Address validation
## Why This Library?
Radar's [official Python SDK](https://github.com/radarlabs/radar-sdk-python) is severely outdated and has not been maintained in years. It lacks modern Python features, type safety, and support for many current API endpoints. This library was created to provide:
- Up-to-date API coverage
- Modern Python practices (type hints, Pydantic models, etc.)
- Active maintenance and bug fixes
- Production-ready error handling and retry logic
## Features
- **Type-safe**: Built with Pydantic models for full type safety
- **Resilient**: Automatic retry logic with exponential backoff
- **Production-ready**: Error handling and optional Sentry integration
- **Well-tested**: Comprehensive test suite with 100% coverage
- **Modern**: Uses httpx for async-capable HTTP requests
## Installation
```bash
pip install radar-mapping-api
```
Or with optional Sentry integration:
```bash
pip install radar-mapping-api[sentry]
```
## Usage
### Basic Setup
```python
from radar_mapping_api import RadarClient
# Initialize the client with your API key
client = RadarClient(api_key="your_radar_api_key")
```
### Forward Geocoding
Convert an address to coordinates:
```python
result = client.forward_geocode(
query="841 Broadway, New York, NY",
country="US"
)
if result.addresses:
address = result.addresses[0]
print(f"Latitude: {address.latitude}")
print(f"Longitude: {address.longitude}")
print(f"Formatted: {address.formattedAddress}")
```
### Reverse Geocoding
Convert coordinates to an address:
```python
result = client.reverse_geocode(
coordinates="40.7128,-74.0060",
layers="postalCode,locality,state"
)
if result.addresses:
address = result.addresses[0]
print(f"City: {address.city}")
print(f"State: {address.stateCode}")
print(f"Postal Code: {address.postalCode}")
```
### Place Search
Search for places near a location:
```python
result = client.search_places(
near="40.7128,-74.0060",
categories="coffee-shop",
radius=1000,
limit=10
)
for place in result.places:
print(f"{place.name} - {', '.join(place.categories)}")
```
### Address Autocomplete
Get autocomplete suggestions for partial addresses:
```python
result = client.autocomplete(
query="841 Broad",
country_code="US",
limit=5
)
for address in result.addresses:
print(address.formattedAddress)
```
### Address Validation
Validate and normalize a structured address:
```python
result = client.validate_address(
address_label="841 Broadway",
city="New York",
state_code="NY",
postal_code="10003",
country_code="US"
)
if result.address:
print(f"Validated: {result.address.formattedAddress}")
```
### Helper Functions
The library includes convenient helper functions for common operations:
```python
from radar_mapping_api import geocode_postal_code, geocode_coordinates
# Geocode a postal code
result = geocode_postal_code(
client,
postal_code="10007",
country="US"
)
if result:
print(f"Coordinates: {result.lat}, {result.lon}")
print(f"City: {result.city}")
# Reverse geocode coordinates
result = geocode_coordinates(
client,
lat=40.7128,
lon=-74.0060
)
if result:
print(f"Postal Code: {result.postal_code}")
print(f"State: {result.state_code}")
```
## Error Handling
The client includes intelligent retry logic:
- Automatically retries failed requests with exponential backoff (up to 6 attempts)
- Does not retry on HTTP 402 (Payment Required) errors
- Raises `httpx.HTTPError` for failed requests after retries
```python
import httpx
try:
result = client.forward_geocode(query="invalid address")
except httpx.HTTPError as e:
print(f"Request failed: {e}")
```
## Sentry Integration
If you have Sentry installed, the helper functions will automatically log warnings for:
- No geocoding results found
- Multiple geocoding results (ambiguous queries)
The integration is completely optional - if Sentry is not installed, the library works normally without it.
## API Reference
### RadarClient
Main client for interacting with the Radar.io API.
#### Methods
- `forward_geocode(query, layers=None, country=None, lang=None)` - Convert address to coordinates
- `reverse_geocode(coordinates, layers=None, lang=None)` - Convert coordinates to address
- `search_places(near=None, chains=None, categories=None, iata_code=None, ...)` - Search for places
- `autocomplete(query, near=None, layers=None, limit=None, ...)` - Autocomplete addresses
- `validate_address(address_label, city=None, state_code=None, ...)` - Validate addresses
### Models
All API responses are returned as Pydantic models with full type safety:
- `GeocodeResponse` - Forward/reverse geocoding response
- `SearchPlacesResponse` - Place search response
- `ValidateAddressResponse` - Address validation response
- `GeocodeResult` - Simplified geocoding result
- `Address` - Detailed address information
- `Place` - Place information
## Development
```bash
# Install with development dependencies
uv sync
# Run tests
uv run pytest
# Run linting
uv run ruff check
# Type checking
uv run pyright
```
## Requirements
- Python 3.10+
- httpx
- pydantic
- tenacity
## License
See LICENSE file for details.
## Links
- [Radar.io API Documentation](https://docs.radar.com/api)
- [GitHub Repository](https://github.com/iloveitaly/radar-mapping-api)
## Credits
Created by [Michael Bianco](https://github.com/iloveitaly)
Raw data
{
"_id": null,
"home_page": null,
"name": "radar-mapping-api",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "radar, radar.io, geocoding, geolocation, mapping, reverse-geocoding, places, api-client",
"author": "Michael Bianco",
"author_email": "Michael Bianco <mike@mikebian.co>",
"download_url": "https://files.pythonhosted.org/packages/92/4e/284222a2563dfa4abe9ad4e2331614841466821cbcd0f1480bbd857b8144/radar_mapping_api-0.1.0.tar.gz",
"platform": null,
"description": "# radar-mapping-api\n\nA Python client library for the [Radar.io](https://radar.com) geocoding, mapping, and geolocation API.\n\n> [!CAUTION]\n> **Pricing Alert for Startups**: While Radar offers an excellent free tier and well-designed APIs, their pricing model has a significant gap that may not work for growing startups. Pricing jumps from free to $20,000/year with no incremental pricing options in between, even when working directly with their startup sales team. If you're building a startup that expects to scale beyond the free tier limits, consider whether this pricing structure fits your growth trajectory.\n\nThis library provides a type-safe, production-ready client for interacting with Radar.io's APIs, including:\n- Forward and reverse geocoding\n- Place search\n- Address autocomplete\n- Address validation\n\n## Why This Library?\n\nRadar's [official Python SDK](https://github.com/radarlabs/radar-sdk-python) is severely outdated and has not been maintained in years. It lacks modern Python features, type safety, and support for many current API endpoints. This library was created to provide:\n\n- Up-to-date API coverage\n- Modern Python practices (type hints, Pydantic models, etc.)\n- Active maintenance and bug fixes\n- Production-ready error handling and retry logic\n\n## Features\n\n- **Type-safe**: Built with Pydantic models for full type safety\n- **Resilient**: Automatic retry logic with exponential backoff\n- **Production-ready**: Error handling and optional Sentry integration\n- **Well-tested**: Comprehensive test suite with 100% coverage\n- **Modern**: Uses httpx for async-capable HTTP requests\n\n## Installation\n\n```bash\npip install radar-mapping-api\n```\n\nOr with optional Sentry integration:\n\n```bash\npip install radar-mapping-api[sentry]\n```\n\n## Usage\n\n### Basic Setup\n\n```python\nfrom radar_mapping_api import RadarClient\n\n# Initialize the client with your API key\nclient = RadarClient(api_key=\"your_radar_api_key\")\n```\n\n### Forward Geocoding\n\nConvert an address to coordinates:\n\n```python\nresult = client.forward_geocode(\n query=\"841 Broadway, New York, NY\",\n country=\"US\"\n)\n\nif result.addresses:\n address = result.addresses[0]\n print(f\"Latitude: {address.latitude}\")\n print(f\"Longitude: {address.longitude}\")\n print(f\"Formatted: {address.formattedAddress}\")\n```\n\n### Reverse Geocoding\n\nConvert coordinates to an address:\n\n```python\nresult = client.reverse_geocode(\n coordinates=\"40.7128,-74.0060\",\n layers=\"postalCode,locality,state\"\n)\n\nif result.addresses:\n address = result.addresses[0]\n print(f\"City: {address.city}\")\n print(f\"State: {address.stateCode}\")\n print(f\"Postal Code: {address.postalCode}\")\n```\n\n### Place Search\n\nSearch for places near a location:\n\n```python\nresult = client.search_places(\n near=\"40.7128,-74.0060\",\n categories=\"coffee-shop\",\n radius=1000,\n limit=10\n)\n\nfor place in result.places:\n print(f\"{place.name} - {', '.join(place.categories)}\")\n```\n\n### Address Autocomplete\n\nGet autocomplete suggestions for partial addresses:\n\n```python\nresult = client.autocomplete(\n query=\"841 Broad\",\n country_code=\"US\",\n limit=5\n)\n\nfor address in result.addresses:\n print(address.formattedAddress)\n```\n\n### Address Validation\n\nValidate and normalize a structured address:\n\n```python\nresult = client.validate_address(\n address_label=\"841 Broadway\",\n city=\"New York\",\n state_code=\"NY\",\n postal_code=\"10003\",\n country_code=\"US\"\n)\n\nif result.address:\n print(f\"Validated: {result.address.formattedAddress}\")\n```\n\n### Helper Functions\n\nThe library includes convenient helper functions for common operations:\n\n```python\nfrom radar_mapping_api import geocode_postal_code, geocode_coordinates\n\n# Geocode a postal code\nresult = geocode_postal_code(\n client,\n postal_code=\"10007\",\n country=\"US\"\n)\n\nif result:\n print(f\"Coordinates: {result.lat}, {result.lon}\")\n print(f\"City: {result.city}\")\n\n# Reverse geocode coordinates\nresult = geocode_coordinates(\n client,\n lat=40.7128,\n lon=-74.0060\n)\n\nif result:\n print(f\"Postal Code: {result.postal_code}\")\n print(f\"State: {result.state_code}\")\n```\n\n## Error Handling\n\nThe client includes intelligent retry logic:\n\n- Automatically retries failed requests with exponential backoff (up to 6 attempts)\n- Does not retry on HTTP 402 (Payment Required) errors\n- Raises `httpx.HTTPError` for failed requests after retries\n\n```python\nimport httpx\n\ntry:\n result = client.forward_geocode(query=\"invalid address\")\nexcept httpx.HTTPError as e:\n print(f\"Request failed: {e}\")\n```\n\n## Sentry Integration\n\nIf you have Sentry installed, the helper functions will automatically log warnings for:\n- No geocoding results found\n- Multiple geocoding results (ambiguous queries)\n\nThe integration is completely optional - if Sentry is not installed, the library works normally without it.\n\n## API Reference\n\n### RadarClient\n\nMain client for interacting with the Radar.io API.\n\n#### Methods\n\n- `forward_geocode(query, layers=None, country=None, lang=None)` - Convert address to coordinates\n- `reverse_geocode(coordinates, layers=None, lang=None)` - Convert coordinates to address\n- `search_places(near=None, chains=None, categories=None, iata_code=None, ...)` - Search for places\n- `autocomplete(query, near=None, layers=None, limit=None, ...)` - Autocomplete addresses\n- `validate_address(address_label, city=None, state_code=None, ...)` - Validate addresses\n\n### Models\n\nAll API responses are returned as Pydantic models with full type safety:\n\n- `GeocodeResponse` - Forward/reverse geocoding response\n- `SearchPlacesResponse` - Place search response\n- `ValidateAddressResponse` - Address validation response\n- `GeocodeResult` - Simplified geocoding result\n- `Address` - Detailed address information\n- `Place` - Place information\n\n## Development\n\n```bash\n# Install with development dependencies\nuv sync\n\n# Run tests\nuv run pytest\n\n# Run linting\nuv run ruff check\n\n# Type checking\nuv run pyright\n```\n\n## Requirements\n\n- Python 3.10+\n- httpx\n- pydantic\n- tenacity\n\n## License\n\nSee LICENSE file for details.\n\n## Links\n\n- [Radar.io API Documentation](https://docs.radar.com/api)\n- [GitHub Repository](https://github.com/iloveitaly/radar-mapping-api)\n\n## Credits\n\nCreated by [Michael Bianco](https://github.com/iloveitaly)\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python client for the Radar.io geocoding, mapping, and geolocation API",
"version": "0.1.0",
"project_urls": {
"Repository": "https://github.com/iloveitaly/radar-mapping-api"
},
"split_keywords": [
"radar",
" radar.io",
" geocoding",
" geolocation",
" mapping",
" reverse-geocoding",
" places",
" api-client"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3b0dc13535f64813ce7de8bcf119659358c372a41b9b93a4a7eaa5b51f839224",
"md5": "6d7ef7bc8b1de2710d87aad2911fc2fa",
"sha256": "e4b7c830f822f49bbe62c66eb77209fd5bbc587650add3a72855ffa22084002d"
},
"downloads": -1,
"filename": "radar_mapping_api-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6d7ef7bc8b1de2710d87aad2911fc2fa",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 8955,
"upload_time": "2025-11-04T23:18:48",
"upload_time_iso_8601": "2025-11-04T23:18:48.144246Z",
"url": "https://files.pythonhosted.org/packages/3b/0d/c13535f64813ce7de8bcf119659358c372a41b9b93a4a7eaa5b51f839224/radar_mapping_api-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "924e284222a2563dfa4abe9ad4e2331614841466821cbcd0f1480bbd857b8144",
"md5": "556a7db0ba8597dbd2a96531e33d3b74",
"sha256": "17bd8800ad19f9421fee3c8a1f7abcc4edca6ec62946203a2dc0397bdd91fedb"
},
"downloads": -1,
"filename": "radar_mapping_api-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "556a7db0ba8597dbd2a96531e33d3b74",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 7111,
"upload_time": "2025-11-04T23:18:48",
"upload_time_iso_8601": "2025-11-04T23:18:48.891344Z",
"url": "https://files.pythonhosted.org/packages/92/4e/284222a2563dfa4abe9ad4e2331614841466821cbcd0f1480bbd857b8144/radar_mapping_api-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-04 23:18:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "iloveitaly",
"github_project": "radar-mapping-api",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "radar-mapping-api"
}