This repository creates a Static Maps API using the FastAPI framework and the py-staticmaps package. The API accepts query parameters to customize the map and responds with a PNG image. The code is tested with pytest, linted with ruff, and formatted with black.
This API is designed to be deployed as an Azure Function with an Azure CDN in front. The function is secured, so the CDN endpoint uses a rule to pass the function key in the x-function-key header. The CDN endpoint also uses rules to cache the images for 7 days, to reduce unneeded function traffic.
This project has Dev Container support, so it will be automatically setup if you open it in Github Codespaces or in local VS Code with the Dev Containers extension.
If you're unable to open the Dev Container, then you'll need to:
-
Create a Python virtual environment and activate it.
-
Install requirements:
python3 -m pip install --user -r requirements-dev.txt
-
Install the Azure Dev CLI.
Use the local emulator from Azure Functions Core Tools to test the function locally. (There is no local emulator for the API Management service).
- Open this repository in Github Codespaces or VS Code with Remote Dev Containers extension.
- Open the Terminal and make sure you're in the root folder.
- Run
func host start --python
- Click 'http://localhost:7071/{*route}' in the terminal, which should open a website in a new tab. Change the URL to "/" to see the auto-generated documentation and try generating a map.
This repo is set up for deployment using the
Azure Developer CLI,
which relies on the azure.yaml
file and the configuration files in the infra
folder.
Steps for deployment:
-
Sign up for a free Azure account and create an Azure Subscription.
-
Login to Azure:
azd auth login
-
Provision and deploy all the resources:
azd up
It will prompt you to provide an
azd
environment name (like "staticmaps"), select a subscription from your Azure account, and select a location (like "eastus"). Then it will provision the resources in your account and deploy the latest code. -
Once it finishes deploying, navigate to the API endpoint URL from the output. Since the function is secured, you should see a 401 when navigating to the function endpoint. However, the CDN endpoint should successfully display the documentation.
-
When you've made any changes to the app code, you can just run:
azd deploy
This project includes a Github workflow for deploying the resources to Azure on every push to main. That workflow requires several Azure-related authentication secrets to be stored as Github action secrets. To set that up, run:
azd pipeline config
The deployed resources include a Log Analytics workspace with an Application Insights dashboard to measure metrics like server response time.
To open that dashboard, run this command once you've deployed:
azd monitor --overview
(only provided as an example, as of February 2023)
Costs for this architecture are based on incoming traffic / usage, so cost should be near $0 if you're only testing it out, and otherwise increase based on usage.
- Azure CDN - Standard tier, $0.081 per GB for first 10 TB per month. Pricing
- Azure Functions - Consumption tier: $0.20 per 1 million calls. The first 1 million calls per Azure subscription are free. Pricing
- Storage account - Standard tier (Hot): $0.0255 per used GiB, $0.065 per 10,000 write transactions. The account is only used to store the function code, so cost depends on size of function code and number of deploys (but should be quite low). Pricing
- Application Insights: $2.88 per GB ingested data. The first 5 GB per billing account are included per month. Pricing
This repository includes locustfile.py
for use with the Python locust
framework for performance testing.
Modify that test based on your anticipated usage and run the following command, substituting the host name with your CDN host name:
locust --headless --users 10 --spawn-rate 1 -H https://YOUR-ENDPOINT.azureedge.net/
The py-staticmaps project offers several tile providers as options, all based on OpenStreetMap. Before using their tiles in production, read through their tile usage guidelines:
If you're working with this project and running into issues, please post in Discussions.