Skip to content

Commit 4f6688b

Browse files
✨(models) add downloaded verb to tincan vocabulary
Simply add the http://id.tincanapi.com/verb/downloaded to the tincan vocabulary so it can be used by other projects (here warren)
1 parent 0735466 commit 4f6688b

File tree

7 files changed

+85
-3
lines changed

7 files changed

+85
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to
1212

1313
- Implement edX open response assessment events pydantic models
1414
- Implement edx peer instruction events pydantic models
15+
- Implement xAPI VideoDownloaded pydantic model
16+
(using xAPI TinCan `downloaded` verb)
1517

1618
### Changed
1719

@@ -32,7 +34,7 @@ and this project adheres to
3234
- Clean xAPI pydantic models naming convention
3335
- Upgrade `fastapi` to `0.97.0`
3436
- Upgrade `sentry_sdk` to `1.25.1`
35-
- Set Clickhouse `client_options` to a dedicated Pydantic model
37+
- Set Clickhouse `client_options` to a dedicated pydantic model
3638
- Upgrade `httpx` to `0.24.1`
3739
- Force a valid (JSON-formatted) IFI to be passed for the `/statements`
3840
GET query `agent` filtering

src/ralph/models/xapi/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .navigation.statements import PageTerminated, PageViewed
66
from .video.statements import (
77
VideoCompleted,
8+
VideoDownloaded,
89
VideoEnableClosedCaptioning,
910
VideoInitialized,
1011
VideoPaused,

src/ralph/models/xapi/concepts/verbs/tincan_vocabulary.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,17 @@ class ViewedVerb(BaseXapiVerb):
2424
"http://id.tincanapi.com/verb/viewed"
2525
] = "http://id.tincanapi.com/verb/viewed"
2626
display: Optional[Dict[Literal[LANG_EN_US_DISPLAY], Literal["viewed"]]]
27+
28+
29+
class DownloadedVerb(BaseXapiVerb):
30+
"""Pydantic model for downloaded `verb`.
31+
32+
Attributes:
33+
id (str): Consists of the value `http://id.tincanapi.com/verb/downloaded`.
34+
display (dict): Consists of the dictionary `{"en-US": "downloaded"}`.
35+
"""
36+
37+
id: Literal[
38+
"http://id.tincanapi.com/verb/downloaded"
39+
] = "http://id.tincanapi.com/verb/downloaded"
40+
display: Optional[Dict[Literal[LANG_EN_US_DISPLAY], Literal["downloaded"]]]

src/ralph/models/xapi/video/contexts.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from uuid import UUID
1111

12-
from pydantic import Field, NonNegativeFloat
12+
from pydantic import Field, NonNegativeFloat, PositiveInt
1313

1414
from ..base.contexts import BaseXapiContext, BaseXapiContextContextActivities
1515
from ..base.unnested_objects import BaseXapiActivity
@@ -20,6 +20,7 @@
2020
CONTEXT_EXTENSION_COMPLETION_THRESHOLD,
2121
CONTEXT_EXTENSION_FULL_SCREEN,
2222
CONTEXT_EXTENSION_LENGTH,
23+
CONTEXT_EXTENSION_QUALITY,
2324
CONTEXT_EXTENSION_SCREEN_SIZE,
2425
CONTEXT_EXTENSION_SESSION_ID,
2526
CONTEXT_EXTENSION_SPEED,
@@ -132,6 +133,20 @@ class VideoBrowsingContextExtensions(VideoContextExtensions):
132133
)
133134

134135

136+
class VideoDownloadedContextExtensions(VideoContextExtensions):
137+
"""Represents the context.extensions field for video `downloaded` xAPI statement.
138+
139+
Attributes:
140+
length (float): Consists of the length of the video.
141+
quality (int): Consists of the video resolution or quality of the video.
142+
session (uuid): Consists of the ID of the active session.
143+
"""
144+
145+
length: NonNegativeFloat = Field(alias=CONTEXT_EXTENSION_LENGTH)
146+
quality: PositiveInt = Field(alias=CONTEXT_EXTENSION_QUALITY)
147+
session_id: Optional[UUID] = Field(alias=CONTEXT_EXTENSION_SESSION_ID)
148+
149+
135150
class VideoEnableClosedCaptioningContextExtensions(VideoContextExtensions):
136151
"""Represents the context.extensions field for video `interacted` xAPI statement.
137152
@@ -232,6 +247,16 @@ class VideoTerminatedContext(BaseVideoContext):
232247
extensions: VideoBrowsingContextExtensions
233248

234249

250+
class VideoDownloadedContext(BaseVideoContext):
251+
"""Pydantic model for video downloaded `context` property.
252+
253+
Attributes:
254+
extensions (dict): See VideoDownloadedContextExtensions.
255+
"""
256+
257+
extensions: VideoDownloadedContextExtensions
258+
259+
235260
class VideoEnableClosedCaptioningContext(BaseVideoContext):
236261
"""Pydantic model for video enable closed captioning `context` property.
237262

src/ralph/models/xapi/video/statements.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
InteractedVerb,
1212
TerminatedVerb,
1313
)
14+
from ..concepts.verbs.tincan_vocabulary import DownloadedVerb
1415
from ..concepts.verbs.video import PausedVerb, PlayedVerb, SeekedVerb
1516
from .contexts import (
1617
VideoCompletedContext,
18+
VideoDownloadedContext,
1719
VideoEnableClosedCaptioningContext,
1820
VideoInitializedContext,
1921
VideoPausedContext,
@@ -170,6 +172,25 @@ class VideoTerminated(BaseVideoStatement):
170172
context: VideoTerminatedContext
171173

172174

175+
class VideoDownloaded(BaseVideoStatement):
176+
"""Pydantic model for video downloaded statement.
177+
178+
Example: John downloaded (rather than accessed or opened) a video.
179+
180+
Attributes:
181+
verb (dict): See DownloadedVerb.
182+
context (dict): See VideoDownloadedContext.
183+
"""
184+
185+
__selector__ = selector(
186+
object__definition__type="https://w3id.org/xapi/video/activity-type/video",
187+
verb__id="http://id.tincanapi.com/verb/downloaded",
188+
)
189+
190+
verb: DownloadedVerb = DownloadedVerb()
191+
context: VideoDownloadedContext
192+
193+
173194
class VideoEnableClosedCaptioning(BaseVideoStatement):
174195
"""Pydantic model for video enable closed captioning statement.
175196

tests/models/xapi/concepts/test_verbs.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
InteractedVerb,
1818
TerminatedVerb,
1919
)
20-
from ralph.models.xapi.concepts.verbs.tincan_vocabulary import ViewedVerb
20+
from ralph.models.xapi.concepts.verbs.tincan_vocabulary import (
21+
DownloadedVerb,
22+
ViewedVerb,
23+
)
2124
from ralph.models.xapi.concepts.verbs.video import PausedVerb, PlayedVerb, SeekedVerb
2225
from ralph.models.xapi.concepts.verbs.virtual_classroom import (
2326
LoweredHandVerb,
@@ -47,6 +50,7 @@
4750
(InteractedVerb, "http://adlnet.gov/expapi/verbs/interacted"),
4851
(TerminatedVerb, "http://adlnet.gov/expapi/verbs/terminated"),
4952
(ViewedVerb, "http://id.tincanapi.com/verb/viewed"),
53+
(DownloadedVerb, "http://id.tincanapi.com/verb/downloaded"),
5054
(PausedVerb, "https://w3id.org/xapi/video/verbs/paused"),
5155
(PlayedVerb, "https://w3id.org/xapi/video/verbs/played"),
5256
(SeekedVerb, "https://w3id.org/xapi/video/verbs/seeked"),

tests/models/xapi/test_video.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ralph.models.validator import Validator
1111
from ralph.models.xapi.video.statements import (
1212
VideoCompleted,
13+
VideoDownloaded,
1314
VideoEnableClosedCaptioning,
1415
VideoInitialized,
1516
VideoPaused,
@@ -33,6 +34,7 @@
3334
VideoPlayed,
3435
VideoSeeked,
3536
VideoTerminated,
37+
VideoDownloaded,
3638
],
3739
)
3840
@custom_given(st.data())
@@ -148,6 +150,19 @@ def test_models_xapi_video_terminated_with_valid_statement(statement):
148150
)
149151

150152

153+
@custom_given(VideoDownloaded)
154+
def test_models_xapi_video_downloaded_with_valid_statement(statement):
155+
"""Tests that a video terminated statement has the expected `verb`.`id` and
156+
`object`.`definition`.`type` property values.
157+
"""
158+
159+
assert statement.verb.id == "http://id.tincanapi.com/verb/downloaded"
160+
assert (
161+
statement.object.definition.type
162+
== "https://w3id.org/xapi/video/activity-type/video"
163+
)
164+
165+
151166
@custom_given(VideoEnableClosedCaptioning)
152167
def test_models_xapi_video_enable_closed_captioning_with_valid_statement(statement):
153168
"""Tests that a video enable closed captioning statement has the expected

0 commit comments

Comments
 (0)