NOTE: I stopped working on this project. So, the dependencies and setup are probably out of date. However, it's probably still worth having a look at the code to get an idea of how I worked at the time it was written.
This is a single-page web application for managing meals (e.g. recipes).
Web client:
- FontAwesome
- Radix UI
- React
- Sass
- TypeScript
API server:
- Celery
- Django
- Django REST framework
- mypy
- PostgreSQL
- Python
- Redis
For the API, I wanted to try following the advice in this article:
Django Views โ The Right Way
That article inspired me to create code that's simpler and easier to understand than what I would have created otherwise. However, I also ended up creating too much "boilerplate," which I'm not happy with. In the future, I'd like to find a way to improve things.
The following assumes the use of a Linux development environment (tested on Ubuntu 20.04).
-
Install PostgreSQL (tested on version 12.8):
sudo apt update -y sudo apt install postgresql postgresql-contrib
-
Configure PostgreSQL:
sudo service postgresql start sudo -u postgres createuser --interactive Enter name of role to add: meals Shall the new role be a superuser? (y/n) y sudo -u postgres createdb meals sudo -u postgres psql alter user meals password '$PASSWORD'; \q psql -d meals -U meals -W # Test that user and privileges work. create table testtable (id serial primary key, testcol text); drop table testtable; \q
-
Install Redis (tested on version 6.0.6):
sudo apt update -y sudo apt install redis-server
-
Configure Redis:
sudo $EDITOR /etc/redis/redis.conf # ... # supervised no supervised systemd # ... # requirepass foobared requirepass $PASSWORD # ... sudo service redis-server restart
-
Install programming language version managers:
-
Install Python:
cd api PYTHON_VERSON=$(awk -F/ '{print $1}' .python-version) pyenv install $PYTHON_VERSION pyenv shell $PYTHON_VERSION
-
Install API packages:
cd api python -m venv venv source venv/bin/activate python -m pip install --upgrade pip wheel python -m pip install . && pip install .[dev] python -m pip check # Ensure no broken dependencies
-
Install Node.js:
cd web NODE_VERSION=$(cat .node-version) nodenv install $NODE_VERSION nodenv shell $NODE_VERSION
-
Install web packages:
cd web npm install npx playwright install chromium firefox # To avoid running this sudo command, run the end-to-end tests for the web # subproject, and follow the instructions in the test errors to install the # dependencies directly for the browsers above. sudo npx playwright install-deps chromium firefox
-
Setup environment variables for API server:
cd api source venv/bin/activate # ...if not already active. cp config/.env.example config/.env # Generate a SECRET_KEY for use below. python manage.py generate_secret_key # Edit config file, and put in valid values. $EDITOR config/.env
-
Run database migrations:
cd api source venv/bin/activate # ...if not already active. python manage.py migrate
-
Create Django superuser for access to the admin site (not currently used):
cd api source venv/bin/activate # ..if not already active. python manage.py createsuperuser
-
Start the Django server (API server):
cd api source venv/bin/activate # ..if not already active. python ./manage.py runserver
-
Start Celery (background jobs):
cd api source venv/bin/activate # ..if not already active. watchmedo auto-restart --directory=./ -p '*tasks*.py' -R -- celery -A config worker -l INFO
-
Start the React server (web client):
cd web npm run dev
-
Create test user within the API:
cd api source venv/bin/activate # ..if not already active. python manage.py shell # TODO this user creation needs to be automated >>> from datetime import datetime >>> from django.conf import settings >>> from django.contrib.auth.models import User >>> from zoneinfo import ZoneInfo >>> user = User.objects.create_user('testuser', password='testpassword') >>> user.email_confirmed_datetime = datetime.now(tz=ZoneInfo(settings.TIME_ZONE)) >>> user.is_active=True >>> user.save() >>> exit()
-
Ensure API server is running on correct port:
# In a separate shell... cd api source venv/bin/activate # ..if not already active. python ./manage.py runserver 5174
-
Run all tests:
cd web npm test
-
Run unit tests:
cd web npm run test:unit
-
Run unit tests, and report on test coverage:
cd web npm run test:unit:coverage
-
Run end-to-end (e2e) tests:
cd web npm run test:e2e npm run test:e2e:report # Optional: see HTML report.
-
Run unit tests:
cd api source venv/bin/activate # ..if not already active. pytest
-
Run unit tests, and report on test coverage:
cd api source venv/bin/activate # ..if not already active. # Pick one of: pytest --cov --cov-report html # HTML report pytest --cov --cov-report term-missing # terminal report # Open htmlcov/index.html with a browser if HTML report was chosen.
-
Identify outdated web packages, and update them:
cd web npm outdated $EDITOR package.json # Update package version specifications npm update --save
-
Identify outdated API packages, and update them (not necessarily a good production process, but good enough for this project):
cd api source venv/bin/activate # ..if not already active. python -m pip list --outdated $EDITOR pyproject.toml # Update package version specifications python -m pip install . && pip install .[dev]