librus-python-api 1.6.3__tar.gz → 1.6.4__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.6.3 → librus_python_api-1.6.4}/API.md +2 -2
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/CHANGELOG.md +22 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/PKG-INFO +7 -6
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/README.md +6 -5
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/SECURITY.md +11 -1
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/__init__.py +1 -1
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/modern_body.py +33 -6
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/uv.lock +30 -30
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/.gitignore +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/LICENSE +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/pyproject.toml +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_notification_bootstrap.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_notification_codec.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_storage.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_windows_filesystem.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/announcements.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attachment_routes.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attachments.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attendance.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attendance_frequency.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/budget.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/checkpoint.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/class_free_days.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/completed_lessons.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/config.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/detail_fields.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/diagnostics.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/exceptions.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/files.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/formative_grades.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/grade_parsers.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/grade_records.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/homework_range.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/lifecycle.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/markup.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/message_content.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/messages.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/models.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/modern_mailbox.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/modern_messages.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/notification_models.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/notification_persistence.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/notification_workflow.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/notifications.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/parsers.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/parsing.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/persistence.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/py.typed +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/recipients.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/scheduler.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/school_reads.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/school_year_archive.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/sending.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/service.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/timetable.py +0 -0
- {librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/transport.py +0 -0
|
@@ -657,7 +657,7 @@ creates state, reads old MCP files or starts background recovery.
|
|
|
657
657
|
files and unsafe POSIX permissions or Windows ACLs fail closed, never reset state.
|
|
658
658
|
No automatic retry, reconciliation, deletion of consumed history or polling.
|
|
659
659
|
- Defaults: 8 admitted storage workers and 8 send workflows, 256 total records,
|
|
660
|
-
32 unused previews, 300-second expiry and
|
|
660
|
+
32 unused previews, 300-second expiry and 1-second SQLite busy timeout.
|
|
661
661
|
Configured maxima: 64 each, 4,096 records, 256 previews, 300 seconds and 5 seconds.
|
|
662
662
|
Storage workers are serialized per store; full queues/contention fail immediately
|
|
663
663
|
or after the bounded busy interval. The final outcome save after a claim waits
|
|
@@ -760,7 +760,7 @@ async with NotificationStore(Path("/absolute/private/notification-state")) as st
|
|
|
760
760
|
state without HTTP. Pending batches do not mark IDs seen. Defaults are bounded:
|
|
761
761
|
16 contexts, 8 workers/workflows, 32 raw/reservation records, 16 MiB checkpoint
|
|
762
762
|
bytes, 4 MiB total seen-state bytes, 4,096 IDs/category, 500 items/1 MiB per batch,
|
|
763
|
-
500 events/128 KiB value JSON per replay slice,
|
|
763
|
+
500 events/128 KiB value JSON per replay slice, 1 s busy timeout, and 5 s
|
|
764
764
|
`final_busy_timeout_seconds` for checkpoint, staging and acknowledgement saves
|
|
765
765
|
that follow upstream work, since all contexts share one write lock. The full
|
|
766
766
|
envelope is capped at 4 MiB encoded body plus 4 MiB metadata; database main file
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.4 (2026-10-26) - Message body rendering security fix
|
|
4
|
+
|
|
5
|
+
Fixes a denial of service in message body rendering. Public types, signatures
|
|
6
|
+
and parser behaviour are unchanged.
|
|
7
|
+
|
|
8
|
+
- Security (GHSA-c9qq-qqr2-hf23, CWE-1333): `modern_message_content` decided
|
|
9
|
+
whether a body is an XML `Message` wrapper with a regular expression that
|
|
10
|
+
backtracked exponentially over a run of XML comments or processing
|
|
11
|
+
instructions with no wrapper after it. A body of a few hundred bytes, which any
|
|
12
|
+
Librus user can send, blocked the calling thread for minutes; that includes
|
|
13
|
+
every client that renders received messages, such as librus-mcp. A single
|
|
14
|
+
linear scan now makes the same decision: it accepts exactly the inputs the
|
|
15
|
+
expression accepted, so routing between the XML and HTML readers is
|
|
16
|
+
unchanged. All releases up to 1.6.3 are affected.
|
|
17
|
+
- Development lock: virtualenv 21.14.13 fixes CVE-2026-115586, pre-commit 4.7.0
|
|
18
|
+
and ruff 0.17.1. None is a runtime dependency.
|
|
19
|
+
- CI and release workflows use setup-uv 10.3.2 and pypi-publish 1.14.3. The
|
|
20
|
+
publish action up to 1.14.2 trusted the revoked emSign root CA in the
|
|
21
|
+
Sigstore chain used for Trusted Publishing (GHSA-5xjx-3w67-w9x9).
|
|
22
|
+
- SECURITY.md adds GitHub private vulnerability reporting beside email and lists
|
|
23
|
+
the repository protections; Dependabot runs on a fixed weekly schedule.
|
|
24
|
+
|
|
3
25
|
## 1.6.3 (2026-10-22) - Dependency security update
|
|
4
26
|
|
|
5
27
|
Raises dependency floors and tooling pins past published advisories. Public
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: librus-python-api
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
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,10 @@ 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.6.
|
|
46
|
-
keeps the 1.6.2 completed-lesson and grade layouts,
|
|
47
|
-
which are validated and not reported as grades.
|
|
45
|
+
**Status:** `1.6.4` renders message bodies in linear time, so a crafted body can
|
|
46
|
+
no longer stall a client, and keeps the 1.6.2 completed-lesson and grade layouts,
|
|
47
|
+
including behaviour points, which are validated and not reported as grades.
|
|
48
|
+
Class free days, typed capability outcomes and the live-check freshness watchdog
|
|
48
49
|
remain available. See [verification](VERIFICATION.md).
|
|
49
50
|
The stable 1.x API does not guarantee every school layout. School features depend
|
|
50
51
|
on what each account can access. See the [compatibility policy](API.md#compatibility-policy).
|
|
@@ -55,7 +56,7 @@ See [limitations](#supported-features-and-limitations) below.
|
|
|
55
56
|
Install the exact release from PyPI after its gated publication completes:
|
|
56
57
|
|
|
57
58
|
```sh
|
|
58
|
-
python -m pip install librus-python-api==1.6.
|
|
59
|
+
python -m pip install librus-python-api==1.6.4
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
Pin the exact version qualified by your application. Before publication, use a
|
|
@@ -71,7 +72,7 @@ python -m pip install .
|
|
|
71
72
|
To install a locally built wheel instead:
|
|
72
73
|
|
|
73
74
|
```sh
|
|
74
|
-
python -m pip install ./dist/librus_python_api-1.6.
|
|
75
|
+
python -m pip install ./dist/librus_python_api-1.6.4-py3-none-any.whl
|
|
75
76
|
```
|
|
76
77
|
|
|
77
78
|
No CLI or background process is installed: import the library in your own program.
|
|
@@ -16,9 +16,10 @@ 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.6.
|
|
20
|
-
keeps the 1.6.2 completed-lesson and grade layouts,
|
|
21
|
-
which are validated and not reported as grades.
|
|
19
|
+
**Status:** `1.6.4` renders message bodies in linear time, so a crafted body can
|
|
20
|
+
no longer stall a client, and keeps the 1.6.2 completed-lesson and grade layouts,
|
|
21
|
+
including behaviour points, which are validated and not reported as grades.
|
|
22
|
+
Class free days, typed capability outcomes and the live-check freshness watchdog
|
|
22
23
|
remain available. See [verification](VERIFICATION.md).
|
|
23
24
|
The stable 1.x API does not guarantee every school layout. School features depend
|
|
24
25
|
on what each account can access. See the [compatibility policy](API.md#compatibility-policy).
|
|
@@ -29,7 +30,7 @@ See [limitations](#supported-features-and-limitations) below.
|
|
|
29
30
|
Install the exact release from PyPI after its gated publication completes:
|
|
30
31
|
|
|
31
32
|
```sh
|
|
32
|
-
python -m pip install librus-python-api==1.6.
|
|
33
|
+
python -m pip install librus-python-api==1.6.4
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
Pin the exact version qualified by your application. Before publication, use a
|
|
@@ -45,7 +46,7 @@ python -m pip install .
|
|
|
45
46
|
To install a locally built wheel instead:
|
|
46
47
|
|
|
47
48
|
```sh
|
|
48
|
-
python -m pip install ./dist/librus_python_api-1.6.
|
|
49
|
+
python -m pip install ./dist/librus_python_api-1.6.4-py3-none-any.whl
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
No CLI or background process is installed: import the library in your own program.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Security
|
|
2
2
|
|
|
3
3
|
Please do not report vulnerabilities or expose school data in public issues.
|
|
4
|
-
|
|
4
|
+
Report vulnerabilities privately through the repository's **Security** tab
|
|
5
|
+
(**Report a vulnerability**) or by email to
|
|
6
|
+
[contact@datacraze.io](mailto:contact@datacraze.io).
|
|
5
7
|
|
|
6
8
|
Include the affected version or commit, steps to reproduce, expected and
|
|
7
9
|
observed behavior, and impact. Redact credentials, context keys, cookies, tokens, and any
|
|
@@ -11,3 +13,11 @@ The [client API security review](contracts/api-security-review.md) maps the
|
|
|
11
13
|
outbound-client threat boundary and existing controls to Snyk's OWASP API guidance.
|
|
12
14
|
It also records consumer authorization/serialization responsibilities and local
|
|
13
15
|
filesystem/persistence limits; it is not a third-party security certification.
|
|
16
|
+
|
|
17
|
+
## Repository protections
|
|
18
|
+
|
|
19
|
+
The default branch requires a pull request and the CI checks, and refuses force
|
|
20
|
+
pushes and deletion. Secret scanning with push protection, Dependabot alerts and
|
|
21
|
+
security updates, CodeQL default setup and private vulnerability reporting are
|
|
22
|
+
enabled. Workflows default to a read-only token and need approval before running
|
|
23
|
+
for outside contributors.
|
|
@@ -138,7 +138,7 @@ from librus_python_api.models import (
|
|
|
138
138
|
from librus_python_api.sending import SendAttempt
|
|
139
139
|
from librus_python_api.service import AccountClient, LibrusService
|
|
140
140
|
|
|
141
|
-
__version__ = "1.6.
|
|
141
|
+
__version__ = "1.6.4"
|
|
142
142
|
|
|
143
143
|
__all__ = [
|
|
144
144
|
"ArchiveAbsences",
|
|
@@ -11,11 +11,8 @@ from librus_python_api.exceptions import ErrorKind, LibrusError
|
|
|
11
11
|
from librus_python_api.markup import text
|
|
12
12
|
from librus_python_api.parsers import parse_html_document
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
r"(?:<\?xml\b|<Message(?=[\s/>]))",
|
|
17
|
-
re.DOTALL,
|
|
18
|
-
)
|
|
14
|
+
_XML_START = re.compile(r"<\?xml\b|<Message(?=[\s/>])")
|
|
15
|
+
_XML_DECLARATION = re.compile(r"<\?xml\b")
|
|
19
16
|
|
|
20
17
|
|
|
21
18
|
def render_body(encoded: str) -> str:
|
|
@@ -34,7 +31,7 @@ def render_body(encoded: str) -> str:
|
|
|
34
31
|
decoded = decoded.removeprefix("\ufeff")
|
|
35
32
|
# XML comments/PIs and a UTF-8 BOM must not route a Message wrapper through
|
|
36
33
|
# the permissive HTML renderer, losing CDATA or bypassing Content checks.
|
|
37
|
-
if
|
|
34
|
+
if _xml_prefixed(decoded):
|
|
38
35
|
decoded = _xml_content(decoded)
|
|
39
36
|
if not decoded:
|
|
40
37
|
return ""
|
|
@@ -47,6 +44,36 @@ def render_body(encoded: str) -> str:
|
|
|
47
44
|
)
|
|
48
45
|
|
|
49
46
|
|
|
47
|
+
def _xml_prefixed(decoded: str) -> bool:
|
|
48
|
+
"""Whether whitespace, comments and non-declaration PIs precede an XML start.
|
|
49
|
+
|
|
50
|
+
A comment or PI may end at any later terminator, as the lazy pattern this
|
|
51
|
+
replaces allowed, but one left-to-right pass decides it: once an item has
|
|
52
|
+
opened, every later terminator closes it. A regex backtracks exponentially
|
|
53
|
+
over a run of items with no XML start after it.
|
|
54
|
+
"""
|
|
55
|
+
starts = bytearray(len(decoded) + 1)
|
|
56
|
+
starts[0] = 1
|
|
57
|
+
comment_from = pi_from = len(decoded) + 1
|
|
58
|
+
for index, char in enumerate(decoded):
|
|
59
|
+
if starts[index]:
|
|
60
|
+
if char.isspace():
|
|
61
|
+
starts[index + 1] = 1
|
|
62
|
+
elif _XML_START.match(decoded, index):
|
|
63
|
+
return True
|
|
64
|
+
elif decoded.startswith("<!--", index):
|
|
65
|
+
comment_from = min(comment_from, index + 4)
|
|
66
|
+
elif decoded.startswith("<?", index) and not _XML_DECLARATION.match(
|
|
67
|
+
decoded, index
|
|
68
|
+
):
|
|
69
|
+
pi_from = min(pi_from, index + 2)
|
|
70
|
+
if index >= comment_from and decoded.startswith("-->", index):
|
|
71
|
+
starts[index + 3] = 1
|
|
72
|
+
if index >= pi_from and decoded.startswith("?>", index):
|
|
73
|
+
starts[index + 2] = 1
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
|
|
50
77
|
def _xml_content(decoded: str) -> str:
|
|
51
78
|
parser = etree.XMLParser(
|
|
52
79
|
no_network=True,
|
|
@@ -553,11 +553,11 @@ wheels = [
|
|
|
553
553
|
|
|
554
554
|
[[package]]
|
|
555
555
|
name = "filelock"
|
|
556
|
-
version = "4.
|
|
556
|
+
version = "4.2.4"
|
|
557
557
|
source = { registry = "https://pypi.org/simple" }
|
|
558
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
558
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/28/3893324bcadf8f89b1616637468d766af3f625008c0735bf704fdfa86617/filelock-4.2.4.tar.gz", hash = "sha256:c6d8663535e1650ee430507b4ffbac7b464dd64b7647ea0112a9f406499d163d", size = 652444, upload-time = "2026-10-19T01:57:51.001Z" }
|
|
559
559
|
wheels = [
|
|
560
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
560
|
+
{ url = "https://files.pythonhosted.org/packages/e0/1b/5e74289a1878e666bb4b65fe5805a04cafcac2aa5f519ef1ead67ef91c56/filelock-4.2.4-py3-none-any.whl", hash = "sha256:301241438c57936ef93f4243a94f2559022268bfcf9b375a9a72eb0f8db8358e", size = 162475, upload-time = "2026-10-19T01:57:49.419Z" },
|
|
561
561
|
]
|
|
562
562
|
|
|
563
563
|
[[package]]
|
|
@@ -1518,7 +1518,7 @@ wheels = [
|
|
|
1518
1518
|
|
|
1519
1519
|
[[package]]
|
|
1520
1520
|
name = "pre-commit"
|
|
1521
|
-
version = "4.
|
|
1521
|
+
version = "4.7.0"
|
|
1522
1522
|
source = { registry = "https://pypi.org/simple" }
|
|
1523
1523
|
dependencies = [
|
|
1524
1524
|
{ name = "cfgv" },
|
|
@@ -1527,9 +1527,9 @@ dependencies = [
|
|
|
1527
1527
|
{ name = "pyyaml" },
|
|
1528
1528
|
{ name = "virtualenv" },
|
|
1529
1529
|
]
|
|
1530
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1530
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3a/c3/6965c2690ddce885ec75121572d065a5b94c5a5d8d3e657927ecda9fd715/pre_commit-4.7.0.tar.gz", hash = "sha256:1f3deee12b914c8fa184bd2b5953391c2e4f36763e403d4a23dc9983fa7c6e86", size = 198120, upload-time = "2026-10-12T20:45:40.32Z" }
|
|
1531
1531
|
wheels = [
|
|
1532
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1532
|
+
{ url = "https://files.pythonhosted.org/packages/eb/83/ce0a196e4f7b20b11ce3aa1fc72fb973f64b7628d51c1b8aebad37fb7f81/pre_commit-4.7.0-py2.py3-none-any.whl", hash = "sha256:2e229038ad3656081b70c27913157e4b636ef306f643f024a8a8e3f0f7b2f877", size = 226261, upload-time = "2026-10-12T20:45:38.858Z" },
|
|
1533
1533
|
]
|
|
1534
1534
|
|
|
1535
1535
|
[[package]]
|
|
@@ -2050,27 +2050,27 @@ wheels = [
|
|
|
2050
2050
|
|
|
2051
2051
|
[[package]]
|
|
2052
2052
|
name = "ruff"
|
|
2053
|
-
version = "0.17.
|
|
2054
|
-
source = { registry = "https://pypi.org/simple" }
|
|
2055
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
2056
|
-
wheels = [
|
|
2057
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2058
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2059
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2060
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2061
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2062
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2063
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2064
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2065
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2066
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2067
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2068
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2069
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2070
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2071
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2072
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2073
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2053
|
+
version = "0.17.1"
|
|
2054
|
+
source = { registry = "https://pypi.org/simple" }
|
|
2055
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e7/e6d5749983b020e6cb1055abec0a6f361a8e94f0184cdcf56d4760995f02/ruff-0.17.1.tar.gz", hash = "sha256:5bb796c5112e9fb9527f2ef2faa0a130d6312d19de92bcfaddd70dbb2d41020f", size = 5323349, upload-time = "2026-10-15T15:23:18.64Z" }
|
|
2056
|
+
wheels = [
|
|
2057
|
+
{ url = "https://files.pythonhosted.org/packages/2e/78/90c46ca6250709f7c37e397b60d06061adee8d0f7d13959ed6a8e49b14fd/ruff-0.17.1-py3-none-linux_armv6l.whl", hash = "sha256:1796c41eafec66f4635125dd1e074a7aa27b8d20c187d484360acf11d247fc4a", size = 10147528, upload-time = "2026-10-15T15:22:33.667Z" },
|
|
2058
|
+
{ url = "https://files.pythonhosted.org/packages/aa/d2/a2e28bc35b083ae51fa07dfba5280a667c8b01ecaee7802fc8849dcd5c46/ruff-0.17.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8eadb09a788010be29c895418bdfa513e4e1c65e64b94e5b19e4cd381f6cc7fb", size = 10225974, upload-time = "2026-10-15T15:22:36.328Z" },
|
|
2059
|
+
{ url = "https://files.pythonhosted.org/packages/8e/71/7a9029a81c8206ee01a98f6cfeeb56e6c095af86857581a37045c46d7e94/ruff-0.17.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:29b454f18ca3eeaf37fbf140841dcf27d36109e29dee9aae8acecb68c26c6f74", size = 9270361, upload-time = "2026-10-15T15:22:38.651Z" },
|
|
2060
|
+
{ url = "https://files.pythonhosted.org/packages/c0/8c/e075e9c917cb0575297880c96768304e881240171c870cbd8d9b7b54bec2/ruff-0.17.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872e03dd231744d6c5ec5c8af6be52b71323fc6ee096e4c8b34d9f844ee3b978", size = 9938300, upload-time = "2026-10-15T15:22:41.284Z" },
|
|
2061
|
+
{ url = "https://files.pythonhosted.org/packages/87/27/0b4bb926a49de2383f161272b4d863571a4c7ecdbf595a6bc58813a13367/ruff-0.17.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c0d6cb5f8fbac77eec9af49f4fc0eaf856b05545e372b0694d24b4e76b1c640", size = 9948464, upload-time = "2026-10-15T15:22:43.681Z" },
|
|
2062
|
+
{ url = "https://files.pythonhosted.org/packages/14/27/518d57e0e02aecb8ea4acac6b57b51a53173d25fa734952bfdd7d531e88e/ruff-0.17.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78beced4a3c94dfedbee4b999b95b6a27b35820fdc0afbacc6d37a8da26c1cd1", size = 10638639, upload-time = "2026-10-15T15:22:46.081Z" },
|
|
2063
|
+
{ url = "https://files.pythonhosted.org/packages/01/82/d89a4e498ade59e6cee52d67f8da569019372212b87468c1fdeae884601c/ruff-0.17.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7feefc63921202894f0e158b0e32f45a5950d70a7fb693ccb9264816c25b1c05", size = 11337238, upload-time = "2026-10-15T15:22:48.894Z" },
|
|
2064
|
+
{ url = "https://files.pythonhosted.org/packages/a2/7c/3b0fdef9352656317c977086fe1d802902406e4f2a0d8578da90c0e6d1c5/ruff-0.17.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684154861a819bf1f433669d2a0ce9c3e54677c65b8ebb866cc2a7ec86345785", size = 10896327, upload-time = "2026-10-15T15:22:51.45Z" },
|
|
2065
|
+
{ url = "https://files.pythonhosted.org/packages/62/86/5566290219708ce2928f3a29c4f843a1185b341ec6111c4631a33c5ceced/ruff-0.17.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ef98e51de8ef38082f90653ceeb84944bd7673783eea13e1647c5b9b064189", size = 10350811, upload-time = "2026-10-15T15:22:54.401Z" },
|
|
2066
|
+
{ url = "https://files.pythonhosted.org/packages/ad/d2/ca8462dabb3c413990d49703ba306c30c862195a75448d080fa8fcce9775/ruff-0.17.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8f9aa5b5bd5fa1937803ea609c8f153b8de39bf3e0e149897ae34b0c5b52f467", size = 10569994, upload-time = "2026-10-15T15:22:57.142Z" },
|
|
2067
|
+
{ url = "https://files.pythonhosted.org/packages/e3/ad/dd1864c1f1db17c8cfb297ce70b352388e6977620f66f7182c52855407df/ruff-0.17.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:80e53b0e5faa3c5667f035daaa032893ae42b7cfe708c886d39ed131e54688ab", size = 10059672, upload-time = "2026-10-15T15:23:00.084Z" },
|
|
2068
|
+
{ url = "https://files.pythonhosted.org/packages/65/45/3f56cf1d2168c2165cdd5ac6f9668aee66a4cfdd4caf2b2cc5ccb2b1d568/ruff-0.17.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:056c5d5fa0ac790051ae165d7035c7bf956d02de2db557f2e9b31d877a505fca", size = 9947803, upload-time = "2026-10-15T15:23:03.132Z" },
|
|
2069
|
+
{ url = "https://files.pythonhosted.org/packages/aa/4b/5457cb2be4c1d1ea5e919558131a0f197a4a454a0530d9e30820e8206e4c/ruff-0.17.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd8f5a55b10f371642eacd0e8665a42a8b97da15c9a7187c79e697b77b5e0ce4", size = 10351807, upload-time = "2026-10-15T15:23:05.628Z" },
|
|
2070
|
+
{ url = "https://files.pythonhosted.org/packages/49/fb/db15b4f8fa24a1e36b99e1401f42ef6df16ee299a48670d5d262b771e7d7/ruff-0.17.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ce05e6f3973611d9550a600e04bb531061e368baba31610eb57c1509a8f21a0a", size = 10765716, upload-time = "2026-10-15T15:23:08.092Z" },
|
|
2071
|
+
{ url = "https://files.pythonhosted.org/packages/0a/e8/1e186578076aff7a80735f625005fde678412ab609cd323ed182eb7d6b87/ruff-0.17.1-py3-none-win32.whl", hash = "sha256:1de0030a8aa78c65c5fecb84b2e5c390ac684c0452875a02afc7c083d49a496a", size = 9895093, upload-time = "2026-10-15T15:23:10.582Z" },
|
|
2072
|
+
{ url = "https://files.pythonhosted.org/packages/6a/2e/da3d9589bae8e8b58f3a48bd5bc0b980232fb14a83bf02c3be7660f87c1b/ruff-0.17.1-py3-none-win_amd64.whl", hash = "sha256:5df76f16580fab58d0f6c98a3ac254a4abceb7b2489b8b678335869cff77b3d7", size = 10097955, upload-time = "2026-10-15T15:23:13.309Z" },
|
|
2073
|
+
{ url = "https://files.pythonhosted.org/packages/df/c9/0f2a4dea06a5e12c1191ee3d96b1e1233797d0d5e18f97a2b909a95a9836/ruff-0.17.1-py3-none-win_arm64.whl", hash = "sha256:42400b9a6ff8515ff27796f07f92e0195be011c86e81e381606f58ea5502fef4", size = 9853542, upload-time = "2026-10-15T15:23:16.05Z" },
|
|
2074
2074
|
]
|
|
2075
2075
|
|
|
2076
2076
|
[[package]]
|
|
@@ -2291,7 +2291,7 @@ wheels = [
|
|
|
2291
2291
|
|
|
2292
2292
|
[[package]]
|
|
2293
2293
|
name = "virtualenv"
|
|
2294
|
-
version = "21.14.
|
|
2294
|
+
version = "21.14.13"
|
|
2295
2295
|
source = { registry = "https://pypi.org/simple" }
|
|
2296
2296
|
dependencies = [
|
|
2297
2297
|
{ name = "distlib" },
|
|
@@ -2300,9 +2300,9 @@ dependencies = [
|
|
|
2300
2300
|
{ name = "platformdirs" },
|
|
2301
2301
|
{ name = "python-discovery" },
|
|
2302
2302
|
]
|
|
2303
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
2303
|
+
sdist = { url = "https://files.pythonhosted.org/packages/70/aa/bff50daee0488e16d611258a9b6c5a1d0c9e128f8ca424e9f4e1c0444ef2/virtualenv-21.14.13.tar.gz", hash = "sha256:de5307ba4b9a0001d9c8ea02832d38f63ca432880f416c1bface61c4323fd905", size = 5570301, upload-time = "2026-10-22T20:10:16.952Z" }
|
|
2304
2304
|
wheels = [
|
|
2305
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2305
|
+
{ url = "https://files.pythonhosted.org/packages/bb/a9/c10d8a44a29fb94a18b43fdf11f38caca53ae7c9406f11a72b1cb8f624f1/virtualenv-21.14.13-py3-none-any.whl", hash = "sha256:5fbb04138a4861580b78ba9110d529a26bc48fcc93c8ec36bc0202eeed96a788", size = 5557094, upload-time = "2026-10-22T20:10:15.096Z" },
|
|
2306
2306
|
]
|
|
2307
2307
|
|
|
2308
2308
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_notification_bootstrap.py
RENAMED
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_notification_codec.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/_windows_filesystem.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attachment_routes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/attendance_frequency.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/class_free_days.py
RENAMED
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/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.6.3 → librus_python_api-1.6.4}/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
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/message_content.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/modern_messages.py
RENAMED
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/src/librus_python_api/notification_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{librus_python_api-1.6.3 → librus_python_api-1.6.4}/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.6.3 → librus_python_api-1.6.4}/src/librus_python_api/school_year_archive.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|