This service provides autocomplete suggestions for large cities in the USA and Canada based on given search parameters. It utilizes FastAPI for the API endpoints and integrates with Redis for caching.
- Overview
- How it Works
- Installation
- Usage
- API Endpoint
- Deployment
- Swagger Docs
- Testing
- Dataset
- Evaluation
- Contributing
- License
The Autocomplete Service provides suggestions for cities based on a search term (q
). Optional parameters (latitude
and longitude
) can be provided to refine results based on the caller's location. Suggestions are sorted by score, which indicates the confidence level of the match.
The autocomplete service utilizes a dataset containing cities in the USA and Canada to provide suggestions based on user queries. The service accepts a search term (q) and optionally, the caller's location (latitude and longitude) to refine suggestions. The core functionalities include:
- Query Handling: The service parses the query string to retrieve search parameters.
- Location Awareness: If provided, the caller's location helps prioritize suggestions based on proximity using geographic coordinates.
- Scoring: Suggestions are scored based on relevance and confidence, represented as a floating-point value between 0 and 1. A score of 1 indicates high confidence in the suggestion's relevance.
- Population-Based Scoring: When latitude and longitude are not provided, suggestions are ordered by population descending to provide relevant options based on city size.
To ensure relevant and accurate suggestions, the scoring mechanism includes:
- Proximity Scoring: Uses the Haversine formula to calculate distances between the caller's location and each city's coordinates, influencing the suggestion's score.
- Population Thresholding: Sets a baseline score based on city population when geographic coordinates are unavailable. Cities with higher populations receive higher scores, ensuring more populous areas are prioritized in suggestions.
The service is implemented in Python using FastAPI for handling HTTP requests and responses. It integrates with Redis for caching and Kubernetes for scalable deployment. Tests are implemented using pytest to validate functionality and edge cases.
-
Clone the repository:
SSH
git clone git@github.com:barrylee111/buzzsolutions.git cd autocomplete_service
HTTPS
git clone https://github.com:barrylee111/buzzsolutions.git cd autocomplete_service
-
Install dependencies
pip install -r requirements.txt
-
Create an
.env
with the following vars:PYTHONPATH=$PWD FASTAPI_URL=http://localhost:2345/suggestions
This is only used for running the tests locally without Docker or Kubernetes.
-
Start the FastAPI application:
uvicorn autocomplete_service.server:app --host 0.0.0.0 --port 2345
-
Access the API at:
http://localhost:2345/suggestions?q=London&latitude=43.70011&longitude=-79.4163
-
Sample cURL cmd:
curl -X GET "http://localhost:2345/suggestions?q=London&latitude=43.70011&longitude=-79.4163"
- Python 3.12.4 or higher installed
- Redis Server installed and running
- k8s installed (for Kubernetes deployment)
sudo apt-get update
sudo apt-get install redis-server
brew install redis
Start Redis Server:
redis-server
If you're running on Ubuntu, set the PYTHONPATH to the current directory:
export PYTHONPATH=$PWD
This ensures that Python can find the necessary modules when running the FastAPI application.
docker build -t autocomplete-service .
docker run -d -p 2345:2345 autocomplete-service
http://localhost:2345/suggestions?q=London&latitude=43.70011&longitude=-79.4163
curl -X GET "http://localhost:2345/suggestions?q=London&latitude=43.70011&longitude=-79.4163"
If you have not installed kubectl
or minikube
, you will need to do so to run the cluster. Kubernetes Documentation
minikube start --kubernetes-version=v1.21.2
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
minikube service autocomplete-service
<minikube_service_URL>/suggestions?q=London&latitude=43.70011&longitude=-79.4163
curl -X GET "<minikube_service_URL>/suggestions?q=London&latitude=43.70011&longitude=-79.4163"
Note: If you encounter issues pulling the Docker image for the Kubernetes build which calls an image from Dockerhub, ensure you are logged in to Docker Hub. You can log in using docker login
command and entering your credentials. If you do not have a Docker Hub account, you can create one for free at Docker Hub.
Endpoint: /suggestions
- q: Search term (required)
- latitude, longitude: Optional parameters to refine results based on caller's location
- Response: JSON array of scored city suggestions, sorted by score descending
GET /suggestions?q=London&latitude=43.70011&longitude=-79.4163
{
"suggestions": [
{
"name": "London, ON, Canada",
"latitude": "42.98339",
"longitude": "-81.23304",
"score": 0.9
},
{
"name": "London, OH, USA",
"latitude": "39.88645",
"longitude": "-83.44825",
"score": 0.5
},
{
"name": "London, KY, USA",
"latitude": "37.12898",
"longitude": "-84.08326",
"score": 0.5
},
{
"name": "Londontowne, MD, USA",
"latitude": "38.93345",
"longitude": "-76.54941",
"score": 0.3
}
]
}
GET /suggestions?q=SomeRandomCityInTheMiddleOfNowhere
{
"suggestions": []
}
For production deployment, deploy the application using Docker or Kubernetes and expose the service endpoint.
http://localhost:2345/docs
pytest tests/test.py
Ensure Redis is running before running tests.
The dataset cities_canada-usa.tsv provides city information used for autocomplete suggestions.
This solution meets the challenge requirements, focusing on:
- Capacity to follow instructions
- Developer experience (ease of setup and usage)
- Solution correctness and performance
- Test quality and coverage
- Code style and cleanliness
- Attention to detail and sensible assumptions
Contributions are welcome. For major changes, please open an issue first to discuss what you would like to change.
MIT License