From 4bd899c86d34c40a2fcea625dc463e086836fd6e Mon Sep 17 00:00:00 2001 From: epicadk Date: Mon, 8 Mar 2021 11:53:10 +0530 Subject: [PATCH 01/10] docker --- Dockerfile | 11 +++++ app/api/request_api_utils.py | 60 +++++++++++++++------------ config.py | 78 ++++++++++++++++++++---------------- docker-compose.yml | 37 +++++++++++++++++ run.py | 18 ++++++--- 5 files changed, 138 insertions(+), 66 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..25a2ff3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM python:latest +COPY . . +ENV DB_TYPE=postgresql+psycopg2 +ENV DB_USERNAME=postgres +ENV DB_PASSWORD=postgres +ENV DB_ENDPOINT=localhost:5432 +ENV DB_TEST_NAME=bit_schema_test +ENV POSTGRES_HOST=localhost +ENV POSTGRES_PORT=5432 +RUN pip install -r requirements.txt +CMD python run.py \ No newline at end of file diff --git a/app/api/request_api_utils.py b/app/api/request_api_utils.py index 5b798ef..7f21efa 100644 --- a/app/api/request_api_utils.py +++ b/app/api/request_api_utils.py @@ -7,12 +7,12 @@ from app.utils.decorator_utils import http_response_namedtuple_converter -BASE_MS_API_URL = "http://127.0.0.1:4000" +BASE_MS_API_URL = "http://MS:5000" AUTH_COOKIE = cookies.SimpleCookie() def post_request(request_string, data): - request_url = f"{BASE_MS_API_URL}{request_string}" + request_url = f"{BASE_MS_API_URL}{request_string}" try: response = requests.post( request_url, json=data, headers={"Accept": "application/json"} @@ -37,55 +37,62 @@ def post_request(request_string, data): access_expiry_cookie = response_message.get("access_expiry") AUTH_COOKIE["Authorization"] = f"Bearer {access_token_cookie}" AUTH_COOKIE["Authorization"]["expires"] = access_expiry_cookie - set_user = http_response_checker(get_user(AUTH_COOKIE["Authorization"].value)) + set_user = http_response_checker( + get_user(AUTH_COOKIE["Authorization"].value) + ) if set_user.status_code != 200: response_message = set_user.message response_code = set_user.status_code else: - response_message = {"access_token": response_message.get("access_token"), "access_expiry": response_message.get("access_expiry")} + response_message = { + "access_token": response_message.get("access_token"), + "access_expiry": response_message.get("access_expiry"), + } logging.fatal(f"{response_message}") return response_message, response_code def get_user(token): - request_url = "/user" + request_url = "/user" return get_request(request_url, token, params=None) def get_headers(request_string, params): if request_string == "/user": - return {"Authorization": AUTH_COOKIE["Authorization"].value, "Accept": "application/json"} + return { + "Authorization": AUTH_COOKIE["Authorization"].value, + "Accept": "application/json", + } if request_string == "/users/verified": return { - "Authorization": AUTH_COOKIE["Authorization"].value, + "Authorization": AUTH_COOKIE["Authorization"].value, "search": params["search"], "page": str(params["page"]), "per_page": str(params["per_page"]), - "Accept": "application/json" + "Accept": "application/json", } if request_string == "/organizations": return { - "Authorization": AUTH_COOKIE["Authorization"].value, + "Authorization": AUTH_COOKIE["Authorization"].value, "name": params["name"], "page": str(params["page"]), "per_page": str(params["per_page"]), - "Accept": "application/json" + "Accept": "application/json", } return { "Authorization": AUTH_COOKIE["Authorization"].value, - "Accept": "application/json" + "Accept": "application/json", } def get_request(request_string, token, params): - request_url = f"{BASE_MS_API_URL}{request_string}" + request_url = f"{BASE_MS_API_URL}{request_string}" is_wrong_token = validate_token(token) if not is_wrong_token: - try: + try: response = requests.get( - request_url, - headers=get_headers(request_string, params) + request_url, headers=get_headers(request_string, params) ) response.raise_for_status() response_message = response.json() @@ -110,15 +117,18 @@ def get_request(request_string, token, params): def put_request(request_string, token, data): - request_url = f"{BASE_MS_API_URL}{request_string}" + request_url = f"{BASE_MS_API_URL}{request_string}" is_wrong_token = validate_token(token) if not is_wrong_token: - try: + try: response = requests.put( - request_url, - json=data, - headers={"Authorization": AUTH_COOKIE["Authorization"].value, "Accept": "application/json"}, + request_url, + json=data, + headers={ + "Authorization": AUTH_COOKIE["Authorization"].value, + "Accept": "application/json", + }, ) response.raise_for_status() response_message = response.json() @@ -146,20 +156,20 @@ def validate_token(token): if AUTH_COOKIE: if token != AUTH_COOKIE["Authorization"].value: return messages.TOKEN_IS_INVALID, HTTPStatus.UNAUTHORIZED - if datetime.utcnow().timestamp() > AUTH_COOKIE["Authorization"]["expires"]: + if datetime.utcnow().timestamp() > AUTH_COOKIE["Authorization"]["expires"]: return messages.TOKEN_HAS_EXPIRED, HTTPStatus.UNAUTHORIZED - + @http_response_namedtuple_converter def http_response_checker(result): - # TO DO: REMOVE ALL IF CONDITIONS ONCE ALL BIT-MS HTTP ERROR ISSUES ON MS ARE FIXED + # TO DO: REMOVE ALL IF CONDITIONS ONCE ALL BIT-MS HTTP ERROR ISSUES ON MS ARE FIXED # if result.status_code == HTTPStatus.OK: # result = http_ok_status_checker(result) # # if result.status_code == HTTPStatus.BAD_REQUEST: # result = http_bad_request_status_checker(result) # if result.status_code == HTTPStatus.NOT_FOUND: # result = http_not_found_status_checker(result) - # if result.status_code == json.dumps(HTTPStatus.INTERNAL_SERVER_ERROR) and not AUTH_COOKIE: + # if result.status_code == json.dumps(HTTPStatus.INTERNAL_SERVER_ERROR) and not AUTH_COOKIE: # # if not AUTH_COOKIE: # return messages.TOKEN_IS_INVALID, HTTPStatus.UNAUTHORIZED return result @@ -184,5 +194,3 @@ def http_response_checker(result): # # TO DO: REMOVE ONCE ISSUE#624 ON MS BACKEND IS FIXED # if result.message == messages.WRONG_USERNAME_OR_PASSWORD: # return result._replace(status_code = HTTPStatus.UNAUTHORIZED) - - diff --git a/config.py b/config.py index 1d3101c..bb167f3 100644 --- a/config.py +++ b/config.py @@ -1,19 +1,20 @@ import os from datetime import timedelta + def get_mock_email_config() -> bool: MOCK_EMAIL = os.getenv("MOCK_EMAIL") - #if MOCK_EMAIL env variable is set - if MOCK_EMAIL: + # if MOCK_EMAIL env variable is set + if MOCK_EMAIL: # MOCK_EMAIL is case insensitive MOCK_EMAIL = MOCK_EMAIL.lower() - - if MOCK_EMAIL=="true": + + if MOCK_EMAIL == "true": return True - elif MOCK_EMAIL=="false": + elif MOCK_EMAIL == "false": return False - else: + else: # if MOCK_EMAIL env variable is set a wrong value raise ValueError( "MOCK_EMAIL environment variable is optional if set, it has to be valued as either 'True' or 'False'" @@ -22,11 +23,12 @@ def get_mock_email_config() -> bool: # Default behaviour is to send the email if MOCK_EMAIL is not set return False + class BaseConfig(object): DEBUG = False TESTING = False - SQLALCHEMY_TRACK_MODIFICATIONS = False - + SQLALCHEMY_TRACK_MODIFICATIONS = False + # Flask JWT settings JWT_ACCESS_TOKEN_EXPIRES = timedelta(weeks=1) JWT_REFRESH_TOKEN_EXPIRES = timedelta(weeks=4) @@ -36,7 +38,7 @@ class BaseConfig(object): SECRET_KEY = os.getenv("SECRET_KEY", None) BCRYPT_LOG_ROUNDS = 13 WTF_CSRF_ENABLED = True - + # mail settings MAIL_SERVER = os.getenv("MAIL_SERVER") MAIL_PORT = 465 @@ -50,33 +52,34 @@ class BaseConfig(object): # mail accounts MAIL_DEFAULT_SENDER = os.getenv("MAIL_DEFAULT_SENDER") - DB_TYPE = os.getenv("DB_TYPE"), - DB_USERNAME = os.getenv("DB_USERNAME"), - DB_PASSWORD = os.getenv("DB_PASSWORD"), - DB_ENDPOINT = os.getenv("DB_ENDPOINT"), + DB_TYPE = (os.getenv("DB_TYPE"),) + DB_USERNAME = (os.getenv("DB_USERNAME"),) + DB_PASSWORD = (os.getenv("DB_PASSWORD"),) + DB_ENDPOINT = (os.getenv("DB_ENDPOINT"),) DB_NAME = os.getenv("DB_NAME") DB_TEST_NAME = os.getenv("DB_TEST_NAME") @staticmethod def build_db_uri( - db_type_arg = os.getenv("DB_TYPE"), - db_user_arg = os.getenv("DB_USERNAME"), - db_password_arg = os.getenv("DB_PASSWORD"), - db_endpoint_arg = os.getenv("DB_ENDPOINT"), - db_name_arg = os.getenv("DB_NAME"), + db_type_arg=os.getenv("DB_TYPE"), + db_user_arg=os.getenv("DB_USERNAME"), + db_password_arg=os.getenv("DB_PASSWORD"), + db_endpoint_arg=os.getenv("DB_ENDPOINT"), + db_name_arg=os.getenv("DB_NAME"), ): return f"{db_type_arg}://{db_user_arg}:{db_password_arg}@{db_endpoint_arg}/{db_name_arg}" - + @staticmethod def build_db_test_uri( - db_type_arg = os.getenv("DB_TYPE"), - db_user_arg = os.getenv("DB_USERNAME"), - db_password_arg = os.getenv("DB_PASSWORD"), - db_endpoint_arg = os.getenv("DB_ENDPOINT"), - db_name_arg = os.getenv("DB_TEST_NAME"), + db_type_arg=os.getenv("DB_TYPE"), + db_user_arg=os.getenv("DB_USERNAME"), + db_password_arg=os.getenv("DB_PASSWORD"), + db_endpoint_arg=os.getenv("DB_ENDPOINT"), + db_name_arg=os.getenv("DB_TEST_NAME"), ): return f"{db_type_arg}://{db_user_arg}:{db_password_arg}@{db_endpoint_arg}/{db_name_arg}" + class LocalConfig(BaseConfig): """Local configuration.""" @@ -84,33 +87,39 @@ class LocalConfig(BaseConfig): # Using a local postgre database SQLALCHEMY_DATABASE_URI = "postgresql:///bit_schema" - + # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() - + + class DevelopmentConfig(BaseConfig): DEBUG = True - - SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() - + + # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() + SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@postgres:5432/bit_schema" + + class TestingConfig(BaseConfig): TESTING = True MOCK_EMAIL = True - + # Using a local postgre database - SQLALCHEMY_DATABASE_URI = "postgresql:///bit_schema_test" - + SQLALCHEMY_DATABASE_URI = ( + "postgresql://postgre:postgres@postgres:5432/bit_schema_test" + ) + # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_test_uri() + class StagingConfig(BaseConfig): """Staging configuration.""" DEBUG = True SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() - + class ProductionConfig(BaseConfig): SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() - + def get_env_config() -> str: flask_config_name = os.getenv("FLASK_ENVIRONMENT_CONFIG", "dev") @@ -120,6 +129,7 @@ def get_env_config() -> str: ) return CONFIGURATION_MAPPER[flask_config_name] + CONFIGURATION_MAPPER = { "dev": "config.DevelopmentConfig", "prod": "config.ProductionConfig", diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dae29f6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,37 @@ + +services: + postgres: + image: postgres + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_DB: bit_schema + #options: + #--health-cmd pg_isready + #--health-interval 10s + #--health-timeout 5s + #--health-retries 5 + ports: + - 5432:5432 + networks: + - custom_network + + bit: + container_name: BIT + build: . + ports: + - 5000:5000 + networks: + - custom_network + + ms: + container_name: MS + build: ../mentorship-backend + ports: + - 4000:4000 + networks: + - custom_network + +networks: + custom_network: + name: custom_network + diff --git a/run.py b/run.py index c6b3223..da126e4 100644 --- a/run.py +++ b/run.py @@ -4,8 +4,10 @@ from flask_cors import CORS from config import get_env_config + cors = CORS() + def create_app(config_filename: str) -> Flask: # instantiate the app app = Flask(__name__, instance_relative_config=True) @@ -36,8 +38,8 @@ def create_app(config_filename: str) -> Flask: migrate = Migrate(app, db) - cors.init_app(app, resources={r"*": {"origins": "http://localhost:3000"}}) - + cors.init_app(app, resources={r"*": {"origins": "http://localhost:3000"}}) + from app.api.jwt_extension import jwt jwt.init_app(app) @@ -58,9 +60,7 @@ def create_app(config_filename: str) -> Flask: @application.before_first_request def create_tables(): - from app.database.sqlalchemy_extension import db - from app.database.models.ms_schema.user import UserModel from app.database.models.ms_schema.mentorship_relation import ( MentorshipRelationModel, @@ -77,7 +77,10 @@ def create_tables(): MentorshipRelationExtensionModel, ) - db.create_all() + db.session.execute("CREATE SCHEMA IF NOT EXISTS bit_schema") + db.session.execute("CREATE SCHEMA IF NOT EXISTS bit_schema_test") + db.session.execute("ALTER DATABASE bit_schema SET search_path TO bitschema,public;") + db.session.commit() @application.shell_context_processor def make_shell_context(): @@ -94,5 +97,8 @@ def make_shell_context(): "MentorshipRelationExtensionModel": MentorshipRelationExtensionModel, } + if __name__ == "__main__": - application.run(port=5000) + from app.database.sqlalchemy_extension import db + + application.run(host="0.0.0.0", port=5000) From 00135289480f281cd43fef4de887d76719acd1e3 Mon Sep 17 00:00:00 2001 From: epicadk Date: Mon, 8 Mar 2021 14:04:35 +0530 Subject: [PATCH 02/10] Feat: Docker for setup(2) --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 25a2ff3..1a3197c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ FROM python:latest COPY . . -ENV DB_TYPE=postgresql+psycopg2 +ENV DB_TYPE=postgresql ENV DB_USERNAME=postgres ENV DB_PASSWORD=postgres -ENV DB_ENDPOINT=localhost:5432 +ENV DB_ENDPOINT=postgres:5432 ENV DB_TEST_NAME=bit_schema_test -ENV POSTGRES_HOST=localhost +ENV POSTGRES_HOST=postgres ENV POSTGRES_PORT=5432 -RUN pip install -r requirements.txt +RUN pip install --no-cache-dir -r requirements.txt CMD python run.py \ No newline at end of file From 23c87daf5e720a42c70b87015d67c0e00396c1d1 Mon Sep 17 00:00:00 2001 From: epicadk Date: Mon, 8 Mar 2021 20:26:05 +0530 Subject: [PATCH 03/10] added config --- Dockerfile | 9 ++++++--- app/api/request_api_utils.py | 4 ++-- config.py | 3 +++ run.py | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1a3197c..3d0549a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM python:latest -COPY . . +COPY ./requirements.txt ./requirements.txt +RUN pip install --no-cache-dir -r requirements.txt +COPY . . ENV DB_TYPE=postgresql ENV DB_USERNAME=postgres ENV DB_PASSWORD=postgres @@ -7,5 +9,6 @@ ENV DB_ENDPOINT=postgres:5432 ENV DB_TEST_NAME=bit_schema_test ENV POSTGRES_HOST=postgres ENV POSTGRES_PORT=5432 -RUN pip install --no-cache-dir -r requirements.txt -CMD python run.py \ No newline at end of file +ENV MS_URL=http://MS:5000 +ENV FLASK_APP=run.py +CMD ["flask", "run", "--host", "0.0.0.0"] diff --git a/app/api/request_api_utils.py b/app/api/request_api_utils.py index 7f21efa..c434df2 100644 --- a/app/api/request_api_utils.py +++ b/app/api/request_api_utils.py @@ -5,9 +5,9 @@ import requests from app import messages from app.utils.decorator_utils import http_response_namedtuple_converter +from config import BaseConfig - -BASE_MS_API_URL = "http://MS:5000" +BASE_MS_API_URL = BaseConfig.MS_URL AUTH_COOKIE = cookies.SimpleCookie() diff --git a/config.py b/config.py index bb167f3..616db98 100644 --- a/config.py +++ b/config.py @@ -29,6 +29,9 @@ class BaseConfig(object): TESTING = False SQLALCHEMY_TRACK_MODIFICATIONS = False + # Mentorship System url + MS_URL = os.getenv("MS_URL", "http://localhost:4000") + # Flask JWT settings JWT_ACCESS_TOKEN_EXPIRES = timedelta(weeks=1) JWT_REFRESH_TOKEN_EXPIRES = timedelta(weeks=4) diff --git a/run.py b/run.py index da126e4..358dbd3 100644 --- a/run.py +++ b/run.py @@ -101,4 +101,4 @@ def make_shell_context(): if __name__ == "__main__": from app.database.sqlalchemy_extension import db - application.run(host="0.0.0.0", port=5000) + application.run(port=5000) From b55c0ed53296a8f361fe673b41a5c79aa8d53183 Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 13:58:58 +0530 Subject: [PATCH 04/10] Docker setup(4) --- .dockerignore | 9 ++++++++ Dockerfile | 9 +++++--- Makefile | 6 +++++ config.py | 50 ++++++++++++++++++++--------------------- docker-compose.test.yml | 23 +++++++++++++++++++ docker-compose.yml | 31 +++++++++---------------- init_databases.sql | 5 +++++ init_test_database.sql | 7 ++++++ run.py | 5 ----- tests/base_test_case.py | 4 ---- 10 files changed, 92 insertions(+), 57 deletions(-) create mode 100644 .dockerignore create mode 100644 Makefile create mode 100644 docker-compose.test.yml create mode 100644 init_databases.sql create mode 100644 init_test_database.sql diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d8c92cd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +LICENSE +README.md +__pycache__ +dockerfile +docs +venv +.git +.vscode +.github diff --git a/Dockerfile b/Dockerfile index 3d0549a..ca2818b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,17 @@ FROM python:latest -COPY ./requirements.txt ./requirements.txt +COPY ./requirements.txt /dockerBuild/requirements.txt +WORKDIR /dockerBuild RUN pip install --no-cache-dir -r requirements.txt -COPY . . +COPY . /dockerBuild ENV DB_TYPE=postgresql ENV DB_USERNAME=postgres ENV DB_PASSWORD=postgres ENV DB_ENDPOINT=postgres:5432 +ENV DB_NAME=bit_schema ENV DB_TEST_NAME=bit_schema_test ENV POSTGRES_HOST=postgres ENV POSTGRES_PORT=5432 ENV MS_URL=http://MS:5000 ENV FLASK_APP=run.py -CMD ["flask", "run", "--host", "0.0.0.0"] +ENTRYPOINT ["make"] +CMD ["dockerdev"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e571e4a --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +dev: + python run.py +dockerdev: + flask run --host 0.0.0.0 +dockertest: + python -m unittest discover tests diff --git a/config.py b/config.py index 616db98..43d9923 100644 --- a/config.py +++ b/config.py @@ -55,30 +55,30 @@ class BaseConfig(object): # mail accounts MAIL_DEFAULT_SENDER = os.getenv("MAIL_DEFAULT_SENDER") - DB_TYPE = (os.getenv("DB_TYPE"),) - DB_USERNAME = (os.getenv("DB_USERNAME"),) - DB_PASSWORD = (os.getenv("DB_PASSWORD"),) - DB_ENDPOINT = (os.getenv("DB_ENDPOINT"),) - DB_NAME = os.getenv("DB_NAME") - DB_TEST_NAME = os.getenv("DB_TEST_NAME") + DB_TYPE = os.getenv("DB_TYPE", "") + DB_USERNAME = os.getenv("DB_USERNAME", "") + DB_PASSWORD = os.getenv("DB_PASSWORD", "") + DB_ENDPOINT = os.getenv("DB_ENDPOINT", "") + DB_NAME = os.getenv("DB_NAME", "") + DB_TEST_NAME = os.getenv("DB_TEST_NAME", "") @staticmethod def build_db_uri( - db_type_arg=os.getenv("DB_TYPE"), - db_user_arg=os.getenv("DB_USERNAME"), - db_password_arg=os.getenv("DB_PASSWORD"), - db_endpoint_arg=os.getenv("DB_ENDPOINT"), - db_name_arg=os.getenv("DB_NAME"), + db_type_arg=DB_TYPE, + db_user_arg=DB_USERNAME, + db_password_arg=DB_PASSWORD, + db_endpoint_arg=DB_ENDPOINT, + db_name_arg=DB_NAME, ): return f"{db_type_arg}://{db_user_arg}:{db_password_arg}@{db_endpoint_arg}/{db_name_arg}" @staticmethod def build_db_test_uri( - db_type_arg=os.getenv("DB_TYPE"), - db_user_arg=os.getenv("DB_USERNAME"), - db_password_arg=os.getenv("DB_PASSWORD"), - db_endpoint_arg=os.getenv("DB_ENDPOINT"), - db_name_arg=os.getenv("DB_TEST_NAME"), + db_type_arg=DB_TYPE, + db_user_arg=DB_USERNAME, + db_password_arg=DB_PASSWORD, + db_endpoint_arg=DB_ENDPOINT, + db_name_arg=DB_TEST_NAME, ): return f"{db_type_arg}://{db_user_arg}:{db_password_arg}@{db_endpoint_arg}/{db_name_arg}" @@ -89,16 +89,16 @@ class LocalConfig(BaseConfig): DEBUG = True # Using a local postgre database - SQLALCHEMY_DATABASE_URI = "postgresql:///bit_schema" + # SQLALCHEMY_DATABASE_URI = "postgresql:///bit_schema" - # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() + SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() class DevelopmentConfig(BaseConfig): DEBUG = True - # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() - SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@postgres:5432/bit_schema" + SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_uri() + # SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@postgres:5432/bit_schema" class TestingConfig(BaseConfig): @@ -106,11 +106,11 @@ class TestingConfig(BaseConfig): MOCK_EMAIL = True # Using a local postgre database - SQLALCHEMY_DATABASE_URI = ( - "postgresql://postgre:postgres@postgres:5432/bit_schema_test" - ) + # SQLALCHEMY_DATABASE_URI = ( + # "postgresql:///bit_schema_test" + # ) - # SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_test_uri() + SQLALCHEMY_DATABASE_URI = BaseConfig.build_db_test_uri() class StagingConfig(BaseConfig): @@ -139,4 +139,4 @@ def get_env_config() -> str: "stag": "config.StagingConfig", "local": "config.LocalConfig", "test": "config.TestingConfig", -} \ No newline at end of file +} diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 0000000..749acbe --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,23 @@ + +services: + postgres: + container_name: postgres + image: postgres + environment: + POSTGRES_PASSWORD: postgres + volumes: + - ./init_test_database.sql:/docker-entrypoint-initdb.d/init_test_database.sql + bit: + container_name: BIT_TEST + volumes: + - .:/dockerBuild + build: . + command: dockertest + depends_on: + - ms + ms: + container_name: MS_TEST + build: ../mentorship-backend + depends_on: + - postgres + diff --git a/docker-compose.yml b/docker-compose.yml index dae29f6..ea74cdb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,37 +1,28 @@ services: postgres: + container_name: postgres image: postgres environment: POSTGRES_PASSWORD: postgres - POSTGRES_DB: bit_schema - #options: - #--health-cmd pg_isready - #--health-interval 10s - #--health-timeout 5s - #--health-retries 5 ports: - 5432:5432 - networks: - - custom_network - + volumes: + - ./init_databases.sql:/docker-entrypoint-initdb.d/init_databases.sql bit: - container_name: BIT + container_name: BIT + volumes: + - .:/dockerBuild build: . ports: - 5000:5000 - networks: - - custom_network - + depends_on: + - ms ms: container_name: MS build: ../mentorship-backend ports: - - 4000:4000 - networks: - - custom_network - -networks: - custom_network: - name: custom_network + - 4000:5000 + depends_on: + - postgres diff --git a/init_databases.sql b/init_databases.sql new file mode 100644 index 0000000..12f94a3 --- /dev/null +++ b/init_databases.sql @@ -0,0 +1,5 @@ +CREATE DATABASE bit_schema; +\c bit_schema; +CREATE SCHEMA IF NOT EXISTS bitschema; +CREATE SCHEMA IF NOT EXISTS bitschemastest; +ALTER DATABASE bit_schema SET search_path TO bitschema,public; \ No newline at end of file diff --git a/init_test_database.sql b/init_test_database.sql new file mode 100644 index 0000000..f4866e5 --- /dev/null +++ b/init_test_database.sql @@ -0,0 +1,7 @@ +CREATE DATABASE bit_schema_test; +\c bit_schema_test; +CREATE SCHEMA IF NOT EXISTS bitschema; +CREATE SCHEMA IF NOT EXISTS bitschematest; +CREATE SCHEMA IF NOT EXISTS test_schema; +CREATE SCHEMA IF NOT EXISTS test_schema_2; +ALTER DATABASE bit_schema_test SET search_path TO bitschema,public; \ No newline at end of file diff --git a/run.py b/run.py index 358dbd3..e6eade9 100644 --- a/run.py +++ b/run.py @@ -77,11 +77,6 @@ def create_tables(): MentorshipRelationExtensionModel, ) - db.session.execute("CREATE SCHEMA IF NOT EXISTS bit_schema") - db.session.execute("CREATE SCHEMA IF NOT EXISTS bit_schema_test") - db.session.execute("ALTER DATABASE bit_schema SET search_path TO bitschema,public;") - db.session.commit() - @application.shell_context_processor def make_shell_context(): return { diff --git a/tests/base_test_case.py b/tests/base_test_case.py index 3e54333..c0e8e5b 100644 --- a/tests/base_test_case.py +++ b/tests/base_test_case.py @@ -11,19 +11,15 @@ class BaseTestCase(TestCase): @classmethod def create_app(cls): application.config.from_object("config.TestingConfig") - # Setting up test environment variables application.config["SECRET_KEY"] = "TEST_SECRET_KEY" application.config["SECURITY_PASSWORD_SALT"] = "TEST_SECURITY_PWD_SALT" return application def setUp(self): - db.create_all() - @classmethod def tearDown(cls): db.session.remove() db.drop_all() - \ No newline at end of file From ab97ce8a0b22012df7cc0eb0a8af9b9d235ccff9 Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 16:04:38 +0530 Subject: [PATCH 05/10] Docker setup instructions --- .github/ENV_SETUP_INSTRUCTIONS_DOCKER.md | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/ENV_SETUP_INSTRUCTIONS_DOCKER.md diff --git a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md new file mode 100644 index 0000000..29d79ae --- /dev/null +++ b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md @@ -0,0 +1,27 @@ + BridgeInTech Development Setup Instructions (Docker) + +Before you start, you need to have the following installed: +- [Docker-desktop](https://www.docker.com/products/docker-desktop) + +If you have these already installed, you are ready to start. + +## 1st, Fork, Clone, and Remote +1. Follow the instruction on the [Fork, Clone, and Remote](https://github.com/anitab-org/bridge-in-tech-backend/wiki/Fork,-Clone-&-Remote) page for this step. + + +## 2nd, Clone mentorship-backend for BIT +1.Follow the instruction on the mentorship system [Fork, Clone, and Remote](https://github.com/anitab-org/mentorship-backend/wiki/Fork,-Clone-&-Remote) page for this step. Make sure the two projects are cloned in the same directory. + +## 3rd, Create .env file from .env.template + +You can ignore all the environment variables below flask_app(included) as they have already been set up in docker. + +## 4th running the app locally +Run the command `docker-compose up`. If this is your first time it may take a while to download the images and get everything set up properly. Once this is complete you should be able to see the app running on http://localhost:5000 and the mentorship system running on http://localhost:4000. You can also connect to the Postgres server using `port 5432`. + +## 5th Running test cases +Run the command `docker-compose -f docker-compose.test.yml up` to run the test cases. + + + + From 9e2411fcd6586229f96ae40129f29178f6dcdd5f Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 16:37:11 +0530 Subject: [PATCH 06/10] Add more commands to Makefile --- .github/ENV_SETUP_INSTRUCTIONS_DOCKER.md | 2 +- Dockerfile | 2 +- Makefile | 14 +++++++++++--- docker-compose.test.yml | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md index 29d79ae..23c8dbc 100644 --- a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md +++ b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md @@ -20,7 +20,7 @@ You can ignore all the environment variables below flask_app(included) as they h Run the command `docker-compose up`. If this is your first time it may take a while to download the images and get everything set up properly. Once this is complete you should be able to see the app running on http://localhost:5000 and the mentorship system running on http://localhost:4000. You can also connect to the Postgres server using `port 5432`. ## 5th Running test cases -Run the command `docker-compose -f docker-compose.test.yml up` to run the test cases. +Run the command `docker-compose -f docker-compose.test.yml up --exit-code-from bit` to run the test cases. If you can use Makefiles then you can also run `make docker_test`. (Linux and MacOS support make out of the box) diff --git a/Dockerfile b/Dockerfile index ca2818b..dd20ba0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,4 +14,4 @@ ENV POSTGRES_PORT=5432 ENV MS_URL=http://MS:5000 ENV FLASK_APP=run.py ENTRYPOINT ["make"] -CMD ["dockerdev"] +CMD ["docker_host_dev"] diff --git a/Makefile b/Makefile index e571e4a..f51fc8e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ dev: python run.py -dockerdev: +docker_host_dev: flask run --host 0.0.0.0 -dockertest: - python -m unittest discover tests +tests: + python -m unittest discover tests +docker_test: + docker-compose -f docker-compose.tests.yml up --exit-code-from bit +docker_dev: + docker-compose up + + + + diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 749acbe..dcc0eed 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -12,7 +12,7 @@ services: volumes: - .:/dockerBuild build: . - command: dockertest + command: tests depends_on: - ms ms: From b78fbc80a670d3cf88ebbdb49075c510fb03a811 Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 18:36:48 +0530 Subject: [PATCH 07/10] minor bug fix --- .github/ENV_SETUP_INSTRUCTIONS_DOCKER.md | 2 +- Dockerfile | 3 ++- Makefile | 6 +++--- config.py | 3 ++- docker-compose.test.yml | 10 ++++++---- init_test_database.sql | 1 - 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md index 23c8dbc..cefeb1f 100644 --- a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md +++ b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md @@ -20,7 +20,7 @@ You can ignore all the environment variables below flask_app(included) as they h Run the command `docker-compose up`. If this is your first time it may take a while to download the images and get everything set up properly. Once this is complete you should be able to see the app running on http://localhost:5000 and the mentorship system running on http://localhost:4000. You can also connect to the Postgres server using `port 5432`. ## 5th Running test cases -Run the command `docker-compose -f docker-compose.test.yml up --exit-code-from bit` to run the test cases. If you can use Makefiles then you can also run `make docker_test`. (Linux and MacOS support make out of the box) +Run the command `docker-compose -f docker-compose.test.yml up --exit-code-from bit` to run the test cases. If you can use Makefiles then you can also run `make docker_test`. Linux and MacOS support make out of the box, but you can also use makefiles on windows by installing MinGW. diff --git a/Dockerfile b/Dockerfile index dd20ba0..205939d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,8 @@ COPY . /dockerBuild ENV DB_TYPE=postgresql ENV DB_USERNAME=postgres ENV DB_PASSWORD=postgres -ENV DB_ENDPOINT=postgres:5432 +ENV DB_ENDPOINT=postgres:5432 +ENV DB_TEST_ENDPOINT=test_postgres:5432 ENV DB_NAME=bit_schema ENV DB_TEST_NAME=bit_schema_test ENV POSTGRES_HOST=postgres diff --git a/Makefile b/Makefile index f51fc8e..1aca0c3 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,12 @@ dev: python run.py docker_host_dev: flask run --host 0.0.0.0 -tests: +python_tests: python -m unittest discover tests docker_test: - docker-compose -f docker-compose.tests.yml up --exit-code-from bit + docker-compose -f docker-compose.test.yml up --build --exit-code-from bit --remove-orphans docker_dev: - docker-compose up + docker-compose up --build --remove-orphans diff --git a/config.py b/config.py index 43d9923..f98ddba 100644 --- a/config.py +++ b/config.py @@ -61,6 +61,7 @@ class BaseConfig(object): DB_ENDPOINT = os.getenv("DB_ENDPOINT", "") DB_NAME = os.getenv("DB_NAME", "") DB_TEST_NAME = os.getenv("DB_TEST_NAME", "") + DB_TEST_ENDPOINT = os.getenv("DB_TEST_ENDPOINT", DB_ENDPOINT) @staticmethod def build_db_uri( @@ -77,7 +78,7 @@ def build_db_test_uri( db_type_arg=DB_TYPE, db_user_arg=DB_USERNAME, db_password_arg=DB_PASSWORD, - db_endpoint_arg=DB_ENDPOINT, + db_endpoint_arg=DB_TEST_ENDPOINT, db_name_arg=DB_TEST_NAME, ): return f"{db_type_arg}://{db_user_arg}:{db_password_arg}@{db_endpoint_arg}/{db_name_arg}" diff --git a/docker-compose.test.yml b/docker-compose.test.yml index dcc0eed..cb7f0a6 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -1,7 +1,7 @@ services: - postgres: - container_name: postgres + test_postgres: + container_name: test_postgres image: postgres environment: POSTGRES_PASSWORD: postgres @@ -12,12 +12,14 @@ services: volumes: - .:/dockerBuild build: . - command: tests + command: python_tests depends_on: - ms ms: container_name: MS_TEST build: ../mentorship-backend depends_on: - - postgres + - test_postgres + environment: + -FLASK_ENVIRONMENT_CONFIG: test diff --git a/init_test_database.sql b/init_test_database.sql index f4866e5..e2b477b 100644 --- a/init_test_database.sql +++ b/init_test_database.sql @@ -1,7 +1,6 @@ CREATE DATABASE bit_schema_test; \c bit_schema_test; CREATE SCHEMA IF NOT EXISTS bitschema; -CREATE SCHEMA IF NOT EXISTS bitschematest; CREATE SCHEMA IF NOT EXISTS test_schema; CREATE SCHEMA IF NOT EXISTS test_schema_2; ALTER DATABASE bit_schema_test SET search_path TO bitschema,public; \ No newline at end of file From bb10bd845d8f8151e73ce48bdf26b431f0ae998a Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 19:02:10 +0530 Subject: [PATCH 08/10] minor bug fix(2) --- docker-compose.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.test.yml b/docker-compose.test.yml index cb7f0a6..5049a1b 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -21,5 +21,5 @@ services: depends_on: - test_postgres environment: - -FLASK_ENVIRONMENT_CONFIG: test + FLASK_ENVIRONMENT_CONFIG: test From 16a96a033c69623c63a4d4d187748cf2e6e0fece Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 19:17:55 +0530 Subject: [PATCH 09/10] minor bug fix(3) --- .github/ENV_SETUP_INSTRUCTIONS_DOCKER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md index cefeb1f..498b321 100644 --- a/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md +++ b/.github/ENV_SETUP_INSTRUCTIONS_DOCKER.md @@ -17,7 +17,7 @@ If you have these already installed, you are ready to start. You can ignore all the environment variables below flask_app(included) as they have already been set up in docker. ## 4th running the app locally -Run the command `docker-compose up`. If this is your first time it may take a while to download the images and get everything set up properly. Once this is complete you should be able to see the app running on http://localhost:5000 and the mentorship system running on http://localhost:4000. You can also connect to the Postgres server using `port 5432`. +Run the command `docker-compose up`.If you can use Makefiles then you can also run `make docker_dev`. If this is your first time it may take a while to download the images and get everything set up properly. Once this is complete you should be able to see the app running on http://localhost:5000 and the mentorship system running on http://localhost:4000. You can also connect to the Postgres server using `port 5432`. ## 5th Running test cases Run the command `docker-compose -f docker-compose.test.yml up --exit-code-from bit` to run the test cases. If you can use Makefiles then you can also run `make docker_test`. Linux and MacOS support make out of the box, but you can also use makefiles on windows by installing MinGW. From 9a08d42b9774c17a1e765233e5919daf1022432b Mon Sep 17 00:00:00 2001 From: epicadk Date: Tue, 9 Mar 2021 19:24:36 +0530 Subject: [PATCH 10/10] minor bug fix(4) --- run.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/run.py b/run.py index e6eade9..31f3175 100644 --- a/run.py +++ b/run.py @@ -77,6 +77,8 @@ def create_tables(): MentorshipRelationExtensionModel, ) + db.create_all() + @application.shell_context_processor def make_shell_context(): return {