Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
include make_commands.mk

DOCKER-COMPOSE-FILE=./docker-compose.yml
include .env
DOCKER-COMPOSE-FILE=$(DOCKER_COMPOSE_FILE)

NOW := `date +%Y-%m-%d_%H%M%S`
EXISTING_DUMP_FILE_NAME := existing-${NOW}.bak

Expand All @@ -10,36 +12,38 @@ all: help

help:
@echo "Usage:"
@echo " make build - rebuild all docker containers"
@echo " make up - start all docker containers with existing data"
@echo " make down - stop all executed docker containers"
@echo " make export - export existing data to dump for backup"
@echo " make backup - the same as above"
@echo " make dump - the same as above"
@echo " make import FILE=file_name - import file_name into database container (Be careful! Existing data backup does not performed automatically! Use make backup together!)"
@echo " make latest - import data/latest.bak into database container (Be careful! Existing data backup does not performed automatically! Use make backup together!)"
@echo " make last - the same as above"
@echo " make schema - auto-generation database schema from json file (see backend/src/parser/README.md)"
@echo " make psql - connect to the database using psql"
@echo " make bash/backend - open a shell in the backend container"
@echo " make logs/backend - view logs for the backend container"
@echo " make upload-skills - upload skills using the provided USER and PASS"

@echo " make build - Rebuild all docker containers."
@echo " make up - Start all docker containers with existing data."
@echo " make down - Stop all running docker containers."
@echo " make export - Export existing data to a dump file for backup."
@echo " make backup - Perform a backup of existing data (alias for export)."
@echo " make dump - Alias for export."
@echo " make import FILE=<file_name> - Import <file_name> into the database container. Caution: existing data backup is not performed automatically! Use 'make backup' together."
@echo " make latest - Import the latest backup (data/latest.bak) into the database container. Caution: existing data backup is not performed automatically! Use 'make backup' together."
@echo " make last - Alias for latest."
@echo " make schema - Auto-generate database schema from a JSON file (see backend/src/parser/README.md)."
@echo " make psql - Connect to the database using psql."
@echo " make bash/backend - Open a shell in the backend container."
@echo " make logs/backend - View logs for the backend container."
@echo " make upload-skills - Upload skills using the provided USER and PASS."
@echo " make db-migrate - Run database migrations."
# Add new entries or modify existing ones below
# @echo " make <command> - <Description of the command>."

start:
up:
@docker ps | grep silver-bassoon-db > /dev/null || docker-compose -f ${DOCKER-COMPOSE-FILE} up -d db
@docker ps | grep silver-bassoon-backend > /dev/null || docker-compose -f ${DOCKER-COMPOSE-FILE} up -d backend
@docker ps | grep silver-bassoon-client > /dev/null || docker-compose -f ${DOCKER-COMPOSE-FILE} up -d client
@docker ps | grep 1gency-app-db > /dev/null || docker compose -f ${DOCKER-COMPOSE-FILE} up -d db
@docker ps | grep 1gency-app-backend > /dev/null || docker compose -f ${DOCKER-COMPOSE-FILE} up -d backend
@docker ps | grep 1gency-app-client > /dev/null || docker compose -f ${DOCKER-COMPOSE-FILE} up -d client

stop:
down:
@docker-compose -f ${DOCKER-COMPOSE-FILE} stop client
@docker-compose -f ${DOCKER-COMPOSE-FILE} stop backend
@docker-compose -f ${DOCKER-COMPOSE-FILE} stop db
@docker compose -f ${DOCKER-COMPOSE-FILE} stop client
@docker compose -f ${DOCKER-COMPOSE-FILE} stop backend
@docker compose -f ${DOCKER-COMPOSE-FILE} stop db

build: stop
docker-compose -f ${DOCKER-COMPOSE-FILE} build --no-cache --force-rm
docker compose -f ${DOCKER-COMPOSE-FILE} build --no-cache --force-rm


################################################################################
Expand All @@ -57,8 +61,8 @@ schema:
real_backup:
@test -d backend/data || mkdir backend/data
@echo ${EXISTING_DUMP_FILE_NAME} > /tmp/current_export_file_name.txt
@docker ps | grep silver-bassoon-db > /dev/null || docker-compose -f ${DOCKER-COMPOSE-FILE} up -d db
@docker exec -it silver-bassoon-db pg_dump -U python upwork_tools -p 5434 > backend/data/`cat /tmp/current_export_file_name.txt`
@docker ps | grep 1gency-app-db > /dev/null || docker compose -f ${DOCKER-COMPOSE-FILE} up -d db
@docker exec -it 1gency-app-db pg_dump -U python upwork_tools -p 5434 > backend/data/`cat /tmp/current_export_file_name.txt`
@( cd backend/data && ln -sf ./`cat /tmp/current_export_file_name.txt` ./latest.bak )
@rm -f /tmp/current_export_file_name.txt

Expand All @@ -78,17 +82,17 @@ import-v1: stop
@if [ -z ${FILE} ]; then ( echo "Usage: make import FILE=some_file_for_import"; exit 1; ) fi
@if [ ! -f ${FILE} -a ! -h ${FILE} ]; then ( echo "File ${FILE} not found"; exit 1 ) fi
# Оставляем гарантированно только один контейнер, db (совместно с операцией stop).
@docker ps | grep silver-bassoon-db > /dev/null || docker-compose -f ${DOCKER-COMPOSE-FILE} up -d db
@docker ps | grep 1gency-app-db > /dev/null || docker compose -f ${DOCKER-COMPOSE-FILE} up -d db
@echo "Copy db file to container..."
@docker cp -L ${FILE} silver-bassoon-db:/tmp/imported_dump.bak || exit 1
@docker cp -L ${FILE} 1gency-app-db:/tmp/imported_dump.bak || exit 1
@echo "recreate db in container..."
@docker exec -it silver-bassoon-db psql -U python -d postgres -p 5434 -c 'drop database if exists upwork_tools;'
@docker exec -it silver-bassoon-db psql -U python -d postgres -p 5434 -c 'create database upwork_tools;'
@docker exec -it 1gency-app-db psql -U python -d postgres -p 5434 -c 'drop database if exists upwork_tools;'
@docker exec -it 1gency-app-db psql -U python -d postgres -p 5434 -c 'create database upwork_tools;'
@echo "Import db into container..."
@echo "psql -U python -d upwork_tools -p 5434 < /tmp/imported_dump.bak" > /tmp/recreate_in_docker.sh
@chmod a+x /tmp/recreate_in_docker.sh
@docker cp /tmp/recreate_in_docker.sh silver-bassoon-db:/tmp
@docker exec -it silver-bassoon-db bash /tmp/recreate_in_docker.sh
@docker cp /tmp/recreate_in_docker.sh 1gency-app-db:/tmp
@docker exec -it 1gency-app-db bash /tmp/recreate_in_docker.sh
@echo "** data/latest.bak imported into database container. **"
@make start
@echo "** all containers has been started. **"
Expand Down Expand Up @@ -126,7 +130,7 @@ last: latest
################################################################################

psql:
@docker exec -it silver-bassoon-db psql -U python upwork_tools -p 5434
@docker exec -it 1gency-app-db psql -U python upwork_tools -p 5434

bash/backend:
@docker compose exec backend /bin/sh
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,28 @@

#### docker-compose:

`docker-compose up` or `docker-compose up -d`
`docker compose up` or `docker compose up -d`

`docker-compose stop`
`docker compose stop`

`docker-compose build`
`docker compose build`

`docker-compose logs` or `docker-compose logs backend`
`docker compose logs` or `docker compose logs backend`

`docker-compose logs --tail 10`
`docker compose logs --tail 10`

#### Create the first user in database:
docker exec -it silver-bassoon-backend bash
docker exec -it 1gency-app-backend bash

Then execute inside the container:

./commands.py createuser --username=YourUsername --password=YourPassword --is-super

#### connect to DB:
docker exec -it silver-bassoon-db psql -U python upwork_tools -p 5434
docker exec -it 1gency-app-db psql -U python upwork_tools -p 5434

#### create dump:
docker exec -it silver-bassoon-db pg_dump -U python upwork_tools -p 5434 > dump-`date +%Y-%m-%d_%H:%m:%S`.bak
docker exec -it 1gency-app-db pg_dump -U python upwork_tools -p 5434 > dump-`date +%Y-%m-%d_%H:%m:%S`.bak

#### Recreating a database inside a DB docker container from a dump

Expand All @@ -46,10 +46,10 @@ For further info, click either `backend` or `client`. Thanks.
```bash

# Build and start the containers:
sudo docker-compose up -d --build
sudo docker compose up -d --build

# Then create a user:
sudo docker-compose exec backend ./commands.py createuser --username admin --password admin --is-super
sudo docker compose exec backend ./commands.py createuser --username admin --password admin --is-super

# Obtain your auth token:
token=$(curl --request POST \
Expand Down
4 changes: 2 additions & 2 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ See [corresponding README](./src/parser/README.md) for details.
### Backend: About migrations:
1. Migrations run automatically when you run the ./app.py file
3. Execute
docker-compose build
docker-compose up
docker compose build
docker compose up
Refer to `./app.py` for insights.

### Backend: Migrations workflow:
Expand Down
2 changes: 0 additions & 2 deletions backend/aieye_credentials.json.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"aieye_api_public_token": "<public token>",
"aieye_api_host": "http://127.0.0.1:8000",
"aieye_api_generate_proposal_harendra_pipeline_id": 63,
"aieye_api_generate_proposal_digvijaj_pipeline_id": 64,
"aieye_api_generate_question_answers_pipeline_id": 6
}
2 changes: 1 addition & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ flask-sqlalchemy == 2.5.1
flask-cors == 3.0.10
flask-marshmallow == 0.14.0
marshmallow-sqlalchemy == 0.27.0
sqlalchemy == 1.4.30
sqlalchemy == 1.4.50
sqlalchemy-json == 0.5.0
psycopg2 == 2.9.3
requests == 2.27.1
Expand Down
28 changes: 27 additions & 1 deletion backend/schemas.json5
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@
"Main",
"Links",
"Skills",
// "Profiles",
// "Profiles",
"Questions answers",
],
"modal_size": "xl"
Expand Down Expand Up @@ -1521,5 +1521,31 @@
},
},
],
},
{
"entity": "Company",
"comment": "Represents a company in the system",
"db": {
"tablename": "company",
"name": "Company"
},
"fields": [
{
"name": "id",
"type": "Integer",
"db": {
"primary_key": true,
"autoincrement": true
}
},
{
"name": "name",
"type": "String",
"db": {
"nullable": false,
"max_length": 254
}
}
]
}
]
12 changes: 6 additions & 6 deletions backend/scripts/recreate_db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ fi

# Backing up an existing database
echo "Backup the db from container..."
docker exec -it silver-bassoon-db pg_dump -U python upwork_tools -p 5434 > ./existing-`date +%Y-%m-%d_%H%M%S`.bak
docker exec -it 1gency-app-db pg_dump -U python upwork_tools -p 5434 > ./existing-`date +%Y-%m-%d_%H%M%S`.bak
# Copy new db file to docker container.
echo "Copy db file ($1) to container..."
docker cp -L $1 silver-bassoon-db:/tmp/imported_dump.bak || exit 1
docker cp -L $1 1gency-app-db:/tmp/imported_dump.bak || exit 1

# Recreate database
echo "recreate db in container..."
docker exec -it silver-bassoon-db psql -U python -d postgres -p 5434 -c 'drop database if exists upwork_tools;'
docker exec -it silver-bassoon-db psql -U python -d postgres -p 5434 -c 'create database upwork_tools;'
docker exec -it 1gency-app-db psql -U python -d postgres -p 5434 -c 'drop database if exists upwork_tools;'
docker exec -it 1gency-app-db psql -U python -d postgres -p 5434 -c 'create database upwork_tools;'

# Import new database
echo "Import db into container..."
echo "psql -U python -d upwork_tools -p 5434 < /tmp/imported_dump.bak" > /tmp/recreate_in_docker.sh
chmod a+x /tmp/recreate_in_docker.sh
docker cp /tmp/recreate_in_docker.sh silver-bassoon-db:/tmp
docker exec -it silver-bassoon-db bash /tmp/recreate_in_docker.sh
docker cp /tmp/recreate_in_docker.sh 1gency-app-db:/tmp
docker exec -it 1gency-app-db bash /tmp/recreate_in_docker.sh
27 changes: 14 additions & 13 deletions backend/src/application/app_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
from flask_cors import CORS
from flask_mail import Mail

# Добавление автоматически сгенерированных моделей.
logger = logging.getLogger()

try:
# pylint: disable-next=wildcard-import,unused-wildcard-import
from src.database.generated_models import *
except (ImportError, ModuleNotFoundError):
logger = logging.getLogger()
logger.error("generated_models module not found")

from src.database import dbconfig
Expand Down Expand Up @@ -42,6 +42,14 @@ def logger(self) -> logging.Logger:
return lgr


def _store_tenant_id_in_context():
g.tenant_id = None
tenant_id = g.user.company_id if g.user else None
logger.info(f"Tenant id: {tenant_id}")
if tenant_id:
g.tenant_id = tenant_id


def _store_authorized_user_in_context():
# Store authorized user in the context, if any
g.user = None
Expand All @@ -62,7 +70,7 @@ def _store_authorized_user_in_context():

try:
user_id = User.decode_auth_token(token)
g.user = User.query.get(user_id)
g.user = User.query.get_without_tenant(user_id)
except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
g.token_is_deprecated = True
return
Expand All @@ -85,6 +93,7 @@ def invalid_api_usage(exc):
@app.before_request
def before_request():
_store_authorized_user_in_context()
_store_tenant_id_in_context()

# enable CORS
CORS(app, resources={r"/*": {"origins": config.FLASK_HTTP_ORIGIN}})
Expand All @@ -107,22 +116,14 @@ def before_request():
try:
app.config["AIEYE_API_PUBLIC_TOKEN"] = credentials["aieye_api_public_token"]
app.config["AIEYE_API_HOST"] = credentials["aieye_api_host"]
app.config["AIEYE_API_GENERATE_PROPOSAL_PIPELINE_IDS"] = []
app.config["AIEYE_API_GENERATE_PROPOSAL_PIPELINE_IDS"].append(
credentials["aieye_api_generate_proposal_harendra_pipeline_id"])
app.config["AIEYE_API_GENERATE_PROPOSAL_PIPELINE_IDS"].append(
credentials["aieye_api_generate_proposal_digvijaj_pipeline_id"])

app.config["AIEYE_API_HARENDRA_PIPELINE_ID"] = credentials["aieye_api_generate_proposal_harendra_pipeline_id"]
app.config["AIEYE_API_DIGVIJAJ_PIPELINE_ID"] = credentials["aieye_api_generate_proposal_digvijaj_pipeline_id"]

app.config["AIEYE_API_GENERATE_QUESTION_ANSWERS_PIPELINE_ID"] = credentials[
"aieye_api_generate_question_answers_pipeline_id"]
logger.info(f"AIEYE API Host: {app.config['AIEYE_API_HOST']}")
except KeyError:
app.logger.warning("AiEye credentials file invalid.")
app.config["AIEYE_API_PUBLIC_TOKEN"] = None
app.config["AIEYE_API_HOST"] = None
app.config["AIEYE_API_GENERATE_PROPOSAL_PIPELINE_IDS"] = []
app.config["AIEYE_API_GENERATE_QUESTION_ANSWERS_PIPELINE_ID"] = None
except FileNotFoundError:
app.logger.warning("AiEye credentials file not found.")
Expand All @@ -139,6 +140,6 @@ def migrate(app: Flask):

def server_started(app: Flask):
with app.app_context():
message = "Silver-Bassoon server started."
message = "1gency-app server started."
current_app.logger.info(message)
current_app.logger.debug("Server started with ** DEBUG ** configuration")
6 changes: 0 additions & 6 deletions backend/src/application/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ class SkillLevel(int, Enum):
EXPERT = 5


@unique
class GenerateProposalStyle(UnderpinningEnum):
FORMAL_STYLE = 1
INFORMAL_STYLE = 2


APPLICATION_UID_STR = "applicationUID"
ONHOLD_STR = "onHold"
STATUS_STR = "status"
Expand Down
3 changes: 1 addition & 2 deletions backend/src/application/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
)
from werkzeug.exceptions import BadRequest

from src.application.enums import GenerateProposalStyle, ProposalStatus
from src.application.enums import ProposalStatus
from src.application.marshmallow_ma import ma
from src.database import models

Expand Down Expand Up @@ -105,7 +105,6 @@ class UserUpdateRequest(UserCommonRequest):

class GenerateProposalRequestSchema(Schema):
template_id = fields.Integer(allow_none=False, required=True)
style_id = fields.Integer(required=True, validate=validate.OneOf(GenerateProposalStyle.values()))
job_description = fields.String(allow_none=False, required=True)
job_title = fields.String(allow_none=False, required=True)
tags = fields.String(allow_none=True, required=False)
Expand Down
6 changes: 4 additions & 2 deletions backend/src/application/stub_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from flask import current_app, g, request
from flask.views import MethodView

from src.database.tenant import TenantScopedModel
from src.application import config, exceptions, schemas
from src.database.db import db

Expand Down Expand Up @@ -173,7 +175,7 @@ def _ordinary_insert_or_update(self, ordinary_schema, ordinary_model):
self.current_item = element
return {"result": ordinary_schema().dump(element)}

def _update_existing_element(self, existing_element: db.Model, data: dict):
def _update_existing_element(self, existing_element: TenantScopedModel, data: dict):
"""Обновление элемента в базе.
По умолчанию обновляются все элементы, значение которых не равно
полученной в запросе схеме. Это поведение не всегда устраивает, иногда
Expand All @@ -192,7 +194,7 @@ def _update_existing_element(self, existing_element: db.Model, data: dict):
setattr(existing_element, key, value)
db.session.commit()

def _update_only_from_request_fields(self, existing_element: db.Model, data: dict):
def _update_only_from_request_fields(self, existing_element: TenantScopedModel, data: dict):
"""Модифицируются - только те элементы, которые были в исходном запросе.

Args:
Expand Down
Loading