Skip to content

Commit

Permalink
feat: [NR-NMP-14] Django backend (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
raarielgrace authored Jan 14, 2025
1 parent a4a72e2 commit f3e1f86
Show file tree
Hide file tree
Showing 45 changed files with 392 additions and 10,213 deletions.
3 changes: 2 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ API_HOST=
# POSTGRES
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=
POSTGRES_HOST=
POSTGRES_DATABASE=
POSTGRES_PORT=
POSTGRES_DATABASE=

# POSTGRES ADMIN PAGE
PGADMIN_DEFAULT_EMAIL=
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/.deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
-p IMAGE_TAG=${{ inputs.tag }}
-p TARGET=${{ inputs.target }}
-p SSOAUTH=${{ vars.SSO_AUTH_SERVER_URL }}
verification_path: /api/health
verification_path: /healthcheck/
verification_retry_attempts: "5"
verification_retry_seconds: "15"

Expand Down
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach (remote debug)",
"type": "python",
"request": "attach",
"connect":{
"host":"localhost",
"port":3000
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "app/"
}
]
}
]
}
41 changes: 0 additions & 41 deletions backend/.dockerignore

This file was deleted.

10 changes: 0 additions & 10 deletions backend/.env.template

This file was deleted.

36 changes: 0 additions & 36 deletions backend/.eslintrc.cjs

This file was deleted.

8 changes: 0 additions & 8 deletions backend/.prettierrc

This file was deleted.

29 changes: 20 additions & 9 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
# Base image for the container
FROM node:20.17.0
FROM python:3.13-slim

# Copy files and install dependencies
WORKDIR /app/
COPY . ./
RUN npm ci && \
npm run build
WORKDIR /app

# Run in dev mode, `npm run serve` for production
CMD ["npm", "run", "serve", "--no-update-notifier", "--max-old-space-size=50"]
RUN apt update && \
apt install -y curl

RUN python3 -m pip install --upgrade pip

COPY . /app
COPY ./requirements.txt /requirements.txt

RUN python3 -m pip install -r requirements.txt

CMD sh -c "python3 manage.py migrate && \
python3 manage.py runserver 0.0.0.0:3000"

# Boilerplate, not used in OpenShift/Kubernetes
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000 || exit 1

# Nonroot user
USER 1001
69 changes: 12 additions & 57 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,15 @@
# Welcome to QuackStack 'Better Berries' API 🚀
# How to Debug

## About the API
The backend can be easily debugged in VSCode with the following:

Our backend is a RESTful API written with TypeScript and the Express framework. It integrates with a PostgreSQL database and serves content to a React frontend. This API leverages OpenShift for cloud deployment and Docker for containerization.
1. Ensure you have the Python and Python Debugger extensions installed in VSCode.
2. Add `breakpoint()` into the code wherever you'd like the debugger to pause.
3. In one terminal tab, run `docker compose up database`.
4. In a new terminal tab, run `docker compose -d up backend`. This will compose the backend in the background.
5. In the same terminal tab, run `docker attach {container id}`. You can find the container id in Docker Desktop. This command attaches stdin, stdout, and stderr to this terminal.
6. In VSCode, go to the "Run and Debug" tab. In the top bar, click the green triangle next to "Attach (remote debug)".
7. If debugging the API, run `docker compose up frontend` in a new terminal tab. Otherwise proceed to step 8.
8. Open the localhost website and initiate whatever flow you're debugging. The website should pause at the breakpoint, and in the attached terminal tab you'll see the Pdb (Python debugger) interface.
9. Debug away! (Pdb command guide at: https://docs.python.org/3/library/pdb.html#debugger-commands)

Documentation is accessible through Swagger.

## Running this API

This Express API requires connection to this applications database to properly respond to requests. This projects docker-compose config will set things up automatically when running localy. There are default values set up for development.

To run with docker compose with hot reload for development, run:
`docker compose up -watch`

## Accessing the API Documentation

If running with docker compose:
`http://localhost:3000/api/api-docs`

_The OpenShift deploy is on its way and will be published soon._

## Testing the API

This API is tested with Jest framework.

There are suites covering all endpoints. Each suite should test all response statuses and data to ensure proper behaviour of the API.

A test suite for an endpoint should check for status and data to ensure no false positive responses are being created.
The simplest test looks like:

```typescript
describe('Test the health path', () => {
test('returns status code 200 if healthy', async () => {
const res = await testRequest.get('/health');

expect(res.statusCode).toEqual(200);
expect(res.text).toBe('Better Berries API is healthy and ready!');
});
});
```

To run the test suits, just run this command from this backend directory, while the application runs locally with docker compose:
`npm run test`

## Environment Variables

Here's a summary of the essential environment variables:

| Key | Example | Description |
| ------------------- | ------------------ | ---------------------------------------------- |
| `API_HOST` | `'localhost'` | Determines the hosting environment. |
| `API_PORT` | `'3000'` | Specifies the host API port. |
| `POSTGRES_USER` | `'dbUsr'` | PostgreSQL username for database connections. |
| `POSTGRES_PASSWORD` | `'useASafePasswd'` | PostgreSQL password for database connections. |
| `POSTGRES_DATABASE` | `'dbName'` | Name of the PostgreSQL database to connect to. |
| `POSTGRES_HOST` | `'localhost:1234'` | Address of the PostgreSQL host. |
| `POSTGRES_PORT` | `'1234'` | Port where PostgreSQL is exposed. |

Written by @GDamaso
Note that this method of debugging relies on the `stdin_open` and `tty` being set to true in the docker-compose file.
File renamed without changes.
Empty file added backend/apps/admin/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions backend/apps/admin/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.http import HttpResponse

def health_check(response):
return HttpResponse("OK", status=200)
Empty file.
11 changes: 11 additions & 0 deletions backend/apps/authentication/adapters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.conf import settings
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from pprint import pprint

class SocialAccountAdapter(DefaultSocialAccountAdapter):

def populate_user(self, request, sociallogin, data):
# Runs on each login and initial signup. Flag all users as "staff" for the admin interface.
user = super().populate_user(request, sociallogin, data)
user.is_staff = True
return user
4 changes: 0 additions & 4 deletions backend/jest.config.ts

This file was deleted.

22 changes: 22 additions & 0 deletions backend/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nmp.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()
Empty file added backend/nmp/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions backend/nmp/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for nmp project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nmp.settings')

application = get_asgi_application()
Loading

0 comments on commit f3e1f86

Please sign in to comment.