fastAPI codebase for the tryVital.io Task
to run:
-
install all packages
- if theres a
pip3 install
likenpm i
then run that, otherwisepip3 install uvicorn typing fastapi pydantic httpx bs4 sqlmodel
- if theres a
-
run with
uvicorn main:app --reload
-
with postman (or alternative) query POST
http://127.0.0.1:8000/signin
with {"email":"youremail","password":"yourPasssword"} as Raw JSON BODY Params -> will return a bearerToken -
with bearerToken & code in email, query POST
http://127.0.0.1:8000/enter-code
with {"accessCode":"codeAsString","bearerToken":"yourBearerToken"} as Raw JSON BODY Params -
then you're free to query GET
http://127.0.0.1:8000/glucose?start_date=10-12-2021&end_date=2022-4-26
start_date & end_date are QUERY parameters Breakdown of solution: -
Pass the
email
&password
BODY parameters into the POST /signin endpoint -> this calls the LibreView /login endpoint -> it then calls the LibreView /sendCode endpoint to generate a 2fa code -> this will return a bearerToken & will send an email with the 2fa code -
Then pass the
accessCode
&bearerToken
BODY parameters into the POST /enter-code endpoint -> this calls the LibreView /result endpoint to verify the account -> it then calls the LibreView /dashboard endpoint to get the patientIds -> then it calls my query_libre() function -
the query_libre() function fetches the data & stores it in a sqlite database -> this calls the LibreView /reports endpoint to get a new access token & url -> call this next url, this then gets ANOTHER url to call -> this url retreives al the reports based on the data you queryed for. it rerturns another link to call -> this url retreives the data in HTML format. I parsed the data into js & then JSON -> once in JSON, i iterate through the Days[n]Glucose data & add each timestamp, value, & patientId to a GlucoseDataPoint model & store it the SQLite database
-
Once each patient's data has been stored, the /glucose endpoint can be called
-
the /glucose endpoint takes in a start_date & end_date as QUERY parameters & returns the data
Corners I cut:
- I would like to have an optional parameter PatientId on the /glucose endpoint so that you can query depending on the patient
- I would have better endpoint responses that contain data & proper response codes
- The project would be multiple folders & would be separated by function. I'm a big fan of Nest.js & opinionated structures so my ideal structure would look something like main.py auth main.py controller.py helperfunctions.py data-generation main.py controller.py helperfunctions.py However, I'm not entirely sure if separating routes from code is a common thing with FastAPI
- Storing database in just a db file (& not using a .env file to store its name)
- I would have extensive tests on all endpoints, especially storing the username & password as ENV variables and querying /signin
- When Rui queried the /enter-code endpoint, the /reports LibreView request returns
Error response b'{"message":"MissingRequiredRole:hcp"}\n' while requesting https://api-eu.libreview.io/dashboard.
when he uses HIS credentials. I would test more with other credentials to fix this bug & understand why its occuring.
What I learned throughout this challenge
- Python (I've never used it)
- Syntax
- fastAPI
- pydantic
- httpx
- Using a model to create a database table (I always just have an entity file for a backend)
- Parsing HTML response into JSON & then eventually Python (basically webscraping)
- Reverse engineering ANYTHING
I list all that not because I want you to take it easy on me. I don't. I just want to demonstrate that I'm a fast learner!