Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
0b36de6705 | |||
8f3973c961 | |||
4e6f6f5e10 | |||
181dfb06a2 | |||
0688648d75 | |||
c8ba1f2676 | |||
7611c9c2fa |
36
Dockerfile
Normal file
36
Dockerfile
Normal file
@ -0,0 +1,36 @@
|
||||
FROM node:18-bullseye-slim as frontend
|
||||
|
||||
WORKDIR /frontend/
|
||||
COPY frontend/package.json frontend/package-lock.json /frontend/
|
||||
RUN npm install
|
||||
|
||||
COPY frontend /frontend/
|
||||
RUN npm run build
|
||||
|
||||
FROM python:3.10.1-slim-bullseye
|
||||
RUN apt-get update && apt install dumb-init
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
|
||||
EXPOSE 8080
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
|
||||
COPY hypercorn.toml /app/
|
||||
CMD ["pdm", "run", "hypercorn", "--config", "hypercorn.toml", "backend.run:app"]
|
||||
|
||||
RUN python -m venv /ve
|
||||
ENV PATH=/ve/bin:${PATH}
|
||||
RUN pip install --no-cache-dir pdm
|
||||
|
||||
COPY backend/pdm.lock backend/pyproject.toml /app/
|
||||
RUN pdm install --prod --no-lock --no-editable
|
||||
|
||||
COPY --from=frontend /frontend/build/*.js* /app/backend/static/
|
||||
COPY --from=frontend /frontend/build/*.png /frontend/build/*.svg /app/backend/static/
|
||||
COPY --from=frontend /frontend/build/index.html \
|
||||
/app/backend/templates/
|
||||
COPY --from=frontend /frontend/build/static/. /app/backend/static/
|
||||
|
||||
COPY backend/src/ /app/
|
||||
|
||||
USER nobody
|
@ -1,5 +1,9 @@
|
||||
# Todo API
|
||||
|
||||
## To run
|
||||
|
||||
`docker-compose up -d`
|
||||
|
||||
## Frontend
|
||||
|
||||
### Development Workflow
|
||||
|
@ -1,4 +1,3 @@
|
||||
<<<<<<< HEAD
|
||||
# Backend Technical Write-up
|
||||
|
||||
## Steps
|
||||
@ -16,16 +15,6 @@
|
||||
|
||||
`blueprint`: a collection of route handlers/API functionalities.
|
||||
|
||||
## API route trailing slashes
|
||||
|
||||
API paths should end with a slash i.e: `/sessions/` rather than `/session`.
|
||||
This is because requests sent to `/sessions` will be redirected to `/sessions/` whereas `/sessions/` won't get redirected.
|
||||
|
||||
## Difference between database schema and database model
|
||||
|
||||
- A schema defines the structure of data within the database.
|
||||
- A model is a class that can be represented as rows in the database, i.e ID row, age row as class member.
|
||||
|
||||
## Managing user's sessions (Authentication)
|
||||
|
||||
- Login should results in a cookie being set in the user's browser, which is being sent in every subsequent request.
|
||||
@ -35,11 +24,6 @@ This is because requests sent to `/sessions` will be redirected to `/sessions/`
|
||||
## Idempotent routes
|
||||
|
||||
Idempotence is a property of a route where the final state is achieved no matter how many times the route is called, that is, calling the route once or 10 times has the same effect. This is a useful property as it means the route can be safely retried if the request fails. For RESTful and HTTP APIs, the routes using GET, PUT, and DELETE verbs are expected to be idempotent.
|
||||
||||||| 3c78fe9
|
||||
=======
|
||||
# Backend Technical Write Up
|
||||
|
||||
## General Bits of Information
|
||||
|
||||
### SameSite setting
|
||||
|
||||
@ -53,10 +37,6 @@ Pydantic is to validate the schema/the shape of our input/output (works with JSO
|
||||
|
||||
Class full of data. Meant to be used to serialize data into JSON objects.
|
||||
|
||||
### Quart specific terminologies
|
||||
|
||||
`blueprint`: a collection of route handlers/API functionalities.
|
||||
|
||||
### API route trailing slashes
|
||||
|
||||
API paths should end with a slash i.e: `/sessions/` rather than `/session`.
|
||||
@ -66,14 +46,3 @@ This is because requests sent to `/sessions` will be redirected to `/sessions/`
|
||||
|
||||
- A schema defines the structure of data within the database.
|
||||
- A model is a class that can be represented as rows in the database, i.e ID row, age row as class member.
|
||||
|
||||
### Managing user's sessions (Authentication)
|
||||
|
||||
- Login should results in a cookie being set in the user's browser, which is being sent in every subsequent request.
|
||||
The presence and value of this cookie are used to determine whether the member is logged in, and which member made the request.
|
||||
- Logout results in the cookie being deleted.
|
||||
|
||||
### Idempotent routes
|
||||
|
||||
Idempotence is a property of a route where the final state is achieved no matter how many times the route is called, that is, calling the route once or 10 times has the same effect. This is a useful property as it means the route can be safely retried if the request fails. For RESTful and HTTP APIs, the routes using GET, PUT, and DELETE verbs are expected to be idempotent.
|
||||
>>>>>>> master
|
||||
|
11
backend/src/backend/blueprints/serving.py
Normal file
11
backend/src/backend/blueprints/serving.py
Normal file
@ -0,0 +1,11 @@
|
||||
from quart import Blueprint, ResponseReturnValue, render_template
|
||||
from quart_rate_limiter import rate_exempt
|
||||
|
||||
blueprint = Blueprint("serving", __name__)
|
||||
|
||||
|
||||
@blueprint.get("/")
|
||||
@blueprint.get("/<path:path>")
|
||||
@rate_exempt
|
||||
async def index(path: str | None = None) -> ResponseReturnValue:
|
||||
return await render_template("index.html")
|
@ -21,6 +21,7 @@ from quart_schema import QuartSchema, RequestSchemaValidationError
|
||||
# Each blueprint is a logical collection of features in our web app
|
||||
from backend.blueprints.control import blueprint as control_blueprint
|
||||
from backend.blueprints.members import blueprint as members_blueprint
|
||||
from backend.blueprints.serving import blueprint as serving_blueprint
|
||||
from backend.blueprints.sessions import blueprint as sessions_blueprint
|
||||
from backend.blueprints.todos import blueprint as todos_blueprint
|
||||
|
||||
@ -48,6 +49,7 @@ app.register_blueprint(control_blueprint)
|
||||
app.register_blueprint(sessions_blueprint)
|
||||
app.register_blueprint(members_blueprint)
|
||||
app.register_blueprint(todos_blueprint)
|
||||
app.register_blueprint(serving_blueprint)
|
||||
|
||||
|
||||
# Rate limiting
|
||||
|
38
docker-compose.yaml
Normal file
38
docker-compose.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
version: "3"
|
||||
services:
|
||||
web-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./Dockerfile
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- my_network
|
||||
environment:
|
||||
TODO_SECRET_KEY: "secret key"
|
||||
TODO_QUART_DB_DATABASE_URL: postgres://postgres:postgres_password@postgres:5432/todo
|
||||
TODO_QUART_DB_DATA_PATH: migrations/data.py
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres_password
|
||||
POSTGRES_DB: todo
|
||||
POSTGRES_USER: postgres
|
||||
networks:
|
||||
- my_network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
my_network:
|
4
hypercorn.toml
Normal file
4
hypercorn.toml
Normal file
@ -0,0 +1,4 @@
|
||||
accesslog = "-"
|
||||
access_log_format = "%(t)s %(h)s %(f)s - %(S)s '%(r)s' %(s)s %(b)s %(D)s"
|
||||
bind = "0.0.0.0:8080"
|
||||
errorlog = "-"
|
Loading…
x
Reference in New Issue
Block a user