timeback-edubridge 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- timeback_edubridge-0.1.0/.gitignore +48 -0
- timeback_edubridge-0.1.0/PKG-INFO +230 -0
- timeback_edubridge-0.1.0/README.md +209 -0
- timeback_edubridge-0.1.0/pyproject.toml +34 -0
- timeback_edubridge-0.1.0/pytest.ini +5 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/__init__.py +158 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/client.py +230 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/constants.py +24 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/exceptions.py +30 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/lib/__init__.py +10 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/lib/pagination.py +281 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/lib/transport.py +110 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/py.typed +0 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/__init__.py +19 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/analytics.py +251 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/applications.py +73 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/enrollments.py +213 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/learning_reports.py +80 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/subject_track.py +135 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/resources/users.py +213 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/__init__.py +93 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/analytics.py +153 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/applications.py +43 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/base.py +51 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/enrollments.py +139 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/learning_reports.py +43 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/subject_track.py +67 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/types/users.py +102 -0
- timeback_edubridge-0.1.0/src/timeback_edubridge/utils.py +200 -0
- timeback_edubridge-0.1.0/tests/__init__.py +1 -0
- timeback_edubridge-0.1.0/tests/test_client.py +132 -0
- timeback_edubridge-0.1.0/tests/test_types.py +197 -0
- timeback_edubridge-0.1.0/tests/test_utils.py +240 -0
- timeback_edubridge-0.1.0/tests/test_validation.py +202 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib64/
|
|
14
|
+
parts/
|
|
15
|
+
sdist/
|
|
16
|
+
var/
|
|
17
|
+
wheels/
|
|
18
|
+
*.egg-info/
|
|
19
|
+
.installed.cfg
|
|
20
|
+
*.egg
|
|
21
|
+
|
|
22
|
+
# Virtual environments
|
|
23
|
+
.venv/
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
|
|
27
|
+
# uv
|
|
28
|
+
uv.lock
|
|
29
|
+
|
|
30
|
+
# ruff
|
|
31
|
+
.ruff_cache/
|
|
32
|
+
|
|
33
|
+
# Testing
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.coverage
|
|
36
|
+
htmlcov/
|
|
37
|
+
.tox/
|
|
38
|
+
.nox/
|
|
39
|
+
|
|
40
|
+
# IDEs
|
|
41
|
+
.idea/
|
|
42
|
+
.vscode/
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
|
|
46
|
+
# OS
|
|
47
|
+
.DS_Store
|
|
48
|
+
Thumbs.db
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: timeback-edubridge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the Timeback EduBridge API
|
|
5
|
+
Project-URL: Homepage, https://timeback.ai
|
|
6
|
+
Project-URL: Documentation, https://docs.timeback.ai
|
|
7
|
+
Project-URL: Repository, https://github.com/timeback-ai/timeback-python
|
|
8
|
+
Author: Timeback
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: api,edubridge,education,sdk,timeback
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: timeback-common>=0.1.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Timeback EduBridge Client
|
|
23
|
+
|
|
24
|
+
Python client for the Timeback EduBridge API with async support.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install timeback-edubridge
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from timeback_edubridge import EdubridgeClient
|
|
36
|
+
|
|
37
|
+
# Initialize with explicit configuration
|
|
38
|
+
client = EdubridgeClient(
|
|
39
|
+
base_url="https://api.timeback.ai",
|
|
40
|
+
auth_url="https://auth.timeback.ai/oauth2/token",
|
|
41
|
+
client_id="your-client-id",
|
|
42
|
+
client_secret="your-client-secret",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Or use environment variables with a prefix
|
|
46
|
+
client = EdubridgeClient(env="PRODUCTION")
|
|
47
|
+
# Reads: PRODUCTION_EDUBRIDGE_BASE_URL, PRODUCTION_EDUBRIDGE_TOKEN_URL, etc.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Resources
|
|
51
|
+
|
|
52
|
+
### Enrollments
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
# List enrollments for a user
|
|
56
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
57
|
+
|
|
58
|
+
# Enroll a user in a course
|
|
59
|
+
enrollment = await client.enrollments.enroll(
|
|
60
|
+
user_id="user-123",
|
|
61
|
+
course_id="course-456",
|
|
62
|
+
school_id="school-789", # Optional
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Unenroll a user
|
|
66
|
+
await client.enrollments.unenroll(
|
|
67
|
+
user_id="user-123",
|
|
68
|
+
course_id="course-456",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Reset goals for a course
|
|
72
|
+
result = await client.enrollments.reset_goals("course-456")
|
|
73
|
+
|
|
74
|
+
# Reset a user's progress
|
|
75
|
+
await client.enrollments.reset_progress("user-123", "course-456")
|
|
76
|
+
|
|
77
|
+
# Get default class for a course
|
|
78
|
+
default_class = await client.enrollments.get_default_class("course-456")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Users
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# List users by role
|
|
85
|
+
users = await client.users.list(roles=["student", "teacher"])
|
|
86
|
+
|
|
87
|
+
# Convenience methods
|
|
88
|
+
students = await client.users.list_students()
|
|
89
|
+
teachers = await client.users.list_teachers()
|
|
90
|
+
|
|
91
|
+
# Search users
|
|
92
|
+
results = await client.users.search(
|
|
93
|
+
roles=["student"],
|
|
94
|
+
search="john",
|
|
95
|
+
limit=50,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# With additional filters
|
|
99
|
+
filtered = await client.users.list(
|
|
100
|
+
roles=["student"],
|
|
101
|
+
org_sourced_ids=["school-123"],
|
|
102
|
+
limit=100,
|
|
103
|
+
offset=0,
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Analytics
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
# Get activity for a date range
|
|
111
|
+
activity = await client.analytics.get_activity(
|
|
112
|
+
student_id="student-123", # or email="student@example.com"
|
|
113
|
+
start_date="2025-01-01",
|
|
114
|
+
end_date="2025-01-31",
|
|
115
|
+
timezone="America/New_York",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Get weekly facts
|
|
119
|
+
facts = await client.analytics.get_weekly_facts(
|
|
120
|
+
student_id="student-123",
|
|
121
|
+
week_date="2025-01-15",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Get enrollment-specific facts
|
|
125
|
+
enrollment_facts = await client.analytics.get_enrollment_facts(
|
|
126
|
+
enrollment_id="enrollment-123",
|
|
127
|
+
start_date="2025-01-01",
|
|
128
|
+
end_date="2025-01-31",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Get highest grade mastered
|
|
132
|
+
grade = await client.analytics.get_highest_grade_mastered(
|
|
133
|
+
student_id="student-123",
|
|
134
|
+
subject="Math",
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Applications
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
# List all applications
|
|
142
|
+
apps = await client.applications.list()
|
|
143
|
+
|
|
144
|
+
# Get metrics for an application
|
|
145
|
+
metrics = await client.applications.get_metrics("app-123")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Subject Tracks
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from timeback_edubridge import SubjectTrackInput
|
|
152
|
+
|
|
153
|
+
# List all subject tracks
|
|
154
|
+
tracks = await client.subject_tracks.list()
|
|
155
|
+
|
|
156
|
+
# Create or update a subject track
|
|
157
|
+
track = await client.subject_tracks.upsert(
|
|
158
|
+
id="track-123",
|
|
159
|
+
data=SubjectTrackInput(
|
|
160
|
+
subject="Math",
|
|
161
|
+
grade_level="9",
|
|
162
|
+
target_course_id="course-456",
|
|
163
|
+
),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# Delete a subject track
|
|
167
|
+
await client.subject_tracks.delete("track-123")
|
|
168
|
+
|
|
169
|
+
# List subject track groups
|
|
170
|
+
groups = await client.subject_tracks.list_groups()
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Learning Reports
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
# Get MAP profile for a user
|
|
177
|
+
profile = await client.learning_reports.get_map_profile("user-123")
|
|
178
|
+
|
|
179
|
+
# Get time saved metrics
|
|
180
|
+
time_saved = await client.learning_reports.get_time_saved("user-123")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Context Manager
|
|
184
|
+
|
|
185
|
+
The client can be used as an async context manager:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
async with EdubridgeClient(base_url="...") as client:
|
|
189
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
190
|
+
# Client is automatically closed
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Error Handling
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from timeback_edubridge import (
|
|
197
|
+
EdubridgeError,
|
|
198
|
+
AuthenticationError,
|
|
199
|
+
ForbiddenError,
|
|
200
|
+
NotFoundError,
|
|
201
|
+
ValidationError,
|
|
202
|
+
APIError,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
207
|
+
except AuthenticationError:
|
|
208
|
+
print("Invalid credentials")
|
|
209
|
+
except ForbiddenError:
|
|
210
|
+
print("Access denied")
|
|
211
|
+
except NotFoundError:
|
|
212
|
+
print("Resource not found")
|
|
213
|
+
except ValidationError as e:
|
|
214
|
+
print(f"Invalid request: {e}")
|
|
215
|
+
except APIError as e:
|
|
216
|
+
print(f"API error {e.status_code}: {e}")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Environment Variables
|
|
220
|
+
|
|
221
|
+
When using `env` parameter, the client looks for these variables:
|
|
222
|
+
|
|
223
|
+
| Variable | Description |
|
|
224
|
+
|----------|-------------|
|
|
225
|
+
| `{PREFIX}_EDUBRIDGE_BASE_URL` | Base URL for the API |
|
|
226
|
+
| `{PREFIX}_EDUBRIDGE_TOKEN_URL` | OAuth2 token endpoint |
|
|
227
|
+
| `{PREFIX}_EDUBRIDGE_CLIENT_ID` | OAuth2 client ID |
|
|
228
|
+
| `{PREFIX}_EDUBRIDGE_CLIENT_SECRET` | OAuth2 client secret |
|
|
229
|
+
|
|
230
|
+
Without a prefix, it uses the variables without the prefix (e.g., `EDUBRIDGE_BASE_URL`).
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Timeback EduBridge Client
|
|
2
|
+
|
|
3
|
+
Python client for the Timeback EduBridge API with async support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install timeback-edubridge
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from timeback_edubridge import EdubridgeClient
|
|
15
|
+
|
|
16
|
+
# Initialize with explicit configuration
|
|
17
|
+
client = EdubridgeClient(
|
|
18
|
+
base_url="https://api.timeback.ai",
|
|
19
|
+
auth_url="https://auth.timeback.ai/oauth2/token",
|
|
20
|
+
client_id="your-client-id",
|
|
21
|
+
client_secret="your-client-secret",
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Or use environment variables with a prefix
|
|
25
|
+
client = EdubridgeClient(env="PRODUCTION")
|
|
26
|
+
# Reads: PRODUCTION_EDUBRIDGE_BASE_URL, PRODUCTION_EDUBRIDGE_TOKEN_URL, etc.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Resources
|
|
30
|
+
|
|
31
|
+
### Enrollments
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
# List enrollments for a user
|
|
35
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
36
|
+
|
|
37
|
+
# Enroll a user in a course
|
|
38
|
+
enrollment = await client.enrollments.enroll(
|
|
39
|
+
user_id="user-123",
|
|
40
|
+
course_id="course-456",
|
|
41
|
+
school_id="school-789", # Optional
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Unenroll a user
|
|
45
|
+
await client.enrollments.unenroll(
|
|
46
|
+
user_id="user-123",
|
|
47
|
+
course_id="course-456",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Reset goals for a course
|
|
51
|
+
result = await client.enrollments.reset_goals("course-456")
|
|
52
|
+
|
|
53
|
+
# Reset a user's progress
|
|
54
|
+
await client.enrollments.reset_progress("user-123", "course-456")
|
|
55
|
+
|
|
56
|
+
# Get default class for a course
|
|
57
|
+
default_class = await client.enrollments.get_default_class("course-456")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Users
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# List users by role
|
|
64
|
+
users = await client.users.list(roles=["student", "teacher"])
|
|
65
|
+
|
|
66
|
+
# Convenience methods
|
|
67
|
+
students = await client.users.list_students()
|
|
68
|
+
teachers = await client.users.list_teachers()
|
|
69
|
+
|
|
70
|
+
# Search users
|
|
71
|
+
results = await client.users.search(
|
|
72
|
+
roles=["student"],
|
|
73
|
+
search="john",
|
|
74
|
+
limit=50,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# With additional filters
|
|
78
|
+
filtered = await client.users.list(
|
|
79
|
+
roles=["student"],
|
|
80
|
+
org_sourced_ids=["school-123"],
|
|
81
|
+
limit=100,
|
|
82
|
+
offset=0,
|
|
83
|
+
)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Analytics
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Get activity for a date range
|
|
90
|
+
activity = await client.analytics.get_activity(
|
|
91
|
+
student_id="student-123", # or email="student@example.com"
|
|
92
|
+
start_date="2025-01-01",
|
|
93
|
+
end_date="2025-01-31",
|
|
94
|
+
timezone="America/New_York",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Get weekly facts
|
|
98
|
+
facts = await client.analytics.get_weekly_facts(
|
|
99
|
+
student_id="student-123",
|
|
100
|
+
week_date="2025-01-15",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Get enrollment-specific facts
|
|
104
|
+
enrollment_facts = await client.analytics.get_enrollment_facts(
|
|
105
|
+
enrollment_id="enrollment-123",
|
|
106
|
+
start_date="2025-01-01",
|
|
107
|
+
end_date="2025-01-31",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Get highest grade mastered
|
|
111
|
+
grade = await client.analytics.get_highest_grade_mastered(
|
|
112
|
+
student_id="student-123",
|
|
113
|
+
subject="Math",
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Applications
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# List all applications
|
|
121
|
+
apps = await client.applications.list()
|
|
122
|
+
|
|
123
|
+
# Get metrics for an application
|
|
124
|
+
metrics = await client.applications.get_metrics("app-123")
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Subject Tracks
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from timeback_edubridge import SubjectTrackInput
|
|
131
|
+
|
|
132
|
+
# List all subject tracks
|
|
133
|
+
tracks = await client.subject_tracks.list()
|
|
134
|
+
|
|
135
|
+
# Create or update a subject track
|
|
136
|
+
track = await client.subject_tracks.upsert(
|
|
137
|
+
id="track-123",
|
|
138
|
+
data=SubjectTrackInput(
|
|
139
|
+
subject="Math",
|
|
140
|
+
grade_level="9",
|
|
141
|
+
target_course_id="course-456",
|
|
142
|
+
),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Delete a subject track
|
|
146
|
+
await client.subject_tracks.delete("track-123")
|
|
147
|
+
|
|
148
|
+
# List subject track groups
|
|
149
|
+
groups = await client.subject_tracks.list_groups()
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Learning Reports
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Get MAP profile for a user
|
|
156
|
+
profile = await client.learning_reports.get_map_profile("user-123")
|
|
157
|
+
|
|
158
|
+
# Get time saved metrics
|
|
159
|
+
time_saved = await client.learning_reports.get_time_saved("user-123")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Context Manager
|
|
163
|
+
|
|
164
|
+
The client can be used as an async context manager:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
async with EdubridgeClient(base_url="...") as client:
|
|
168
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
169
|
+
# Client is automatically closed
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Error Handling
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from timeback_edubridge import (
|
|
176
|
+
EdubridgeError,
|
|
177
|
+
AuthenticationError,
|
|
178
|
+
ForbiddenError,
|
|
179
|
+
NotFoundError,
|
|
180
|
+
ValidationError,
|
|
181
|
+
APIError,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
186
|
+
except AuthenticationError:
|
|
187
|
+
print("Invalid credentials")
|
|
188
|
+
except ForbiddenError:
|
|
189
|
+
print("Access denied")
|
|
190
|
+
except NotFoundError:
|
|
191
|
+
print("Resource not found")
|
|
192
|
+
except ValidationError as e:
|
|
193
|
+
print(f"Invalid request: {e}")
|
|
194
|
+
except APIError as e:
|
|
195
|
+
print(f"API error {e.status_code}: {e}")
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Environment Variables
|
|
199
|
+
|
|
200
|
+
When using `env` parameter, the client looks for these variables:
|
|
201
|
+
|
|
202
|
+
| Variable | Description |
|
|
203
|
+
|----------|-------------|
|
|
204
|
+
| `{PREFIX}_EDUBRIDGE_BASE_URL` | Base URL for the API |
|
|
205
|
+
| `{PREFIX}_EDUBRIDGE_TOKEN_URL` | OAuth2 token endpoint |
|
|
206
|
+
| `{PREFIX}_EDUBRIDGE_CLIENT_ID` | OAuth2 client ID |
|
|
207
|
+
| `{PREFIX}_EDUBRIDGE_CLIENT_SECRET` | OAuth2 client secret |
|
|
208
|
+
|
|
209
|
+
Without a prefix, it uses the variables without the prefix (e.g., `EDUBRIDGE_BASE_URL`).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "timeback-edubridge"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Python client for the Timeback EduBridge API"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
authors = [{ name = "Timeback" }]
|
|
9
|
+
keywords = ["timeback", "edubridge", "education", "api", "sdk"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 4 - Beta",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"Programming Language :: Python :: 3.10",
|
|
14
|
+
"Programming Language :: Python :: 3.11",
|
|
15
|
+
"Programming Language :: Python :: 3.12",
|
|
16
|
+
"Programming Language :: Python :: 3.13",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
]
|
|
19
|
+
dependencies = ["timeback-common>=0.1.0"]
|
|
20
|
+
|
|
21
|
+
[tool.uv.sources]
|
|
22
|
+
timeback-common = { workspace = true }
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://timeback.ai"
|
|
26
|
+
Documentation = "https://docs.timeback.ai"
|
|
27
|
+
Repository = "https://github.com/timeback-ai/timeback-python"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["hatchling"]
|
|
31
|
+
build-backend = "hatchling.build"
|
|
32
|
+
|
|
33
|
+
[tool.hatch.build.targets.wheel]
|
|
34
|
+
packages = ["src/timeback_edubridge"]
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Timeback EduBridge Client
|
|
3
|
+
|
|
4
|
+
A Python client for the Timeback EduBridge API with async support.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
```python
|
|
8
|
+
from timeback_edubridge import EdubridgeClient
|
|
9
|
+
|
|
10
|
+
client = EdubridgeClient(
|
|
11
|
+
base_url="https://api.example.com",
|
|
12
|
+
auth_url="https://auth.example.com/oauth2/token",
|
|
13
|
+
client_id="your-client-id",
|
|
14
|
+
client_secret="your-client-secret",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# List enrollments for a user
|
|
18
|
+
enrollments = await client.enrollments.list(user_id="user-123")
|
|
19
|
+
|
|
20
|
+
# Get analytics
|
|
21
|
+
activity = await client.analytics.get_activity(
|
|
22
|
+
student_id="student-123",
|
|
23
|
+
start_date="2025-01-01",
|
|
24
|
+
end_date="2025-01-31",
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from .client import EdubridgeClient
|
|
30
|
+
from .exceptions import (
|
|
31
|
+
APIError,
|
|
32
|
+
AuthenticationError,
|
|
33
|
+
EdubridgeError,
|
|
34
|
+
ForbiddenError,
|
|
35
|
+
NotFoundError,
|
|
36
|
+
ValidationError,
|
|
37
|
+
)
|
|
38
|
+
from .types import (
|
|
39
|
+
# Analytics
|
|
40
|
+
ActivityMetricsData,
|
|
41
|
+
AggregatedMetrics,
|
|
42
|
+
# Applications
|
|
43
|
+
Application,
|
|
44
|
+
ApplicationMetrics,
|
|
45
|
+
DailyActivityMap,
|
|
46
|
+
# Base
|
|
47
|
+
DataResponse,
|
|
48
|
+
# Enrollments
|
|
49
|
+
DefaultClass,
|
|
50
|
+
Enrollment,
|
|
51
|
+
EnrollmentCourse,
|
|
52
|
+
EnrollmentFacts,
|
|
53
|
+
EnrollmentGoals,
|
|
54
|
+
EnrollmentMetadata,
|
|
55
|
+
EnrollmentMetrics,
|
|
56
|
+
EnrollmentPeriod,
|
|
57
|
+
EnrollmentPrimaryApp,
|
|
58
|
+
EnrollmentRole,
|
|
59
|
+
EnrollmentSchool,
|
|
60
|
+
EnrollOptions,
|
|
61
|
+
GradeMasteryData,
|
|
62
|
+
GUIDRef,
|
|
63
|
+
HighestGradeMastered,
|
|
64
|
+
# Learning Reports
|
|
65
|
+
MapProfile,
|
|
66
|
+
# Users
|
|
67
|
+
PrimaryOrg,
|
|
68
|
+
ResetGoalsResult,
|
|
69
|
+
Role,
|
|
70
|
+
Status,
|
|
71
|
+
SubjectMetrics,
|
|
72
|
+
# Subject Track
|
|
73
|
+
SubjectTrack,
|
|
74
|
+
SubjectTrackGroup,
|
|
75
|
+
SubjectTrackInput,
|
|
76
|
+
SubjectTrackUpsertInput,
|
|
77
|
+
TimeSaved,
|
|
78
|
+
TimeSpentMetricsData,
|
|
79
|
+
User,
|
|
80
|
+
UserApp,
|
|
81
|
+
UserCredential,
|
|
82
|
+
UserId,
|
|
83
|
+
UserProfile,
|
|
84
|
+
UserRole,
|
|
85
|
+
WeeklyFactRecord,
|
|
86
|
+
WeeklyFacts,
|
|
87
|
+
)
|
|
88
|
+
from .utils import (
|
|
89
|
+
aggregate_activity_metrics,
|
|
90
|
+
normalize_boolean,
|
|
91
|
+
normalize_date,
|
|
92
|
+
normalize_user,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
__all__ = [
|
|
96
|
+
# Exceptions
|
|
97
|
+
"APIError",
|
|
98
|
+
# Analytics
|
|
99
|
+
"ActivityMetricsData",
|
|
100
|
+
"AggregatedMetrics",
|
|
101
|
+
# Applications
|
|
102
|
+
"Application",
|
|
103
|
+
"ApplicationMetrics",
|
|
104
|
+
"AuthenticationError",
|
|
105
|
+
"DailyActivityMap",
|
|
106
|
+
# Base
|
|
107
|
+
"DataResponse",
|
|
108
|
+
# Enrollments
|
|
109
|
+
"DefaultClass",
|
|
110
|
+
# Client
|
|
111
|
+
"EdubridgeClient",
|
|
112
|
+
"EdubridgeError",
|
|
113
|
+
"EnrollOptions",
|
|
114
|
+
"Enrollment",
|
|
115
|
+
"EnrollmentCourse",
|
|
116
|
+
"EnrollmentFacts",
|
|
117
|
+
"EnrollmentGoals",
|
|
118
|
+
"EnrollmentMetadata",
|
|
119
|
+
"EnrollmentMetrics",
|
|
120
|
+
"EnrollmentPeriod",
|
|
121
|
+
"EnrollmentPrimaryApp",
|
|
122
|
+
"EnrollmentRole",
|
|
123
|
+
"EnrollmentSchool",
|
|
124
|
+
"ForbiddenError",
|
|
125
|
+
"GUIDRef",
|
|
126
|
+
"GradeMasteryData",
|
|
127
|
+
"HighestGradeMastered",
|
|
128
|
+
# Learning Reports
|
|
129
|
+
"MapProfile",
|
|
130
|
+
"NotFoundError",
|
|
131
|
+
# Users
|
|
132
|
+
"PrimaryOrg",
|
|
133
|
+
"ResetGoalsResult",
|
|
134
|
+
"Role",
|
|
135
|
+
"Status",
|
|
136
|
+
"SubjectMetrics",
|
|
137
|
+
# Subject Track
|
|
138
|
+
"SubjectTrack",
|
|
139
|
+
"SubjectTrackGroup",
|
|
140
|
+
"SubjectTrackInput",
|
|
141
|
+
"SubjectTrackUpsertInput",
|
|
142
|
+
"TimeSaved",
|
|
143
|
+
"TimeSpentMetricsData",
|
|
144
|
+
"User",
|
|
145
|
+
"UserApp",
|
|
146
|
+
"UserCredential",
|
|
147
|
+
"UserId",
|
|
148
|
+
"UserProfile",
|
|
149
|
+
"UserRole",
|
|
150
|
+
"ValidationError",
|
|
151
|
+
"WeeklyFactRecord",
|
|
152
|
+
"WeeklyFacts",
|
|
153
|
+
# Utilities
|
|
154
|
+
"aggregate_activity_metrics",
|
|
155
|
+
"normalize_boolean",
|
|
156
|
+
"normalize_date",
|
|
157
|
+
"normalize_user",
|
|
158
|
+
]
|