6.3 KiB
Open-Meteo Coordinates Service
A FastAPI-based microservice that queries the Open-Meteo Geocoding API to retrieve coordinates for various cities. The service includes caching, Prometheus metrics, and Grafana dashboards for monitoring.
Features
- RESTful API for retrieving city coordinates
- Intelligent caching to reduce external API calls
- Prometheus metrics for observability
- Pre-configured Grafana dashboards with 5 panels
- Docker Compose setup for easy deployment
Prerequisites
- Docker
- Docker Compose
Quick Start
-
Clone the repository
cd open-meteo-service -
Start all services
docker compose up --build -
Access the services
- API: http://localhost:8000/docs
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
Helm (Kubernetes)
The Helm chart in the helm folder deploys the FastAPI app and, by default, Prometheus and Grafana.
What it deploys
- App: FastAPI service with
/healthzprobes and Prometheus scrape annotations - Prometheus: Scrapes the app metrics at
/metrics - Grafana: Pre-provisioned datasource and dashboard for the app metrics
Prerequisites
- Kubernetes cluster
- Helm v3
Install
helm install open-meteo-service ./helm
Upgrade
helm upgrade open-meteo-service ./helm
Access the services
kubectl port-forward svc/open-meteo-service-open-meteo-service 8080:8000
kubectl port-forward svc/open-meteo-service-open-meteo-service-prometheus 9090:9090
kubectl port-forward svc/open-meteo-service-open-meteo-service-grafana 3000:3000
Values overview
You can customize the chart via helm/values.yaml or --set flags.
App values
image.repository,image.tag,image.pullPolicyservice.type,service.portenv.cacheFilepersistence.enabled,persistence.size,persistence.storageClassName
Prometheus values
prometheus.enabledprometheus.imageprometheus.service.type,prometheus.service.portprometheus.persistence.enabled,prometheus.persistence.size,prometheus.persistence.storageClassName
Grafana values
grafana.enabledgrafana.imagegrafana.service.type,grafana.service.portgrafana.adminUser,grafana.adminPasswordgrafana.persistence.enabled,grafana.persistence.size,grafana.persistence.storageClassName
Example: disable Grafana and Prometheus
helm install open-meteo-service ./helm \
--set grafana.enabled=false \
--set prometheus.enabled=false
Example: enable persistence for all components
helm install open-meteo-service ./helm \
--set persistence.enabled=true \
--set prometheus.persistence.enabled=true \
--set grafana.persistence.enabled=true
API Documentation
Endpoints
GET /coordinates
Retrieve coordinates for all configured cities.
Response:
{
"source": "cache",
"data": {
"Tel Aviv": {
"name": "Tel Aviv",
"latitude": 32.08088,
"longitude": 34.78057,
"country": "Israel"
},
...
}
}
GET /coordinates/{city}
Retrieve coordinates for a specific city.
Parameters:
city(path) - City name (e.g., "Ashkelon", "London")
Example:
curl http://localhost:8000/coordinates/Paris
Response:
{
"source": "open-meteo",
"data": {
"name": "Paris",
"latitude": 48.85341,
"longitude": 2.3488,
"country": "France"
}
}
GET /metrics
Prometheus metrics endpoint exposing service metrics.
Example:
curl http://localhost:8000/metrics
GET /healthz
Health check endpoint.
Response:
{
"status": "ok"
}
Metrics
The service exposes the following Prometheus metrics:
HTTP Metrics
-
http_requests_total- Counter of total HTTP requests- Labels:
endpoint,method,status
- Labels:
-
http_request_duration_seconds- Histogram of request durations- Labels:
endpoint,method
- Labels:
Cache Metrics
coordinates_cache_hits_total- Counter of cache hitscoordinates_cache_misses_total- Counter of cache misses
External API Metrics
openmeteo_api_calls_total- Counter of calls to Open-Meteo Geocoding API- Labels:
city
- Labels:
Grafana Dashboard
The pre-configured dashboard includes 5 panels:
- Request Rate - Requests per second by endpoint
- Request Duration p95 - 95th percentile latency
- Cache Hits vs Misses - Cache effectiveness
- Open-Meteo Calls by City - External API usage per city
- Requests by Status - HTTP status code distribution
Access the dashboard at http://localhost:3000 after logging in with admin/admin.
Caching
The service uses a local JSON file (coordinates_cache.json) to cache city coordinates:
- Reduces external API calls
- Shared across all API endpoints
- Persists between requests (not container restarts)
- Automatically updated when new cities are queried
Development
Project Structure
.
├── app/
│ ├── main.py # FastAPI application
│ ├── service.py # Business logic & caching
│ └── metrics.py # Prometheus metrics definitions
├── grafana/
│ ├── provisioning/ # Auto-configured datasources & dashboards
│ └── dashboards/ # Dashboard JSON definitions
├── docker-compose.yml # Service orchestration
├── Dockerfile # Python app container
├── prometheus.yml # Prometheus scrape configuration
└── requirements.txt # Python dependencies
Stop Services
docker compose down
View Logs
docker compose logs -f open-meteo-service
Rebuild After Code Changes
docker compose up --build
Configuration
Environment Variables
CACHE_FILE- Path to cache file (default:coordinates_cache.json)
Scrape Interval
Edit prometheus.yml to adjust the scrape interval (default: 15s).
Testing
Generate test traffic to populate metrics:
# Test all endpoints
curl http://localhost:8000/coordinates
curl http://localhost:8000/coordinates/Paris
curl http://localhost:8000/coordinates/London
# Generate load
for i in {1..10}; do curl -s http://localhost:8000/coordinates > /dev/null; done
License
MIT