librus-python-api 1.4.0__tar.gz → 1.5.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.
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/API.md +6 -3
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/CHANGELOG.md +14 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/PKG-INFO +6 -6
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/README.md +5 -5
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/__init__.py +1 -1
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/message_content.py +18 -11
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/models.py +2 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/.gitignore +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/LICENSE +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/SECURITY.md +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/pyproject.toml +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_notification_bootstrap.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_notification_codec.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_storage.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_windows_filesystem.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/announcements.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attachment_routes.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attachments.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attendance.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attendance_frequency.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/budget.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/checkpoint.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/completed_lessons.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/config.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/detail_fields.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/diagnostics.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/exceptions.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/files.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/formative_grades.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/grade_parsers.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/grade_records.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/homework_range.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/lifecycle.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/markup.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/messages.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/modern_body.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/modern_mailbox.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/modern_messages.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notification_models.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notification_persistence.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notification_workflow.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notifications.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/parsers.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/parsing.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/persistence.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/py.typed +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/recipients.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/scheduler.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/school_reads.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/school_year_archive.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/sending.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/service.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/timetable.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/transport.py +0 -0
- {librus_python_api-1.4.0 → librus_python_api-1.5.0}/uv.lock +0 -0
|
@@ -883,12 +883,15 @@ Foreign accounts, arbitrary URLs and injected IDs fail before authentication.
|
|
|
883
883
|
`Przeczytano` value; it is not inbox unread or per-recipient status.
|
|
884
884
|
- Sent content may omit an `Adresat` field: `correspondent=None` then preserves
|
|
885
885
|
absence rather than inventing a name from another table. `recipient_receipts`
|
|
886
|
-
holds ordered `MessageRecipientReceipt(recipient, raw_status, read_timestamp
|
|
887
|
-
records when a separate individual receipt table is displayed.
|
|
886
|
+
holds ordered `MessageRecipientReceipt(recipient, raw_status, read_timestamp,
|
|
887
|
+
recipient_class)` records when a separate individual receipt table is displayed.
|
|
888
|
+
`recipient_class` (1.5.0) keeps the displayed class label when the table has the
|
|
889
|
+
middle class column, and is `None` without it or when that cell is empty.
|
|
890
|
+
Rows of one table must share one layout. Equal labels
|
|
888
891
|
survive; no recipient IDs or aggregate read time are invented. `NIE` has no
|
|
889
892
|
read timestamp; displayed dates retain school civil time. Unknown statuses fail.
|
|
890
893
|
At most 256 receipt rows, 4,096 characters per field and 128 KiB total receipt
|
|
891
|
-
text are accepted. An absent table means no reported receipts, not zero recipients.
|
|
894
|
+
text (class labels included) are accepted. An absent table means no reported receipts, not zero recipients.
|
|
892
895
|
- `text` is full plain text with supported block/`br` boundaries and normalized
|
|
893
896
|
whitespace, at most 65,536 characters. No HTML, scripts or external resources
|
|
894
897
|
are returned or fetched. Active body content is unsupported, not executed.
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.0 (2026-10-08) - Sent receipts with a recipient class column
|
|
4
|
+
|
|
5
|
+
Compatible minor release. Existing fields, results and the two-column receipt
|
|
6
|
+
layout are unchanged.
|
|
7
|
+
|
|
8
|
+
- Read sent-message individual receipt tables that add a middle class-label
|
|
9
|
+
column (recipient, class, status). Such a sent open previously failed with
|
|
10
|
+
`UNSUPPORTED_CAPABILITY` (#60).
|
|
11
|
+
- Add `MessageRecipientReceipt.recipient_class` (default `None`, hidden from
|
|
12
|
+
repr): the displayed class label, or `None` without that column or when its
|
|
13
|
+
cell is empty. Consumers serializing receipts field by field see one new key.
|
|
14
|
+
- Rows of one receipt table must share one layout; mixed or other widths still
|
|
15
|
+
fail. Class labels count toward the existing receipt text bounds.
|
|
16
|
+
|
|
3
17
|
## 1.4.0 (2026-10-08) - Formative assessments and the observation card
|
|
4
18
|
|
|
5
19
|
Compatible minor release. Existing fields, results and stored notification
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: librus-python-api
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: Independent bounded async Librus Synergia client
|
|
5
5
|
Project-URL: Repository, https://github.com/krzysztofbury/librus-python-api
|
|
6
6
|
Project-URL: Issues, https://github.com/krzysztofbury/librus-python-api/issues
|
|
@@ -42,9 +42,9 @@ private ACLs. Windows installations include `pywin32` and `tzdata` automatically
|
|
|
42
42
|
Network paths, reparse-point paths and unsafe storage permissions fail closed.
|
|
43
43
|
See [platform requirements](contracts/persistence.md#windows-disk-boundary-25).
|
|
44
44
|
|
|
45
|
-
**Status:** `1.
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
**Status:** `1.5.0` reads sent-message receipt tables that show a recipient
|
|
46
|
+
class column. `1.4.0` added formative assessments, including the observation
|
|
47
|
+
card, to grade results; see [verification](VERIFICATION.md).
|
|
48
48
|
The stable 1.x API does not guarantee every school layout. School features depend
|
|
49
49
|
on what each account can access. See the [compatibility policy](API.md#compatibility-policy).
|
|
50
50
|
See [limitations](#supported-features-and-limitations) below.
|
|
@@ -54,7 +54,7 @@ See [limitations](#supported-features-and-limitations) below.
|
|
|
54
54
|
Install the exact release from PyPI after its gated publication completes:
|
|
55
55
|
|
|
56
56
|
```sh
|
|
57
|
-
python -m pip install librus-python-api==1.
|
|
57
|
+
python -m pip install librus-python-api==1.5.0
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Pin the exact version qualified by your application. Before publication, use a
|
|
@@ -70,7 +70,7 @@ python -m pip install .
|
|
|
70
70
|
To install a locally built wheel instead:
|
|
71
71
|
|
|
72
72
|
```sh
|
|
73
|
-
python -m pip install ./dist/librus_python_api-1.
|
|
73
|
+
python -m pip install ./dist/librus_python_api-1.5.0-py3-none-any.whl
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
No CLI or background process is installed: import the library in your own program.
|
|
@@ -16,9 +16,9 @@ private ACLs. Windows installations include `pywin32` and `tzdata` automatically
|
|
|
16
16
|
Network paths, reparse-point paths and unsafe storage permissions fail closed.
|
|
17
17
|
See [platform requirements](contracts/persistence.md#windows-disk-boundary-25).
|
|
18
18
|
|
|
19
|
-
**Status:** `1.
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
**Status:** `1.5.0` reads sent-message receipt tables that show a recipient
|
|
20
|
+
class column. `1.4.0` added formative assessments, including the observation
|
|
21
|
+
card, to grade results; see [verification](VERIFICATION.md).
|
|
22
22
|
The stable 1.x API does not guarantee every school layout. School features depend
|
|
23
23
|
on what each account can access. See the [compatibility policy](API.md#compatibility-policy).
|
|
24
24
|
See [limitations](#supported-features-and-limitations) below.
|
|
@@ -28,7 +28,7 @@ See [limitations](#supported-features-and-limitations) below.
|
|
|
28
28
|
Install the exact release from PyPI after its gated publication completes:
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
|
-
python -m pip install librus-python-api==1.
|
|
31
|
+
python -m pip install librus-python-api==1.5.0
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Pin the exact version qualified by your application. Before publication, use a
|
|
@@ -44,7 +44,7 @@ python -m pip install .
|
|
|
44
44
|
To install a locally built wheel instead:
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
python -m pip install ./dist/librus_python_api-1.
|
|
47
|
+
python -m pip install ./dist/librus_python_api-1.5.0-py3-none-any.whl
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
No CLI or background process is installed: import the library in your own program.
|
|
@@ -136,7 +136,7 @@ from librus_python_api.models import (
|
|
|
136
136
|
from librus_python_api.sending import SendAttempt
|
|
137
137
|
from librus_python_api.service import AccountClient, LibrusService
|
|
138
138
|
|
|
139
|
-
__version__ = "1.
|
|
139
|
+
__version__ = "1.5.0"
|
|
140
140
|
|
|
141
141
|
__all__ = [
|
|
142
142
|
"ArchiveAbsences",
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/message_content.py
RENAMED
|
@@ -57,26 +57,33 @@ def _recipient_receipts(
|
|
|
57
57
|
raise LibrusError(ErrorKind.UNSUPPORTED_CAPABILITY)
|
|
58
58
|
result = []
|
|
59
59
|
total = 0
|
|
60
|
+
# Rows are recipient/status, or recipient/class/status when the page adds
|
|
61
|
+
# the class-label column; one table never mixes the two.
|
|
62
|
+
width = len(cells(table_rows[1]))
|
|
60
63
|
for row in table_rows[1:]:
|
|
61
64
|
columns = cells(row)
|
|
62
|
-
if
|
|
63
|
-
|
|
64
|
-
or
|
|
65
|
-
or
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (
|
|
66
|
+
len(columns) != width
|
|
67
|
+
or width not in (2, 3)
|
|
68
|
+
or any(
|
|
69
|
+
c.tag != "td"
|
|
70
|
+
or c.get("colspan", "1") != "1"
|
|
71
|
+
or c.get("rowspan", "1") != "1"
|
|
72
|
+
or next(c.iterdescendants("table"), None) is not None
|
|
73
|
+
for c in columns
|
|
74
|
+
)
|
|
68
75
|
):
|
|
69
76
|
raise LibrusError(ErrorKind.UNSUPPORTED_CAPABILITY)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
]
|
|
77
|
+
values = [text(c, MESSAGE_MAX_FIELD_LENGTH, multiline=True) for c in columns]
|
|
78
|
+
recipient, status = values[0], values[-1]
|
|
73
79
|
if not recipient or not status:
|
|
74
80
|
raise LibrusError(ErrorKind.PARSE)
|
|
75
|
-
total += len
|
|
81
|
+
total += sum(map(len, values))
|
|
76
82
|
if total > MESSAGE_MAX_RECEIPT_TEXT_LENGTH:
|
|
77
83
|
raise LibrusError(ErrorKind.LIMIT)
|
|
78
84
|
stamp = None if status == "NIE" else _timestamp(status)
|
|
79
|
-
|
|
85
|
+
label = values[1] if width == 3 and values[1] else None
|
|
86
|
+
result.append(MessageRecipientReceipt(recipient, status, stamp, label))
|
|
80
87
|
return tuple(result)
|
|
81
88
|
|
|
82
89
|
|
|
@@ -210,6 +210,8 @@ class MessageRecipientReceipt:
|
|
|
210
210
|
recipient: str = field(repr=False)
|
|
211
211
|
raw_status: str = field(repr=False)
|
|
212
212
|
read_timestamp: MessageTimestamp | None = field(repr=False)
|
|
213
|
+
# Displayed class label of the optional middle column; None without it.
|
|
214
|
+
recipient_class: str | None = field(default=None, repr=False)
|
|
213
215
|
|
|
214
216
|
|
|
215
217
|
@dataclass(frozen=True, slots=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_notification_bootstrap.py
RENAMED
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_notification_codec.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/_windows_filesystem.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attachment_routes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/attendance_frequency.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/completed_lessons.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/formative_grades.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/modern_messages.py
RENAMED
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notification_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/notification_workflow.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.4.0 → librus_python_api-1.5.0}/src/librus_python_api/school_year_archive.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|