Getting Started¶
This guide will walk you through the basics of using RepeaterBook to access and work with amateur radio repeater data.
What is RepeaterBook?¶
RepeaterBook is a Python library that provides a convenient interface to RepeaterBook.com, a comprehensive database of amateur radio repeaters worldwide. It allows you to:
- Download repeater data from the RepeaterBook API
- Store repeater information in a local SQLite database
- Query repeaters by location, frequency, capabilities, and more
- Filter repeaters based on distance from a point
- Work with different digital modes (DMR, P25, NXDN, etc.)
Installation¶
Prerequisites¶
- Python 3.10 or higher
- pip, uv, or Poetry for package management
Install from PyPI¶
Install from Source¶
To install the latest development version:
Quick Start¶
1. Download Repeater Data¶
First, let's download repeater data for a specific region. RepeaterBook provides data for different countries and states.
import asyncio
from repeaterbook.services import RepeaterBookAPI
from repeaterbook.models import ExportQuery
import pycountry
async def download_repeaters():
# Create an API client
api = RepeaterBookAPI()
# Download repeaters for Brazil
brazil = pycountry.countries.get(name="Brazil")
repeaters = await api.download(
query=ExportQuery(countries={brazil})
)
print(f"Downloaded {len(repeaters)} repeaters")
return repeaters
# Run the async function
repeaters = asyncio.run(download_repeaters())
2. Store in Local Database¶
Now let's store the downloaded data in a local SQLite database for easier querying:
from repeaterbook import RepeaterBook
# Create a database connection (defaults to repeaterbook.db)
rb = RepeaterBook()
# Populate the database with our repeaters
rb.populate(repeaters)
print(f"Database populated with {len(repeaters)} repeaters")
3. Query Repeaters¶
With data in the database, you can perform various queries:
from repeaterbook import Repeater
from repeaterbook.models import Status, Use
# Find all operational open repeaters
results = rb.query(
Repeater.operational_status == Status.ON_AIR,
Repeater.use_membership == Use.OPEN
)
print(f"Found {len(results)} open repeaters")
# Print first 5 repeaters
for repeater in results[:5]:
print(f"{repeater.frequency:.4f} MHz - {repeater.callsign} - {repeater.location_nearest_city}")
4. Geographic Queries¶
Find repeaters near a specific location:
from repeaterbook.utils import LatLon, Radius
from repeaterbook.queries import filter_radius, square
# Define a search area (São Paulo, Brazil)
sao_paulo = LatLon(lat=-23.5505, lon=-46.6333)
radius = Radius(
origin=sao_paulo,
distance=50 # kilometers
)
# Find repeaters within the square bounding box
nearby = rb.query(square(radius))
# Filter by actual distance from origin
nearby_exact = filter_radius(nearby, radius)
print(f"Found {len(nearby_exact)} repeaters within 50km of São Paulo")
# Print repeaters with distances
# filter_radius returns repeaters sorted by distance, but doesn't add distance attribute
from haversine import haversine
for repeater in nearby_exact[:5]:
distance = haversine(sao_paulo, (repeater.latitude, repeater.longitude))
print(f"{distance:.1f}km - {repeater.frequency:.4f} MHz - {repeater.callsign}")
5. Filter by Capabilities¶
Find repeaters with specific digital modes:
from repeaterbook.queries import Bands, band
# Find DMR-capable repeaters on 2m or 70cm bands
dmr_repeaters = rb.query(
Repeater.dmr_capable == True,
band(Bands.M_2, Bands.CM_70),
Repeater.operational_status == Status.ON_AIR
)
print(f"Found {len(dmr_repeaters)} DMR repeaters")
for repeater in dmr_repeaters[:5]:
modes = []
if repeater.dmr_capable:
modes.append("DMR")
if repeater.apco_p_25_capable:
modes.append("P25")
if repeater.nxdn_capable:
modes.append("NXDN")
print(f"{repeater.callsign} - {repeater.frequency:.4f} MHz - {', '.join(modes)}")
Complete Example¶
Here's a complete example that ties everything together:
import asyncio
from repeaterbook import RepeaterBook, Repeater
from repeaterbook.services import RepeaterBookAPI
from repeaterbook.models import ExportQuery, Status, Use
from repeaterbook.utils import LatLon, Radius
from repeaterbook.queries import filter_radius, square, band, Bands
import pycountry
async def main():
# 1. Download repeater data
api = RepeaterBookAPI()
brazil = pycountry.countries.get(name="Brazil")
print("Downloading repeaters...")
repeaters = await api.download(
query=ExportQuery(countries={brazil})
)
print(f"Downloaded {len(repeaters)} repeaters")
# 2. Store in database
rb = RepeaterBook(database="my_repeaters.db")
rb.populate(repeaters)
# 3. Find DMR repeaters near São Paulo
sao_paulo = LatLon(lat=-23.5505, lon=-46.6333)
radius = Radius(origin=sao_paulo, distance=50)
nearby = rb.query(
square(radius),
Repeater.dmr_capable == True,
Repeater.operational_status == Status.ON_AIR,
Repeater.use_membership == Use.OPEN,
band(Bands.CM_70) # 70cm band
)
nearby_filtered = filter_radius(nearby, radius)
print(f"\nFound {len(nearby_filtered)} DMR repeaters within 50km:")
# filter_radius returns repeaters sorted by distance
# Calculate distances for display
from haversine import haversine
for rep in nearby_filtered[:10]:
distance = haversine(radius.origin, (rep.latitude, rep.longitude), unit=radius.unit)
print(f" {distance:5.1f}km - {rep.frequency:.4f} MHz - {rep.callsign:8s} - {rep.location_nearest_city}")
if __name__ == "__main__":
asyncio.run(main())
Next Steps¶
Now that you understand the basics, explore:
- Usage Guide - Detailed usage examples and patterns
- Architecture - Understanding how RepeaterBook works
- Examples - Real-world use cases
- API Reference - Complete API documentation
- FAQ - Common questions and troubleshooting
Tips¶
- Caching: The API client automatically caches responses to avoid unnecessary downloads
- Database Updates: Use
rb.populate()to merge new data without duplicates - Async/Await: Most API operations are asynchronous for better performance
- Units: Distance calculations use kilometers by default (configurable with
haversineunits) - Filtering: Combine multiple query conditions using standard SQLAlchemy expressions
Common Patterns¶
Search by State (USA)¶
from repeaterbook.models import ExportQuery
import pycountry
usa = pycountry.countries.get(alpha_2="US")
query = ExportQuery(countries={usa}, state_ids={"06", "32"}) # CA, NV (FIPS codes)
repeaters = await api.download(query=query)
Find All Digital Modes¶
digital_repeaters = rb.query(
(Repeater.dmr_capable | Repeater.apco_p_25_capable | Repeater.nxdn_capable),
Repeater.operational_status == Status.ON_AIR
)