diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cdbb105 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,28 @@ +**/__pycache__ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +README.md + +venv/ +.pre-commit-config.yaml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c724780 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,51 @@ +name: TEST + +on: [push] + +env: + APP_ENV: TEST + +jobs: + test: + runs-on: ubuntu-latest + services: + mysql: + image: mysql8.0 + ports: + - 3306:3306 + env: + MYSQL_USER: test + MYSQL_PASSWORD: 1234 + MYSQL_ROOT_PASSWORD: 1234 + MYSQL_DATABASE: teting + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 + + steps: + - name: MySQL Check + env: + PORT: ${{ job.services.mysql.ports[3306] }} + run: | + while ! mysqladmin ping -h"127.0.0.1" -P"$PORT" --silent; do + sleep 1 + done + + - uses: actions/checkout@v2 + - name: Set Up Python + uses: actions/setup-python@v2 + with: + python-version: "3.8" + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Test + env: + DB_USERNAME: test + DB_PASSWORD: 1234 + DB_HOST: 127.0.0.1 + DB_PORT: 3306 + DB_NAME: testing + run: + pytest \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..cc755df --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: +- repo: https://github.com/psf/black + rev: 22.3.0 + hooks: + - id: black + language_version: python3 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6a4b107 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# For more information, please refer to https://aka.ms/vscode-docker-python +FROM python:3.8-slim + +EXPOSE 8000 + +# Keeps Python from generating .pyc files in the container +ENV PYTHONDONTWRITEBYTECODE=1 + +# Turns off buffering for easier container logging +ENV PYTHONUNBUFFERED=1 + +# Install pip requirements +COPY requirements.txt . +RUN python -m pip install -r requirements.txt + +WORKDIR /app +COPY . /app + +# Creates a non-root user with an explicit UID and adds permission to access the /app folder +# For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers +RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app +USER appuser + +# During debugging, this entry point will be overridden. For more information, please refer to https://aka.ms/vscode-docker-python-debug +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "-k", "uvicorn.workers.UvicornWorker", "backend\main:app"] diff --git a/backend/core/config.py b/backend/core/config.py index 2858312..99c4b4c 100644 --- a/backend/core/config.py +++ b/backend/core/config.py @@ -1,6 +1,6 @@ from pydantic import BaseSettings, SecretStr - from pathlib import Path +import os BASE_DIR = Path(__file__).resolve().parents[2] @@ -19,11 +19,11 @@ class Settings(BaseSettings): SECRET_ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 - class Config: env_file = str(BASE_DIR / ".env") env_file_encoding = "utf-8" + class TestSettings(BaseSettings): TEST_DB_USERNAME: str TEST_DB_PASSWORD: SecretStr @@ -35,11 +35,15 @@ class TestSettings(BaseSettings): SECRET_ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 - class Config: env_file = str(BASE_DIR / ".env") env_file_encoding = "utf-8" +def get_settings(): + if os.getenv("APP_ENV", "develop") == "TEST": + return TestSettings() + return Settings + -settings = Settings() +settings = get_settings() diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 1e1821a..aa0d1c7 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -7,12 +7,14 @@ import sys import os + sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from apis.base import api_router from db.base import Base from db.session import get_db -from core.config import TestSettings +from core.config import settings + def start_application() -> FastAPI: app = FastAPI() @@ -20,7 +22,6 @@ def start_application() -> FastAPI: return app -settings = TestSettings() engine = create_engine( "mysql+pymysql://{username}:{password}@{host}:{port}/{name}?charset=utf8mb4".format( username=settings.TEST_DB_USERNAME, @@ -33,6 +34,7 @@ def start_application() -> FastAPI: SessionTesting = sessionmaker(autocommit=False, autoflush=False, bind=engine) + @pytest.fixture(scope="module") def app() -> Generator[FastAPI, Any, None]: Base.metadata.create_all(engine) @@ -40,6 +42,7 @@ def app() -> Generator[FastAPI, Any, None]: yield _app Base.metadata.drop_all(engine) + @pytest.fixture(scope="module") def db_session(app: FastAPI) -> Generator[SessionTesting, Any, None]: connection = engine.connect() @@ -50,6 +53,7 @@ def db_session(app: FastAPI) -> Generator[SessionTesting, Any, None]: transaction.rollback() connection.close() + @pytest.fixture(scope="module") def client( app: FastAPI, db_session: SessionTesting @@ -59,7 +63,7 @@ def _get_test_db(): yield db_session finally: pass - + app.dependency_overrides[get_db] = _get_test_db with TestClient(app) as client: yield client diff --git a/requirements.txt b/requirements.txt index bdec92e..9ef34f6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,51 @@ -pymysql -pydantic[dotenv] - -sqlalchemy -fastapi -requests -pytest -uvicorn[standard] -python-jose[cryptography] -passlib[bcrypt] \ No newline at end of file +anyio==3.5.0 +asgiref==3.5.0 +atomicwrites==1.4.0 +attrs==21.4.0 +bcrypt==3.2.0 +certifi==2021.10.8 +cffi==1.15.0 +cfgv==3.3.1 +charset-normalizer==2.0.12 +click==8.0.4 +colorama==0.4.4 +cryptography==36.0.2 +distlib==0.3.4 +ecdsa==0.17.0 +fastapi==0.75.0 +filelock==3.6.0 +greenlet==1.1.2 +h11==0.13.0 +identify==2.4.12 +idna==3.3 +iniconfig==1.1.1 +install==1.3.5 +nodeenv==1.6.0 +packaging==21.3 +passlib==1.7.4 +platformdirs==2.5.1 +pluggy==1.0.0 +pre-commit==2.17.0 +py==1.11.0 +pyasn1==0.4.8 +pycparser==2.21 +pydantic==1.9.0 +PyMySQL==1.0.2 +pyparsing==3.0.7 +pytest==7.1.1 +python-dotenv==0.20.0 +python-jose==3.3.0 +python-multipart==0.0.5 +PyYAML==6.0 +requests==2.27.1 +rsa==4.8 +six==1.16.0 +sniffio==1.2.0 +SQLAlchemy==1.4.32 +starlette==0.17.1 +toml==0.10.2 +tomli==2.0.1 +typing-extensions==4.1.1 +urllib3==1.26.9 +uvicorn==0.17.6 +virtualenv==20.14.0