Skip to content
This repository has been archived by the owner on Sep 8, 2023. It is now read-only.

snow-born/eng-exercise

 
 

Repository files navigation

Fender Digital Platform Engineering Challenge

I've used Django, flask, falcon and Pyramid before, so I didn't want to use any of them for this challenge. It's an opportunity to learn some new things.

sanic

An asynchronous Python 3 web framework. I chose this for speed and as an excuse to learn how async programming in Python 3 works.

email-validator

Used to validate user email addresses. Deliverability checks are disabled for the sake of brevity.

argon2_cffi

C extension for the Argon2 hashing function. Argon2 was chosen as it is the most promising new algorithm to emerge in recent times: https://en.wikipedia.org/wiki/Argon2

passlib

Manages the salting, hashing and verification of user passwords (depends on argon2_cffi).

aioredis

An asynchronous Redis library. sanic is async, so it made sense to minimise the amount of blocking DB interactions.

Design

Python 3 is the language of choice. While it is the first version of Python that I learnt (in 2009), most of my career has been in Python 2. This was a good opportunity to brush up on the later version, as 2.x is approaching end-of-life.

Redis was chosen as the database as I am familiar with it, it is simple to use and it is extremely fast. I had initially attempted to use DynamoDB, but found that I was spending too much time trying to learn its intricacies. Redis, in contrast, is trivial to set up and start using.

Traditional database models are not used here. Initially, I tried to find a Redis ORM (similar to the one that we had created in Digit Game Studios), but none met my expectations. One potential candidate was astra. For the sake of simplicity, I reverted to using manual Redis commands.

A Dockerfile and docker-compose.yml are included as a basis for containerisation, should the server ever need to be deployed via AWS or similar provider.

Running

$ docker-compose -f docker-compose.yml up -d

The API should be available at 127.0.0.1:9443.

Alternatively:

$ bash create_virtualenv.sh && source env/bin/activate && python src/app.py

Tests

$ pip install --upgrade -r requirements.txt && pytest

Functionality in the acceptance tests is not separated out, in order to allow the entire flow to be tested atomically and to avoid duplication. I would argue that such separation is unnecessary as a failure at any step in the process will break the entire functionality.

Known issues

  • Warnings are raised on some tests, but appear not to affect the outcome.
  • The same database is used between the live application and tests, due to a failure to discover how to effectively override the globally shared reference to the Redis instance.
  • Some modules are named generically, which could interfere with installed packages/modules.
  • While transactions (MULTI/EXEC) are used, atomicity cannot be guaranteed.
  • In accordance with the principle of least privilege, JSON Patch is deliberately not used; the client should (in this circumstance) not have the power to dictate to the server how to process requests.
  • HTTPS/TLS is not enabled by default.
  • Flow should be updated to use sanic's token attribute on requests and responses.
  • There is no test coverage for multiple users and/or concurrency.
  • More logging is required.
  • I've been a bit sick over the last few days. >.<

About

Plataform digital exercise

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 98.2%
  • Other 1.8%