This app is based on four docker services managed by docker-compose: PostgreSQL, redis, Celery and main Python-FastAPI webserver service.
When main docker service is started and database is empty, bash script is executed which runs Celery task, which downloads data from New York open data server and puts them in database. Data contains grades of students in New York City.
Then API client can make API request to get students data. Filters can be optionally applied. Additionally link to chart is provided in response.
Chart is not available immediately. It is generated in separate Celery task in a few seconds and then stored on Docker volume with its path stored in database.
Tested on Python 3.9.5
- Rename
.env.dev.example
to.env.dev
. This file contains environmental variables. - (Recommended) In
.env.dev
file at least change bothPOSTGRES_PASSWORD
andDB_PASS
to new password (the same password for both variables). - Run
docker-compose up --build
- Go to app address: http://localhost:8080/docs
category
is enum, as described in /docs
, takes one of:
'All Students'
'Attend school outside district of residence'
'English Language Learners'
'Poverty'
'Reside in temporary housing'
'Students with Disabilities'
The rest of filters takes float between 0.00 and 1.00.
Client doesn't need to send any of them, if not sent app will use default values:
{
"category": "All Students",
"female_pct_at_least": 0,
"female_pct_at_most": 1,
"male_pct_at_least": 0,
"male_pct_at_most": 1,
"black_pct_at_least": 0,
"black_pct_at_most": 1,
"asian_pct_at_least": 0,
"asian_pct_at_most": 1,
"white_pct_at_least": 0,
"white_pct_at_most": 1,
"other_pct_at_least": 0,
"other_pct_at_most": 1
}
- Create virtual env for this project.
python -m venv .venv --prompt coding-challenge
.\.venv\Scripts\python -m pip install -U pip
.\.venv\Scripts\python -m pip install -U wheel
.\.venv\Scripts\pip install -r requirements.txt
.\.venv\Scripts\pip install pytest pytest-docker requests
source .venv/bin/activate
- Run
pytest -s -v
- Add unit tests.
- Change models to use Enum for
category
. I already changed part of Pydanticschema
. However when I tried to change SQLAlchemymodels
, pandas didn't want to work properly. So I put this task aside for the time being. You can see my attempt in branchswitch_type_to_enum
- Separate
requirements.txt
forapp
andcelery
microservices. - Remove duplicating env vars from .env.dev file
- Allow to choose type of exam between MATH and ELA. Currently MATH exam is hardcoded.
- Add simple html form interface to choose filters easier (to speed up debugging).
- Allow to choose chart file format also as HTML.
- Change plotly chart to use
mapbox
to have nicer background and colors.
I added gunicorn
in addition to uvicorn
to make use of multiple CPU cores.
I chose POST
request type for /school_entries/
because it creates chart, so it has side effect.
{
"category": "All Students"
}
{
"category": "All Students",
"female_pct_at_least": 0.5
}
{
"category": "All Students",
"black_pct_at_least": 0.6
}
{
"category": "All Students",
"asian_pct_at_least": 0.4
}
{
"category": "Students with Disabilities"
}
{
"category": "English Language Learners"
}
{
"category": "Poverty"
}
{
"category": "Reside in temporary housing"
}
{
"category": "Attend school outside district of residence"
}