Skip to content

Commit

Permalink
🏷️(library) restore python 3.7+ compatibility for models
Browse files Browse the repository at this point in the history
Models may now be used in python 3.7+ projects.
  • Loading branch information
jmaupetit committed Feb 3, 2023
1 parent e6a30bd commit 1ddbc13
Show file tree
Hide file tree
Showing 33 changed files with 209 additions and 92 deletions.
10 changes: 8 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ docker-login: &docker-login
echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_USER" --password-stdin ||
echo "Docker Hub anonymous mode"
version: 2
version: 2.1
jobs:
# Git jobs
# Check that the git history is clean and complies with our expectations
Expand Down Expand Up @@ -209,8 +209,11 @@ jobs:
~/.local/bin/pytest
test-library:
parameters:
python-image:
type: string
docker:
- image: cimg/python:3.11
- image: cimg/<< parameters.python-image >>
auth:
username: $DOCKER_HUB_USER
password: $DOCKER_HUB_PASSWORD
Expand Down Expand Up @@ -519,6 +522,9 @@ workflows:
tags:
only: /.*/
- test-library:
matrix:
parameters:
python-image: [python:3.7, python:3.8, python:3.9, python:3.10, python:3.11]
filters:
tags:
only: /.*/
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ and this project adheres to

## [Unreleased]

### Added

- Restored python 3.7+ support for library usage (models)

### Changed

- Allow xAPI extra fields in `extensions` fields

## [3.2.1] - 2023-02-01
Expand Down
11 changes: 8 additions & 3 deletions src/ralph/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import io
from pathlib import Path
from typing import Literal, Union
from typing import List, Tuple, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

try:
from click import get_app_dir
Expand Down Expand Up @@ -46,7 +51,7 @@ class CommaSeparatedTuple(str):

@classmethod
def __get_validators__(cls): # noqa: D105
def validate(value: Union[str, tuple[str]]) -> tuple[str]:
def validate(value: Union[str, Tuple[str]]) -> Tuple[str]:
"""Checks whether the value is a comma separated string or a tuple."""
if isinstance(value, tuple):
return value
Expand Down Expand Up @@ -307,7 +312,7 @@ class Config(BaseSettingsConfig):
SENTRY_DSN: str = None
SENTRY_CLI_TRACES_SAMPLE_RATE = 1.0
SENTRY_LRS_TRACES_SAMPLE_RATE = 0.1
XAPI_FORWARDINGS: list[XapiForwardingConfigurationSettings] = []
XAPI_FORWARDINGS: List[XapiForwardingConfigurationSettings] = []

@property
def APP_DIR(self) -> Path: # pylint: disable=invalid-name
Expand Down
11 changes: 8 additions & 3 deletions src/ralph/models/edx/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from datetime import datetime
from ipaddress import IPv4Address
from pathlib import Path
from typing import Literal, Optional, Union
from typing import Dict, Optional, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import AnyHttpUrl, BaseModel, constr

Expand Down Expand Up @@ -37,7 +42,7 @@ class BaseContextField(BaseModelWithConfig):
"""Pydantic model for core `context` field.
Attributes:
course_user_tags (dict of str): Content from `user_api_usercoursetag` table.
course_user_tags (Dict of str): Content from `user_api_usercoursetag` table.
Retrieved with:
`dict(
UserCourseTag.objects.filter(
Expand Down Expand Up @@ -76,7 +81,7 @@ class BaseContextField(BaseModelWithConfig):
"""

course_id: constr(regex=r"^$|^course-v1:.+\+.+\+.+$") # noqa:F722
course_user_tags: Optional[dict[str, str]]
course_user_tags: Optional[Dict[str, str]]
module: Optional[ContextModuleField]
org_id: str
path: Path
Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/browser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Browser event model definitions."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import AnyUrl, constr

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/enrollment/fields/contexts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Enrollment event models context fields definitions."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from ...base import BaseContextField

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/enrollment/fields/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Enrollment models event field definition."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from ...base import AbstractBaseEventField

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/enrollment/statements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Enrollment event model definitions."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/navigational/statements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Navigational event model definitions."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json, validator

Expand Down
35 changes: 20 additions & 15 deletions src/ralph/models/edx/problem_interaction/fields/events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""Problem interaction events model event fields definitions."""

from datetime import datetime
from typing import Literal, Optional, Union
from typing import Dict, List, Optional, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import constr

Expand Down Expand Up @@ -55,7 +60,7 @@ class State(BaseModelWithConfig):
student_answers (dict): Consists of the answer(s) given by the user.
"""

correct_map: dict[
correct_map: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"), # noqa : F722
CorrectMap,
]
Expand All @@ -80,7 +85,7 @@ class SubmissionAnswerField(BaseModelWithConfig):
this user.
"""

answer: Union[str, list[str]]
answer: Union[str, List[str]]
correct: bool
input_type: str
question: str
Expand Down Expand Up @@ -129,10 +134,10 @@ class EdxProblemHintFeedbackDisplayedEventField(AbstractBaseEventField):
`student_answer` response. Consists either of `single` or `compound` value.
"""

choice_all: Optional[list[str]]
choice_all: Optional[List[str]]
correctness: bool
hint_label: str
hints: list[dict]
hints: List[dict]
module_id: str
problem_part_id: str
question_type: Union[
Expand All @@ -142,7 +147,7 @@ class EdxProblemHintFeedbackDisplayedEventField(AbstractBaseEventField):
Literal["numericalresponse"],
Literal["optionresponse"],
]
student_answer: list[str]
student_answer: List[str]
trigger_type: Union[Literal["single"], Literal["compound"]]


Expand All @@ -163,12 +168,12 @@ class ProblemCheckEventField(AbstractBaseEventField):
success (str): Consists of either the `correct` or `incorrect` value.
"""

answers: dict[
answers: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"), # noqa : F722
Union[list[str], str],
Union[List[str], str],
]
attempts: int
correct_map: dict[
correct_map: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"), # noqa : F722
CorrectMap,
]
Expand All @@ -179,7 +184,7 @@ class ProblemCheckEventField(AbstractBaseEventField):
r"type@problem\+block@[a-f0-9]{32}$" # noqa : F722
)
state: State
submission: dict[
submission: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"), # noqa : F722
SubmissionAnswerField,
]
Expand All @@ -197,9 +202,9 @@ class ProblemCheckFailEventField(AbstractBaseEventField):
state (dict): Consists of the current problem state.
"""

answers: dict[
answers: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"), # noqa : F722
Union[list[str], str],
Union[List[str], str],
]
failure: Union[Literal["closed"], Literal["unreset"]]
problem_id: constr(
Expand Down Expand Up @@ -262,7 +267,7 @@ class UIProblemResetEventField(AbstractBaseEventField):
strings if multiple choices are allowed.
"""

answers: Union[str, list[str]]
answers: Union[str, List[str]]


class UIProblemShowEventField(AbstractBaseEventField):
Expand Down Expand Up @@ -321,7 +326,7 @@ class SaveProblemFailEventField(AbstractBaseEventField):
state (json): see StateField.
"""

answers: dict[str, Union[int, str, list, dict]]
answers: Dict[str, Union[int, str, list, dict]]
failure: Union[Literal["closed"], Literal["done"]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+" # noqa : F722
Expand All @@ -340,7 +345,7 @@ class SaveProblemSuccessEventField(AbstractBaseEventField):
state (json): see StateField.
"""

answers: dict[str, Union[int, str, list, dict]]
answers: Dict[str, Union[int, str, list, dict]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+" # noqa : F722
r"type@problem\+block@[a-f0-9]{32}$" # noqa : F722
Expand Down
9 changes: 7 additions & 2 deletions src/ralph/models/edx/problem_interaction/statements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Problem interaction events model definitions."""

from typing import Literal, Union
from typing import List, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json

Expand Down Expand Up @@ -135,7 +140,7 @@ class UIProblemGraded(BaseBrowserModel):

__selector__ = selector(event_source="browser", event_type="problem_graded")

event: list[Union[str, Literal[None], None]]
event: List[Union[str, Literal[None], None]]
event_type: Literal["problem_graded"]
name: Literal["problem_graded"]

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/server.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""Server event model definitions."""

from pathlib import Path
from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/textbook_interaction/fields/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Textbook interaction event fields definitions."""

from typing import Literal, Optional, Union
from typing import Optional, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Field, constr

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/textbook_interaction/statements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Textbook interaction event model definitions."""

from typing import Literal, Union
from typing import Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json

Expand Down
5 changes: 4 additions & 1 deletion src/ralph/models/edx/video/fields/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Video event fields definitions."""

from typing import Literal
try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from ...base import AbstractBaseEventField

Expand Down
7 changes: 6 additions & 1 deletion src/ralph/models/edx/video/statements.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Video event model definitions."""

from typing import Literal, Optional, Union
from typing import Optional, Union

try:
from typing import Literal
except ImportError:
from typing_extensions import Literal

from pydantic import Json

Expand Down
4 changes: 2 additions & 2 deletions src/ralph/models/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from inspect import getmembers, isclass
from itertools import chain
from types import ModuleType
from typing import Any, Union
from typing import Any, Tuple, Union

from pydantic import BaseModel

Expand All @@ -19,7 +19,7 @@
class LazyModelField:
"""Model field."""

path: tuple[str]
path: Tuple[str]

def __init__(self, path: str):
"""Initalizes Lazy Model Field."""
Expand Down
Loading

0 comments on commit 1ddbc13

Please sign in to comment.