This project was completed over a couple of evenings as part of a coding challenge. The challenge requirement was to implement a RESTful Geocoding proxy service which supports multiple downstream service providers. The service should fallback to a backup service if the primary provider is down or returns no results.
The service was implemented and tested with Python version 3.7.3
. There are several other dependencies which can be seen in requirements.txt
On MacOS, It is recommended to use pyenv to install python3
. pyenv
can be installed via homebrew
You can find the full instructions to install and configure pyenv
here.
Using Python venv is recommended. Luckily, venv
comes as part of a standard python3
installation. Installing the requirements in a new virutal environment can be done as so:
$ cd <geocoding_project_root_dir>
$ python -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
This step is super important ❗
To run the service you need valid credentials for the Google geocoding service and the HERE geocoding service. When you've obtained credentials for both services, copy the geoservice_credentials.json.example file to geoservice_credentials.json
and add your credentials there:
$ cp geoservice_credentials.json.example geoservice_credentials.json
$ # Add your credentials to geoservice_credentials.json
With the previous steps complete, running the service should be as simple as:
$ python server.py
* Serving Flask app "server" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 158-387-064
A Dockerfile is provided to make running via Docker
a breeze. To build the image, do the following:
:warning: Make sure you update the geoservice_credentials.json file before building the docker image
$ cd <geocoding_project_root_dir>
$ docker build -t geocoding-proxy .
With the image built, running the the server is as simple as:
$ docker run -it --rm -p 5000:5000 --name geocoding-proxy-instance geocoding-proxy
Tested with Docker Engine version 18.09.2, build 6247962
The functional tests can be run as follows:
$ python test_geocoding_proxy_functional.py
.........
----------------------------------------------------------------------
Ran 9 tests in 2.057s
OK
A code coverage report for the tests can be obtained also:
$ coverage run test_geocoding_proxy_functional.py
.........
----------------------------------------------------------------------
Ran 9 tests in 1.713s
OK
$ coverage report
Name Stmts Miss Cover
------------------------------------------------------------------------------------------------------
geocode_controller.py 23 1 96%
geocoding_services/__init__.py 0 0 100%
geocoding_services/geocoding_service.py 21 6 71%
geocoding_services/geocoding_service_builder.py 18 3 83%
geocoding_services/google_geocoding_service.py 25 5 80%
geocoding_services/here_geocoding_service.py 23 3 87%
server.py 11 2 82%
The REST Service definition is specified according to the OpenAPI 3.0 standard and can be found viewed in the openapi.yml file.
By default, the service hosts an interactive UI for viewing its RESTful interface. With the service running, navigating to http://0.0.0.0:5000 will launch the SwaggerUI viewer.
An image of the REST Service definition is provided below for convenience:
The Try it out button on the SwaggerUI interface provides a convenient way to try out the REST Service API:
Of course, the venerable cURL
is a tried and true companion:
$ curl "http://0.0.0.0:5000/v1/geocode?address=carmen+sandiego"
{
"results": [
{
"formatted_address": "Calle El Carmen, San Diego, Rep\u00fablica Bolivariana De Venezuela",
"latitude": 10.21208,
"longitude": -67.96923,
"service_provider": "Here"
}
]
}
Another handy tool worth an honorable mention is Postman.
This project is published under the MIT Licence