Skip to content

Commit edc56e0

Browse files
committed
Merge branch 'release'
2 parents 951553a + 89fc14b commit edc56e0

File tree

9 files changed

+214
-4
lines changed

9 files changed

+214
-4
lines changed

README.md

Lines changed: 214 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,214 @@
1-
# parkside_backend_coding_challenge_draft
2-
A simple REST API for the Parkside backend coding challenge that shows my current skills and talent
1+
# Parkside Robo-Dance Coding Challenge (Backend) 🤖
2+
3+
## Live Demo
4+
5+
- API: https://floating-wildwood-42925.herokuapp.com/api/
6+
- Documentation: https://floating-wildwood-42925.herokuapp.com/docs/
7+
8+
![Robot Dance Gif](/docs/images/robot_dance.gif)
9+
_Image Source: https://giphy.com/gifs/uofcalifornia-dancing-robot-robots-3o72F2gJOMNCsKobtK_
10+
11+
## Introduction
12+
13+
This repository was part of my job application process at [Parkside](https://www.parkside-interactive.com/) and contains a simple REST API that shows my current skills and talent as well as my preferred work style. I was asked to built the backend for a **Robo-Dance** competition app.
14+
15+
## Overview 🧑‍💻
16+
17+
Robots love dancing and regularly battle each other in fabulous dance competitions. Goal of the project was to design a API for a Robo-Dance competition app in a way that a frontend application could consume it. Therefore I created two API endpoints with the following features:
18+
19+
- **/robots**
20+
21+
- add a robot
22+
- receive a individual robot
23+
- receive all robots
24+
- (data is stored in a persisted data source)
25+
26+
- **/danceoffs**
27+
- store a danceoff result
28+
- store multiple danceoff results with a single request
29+
- receive all danceoffs
30+
- receive a specific danceoff
31+
32+
Please checkout the [official project description from Parkside](docs/Parkside_Coding_Challenge_Backend.pdf) for more information.
33+
34+
## My Solution
35+
36+
### Honor Code
37+
38+
> I did not cheat or plagiarize the work of others during the whole project. If I used work (e.g. copying code) from others, I gave proper attribution to the author/source.
39+
40+
### Version Control
41+
42+
- I used [git](https://git-scm.com/) and [Github](https://github.com/) as version control system.
43+
- I followed the `Git-Flow` design pattern
44+
- branches: feature branches, develop, release, master
45+
- I used `Github issues` to track all the required features of this project and added their IDs to the feature branch name
46+
- I tried to follow the [Udacity Git Commit Message Style Guide](http://udacity.github.io/git-styleguide/)
47+
48+
![Git Flow Example](docs/images/git_flow.png)
49+
_Git-Flow example (source: https://nvie.com/posts/a-successful-git-branching-model/ )_
50+
51+
### Project Architecture 📂
52+
53+
I decided to use [Django](https://www.djangoproject.com/) and [Django REST Framework](https://www.django-rest-framework.org/) for this project (mainly because I already used these frameworks in some other projects).
54+
55+
This leads to the following folder structure:
56+
57+
```
58+
parkside_backend_coding_challenge // project root dir
59+
|
60+
|- README.md // main doc file
61+
|- requirements.txt // contains python dependencies
62+
|- Procfile // Heroku file
63+
|- runtime.txt // Heroku runtime file
64+
|- /.vscode // settings for my texteditor
65+
|- /.github // github workflow files
66+
|- /.git // used by git
67+
|- /docs // my doc folder
68+
`- /django_webserver // the Django Project
69+
|- manage.py // Django’s main file
70+
|- .gitignore // excludes files from git
71+
|- /config // Django root dir
72+
| |- urls.py // defines the url routing
73+
| |- /settings // Django settings for dev/prod
74+
`- /robodanceapi // Django app for the API
75+
|- models.py // defines database objects
76+
|- test.py // contains the unit tests
77+
|- urls.py // defines the url routing
78+
|- views.py // request -> response
79+
|- serializers.py // convert input to db model
80+
```
81+
82+
### Unit Tests and Continuous Testing
83+
84+
I wrote some test cases in order to validate, that my API works as expected.
85+
86+
We can run the test cases with the following command:
87+
88+
```bash
89+
# setup dev environment first! (see Usage section)
90+
91+
# run all unit tests
92+
python django_webserver/manage.py test
93+
```
94+
95+
> Note: I've also set up a [Github Workflow](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions) to run the unit tests automatically if a new commit is made to the `master` or the `develop` branch. This is done by adding the `.github/workflows/django.yml` file and is called [Continuous Testing](https://en.wikipedia.org/wiki/Continuous_testing).
96+
97+
![Github workflow preview](docs/images/github_workflow_preview.png)
98+
_Github workflow preview_
99+
100+
### API Documentation 📖
101+
102+
I used [drf-yasg](https://github.com/axnsan12/drf-yasg) to generate a Swagger/OpenAPI 2.0 documentation. It exposes 3 documentation endpoints:
103+
104+
- A JSON view of our API specification at `/docs.json`
105+
- A YAML view of our API specification at `/docs.yaml`
106+
- A swagger-ui view of your API specification at `/docs/`
107+
108+
![API documentation preview](docs/images/API_documentation_preview.png)
109+
_API documentation preview_
110+
111+
### Continuous Delivery and Hosting 🚀
112+
113+
The web app is hosted on Heroku and will automatically deploy the new app if you make a new commit to the master branch. This is called [Continuous Delivery](https://en.wikipedia.org/wiki/Continuous_delivery)
114+
115+
The following endpoints might be interesting:
116+
117+
- Documentation:
118+
https://floating-wildwood-42925.herokuapp.com/docs/
119+
- API:
120+
https://floating-wildwood-42925.herokuapp.com/api/
121+
122+
![Heroku Dashboard](docs/images/Heroku_dashboard.png)
123+
124+
To implement this feature I followed the [From Project to Productionized with Python](https://blog.heroku.com/from-project-to-productionized-python) tutorial from the official Heroku website.
125+
126+
> Note: I ran into some issues:
127+
>
128+
> 1. `runtime.txt` wasn't working.
129+
> I had to use `python-3.8.7` instead of `python-3.8.2`, which was used in the tutorial (see: [Supported runtimes](https://devcenter.heroku.com/articles/python-support#supported-runtimes))
130+
> 2. Wrong `BASE_DIR` after doing the `Modularize your settings` step.
131+
> I updated the `BASE_DIR` from `Path(__file__).resolve().parent.parent` to `Path(__file__).resolve().parent.parent.parent`
132+
> 3. collection of static files wasn't working.
133+
> I had to add `STATIC_ROOT = BASE_DIR.joinpath('staticfiles')` to the settings base file (see: [Django and Static Assets](https://devcenter.heroku.com/articles/django-assets))
134+
135+
## Usage (Dev Setup Guide)
136+
137+
We can set up our local development environment on Ubuntu with the following commands:
138+
139+
```bash
140+
# clone the repo from github
141+
git clone https://github.com/michaelhaar/parkside_backend_coding_challenge.git
142+
143+
# install the python dependencies
144+
python -m pip install --upgrade pip
145+
sudo apt install libpq-dev python3-dev #needed for psycopg2
146+
cd parkside_backend_coding_challenge/
147+
pip install -r requirements.txt
148+
149+
# Init the database
150+
python django_webserver/manage.py migrate
151+
```
152+
153+
Next we can start our dev server by typing:
154+
155+
```bash
156+
# start the local development server
157+
python django_webserver/manage.py runserver
158+
```
159+
160+
Now we can open http://localhost:8000/api/ in our Web browser. We should see something like this:
161+
162+
![API endpoint view](docs/images/API_endpoint_view.png)
163+
164+
## Outlook 📈
165+
166+
### What I would do better if I have more time?
167+
168+
- discuss project requirements in more detail
169+
- add authorization and protect _create_ endpoints
170+
- add further validation for the danceoff _bulk_create_ endpoint and add more unit tests
171+
- provide a leaderboard feature
172+
173+
### How would I set up the frontend app?
174+
175+
First, I would try to define the requirements, which would probably give me something like this:
176+
177+
- the user should be able to start a new competition.
178+
- 10 distinct robots will be picked randomly
179+
- robots will be split into two teams
180+
- the user should be able to start the competition.
181+
- each robot battles one robot from the opponent team
182+
- randomly choose a winner
183+
- send results to the backend using the API
184+
185+
Next, I would plan the architecture and the frameworks for the frontend. It would probably look like this:
186+
187+
- inside the django project, create a new django app called `frontend`
188+
- setup everything (urls, templates, static files, etc. )
189+
- use [React](https://reactjs.org/) (maybe also [Redux](https://redux.js.org/), [React Router](https://reactrouter.com/) and [Bootstrap](https://getbootstrap.com/)) to build the frontend application
190+
- use [Axios](https://github.com/axios/axios) to make API calls
191+
- use [webpack](https://webpack.js.org/) to compile the Javascript code
192+
- use Github `issues`, Git-Flow and feature branches to track the progress and organize my tasks
193+
- some UI/UX mockups might be helpful
194+
- create the first drafts by hand and then use [Figma](https://www.figma.com/) for more details
195+
196+
## Used Frameworks, Libraries and APIs
197+
198+
- **[Django](https://www.djangoproject.com/)**: web framework for perfectionists with deadlines.
199+
- **[Django REST Framework](https://www.django-rest-framework.org/)**: powerful and flexible toolkit for building Web APIs.
200+
- **[drf-yasg](https://github.com/axnsan12/drf-yasg)**: generate OpenAPI 2.0 documentation
201+
- for production/hosting:
202+
- **[gunicorn](https://gunicorn.org/)**: Python WSGI HTTP Server for UNIX
203+
- **[psycopg2](https://www.psycopg.org)**: most popular PostgreSQL adapter for the Python
204+
- **[django-environ](https://django-environ.readthedocs.io/en/latest/)**: utilize 12factor inspired environment variables
205+
- **[whitenoise](http://whitenoise.evans.io/en/stable/)**: simplifies static file serving for Python web apps
206+
- **[Heroku](https://www.heroku.com/)**: platform as a service
207+
208+
## Author
209+
210+
👤 **Michael Haar**
211+
212+
- LinkedIn: [@michaelhaar](https://www.linkedin.com/in/michaelhaar/)
213+
- Github: [@michaelhaar](https://github.com/michaelhaar)
214+

django_webserver/config/settings/heroku.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
"""
44

55
import environ
6-
7-
# If using in your own project, update the project namespace below
86
from config.settings.base import *
97

108
env = environ.Env(
148 KB
Binary file not shown.
274 KB
Loading

docs/images/API_endpoint_view.png

108 KB
Loading

docs/images/Heroku_dashboard.png

213 KB
Loading

docs/images/git_flow.png

122 KB
Loading
317 KB
Loading

docs/images/robot_dance.gif

1.96 MB
Loading

0 commit comments

Comments
 (0)