diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..fd7e3e1f288e3b48ddb2a7e8e558b18cd8803f29 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,167 @@ +image: python:3.9 + +variables: + MYSQL_DATABASE: $MYSQL_DATABASE + MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD + MYSQL_USER: $MYSQL_USER + MYSQL_PASSWORD: $MYSQL_PASSWORD + MYSQL_DATABASE: $MYSQL_DATABASE + +services: + - name: mysql:latest + command: ["mysqld", "--authentication-policy=mysql_native_password"] + alias: mysql + +# services: +# - name: mysql:latest +# command: ["mysqld", "--authentication-policy=mysql_native_password"] +# alias: mysql + +# variables: +# MYSQL_DATABASE: $MYSQL_DATABASE +# MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD + +# Host: mysql +# User: $MYSQL_USER +# Password: $MYSQL_PASSWORD +# Database: $MYSQL_DATABASE + +# cache: +# paths: +# - .cache/pip +# - venv/ + # - env/ + +# before_script: + # - python --version # For debugging + # - pip install venv + # - python3 -m venv /venv + # - source /venv/bin/activate + +stages: + - build + - test + - deploy + +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - if: $CI_COMMIT_BRANCH + +# include: +# - template: 'Code-Quality.gitlab-ci.yml' + +####################################################################################################################################### +#### #### +#### Install dependencies #### +#### #### +####################################################################################################################################### + +install: + stage: build + script: + - python3 -m venv ./venv + - source ./venv/bin/activate + - pip install --upgrade pip && pip install pip-tools + - pip install -r ./backend/requirements.txt + artifacts: + paths: + - ./venv/ + expire_in: 30 mins + +####################################################################################################################################### +#### #### +#### Testing code integration #### +#### #### +####################################################################################################################################### + +lint: + stage: test + before_script: + - source ./venv/bin/activate + - pip install pycodestyle + script: + - pycodestyle --config=./backend/setup.cnf ./backend + + +# test: +# stage: test +# variables: +# MYSQL_DATABASE: $MYSQL_DATABASE +# MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD +# MYSQL_DATABASE: $MYSQL_DATABASE +# MYSQL_USER: $MYSQL_USER +# MYSQL_PASSWORD: $MYSQL_PASSWORD +# DB_HOST: mysql +# DB_PORT: 3306 +# WEB_ROOT: http://localhost:3000 +# before_script: +# - source ./venv/bin/activate +# script: +# - cd ./backend +# - docker build -t app ./backend +# - docker run --detach -p 8000:80 app --env-file ./backend/.env +# - curl "http://localhost:8000/api/health" + +####################################################################################################################################### +#### #### +#### Deploy #### +#### #### +####################################################################################################################################### + +.deploy: + stage: deploy + script: + # Install ssh-agent if not already installed, it is required by Docker. + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + + # Run ssh-agent (inside the build environment) + - eval $(ssh-agent -s) + + # Add the SSH key stored in PRIVATE_KEY variable to the agent store + - ssh-add <(echo "$PRIVATE_KEY") + + # For Docker builds disable host key checking. Be aware that by adding that + # you are suspectible to man-in-the-middle attacks. + # WARNING: Use this only with the Docker executor, if you use it with shell + # you will overwrite your user's SSH config. + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + # In order to properly check the server's host key, assuming you created the + # SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines + # instead. + # - mkdir -p ~/.ssh + # - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts' + + # Get build job ID from file in artifact + # - job_id=$(cat job_id) + - > + ssh "eatfast@$DOMAIN" + "cd /var/www/backend && + git stash && + git checkout "$CI_COMMIT_BRANCH" && + git stash && + git pull && + docker-compose build && + docker-compose up -d && + exit" + +# deploy-staging: +# extends: .deploy +# rules: +# - if: $CI_COMMIT_BRANCH == $STAGING_BRANCH +# when: always +# variables: +# DOMAIN: nofist.test.viarezo.fr +# PRIVATE_KEY: "$SSH_PRIVATE_KEY_STAGING" + + +deploy-prod: + extends: .deploy + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + when: always + variables: + DOMAIN: morbiustvplus.cs-campus.fr + PRIVATE_KEY: "$SSH_PRIVATE_KEY" diff --git a/README.md b/README.md index 462bb8b3b86433e65893fea02c9703c53a60f495..e89bd40513892eb1082a9c8e5f19f9509750af12 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,14 @@ Start the development server running `python -m uvicorn main:app --reload --port Navigate to [http://localhost:3001](http://localhost:3001) +<br/> + +### *Le linter* +So the new commits can be deployed, you'll need to use the linter from backend : +`pycodestyle --config=./setup.cnf --exclude=./env ./` +You can use autoformat with autopep8 running : +`autopep8 --in-place --global-config=./setup.cnf --recursive --exclude=./env --aggressive ./` + <br/> ## In production mode diff --git a/backend/db/database.py b/backend/db/database.py index 6f995021c61b44f28e3d48520cfa0a1a4e0ca536..4ea65170ae38296262221fe4341191ebff75975d 100644 --- a/backend/db/database.py +++ b/backend/db/database.py @@ -9,10 +9,15 @@ import os # load environment variables load_dotenv() -SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{os.getenv('MYSQL_USER')}:{os.getenv('MYSQL_PASSWORD')}@{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('MYSQL_DATABASE')}?charset=utf8" +user = os.getenv('MYSQL_USER') +password = os.getenv('MYSQL_PASSWORD') +host = os.getenv('DB_HOST') +port = os.getenv('DB_PORT') +database = os.getenv('MYSQL_DATABASE') + +SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}?charset=utf8" engine = create_engine(SQLALCHEMY_DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() - diff --git a/backend/db/models.py b/backend/db/models.py index 55820de9e561fe85ec3abfa712e33464612e82f8..4971ef343a8108bf26621ace75607ffe0e0afb9b 100644 --- a/backend/db/models.py +++ b/backend/db/models.py @@ -14,4 +14,4 @@ class Records(Base): place = Column(String(10)) date = Column(DateTime) density = Column(Float) - waiting_time = Column(Interval) \ No newline at end of file + waiting_time = Column(Interval) diff --git a/backend/db/schemas.py b/backend/db/schemas.py index 600efc71449952c86b53af757d92db826c9642f4..5f10ba98ce31f03dee794dee223821eee2754bef 100644 --- a/backend/db/schemas.py +++ b/backend/db/schemas.py @@ -8,14 +8,17 @@ from pydantic import BaseModel, Field class RecordBase(BaseModel): """Records base schema""" - place: str = Field(..., title="Name of the RU corresponding the given record") + place: str = Field(..., + title="Name of the RU corresponding the given record") date: datetime = Field(..., title="Date of the record") density: float = Field(..., title="Estimated density of people") - waiting_time: Optional[timedelta] = Field(title="Estimated waiting time for people coming at this date") - + waiting_time: Optional[timedelta] = Field( + title="Estimated waiting time for people coming at this date") + + class Record(RecordBase): """Database records schema""" id: int class Config: - orm_mode = True \ No newline at end of file + orm_mode = True diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 1ef42116d46d4bd5f5d08c3a02dbeead3bc10420..2ae7846e388d77638a0a412611aa3943ce4e71c6 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.3" services: db: - image: mysql + image: mysql:latest container_name: "db" restart: always env_file: .env diff --git a/backend/main.py b/backend/main.py index c808a6faccec6b171b45e3c2f9ba276dc67b2230..4418ddd55a6baa196343a5a2a92ae8361e5ac89c 100644 --- a/backend/main.py +++ b/backend/main.py @@ -26,6 +26,7 @@ app.add_middleware( allow_headers=["*"] ) + def get_db(): """Create a database session.""" db = database.SessionLocal() diff --git a/backend/setup.cnf b/backend/setup.cnf new file mode 100644 index 0000000000000000000000000000000000000000..8fbaf1e1ca767f58e6163e9b65d68610fe7a8ca9 --- /dev/null +++ b/backend/setup.cnf @@ -0,0 +1,2 @@ +[pycodestyle] +max-line-length = 160 \ No newline at end of file diff --git a/backend/utils/preprocessing.py b/backend/utils/preprocessing.py index e4ec2c636251ca0c02258a07d9d899bf13ffc91e..19384b5ed9d4088108722f3a5476751efa2d86d7 100644 --- a/backend/utils/preprocessing.py +++ b/backend/utils/preprocessing.py @@ -23,6 +23,7 @@ def norm_by_imagenet(img): print('Wrong shape of the input.') return None + def fix_singular_shape(img, unit_len=16): """ Some network like w-net has both N maxpooling layers and concatenate layers,