Python/Django code challenge proposed by Jobsity. (I passed and got a job offer at the time)
- A user makes a request asking for Apple's current Stock quote:
GET /stock?q=aapl.us
- The API service calls the stock service to retrieve the requested stock information
- The stock service delegates the call to the external API, parses the response, and returns the information back to the API service.
- The API service saves the response from the stock service in the database.
- The data is formatted and returned to the user.
Install Docker and Docker Compose following the official documentation (https://docs.docker.com/compose/install):
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version # test installation
Use Docker Compose to install and start both Django projects api_service
and stock_service
:
docker-compose build # build containers
docker-compose up # start services
This commands will create two different running containers. To verify that containers started successfully:
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
40bc3b6f6e8f jobsity-django-challenge_api "sh -c 'cd ./api_ser…" 45 minutes ago Up 45 minutes 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp api
b48631b42498 jobsity-django-challenge_stock "sh -c 'cd ./stock_s…" 45 minutes ago Up 45 minutes 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp stock
Please make the sure ports 8000
and 8001
are not being used by another process. These ports will be used by:
http://0.0.0.0:8000
: internal API servicestock_service
http://0.0.0.0:8001
: user-facing API serviceapi_service
Two SQLite databases will be created. The first one to store api_service
requests. The second to store stock_service
unit tests.
Before requesting API endpoints, create a superuser and get a JWT token. All user-facing API endpoints have JWT authentication.
docker exec -it api python api_service/manage.py createsuperuser
To get your JWT token, please visit https://0.0.0.0/auth/token
, and fill in the username and password:
You can use access
to authenticate endpoints for ten hours. After that you need to request another JWT token.
You can also create a user (not superuser) visiting https://0.0.0.0/register
(page created to facilitate
authentication and testing of non-superuser endpoints).
Visit the login page at https://0.0.0.0/login
:
To request endpoints using Postman, download the app at https://www.postman.com/downloads
and export
the postman/jobsity-code-challenge.postman_collection.json
collection.
To authenticate using Postman, paste your JWT token in Authorization
> Type Bearer Token
> Token
.
http://0.0.0.0:8001/auth/token
orPOST /auth/token
Payload
{
"username": "matheus",
"password": "123456"
}
Response
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYzNjY1Nzc3OCwia...
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjM2NjA3Mzc4LCJpYX...
}
http://0.0.0.0:8001/stock?q=aapl.us
orGET /stock?q=aapl.us
Response
{
"name": "APPLE",
"symbol": "AAPL.US",
"open": 123.66,
"high": 123.66,
"low": 122.49,
"close": 123
}
http://0.0.0.0:8001/history
orGET /history
Response
[
{"date": "2021-04-01T19:20:30Z", "name": "APPLE", "symbol": "AAPL.US", "open": "123.66", "high": 123.66, "low": 122.49, "close": "123"},
{"date": "2021-03-25T11:10:55Z", "name": "APPLE", "symbol": "AAPL.US", "open": "121.10", "high": 123.66, "low": 122, "close": "122"},
...
]
http://0.0.0.0:8001/stats
orGET /stats
Response
[
{"stock": "aapl.us", "times_requested": 5},
{"stock": "msft.us", "times_requested": 2},
...
]
http://0.0.0.0:8000/stock?q=aapl.us
or GET /stock?q=aapl.us
Response
{
"name": "APPLE",
"symbol": "AAPL.US",
"open": 123.66,
"high": 123.66,
"low": 122.49,
"close": 123
}
To run API service unit tests:
docker exec -it api python api_service/manage.py test api
api_service
has seven different unit tests, all passing:
.......
----------------------------------------------------------------------
Ran 7 tests in 5.051s
OK
To run Stock service unit tests:
docker exec -it stock python stock_service/manage.py test stock_service
stock_service
has three different unit tests, all passing:
...
----------------------------------------------------------------------
Ran 3 tests in 2.243s
OK
All required features were completed.
✔️ Endpoints in the API service should require authentication (no anonymous requests should be allowed).
Each request should be authenticated via Basic Authentication.
✔️ When a user makes a request to get a stock quote (calls the stock endpoint in the api service), if a
stock is found, it should be saved in the database associated to the user making the request.
✔️ A user can get his history of queries made to the api service by hitting the history endpoint. The
endpoint should return the list of entries saved in the database, showing the latest entries first.
✔️ A super user (and only super users) can hit the stats endpoint, which will return the top 5 most
requested stocks.
✔️ All endpoint responses should be in JSON format.
✔️ Endpoints in this service don't need to be authenticated.
✔️ When a stock request is received, this service should query an external API to get the stock
information. For this challege, use this API: https://stooq.com/q/l/?s={stock_code}&f=sd2t2ohlcvn&h&e=csv
.
Bonus features:
✔️ Add unit tests for the bot and the main app.
✔️ Use JWT instead of basic authentication for endpoints.
Not requested bonus features:
✔️ Login, Register and Homepage pages to authenticate user and request JWT token.
✔️ Project created with Docker for easier project setup and deploy.
✔️ Endpoints documented using Postman.