Note currently in the process of doing a couple of upgrades and running into a few issues.... Standby for a fully functional app.
This is an app for handling your fleet of delivery robots! Is your robot supposed to deliver a New York style slice of pizza to Chicago? Is another robot delivering a time sensitive file from Buenos Aires to Barcelona?
Robots need charging, or docking, stations in order to recharge on their long journeys.
This is an app with models and an API. DockingStations can be created, read, updated, and destroyed. DockingStations are created with a latitude and longtitude.
Robots (delivery drones) can be created, read, updated, and destroyed. Robots are created either at a DockingStation or on a Route. A robot can change routes or docking stations.
Routes can be created, read, updated, and destroyed. Routes are created with a list/array of latitude and longitude points. A route's path can be updated.
This is a Flask app using the Flask-RESTful extension for some boilerplate code to support the REST API. I chose Flask as it is a lightweight, quick to spin up web framework for Python. Flask-RESTful was chosen because of its guidance for a RESTful API and some boilerplate code. It also has a lot of community support. There are some interesting frameworks like FastAPI that may be explored in future to port this API over ot.
The database is PostgreSQL with the PostGIS extension in order to lend support of geographic objects and calculations. PostGIS is a great way to calculate distance spheres on Earth. Rather than importing packages or trying to reinvent the wheel, I use a widely trusted method to handle geometry features.
Marshmallow is used to validate, serialize, and deserialize data from the API layer. This reduces the amount of custom validation needed for data submitted to the API. It's also an easy way to dump data to respond to API requests.
I chose to write unit tests for the models and resources exposed to the API. RobotRoutes exist only to tie together time, robotos, and routes. RobotRoutes are not interacted with directly.
This project was created using Python 3.7.4
- Run postgres locally and create two dbs - delivery_db, delivery_test_db
1a. install postgis
CREATE EXTENSION postgis;
cd delivery_robots/
- Create virtual environment & run
pip install -r requirements.txt
- Run
export FLASK_APP=robots/main.py
in the command line at the root directory - Run
flask db upgrade
flask run
starts the appflask shell
starts the shell- API instructions are below
- Run tests with
pytest app/tests/...
ALL: ids are integers
Base API URL in development: http://127.0.0.1:5000
get a robot
get all robots
create a Robot
- required args: one of
station_id
(int) ORroute_id
(int)
update a Robot
- required args: one of
station_id
(int) ORroute_id
(int)
delete a Robot
get a route
get all routes
Optional:
- To get the route for a robot at a timestamp, pass
robot_id
(required) andtarget_ts
(Unix timestamp, required) in the query string. - To get the route for a robot at a timestamp, pass
robot_id
(required),start_ts
(Unix timestamp, optional),end_ts
(Unix timestamp, optional) in the query string. - default of
start_ts
is epoch - default of
end_ts
is current time
create a route
- required args:
points
as an array of arrays of longitude and latitude - example:
[[-122.3462, 37.8770], [-122.4599, 36.8770]] # [[longitude, latitude], [longitude, latitude]]
- length of points must be greater than or equal to 2
update a route
- required args:
points
as an array of arrays of longitude and latitude floats - example:
[[-122.3462, 37.8770], [-122.4599, 36.8770]] # [[longitude, latitude], [longitude, latitude]]
- length of points must be greater than or equal to 2
delete a route
get a station
get all stations
Optional:
- To get all stations within a radius of a target point, pass
radius
(in NM as an integer),target_longitude
(float), andtarget_latitude
(float) in the query string. - To get all stations within a radius of a target route, pass
radius
(in NM as an integer) androute_id
in the query string.
create a station
- required args:
longitude
(float) ANDlatitude
(float)
update a station
- required args:
longitude
(float) and/orlatitude
(float)
delete a station
- All latitude and longitude points given will be on an ocean
- Any changes to Route paths are acceptable, i.e. not validating route changes
- Robots do not need any guidance when are moved on routes or to stations, i.e. not creating routes between current location and next location
- Users will input longitude & latitude points as specified in the README API notes