From d229973797a307cf5c9a5d95da060b450f92a5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20C=C3=A1rdenas?= Date: Mon, 2 Sep 2024 11:11:04 -0500 Subject: [PATCH] feat: #52 created schemas for newest models - updated the schemas in order to meet the new architecture - cleaned the dependencies at `requirements.txt` - include code coverage for actions --- .github/workflows/pr-conventional-commits.yml | 5 +- .github/workflows/python-app.yml | 26 +++- .pre-commit-config.yaml | 6 + .pylintrc | 2 +- app/schemas/activity.py | 42 +++++ app/schemas/answer.py | 37 +++++ app/schemas/question.py | 35 +++++ app/schemas/study_session.py | 38 +++++ app/schemas/user.py | 15 ++ requirements.txt | 147 +++++------------- 10 files changed, 237 insertions(+), 116 deletions(-) create mode 100644 app/schemas/activity.py create mode 100644 app/schemas/answer.py create mode 100644 app/schemas/question.py create mode 100644 app/schemas/study_session.py diff --git a/.github/workflows/pr-conventional-commits.yml b/.github/workflows/pr-conventional-commits.yml index 9427de9..deab1f8 100644 --- a/.github/workflows/pr-conventional-commits.yml +++ b/.github/workflows/pr-conventional-commits.yml @@ -9,7 +9,8 @@ jobs: runs-on: ubuntu-latest steps: - name: PR Conventional Commit Validation - uses: ytanikin/PRConventionalCommits@1.1.0 + uses: ytanikin/PRConventionalCommits@1.1.0 with: - task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]' + task_types: '["feat","fix","docs","test","ci","refac", + "perf","chore","revert"]' add_label: 'false' diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 88fd663..2cef0ee 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python - name: Python application on: @@ -19,25 +16,40 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up Python 3.10 uses: actions/setup-python@v3 with: python-version: "3.10" + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest black + pip install flake8 pytest black coverage if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - -name: Format with black + + - name: Format with black run: | black . + - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest + + - name: Run tests with coverage + run: | + coverage run -m pytest + + - name: Generate coverage report run: | - pytest + coverage report + coverage html + - name: Upload coverage report + uses: actions/upload-artifact@v3 + with: + name: coverage-report + path: htmlcov/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e4b9a49..584aab5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,3 +13,9 @@ repos: language: system pass_filenames: false + - id: format-yaml + name: Format YAML Files + entry: yamlfmt + language: python + types: [yaml] + files: \.(yml|yaml)$ diff --git a/.pylintrc b/.pylintrc index 5043e4f..4c34911 100644 --- a/.pylintrc +++ b/.pylintrc @@ -81,7 +81,7 @@ indent-string = ' ' indent-after-paren = 4 # Maximum number of characters on a single line. -max-line-length = 120 +max-line-length = 80 msg-template = "{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" output-format = colorized diff --git a/app/schemas/activity.py b/app/schemas/activity.py new file mode 100644 index 0000000..298d592 --- /dev/null +++ b/app/schemas/activity.py @@ -0,0 +1,42 @@ +# app/schemas/activity.py + +from typing import Optional +from enum import Enum +from datetime import datetime +from pydantic import BaseModel +from app.database.models import Question + + +class ActivityType(str, Enum): + question = "question" + + +class ActivityBase(BaseModel): + type: ActivityType + activity: str + created_at: datetime + + +class ActivityCreate(ActivityBase): + pass + + +class ActivityUpdate(ActivityBase): + pass + + +class ActivityInDBBase(ActivityBase): + id: int + user_id: int + study_session_id: int + + class Config: + orm_mode = True + + +class Activity(ActivityInDBBase): + question: Optional["Question"] = None + + +class ActivityInDB(ActivityInDBBase): + pass diff --git a/app/schemas/answer.py b/app/schemas/answer.py new file mode 100644 index 0000000..0797ad2 --- /dev/null +++ b/app/schemas/answer.py @@ -0,0 +1,37 @@ +# app/schemas/answer.py + +from typing import ( + Optional, + List, +) +from pydantic import BaseModel + + +class AnswerBase(BaseModel): + answer: str + + +class AnswerCreate(AnswerBase): + pass + + +class AnswerUpdate(AnswerBase): + pass + + +class AnswerInDBBase(AnswerBase): + id: int + user_id: int + question_id: int + + class Config: + orm_mode = True + + +class Answer(AnswerInDBBase): + parent_answer: Optional["Answer"] = None + child_answers: Optional[List["Answer"]] = [] + + +class AnswerInDB(AnswerInDBBase): + pass diff --git a/app/schemas/question.py b/app/schemas/question.py new file mode 100644 index 0000000..a8e02e7 --- /dev/null +++ b/app/schemas/question.py @@ -0,0 +1,35 @@ +from typing import ( + Optional, + List, +) +from pydantic import BaseModel +from app.database.models import Answer + + +class QuestionBase(BaseModel): + question: str + + +class QuestionCreate(QuestionBase): + pass + + +class QuestionUpdate(QuestionBase): + pass + + +class QuestionInDBBase(QuestionBase): + id: int + user_id: int + activity_id: int + + class Config: + orm_mode = True + + +class Question(QuestionInDBBase): + answers: Optional[List["Answer"]] = [] + + +class QuestionInDB(QuestionInDBBase): + pass diff --git a/app/schemas/study_session.py b/app/schemas/study_session.py new file mode 100644 index 0000000..b0cc017 --- /dev/null +++ b/app/schemas/study_session.py @@ -0,0 +1,38 @@ +# app/schemas/study_session.py + +from typing import ( + List, + Optional, +) +from datetime import datetime +from pydantic import BaseModel +from app.database.models import Activity + + +class StudySessionBase(BaseModel): + start_time: datetime + end_time: Optional[datetime] = None + + +class StudySessionCreate(StudySessionBase): + pass + + +class StudySessionUpdate(StudySessionBase): + pass + + +class StudySessionInDBBase(StudySessionBase): + id: int + user_id: int + + class Config: + orm_mode = True + + +class StudySession(StudySessionInDBBase): + activities: Optional[List["Activity"]] = [] + + +class StudySessionInDB(StudySessionInDBBase): + pass diff --git a/app/schemas/user.py b/app/schemas/user.py index 3b178e4..505c969 100644 --- a/app/schemas/user.py +++ b/app/schemas/user.py @@ -1,6 +1,12 @@ # app/schemas/user.py +from typing import ( + List, + Optional, +) +from datetime import datetime from pydantic import BaseModel +from app.database.models import Activity, Answer, Question, StudySession class UserBase(BaseModel): @@ -19,6 +25,15 @@ class UserUpdate(UserBase): class UserInDBBase(UserBase): id: int + created_at: datetime + updated_at: datetime class Config: orm_mode = True + + +class User(UserInDBBase): + study_sessions: Optional[List["StudySession"]] = [] + activities: Optional[List["Activity"]] = [] + questions: Optional[List["Question"]] = [] + answers: Optional[List["Answer"]] = [] diff --git a/requirements.txt b/requirements.txt index ee5194a..9eb1b84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,131 +1,66 @@ -aiohttp==3.9.3 -aiosignal==1.3.1 -annotated-types==0.6.0 -anthropic==0.25.7 -anyio==4.3.0 -astroid==3.1.0 -async-timeout==4.0.3 -attrs==23.2.0 -beautifulsoup4==4.12.3 +annotated-types==0.7.0 +anyio==4.4.0 +astroid==3.2.4 +babel==2.16.0 black==24.8.0 -Brotli==1.1.0 -bs4==0.0.2 -cachetools==5.3.3 -cairocffi==1.7.0 -certifi==2024.2.2 -cffi==1.16.0 +certifi==2024.8.30 cfgv==3.4.0 charset-normalizer==3.3.2 click==8.1.7 -cssselect2==0.7.0 -dataclasses-json==0.6.4 -defusedxml==0.7.1 +colorama==0.4.6 +coverage==7.6.1 dill==0.3.8 -discord.py==2.3.2 distlib==0.3.8 -distro==1.9.0 -dnspython==2.6.1 -email_validator==2.2.0 -exceptiongroup==1.2.0 -fastapi==0.112.0 -fastapi-cli==0.0.5 -filelock==3.14.0 -flake8==7.0.0 -fonttools==4.53.0 -frozenlist==1.4.1 -fsspec==2024.3.1 -google-ai-generativelanguage==0.6.2 -google-api-core==2.18.0 -google-api-python-client==2.127.0 -google-auth==2.29.0 -google-auth-httplib2==0.2.0 -google-generativeai==0.5.2 -googleapis-common-protos==1.63.0 +fastapi==0.112.2 +filelock==3.15.4 +flake8==7.1.1 +ghp-import==2.1.0 greenlet==3.0.3 -grpcio==1.62.2 -grpcio-status==1.62.2 h11==0.14.0 -html5lib==1.1 -httpcore==1.0.5 -httplib2==0.22.0 -httptools==0.6.1 -httpx==0.27.0 -huggingface-hub==0.22.2 identify==2.6.0 -idna==3.6 +idna==3.8 iniconfig==2.0.0 isort==5.13.2 Jinja2==3.1.4 -jsonpatch==1.33 -jsonpointer==2.4 -langchain==0.1.16 -langchain-anthropic==0.1.11 -langchain-community==0.0.34 -langchain-core==0.1.46 -langchain-google-genai==1.0.3 -langchain-text-splitters==0.0.1 -langsmith==0.1.51 Markdown==3.7 -markdown-it-py==3.0.0 MarkupSafe==2.1.5 -marshmallow==3.21.1 mccabe==0.7.0 -mdurl==0.1.2 -multidict==6.0.5 +mergedeep==1.3.4 +mkdocs==1.6.1 +mkdocs-get-deps==0.2.0 +mkdocs-material==9.5.34 +mkdocs-material-extensions==1.3.1 mypy-extensions==1.0.0 nodeenv==1.9.1 -numpy==1.26.4 -orjson==3.10.1 -packaging==23.2 +packaging==24.1 +paginate==0.5.7 pathspec==0.12.1 -pillow==10.3.0 -platformdirs==4.2.1 -pluggy==1.4.0 +platformdirs==4.2.2 +pluggy==1.5.0 pre-commit==3.8.0 -proto-plus==1.23.0 -protobuf==4.25.3 -pyasn1==0.6.0 -pyasn1_modules==0.4.0 -pycodestyle==2.11.1 -pycparser==2.22 -pydantic==2.7.1 -pydantic_core==2.18.2 -pydyf==0.10.0 +pycodestyle==2.12.1 +pydantic==2.8.2 +pydantic_core==2.20.1 pyflakes==3.2.0 Pygments==2.18.0 -pylint==3.1.0 -pyparsing==3.1.2 -pyphen==0.15.0 -pytest==8.1.1 -python-dotenv==1.0.1 -python-multipart==0.0.9 -PyYAML==6.0.1 -requests==2.31.0 -rich==13.7.1 -rsa==4.9 -shellingham==1.5.4 +pylint==3.2.7 +pymdown-extensions==10.9 +pytest==8.3.2 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +pyyaml_env_tag==0.1 +regex==2024.7.24 +requests==2.32.3 +ruamel.yaml==0.17.40 +ruamel.yaml.clib==0.2.8 six==1.16.0 sniffio==1.3.1 -soupsieve==2.5 SQLAlchemy==2.0.29 -starlette==0.37.2 -tenacity==8.2.3 -tinycss2==1.3.0 -tokenizers==0.19.1 -tomli==2.0.1 -tomlkit==0.12.4 -tqdm==4.66.2 -typer==0.12.3 -typing-inspect==0.9.0 -typing_extensions==4.10.0 -uritemplate==4.1.1 -urllib3==2.2.1 -uvicorn==0.30.5 -uvloop==0.19.0 +starlette==0.38.4 +tomlkit==0.13.2 +typing_extensions==4.12.2 +urllib3==2.2.2 +uvicorn==0.30.6 virtualenv==20.26.3 -watchfiles==0.22.0 -webencodings==0.5.1 -websockets==12.0 -wikipedia==1.4.0 -yarl==1.9.4 -zopfli==0.2.3 +watchdog==5.0.0 +yamlfmt==1.1.1