Skip to content

Commit

Permalink
Merge pull request #40 from ScilifelabDataCentre/fastapi
Browse files Browse the repository at this point in the history
Fastapi
  • Loading branch information
talavis authored Jan 10, 2023
2 parents 0ee7ce5 + e82c1fa commit f22680f
Show file tree
Hide file tree
Showing 16 changed files with 1,071 additions and 1,084 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
# generate image whenever there is a push to the listed branches
push:
branches:
- master
- main
# generate images for releases, using the tag name
# the newest one will be latest as well
release:
Expand All @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
# Cancel earlier job if there is a new one for the same branch/release
concurrency:
group: ${{ github.ref }}-docker-build
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}: ${{ matrix.dockerfile }}'
cancel-in-progress: true
# Define the images/tags to build; will run in parallell
strategy:
Expand Down
23 changes: 13 additions & 10 deletions Dockerfiles/Dockerfile.backend
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
FROM python:3.10-alpine AS base
FROM python:3.11-alpine AS base

RUN apk update && apk upgrade
RUN apk update && apk upgrade && apk add build-base

LABEL org.opencontainers.image.description "Menu aggregator - backend (Fastapi instead of Flask)"

RUN mkdir /code
COPY ./backend/requirements.txt /code/
COPY ./backend/restaurants.json /code/
WORKDIR /code

RUN pip install -r requirements.txt
RUN pip install gunicorn

COPY ./backend/*.py /code/

ENV UVICORN_HOST=0.0.0.0
ENV UVICORN_PORT=8000

CMD ["uvicorn", "app:app"]


FROM base as dev

CMD ["flask", "run", "-h", "0.0.0.0", "--port", "5000"]
ENV VERSION=dev
ENV UVICORN_RELOAD=1


FROM base as production

ARG version
ENV VERSION=$version

ENV GUNICORN_CMD_ARGS "--bind=0.0.0.0:8000 --workers=2 --thread=4 --worker-class=gthread --forwarded-allow-ips='*' --access-logfile -"

CMD ["gunicorn","flask_app:app"]

EXPOSE 8000
10 changes: 5 additions & 5 deletions Dockerfiles/Dockerfile.frontend
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ FROM node:18-alpine as base

RUN yarn global add @quasar/cli

LABEL org.opencontainers.image.description "Menu aggregator - frontend"

COPY ./frontend/package.json /package.json
COPY ./frontend/yarn.lock /yarn.lock
WORKDIR /
Expand All @@ -11,21 +13,19 @@ COPY ./frontend /code
RUN mv /node_modules /code/
WORKDIR /code



FROM base as build

ARG version
ENV VERSION=$version

RUN quasar build

FROM nginx:alpine as production
FROM nginxinc/nginx-unprivileged:alpine as production

COPY --from=build /code/dist/spa/ /usr/share/nginx/html/
COPY ./Dockerfiles/nginx.conf /etc/nginx/nginx.conf
COPY ./Dockerfiles/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
EXPOSE 8080


FROM base as dev
Expand Down
26 changes: 8 additions & 18 deletions Dockerfiles/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
worker_processes 1; ## Default: 1

events {
worker_connections 4096;
}

http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name _;
index index.html;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
server {
listen 8080;
server_name _;
index index.html;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
}
}
76 changes: 29 additions & 47 deletions Dockerfiles/nginx.conf.dev
Original file line number Diff line number Diff line change
@@ -1,53 +1,35 @@
worker_processes 1; ## Default: 1

events {
worker_connections 4096;
}

http {
include mime.types;
default_type application/octet-stream;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

server {
listen 80;
server_name localhost;
location ~ ^/(api) {
proxy_pass http://backend:5000;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;

proxy_redirect off;
}
server {
listen 8080;
server_name localhost;
location ~ ^/(api) {
proxy_pass http://backend:8000;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;

proxy_redirect off;
}

location / {
proxy_pass http://frontend:8080;
location / {
proxy_pass http://frontend:8080;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;

proxy_redirect off;
}
proxy_redirect off;
}
}
70 changes: 70 additions & 0 deletions backend/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import os

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi_cache import FastAPICache
from fastapi_cache.backends.inmemory import InMemoryBackend
from fastapi_cache.decorator import cache
from starlette_context import middleware, plugins

import utils


app = FastAPI(openapi_url="/api/openapi.json",
docs_url="/api/docs",
redoc_url="/api/redoc")

app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["GET"],
allow_headers=["*"],
)

if os.environ.get("REVERSE_PROXY", False):
app.add_middleware(
middleware.ContextMiddleware,
plugins=(
plugins.ForwardedForPlugin(),
),
)


@app.get("/api")
@cache(expire=360000)
async def list_entities():
return {"documentation_swagger": app.url_path_for("swagger_ui_html"),
"documentation_redoc": app.url_path_for("redoc_html"),
"openapi": app.url_path_for("openapi"),}


@app.get("/api/restaurant")
@cache(expire=360000)
async def list_restaurants():
return {
"restaurants": utils.list_restaurants(),
}


@app.get("/api/restaurant/{name}")
@cache(expire=10800)
async def get_restaurant(name):
print("not cached")
data = dict(utils.get_restaurant(name))
if not data:
flask.abort(status=404)
data["menu"] = [{"dish": entry} for entry in data["menu"]]
return {"restaurant": data,}


@app.get("/api/version")
@cache(expire=360000)
async def get_backend_version():
ver = os.environ.get("VERSION", "")
return {"version": ver,}


@app.on_event("startup")
async def startup():
FastAPICache.init(InMemoryBackend())
58 changes: 0 additions & 58 deletions backend/flask_app.py

This file was deleted.

36 changes: 0 additions & 36 deletions backend/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,42 +357,6 @@ def parse_maethai(res_data):
return {"menu": []}


@restaurant
def parse_nanna(res_data):
"""Parse the menu of Nanna Svartz."""
data = {"menu": []}
soup = get_parser(res_data["menuUrl"])

menu_part = soup.find("article", {"class": "article"}).find("div", {"class": "text"})

day = f"{get_weekday().capitalize()} {str(get_day())} {get_month()}"
current_day = False
for tag in menu_part.find_all(("p", "strong")):
if current_day:
if subtag := next(tag.children):
if subtag.name == "strong":
break
# English menu is written in italic
if tag.text.strip() and next(tag.children).name != "em":
data["menu"].append(tag.text)
else:
if tag.name == "strong" and day in tag.text:
current_day = True
if not data["menu"]:
for tag in menu_part.find_all(("ul", "strong", "p")):
if current_day:
if tag.name == "ul":
for subtag in tag.children:
if subtag.text.strip() and next(tag.children).name != "em":
data["menu"].append(subtag.text.strip())
break
else:
if tag.name in ("strong", "p") and day in tag.text:
current_day = True

return data


@restaurant
def parse_rudbeck(res_data):
"""
Expand Down
Loading

0 comments on commit f22680f

Please sign in to comment.