gramflux 0.1.0a1__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.
Files changed (96) hide show
  1. gramflux-0.1.0a1/CHANGELOG.md +15 -0
  2. gramflux-0.1.0a1/CODE_OF_CONDUCT.md +11 -0
  3. gramflux-0.1.0a1/CONTRIBUTING.md +51 -0
  4. gramflux-0.1.0a1/LICENSE +21 -0
  5. gramflux-0.1.0a1/MANIFEST.in +6 -0
  6. gramflux-0.1.0a1/PKG-INFO +136 -0
  7. gramflux-0.1.0a1/README.md +111 -0
  8. gramflux-0.1.0a1/SECURITY.md +16 -0
  9. gramflux-0.1.0a1/THIRD_PARTY_NOTICES.md +16 -0
  10. gramflux-0.1.0a1/docs/api.md +42 -0
  11. gramflux-0.1.0a1/docs/design/architecture.md +57 -0
  12. gramflux-0.1.0a1/docs/design/compatibility.md +39 -0
  13. gramflux-0.1.0a1/docs/design/competitive-analysis.md +37 -0
  14. gramflux-0.1.0a1/docs/design/performance-plan.md +27 -0
  15. gramflux-0.1.0a1/docs/design/security-model.md +31 -0
  16. gramflux-0.1.0a1/docs/guides/authentication.md +35 -0
  17. gramflux-0.1.0a1/docs/guides/events.md +41 -0
  18. gramflux-0.1.0a1/docs/guides/files.md +39 -0
  19. gramflux-0.1.0a1/docs/guides/migration.md +32 -0
  20. gramflux-0.1.0a1/docs/guides/operations.md +61 -0
  21. gramflux-0.1.0a1/docs/guides/sessions.md +36 -0
  22. gramflux-0.1.0a1/docs/index.md +24 -0
  23. gramflux-0.1.0a1/docs/release-report.md +143 -0
  24. gramflux-0.1.0a1/docs/roadmap.md +35 -0
  25. gramflux-0.1.0a1/examples/files.py +28 -0
  26. gramflux-0.1.0a1/examples/graceful.py +29 -0
  27. gramflux-0.1.0a1/examples/login.py +41 -0
  28. gramflux-0.1.0a1/examples/messages.py +26 -0
  29. gramflux-0.1.0a1/examples/raw.py +21 -0
  30. gramflux-0.1.0a1/pyproject.toml +46 -0
  31. gramflux-0.1.0a1/requirements-dev.lock +47 -0
  32. gramflux-0.1.0a1/requirements-runtime.lock +5 -0
  33. gramflux-0.1.0a1/research/Telethon-repository.json +15 -0
  34. gramflux-0.1.0a1/research/benchmark.json +63 -0
  35. gramflux-0.1.0a1/research/dependency-audit.json +1 -0
  36. gramflux-0.1.0a1/research/dependency-audit.txt +3 -0
  37. gramflux-0.1.0a1/research/hydrogram-repository.json +15 -0
  38. gramflux-0.1.0a1/research/installed-wheel-tests.txt +3 -0
  39. gramflux-0.1.0a1/research/native-probe.json +19 -0
  40. gramflux-0.1.0a1/research/native-probe.txt +1 -0
  41. gramflux-0.1.0a1/research/pyrogram-repository.json +15 -0
  42. gramflux-0.1.0a1/research/schema-coverage.json +10 -0
  43. gramflux-0.1.0a1/research/schema-diff.json +5 -0
  44. gramflux-0.1.0a1/research/sdist-schema-coverage.json +10 -0
  45. gramflux-0.1.0a1/research/secret-scan.json +10 -0
  46. gramflux-0.1.0a1/research/source-tests.txt +3 -0
  47. gramflux-0.1.0a1/research/td-repository.json +15 -0
  48. gramflux-0.1.0a1/research/test-inventory.json +85 -0
  49. gramflux-0.1.0a1/research/wheel-schema-coverage.json +10 -0
  50. gramflux-0.1.0a1/setup.cfg +4 -0
  51. gramflux-0.1.0a1/src/gramflux/__init__.py +9 -0
  52. gramflux-0.1.0a1/src/gramflux/backend.py +171 -0
  53. gramflux-0.1.0a1/src/gramflux/client.py +370 -0
  54. gramflux-0.1.0a1/src/gramflux/config.py +37 -0
  55. gramflux-0.1.0a1/src/gramflux/errors.py +72 -0
  56. gramflux-0.1.0a1/src/gramflux/events.py +108 -0
  57. gramflux-0.1.0a1/src/gramflux/files.py +161 -0
  58. gramflux-0.1.0a1/src/gramflux/filters.py +44 -0
  59. gramflux-0.1.0a1/src/gramflux/mtproto/__init__.py +0 -0
  60. gramflux-0.1.0a1/src/gramflux/mtproto/framing.py +74 -0
  61. gramflux-0.1.0a1/src/gramflux/mtproto/probe.py +76 -0
  62. gramflux-0.1.0a1/src/gramflux/py.typed +0 -0
  63. gramflux-0.1.0a1/src/gramflux/raw.py +6 -0
  64. gramflux-0.1.0a1/src/gramflux/storage.py +163 -0
  65. gramflux-0.1.0a1/src/gramflux/tl/__init__.py +6 -0
  66. gramflux-0.1.0a1/src/gramflux/tl/codec.py +239 -0
  67. gramflux-0.1.0a1/src/gramflux/tl/data/api.json +1 -0
  68. gramflux-0.1.0a1/src/gramflux/tl/data/api.tl +2976 -0
  69. gramflux-0.1.0a1/src/gramflux/tl/data/metadata.json +15 -0
  70. gramflux-0.1.0a1/src/gramflux/tl/data/mtproto.tl +83 -0
  71. gramflux-0.1.0a1/src/gramflux/tl/generated/__init__.py +1 -0
  72. gramflux-0.1.0a1/src/gramflux/tl/generated/objects.py +18601 -0
  73. gramflux-0.1.0a1/src/gramflux/tl/generator.py +58 -0
  74. gramflux-0.1.0a1/src/gramflux/tl/model.py +43 -0
  75. gramflux-0.1.0a1/src/gramflux/tl/parser.py +125 -0
  76. gramflux-0.1.0a1/src/gramflux/tools/__init__.py +0 -0
  77. gramflux-0.1.0a1/src/gramflux/tools/benchmark.py +95 -0
  78. gramflux-0.1.0a1/src/gramflux/tools/probe.py +38 -0
  79. gramflux-0.1.0a1/src/gramflux/tools/schema.py +165 -0
  80. gramflux-0.1.0a1/src/gramflux.egg-info/PKG-INFO +136 -0
  81. gramflux-0.1.0a1/src/gramflux.egg-info/SOURCES.txt +94 -0
  82. gramflux-0.1.0a1/src/gramflux.egg-info/dependency_links.txt +1 -0
  83. gramflux-0.1.0a1/src/gramflux.egg-info/requires.txt +10 -0
  84. gramflux-0.1.0a1/src/gramflux.egg-info/top_level.txt +1 -0
  85. gramflux-0.1.0a1/tests/integration/test_client.py +256 -0
  86. gramflux-0.1.0a1/tests/integration/test_live.py +22 -0
  87. gramflux-0.1.0a1/tests/protocol/test_differential.py +30 -0
  88. gramflux-0.1.0a1/tests/protocol/test_framing.py +66 -0
  89. gramflux-0.1.0a1/tests/protocol/test_generated_roundtrips.py +65 -0
  90. gramflux-0.1.0a1/tests/protocol/test_probe.py +45 -0
  91. gramflux-0.1.0a1/tests/unit/test_codec.py +117 -0
  92. gramflux-0.1.0a1/tests/unit/test_config_errors.py +42 -0
  93. gramflux-0.1.0a1/tests/unit/test_events.py +74 -0
  94. gramflux-0.1.0a1/tests/unit/test_files.py +121 -0
  95. gramflux-0.1.0a1/tests/unit/test_schema.py +49 -0
  96. gramflux-0.1.0a1/tests/unit/test_storage.py +90 -0
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0a1 — unreleased
4
+
5
+ - Project and distribution renamed to GramFlux (`gramflux`); import with `import gramflux`.
6
+
7
+ - Initial engineering alpha with explicit Telethon 1.45.0 runtime integration.
8
+ - Official schema provenance, deterministic typed generation, JSON cross-check and diff CLI.
9
+ - Independent bounded TL codec and reference TCP framing, with native initial handshake probe.
10
+ - Bounded public request admission, cancellation/deadline behavior and safe error mapping.
11
+ - GramFlux SQLite/memory session snapshots, ordered events, composable filters and streaming files.
12
+ - Deterministic tests, opt-in identity test, local codec benchmark, documentation and CI.
13
+
14
+ Not a production release candidate. Real-account authorization, message exchange,
15
+ update recovery and media interoperability have not been verified.
@@ -0,0 +1,11 @@
1
+ # Code of conduct
2
+
3
+ Treat contributors and users respectfully. Critique code and evidence, not people.
4
+ Harassment, discrimination, threats, doxxing and publishing others' private information
5
+ are unacceptable. Respect account privacy and Telegram's terms.
6
+
7
+ Maintainers may remove inappropriate content, restrict participation, or remove a
8
+ contributor after considering severity and context. Report conduct concerns privately
9
+ to the hosting project's maintainers once a private contact is configured. Do not
10
+ publish identifying details about affected people. No dedicated conduct contact is
11
+ configured for this unpublished engineering alpha.
@@ -0,0 +1,51 @@
1
+ # Contributing
2
+
3
+ Start with the [architecture](docs/design/architecture.md), [roadmap](docs/roadmap.md)
4
+ and [security model](docs/design/security-model.md). Changes should be small and
5
+ include evidence appropriate to the behavior. Do not claim live Telegram verification
6
+ from a controlled backend test.
7
+
8
+ ```bash
9
+ python3 -m venv .venv
10
+ source .venv/bin/activate
11
+ python -m pip install -e '.[dev]'
12
+ ruff check .
13
+ ruff format --check .
14
+ mypy src
15
+ pytest
16
+ python -m gramflux.tools.schema verify
17
+ python -m build
18
+ ```
19
+
20
+ `requirements-dev.lock` records the complete CPython 3.12/Linux development environment,
21
+ without hashes. Use `pip install -r requirements-dev.lock` to reproduce that environment;
22
+ it is not a platform-independent resolver lock. Runtime versions are also pinned in
23
+ `requirements-runtime.lock`. Never commit session files, account data, or credentials.
24
+
25
+ Schema updates are explicit:
26
+
27
+ ```bash
28
+ python -m gramflux.tools.schema update /tmp/gramflux-new-schema
29
+ python -m gramflux.tools.schema diff src/gramflux/tl/data/api.tl /tmp/gramflux-new-schema/api.tl
30
+ ```
31
+
32
+ Review both snapshots' layer advertisement, all hashes, TL/JSON consistency, removals,
33
+ changed signatures, and unsupported grammar. Copy reviewed files into `tl/data`, run
34
+ `generate`, then `verify`, lint, typing and tests. Generated code is never hand-edited.
35
+ Protocol preludes and bare message records have special binary semantics; parser
36
+ acceptance is not equivalent to standalone runtime support. A backend upgrade requires
37
+ its own schema/protocol/session interoperability review and differential regression run.
38
+
39
+ For release: update version and changelog, run CI and clean wheel/sdist installs,
40
+ review third-party notices and security scan, execute opt-in account tests using a
41
+ dedicated authorized test account, and update `docs/release-report.md` with actual
42
+ results. Reproduce benchmark inputs before discussing performance. Publishing a GitHub
43
+ Release triggers `.github/workflows/publish.yml`, which validates the matching version
44
+ tag, runs quality checks, builds distributions, and publishes them to PyPI. Configure
45
+ a PyPI Trusted Publisher for this repository, workflow `publish.yml`, and GitHub
46
+ environment `pypi` first. The tag must be the package version, optionally prefixed
47
+ with `v` (for example, `v0.1.0a1`). No long-lived PyPI API token is required.
48
+
49
+ Alpha interfaces may change. After 1.0 use semantic versioning, document deprecations
50
+ and keep deprecated public APIs for at least one minor release unless security requires
51
+ faster removal. Report private security issues using SECURITY.md.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GramFlux contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include LICENSE THIRD_PARTY_NOTICES.md CONTRIBUTING.md SECURITY.md CHANGELOG.md CODE_OF_CONDUCT.md
2
+ include requirements*.lock
3
+ recursive-include docs *.md
4
+ recursive-include examples *.py
5
+ recursive-include tests *.py
6
+ recursive-include research *.json *.txt
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: gramflux
3
+ Version: 0.1.0a1
4
+ Summary: Async Telegram client with independently verifiable TL schema tooling
5
+ Author: GramFlux contributors
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Framework :: AsyncIO
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Typing :: Typed
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ License-File: THIRD_PARTY_NOTICES.md
15
+ Requires-Dist: Telethon==1.45.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest==9.1.1; extra == "dev"
18
+ Requires-Dist: pytest-asyncio==1.4.0; extra == "dev"
19
+ Requires-Dist: hypothesis==6.170.5; extra == "dev"
20
+ Requires-Dist: ruff==0.17.1; extra == "dev"
21
+ Requires-Dist: mypy==2.4.0; extra == "dev"
22
+ Requires-Dist: build==1.6.1; extra == "dev"
23
+ Requires-Dist: pip-audit==2.10.1; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # GramFlux
27
+
28
+ An asyncio Telegram client and independently verifiable TL schema toolkit for Python 3.11+.
29
+
30
+ **0.1.0a1 is an engineering alpha, not a production release candidate.** The live
31
+ MTProto runtime is provided by **Telethon 1.45.0**; GramFlux owns its public lifecycle,
32
+ request admission, error mapping, session format, ordered event dispatch, streaming
33
+ file pipeline, and independent schema generator/codec. It is not yet the independent,
34
+ higher-performance replacement described in the long-term roadmap.
35
+
36
+ The design principle is: Simple by default. Powerful when needed. Correct by design.
37
+ Fast when measured. Maintainable by architecture.
38
+
39
+ ## Install
40
+
41
+ From a checkout:
42
+
43
+ ```bash
44
+ python3 -m venv .venv
45
+ source .venv/bin/activate
46
+ python -m pip install -e '.[dev]'
47
+ ```
48
+
49
+ Normal installation ships generated source and exact schemas; no schema download is
50
+ required. Distribution name `gramflux` returned HTTP 404 from PyPI on 2026-10-20.
51
+ That is a point-in-time lookup, not a reservation or trademark clearance.
52
+
53
+ ## Quick start
54
+
55
+ Obtain your own [API credentials](https://core.telegram.org/api/obtaining_api_id)
56
+ and follow [Telegram's API terms](https://core.telegram.org/api/terms).
57
+ Run `python examples/login.py` to authorize a new session, then:
58
+
59
+ ```python
60
+ import asyncio
61
+ import os
62
+ from gramflux import Client, filters
63
+
64
+
65
+ async def main() -> None:
66
+ client = Client(
67
+ session="example",
68
+ api_id=int(os.environ["TELEGRAM_API_ID"]),
69
+ api_hash=os.environ["TELEGRAM_API_HASH"],
70
+ )
71
+
72
+ @client.on_message(filters.incoming & filters.text)
73
+ async def on_message(event):
74
+ print(f"Message received in chat {event.chat_id}")
75
+
76
+ async with client:
77
+ me = await client.get_me()
78
+ print(f"Authenticated as {me.id}")
79
+ await client.send_message("me", "Hello from GramFlux")
80
+ await client.run_until_disconnected()
81
+
82
+
83
+ asyncio.run(main())
84
+ ```
85
+
86
+ The context manager connects; it never prompts, logs in implicitly, or keeps the
87
+ program alive after the context exits. Register handlers before connecting. Text is
88
+ sent literally, without implicit Markdown parsing. Ctrl-C triggers context cleanup.
89
+ Session files contain authentication keys; keep them private.
90
+
91
+ ## Feature status
92
+
93
+ | Capability | Status and evidence |
94
+ | --- | --- |
95
+ | Official schema snapshot | 1,573 constructors + 783 methods; IDs and fields matched against official JSON |
96
+ | Independent typed declarations | Deterministic generated dataclasses, all 1,572 non-vector constructor minimal round trips tested |
97
+ | Independent TL codec | Primitive/property, flags, limits, malformed data and selected differential tests |
98
+ | Raw API at runtime | Backend bindings via `gramflux.raw`, backend layer 229; no all-method live coverage claim |
99
+ | Native TCP framing | Full/intermediate/abridged reference implementations, differential tests |
100
+ | Native initial handshake | One real `req_pq_multi` exchange with DC 2 verified; no authorization key created by native code |
101
+ | User codes, bot login, SRP password | Implemented using backend; controlled tests only, no account login verified |
102
+ | SQLite and memory sessions | Own format; persistence, permissions, locking, corrupt/foreign data tests |
103
+ | Concurrent RPC, deadlines, cancellation | Controlled backend tests; no real-account throughput measurements |
104
+ | New/edited messages, filters | Ordered bounded dispatcher tested; gap recovery delegated to backend, not independently verified |
105
+ | File upload/download | Streaming pipeline and boundary/interruption tests; no live transfer verified |
106
+ | Independent encrypted runtime | Unsupported; cryptography and update reconciliation delegated to backend |
107
+ | Proxy, CDN, resume, foreign sessions | Unsupported by the public API |
108
+ | Production readiness / superiority | Not claimed; see [release assessment](docs/release-report.md) |
109
+
110
+ Generated bindings and wire runtime use separate schema sources. Independent
111
+ `gramflux.tl.generated.objects` values are offline-only and are rejected by `invoke`.
112
+ Use backend-generated functions for live raw access:
113
+
114
+ ```python
115
+ from gramflux.raw import functions, types
116
+
117
+ users = await client.invoke(functions.users.GetUsersRequest([types.InputUserSelf()]))
118
+ ```
119
+
120
+ ## Development checks
121
+
122
+ ```bash
123
+ ruff check .
124
+ ruff format --check .
125
+ mypy src
126
+ pytest
127
+ python -m gramflux.tools.schema verify
128
+ python -m build
129
+ python -m gramflux.tools.benchmark
130
+ ```
131
+
132
+ [Guides and API reference](docs/index.md) · [Architecture](docs/design/architecture.md)
133
+ · [Compatibility](docs/design/compatibility.md) · [Contributing](CONTRIBUTING.md)
134
+ · [Security](SECURITY.md) · [Measured benchmark](research/benchmark.json).
135
+ The initial independent codec is slower than the backend on the recorded input;
136
+ there is no performance superiority claim.
@@ -0,0 +1,111 @@
1
+ # GramFlux
2
+
3
+ An asyncio Telegram client and independently verifiable TL schema toolkit for Python 3.11+.
4
+
5
+ **0.1.0a1 is an engineering alpha, not a production release candidate.** The live
6
+ MTProto runtime is provided by **Telethon 1.45.0**; GramFlux owns its public lifecycle,
7
+ request admission, error mapping, session format, ordered event dispatch, streaming
8
+ file pipeline, and independent schema generator/codec. It is not yet the independent,
9
+ higher-performance replacement described in the long-term roadmap.
10
+
11
+ The design principle is: Simple by default. Powerful when needed. Correct by design.
12
+ Fast when measured. Maintainable by architecture.
13
+
14
+ ## Install
15
+
16
+ From a checkout:
17
+
18
+ ```bash
19
+ python3 -m venv .venv
20
+ source .venv/bin/activate
21
+ python -m pip install -e '.[dev]'
22
+ ```
23
+
24
+ Normal installation ships generated source and exact schemas; no schema download is
25
+ required. Distribution name `gramflux` returned HTTP 404 from PyPI on 2026-10-20.
26
+ That is a point-in-time lookup, not a reservation or trademark clearance.
27
+
28
+ ## Quick start
29
+
30
+ Obtain your own [API credentials](https://core.telegram.org/api/obtaining_api_id)
31
+ and follow [Telegram's API terms](https://core.telegram.org/api/terms).
32
+ Run `python examples/login.py` to authorize a new session, then:
33
+
34
+ ```python
35
+ import asyncio
36
+ import os
37
+ from gramflux import Client, filters
38
+
39
+
40
+ async def main() -> None:
41
+ client = Client(
42
+ session="example",
43
+ api_id=int(os.environ["TELEGRAM_API_ID"]),
44
+ api_hash=os.environ["TELEGRAM_API_HASH"],
45
+ )
46
+
47
+ @client.on_message(filters.incoming & filters.text)
48
+ async def on_message(event):
49
+ print(f"Message received in chat {event.chat_id}")
50
+
51
+ async with client:
52
+ me = await client.get_me()
53
+ print(f"Authenticated as {me.id}")
54
+ await client.send_message("me", "Hello from GramFlux")
55
+ await client.run_until_disconnected()
56
+
57
+
58
+ asyncio.run(main())
59
+ ```
60
+
61
+ The context manager connects; it never prompts, logs in implicitly, or keeps the
62
+ program alive after the context exits. Register handlers before connecting. Text is
63
+ sent literally, without implicit Markdown parsing. Ctrl-C triggers context cleanup.
64
+ Session files contain authentication keys; keep them private.
65
+
66
+ ## Feature status
67
+
68
+ | Capability | Status and evidence |
69
+ | --- | --- |
70
+ | Official schema snapshot | 1,573 constructors + 783 methods; IDs and fields matched against official JSON |
71
+ | Independent typed declarations | Deterministic generated dataclasses, all 1,572 non-vector constructor minimal round trips tested |
72
+ | Independent TL codec | Primitive/property, flags, limits, malformed data and selected differential tests |
73
+ | Raw API at runtime | Backend bindings via `gramflux.raw`, backend layer 229; no all-method live coverage claim |
74
+ | Native TCP framing | Full/intermediate/abridged reference implementations, differential tests |
75
+ | Native initial handshake | One real `req_pq_multi` exchange with DC 2 verified; no authorization key created by native code |
76
+ | User codes, bot login, SRP password | Implemented using backend; controlled tests only, no account login verified |
77
+ | SQLite and memory sessions | Own format; persistence, permissions, locking, corrupt/foreign data tests |
78
+ | Concurrent RPC, deadlines, cancellation | Controlled backend tests; no real-account throughput measurements |
79
+ | New/edited messages, filters | Ordered bounded dispatcher tested; gap recovery delegated to backend, not independently verified |
80
+ | File upload/download | Streaming pipeline and boundary/interruption tests; no live transfer verified |
81
+ | Independent encrypted runtime | Unsupported; cryptography and update reconciliation delegated to backend |
82
+ | Proxy, CDN, resume, foreign sessions | Unsupported by the public API |
83
+ | Production readiness / superiority | Not claimed; see [release assessment](docs/release-report.md) |
84
+
85
+ Generated bindings and wire runtime use separate schema sources. Independent
86
+ `gramflux.tl.generated.objects` values are offline-only and are rejected by `invoke`.
87
+ Use backend-generated functions for live raw access:
88
+
89
+ ```python
90
+ from gramflux.raw import functions, types
91
+
92
+ users = await client.invoke(functions.users.GetUsersRequest([types.InputUserSelf()]))
93
+ ```
94
+
95
+ ## Development checks
96
+
97
+ ```bash
98
+ ruff check .
99
+ ruff format --check .
100
+ mypy src
101
+ pytest
102
+ python -m gramflux.tools.schema verify
103
+ python -m build
104
+ python -m gramflux.tools.benchmark
105
+ ```
106
+
107
+ [Guides and API reference](docs/index.md) · [Architecture](docs/design/architecture.md)
108
+ · [Compatibility](docs/design/compatibility.md) · [Contributing](CONTRIBUTING.md)
109
+ · [Security](SECURITY.md) · [Measured benchmark](research/benchmark.json).
110
+ The initial independent codec is slower than the backend on the recorded input;
111
+ there is no performance superiority claim.
@@ -0,0 +1,16 @@
1
+ # Security policy
2
+
3
+ This is an unaudited engineering alpha. Do not use it for sensitive production accounts.
4
+ The release blockers and threat model are documented in `docs/design/security-model.md`.
5
+
6
+ Do not put authorization keys, session databases, phone numbers, API hashes, bot tokens,
7
+ passwords, codes, or private messages into public issues. For a security report, use the
8
+ hosting project's private vulnerability reporting facility once the repository is hosted.
9
+ No private reporting address or hosted repository has yet been configured. Until one
10
+ exists, a sensitive deployment should not rely on this project's response process.
11
+ A public report can describe the affected component without exploit secrets or account data.
12
+
13
+ Currently only the latest alpha is supported on a best-effort basis; there is no
14
+ security support SLA. Before release, the maintainer must configure a private reporting
15
+ channel, triage owner and advisory process. Dependency scanning does not constitute a
16
+ cryptographic audit or guarantee absence of vulnerabilities.
@@ -0,0 +1,16 @@
1
+ # Third-party notices
2
+
3
+ GramFlux's original implementation is MIT licensed. No competitor implementation
4
+ source is vendored. Telethon is a pinned runtime dependency, distributed separately
5
+ under MIT; its distribution retains its copyright/license notices. Its dependencies
6
+ are pyaes (MIT), rsa (Apache-2.0) and pyasn1 (BSD-2-Clause); retain their notices when
7
+ redistributing their distributions. This project does not relicense dependencies.
8
+
9
+ Official Telegram schema definitions are preserved with provenance in
10
+ `src/gramflux/tl/data/metadata.json`; upstream material and Telegram service use remain
11
+ subject to their respective upstream terms. GramFlux's MIT notice is not a claim to
12
+ exclusive rights over Telegram API definitions. Confirm redistribution obligations
13
+ and project branding before a public stable release.
14
+
15
+ Pyrogram/Hydrogram are LGPL-3.0 projects inspected for research only. Their source is
16
+ not copied into this distribution. gotd/td is MIT licensed and is not a dependency.
@@ -0,0 +1,42 @@
1
+ # Public API reference
2
+
3
+ Import `Client`, `Config`, `LoginChallenge`, `MessageEvent`, `filters` from `gramflux`.
4
+ Signatures and annotations are maintained in source; `python -m pydoc gramflux.client`
5
+ shows the complete reference without a documentation build dependency.
6
+
7
+ | API | Return / semantics |
8
+ | --- | --- |
9
+ | Client(session=None, *, api_id, api_hash, config=None, on_handler_error=None) | Client; path or async Storage; `None` uses memory |
10
+ | async connect() / disconnect() | None; explicit lifecycle, disconnect joins cleanup even on cancellation |
11
+ | connected | bool; local/backend connection status, not authorization |
12
+ | async is_authorized() | bool; server authorization check |
13
+ | async request_login_code(phone) | LoginChallenge; explicit code request |
14
+ | async sign_in(challenge, code) | backend User; may raise PasswordRequired |
15
+ | async check_password(password) | backend User; SRP computation off-loop |
16
+ | async sign_in_bot(token) | backend User; refuses replacement of authorized session |
17
+ | async get_me() | backend User; missing auth raises AuthenticationError |
18
+ | async send_message(peer, text) | backend Message; literal text |
19
+ | async invoke(request) | raw backend result; use gramflux.raw.functions/types and LAYER |
20
+ | on_message(predicate=filters.all_messages, *, edited=False) | async callback decorator, registration order |
21
+ | async run_until_disconnected() | None; wait without disconnecting on waiter cancellation |
22
+ | async upload_file(source, *, name=None, on_progress=None) | backend InputFile or InputFileBig |
23
+ | async send_file(peer, file, *, caption="") | backend Message |
24
+ | async download_file(location, destination, *, size, on_progress=None) | Path for path target, None for caller stream |
25
+ | async download_media(message, destination, *, on_progress=None) | Path; supported document/photo |
26
+
27
+ `Config` is a frozen slots dataclass; defaults: request_timeout=30.0 seconds,
28
+ max_concurrent_requests=32, event_queue_size=256, reconnect_attempts=3,
29
+ transport="intermediate". All client calls must use one event loop.
30
+
31
+ Independent offline API: `gramflux.tl.Codec(registry=None, max_bytes=16777216,
32
+ max_vector=100000, max_depth=64)`; `encode(value, type="Object") -> bytes`,
33
+ `decode(data, type="Object") -> object`. Generated classes are in
34
+ `gramflux.tl.generated.objects`, named with capitalized namespace prefixes and Request
35
+ suffix for methods. Primitive/list fields are annotated; optional fields default to
36
+ None, optional `true` fields to False. Flags are calculated, not constructor arguments.
37
+ Fields sharing a bit must be present together. Repr omits field values.
38
+
39
+ `gramflux.tl.parser.parse(text)` returns validated Definition descriptors. Specialized
40
+ bare MTProto records are recognized but not generated as normal boxed objects.
41
+ `Framing` and `probe_datacenter` are independent experimental protocol utilities.
42
+ The native probe does not establish an authenticated channel or create an auth key.
@@ -0,0 +1,57 @@
1
+ # Architecture and implementation boundary
2
+
3
+ GramFlux is currently a dependency-backed alpha. It is not an independent MTProto engine
4
+ and is not a superficial renamed fork: no competitor implementation is vendored, and
5
+ the schema pipeline, codec, session persistence, dispatch, request admission, file I/O
6
+ and public lifecycle are original modules with separate tests. Independence and measurable
7
+ advantages remain roadmap goals, not shipped claims.
8
+
9
+ | Component | Responsibility |
10
+ | --- | --- |
11
+ | `client.py`, `config.py` | Explicit connect/auth/shutdown; typed convenience methods, deadlines, concurrency admission |
12
+ | `backend.py`, `raw.py` | Pinned Telethon integration; sanitized RPC errors/logs, snapshot adapter, wire bindings |
13
+ | `storage.py` | Async storage protocol, memory store, off-loop transactional SQLite, ownership lock |
14
+ | `events.py`, `filters.py` | Bounded ordered callback queue, async handlers, composable synchronous filters |
15
+ | `files.py` | Seekable uploads, official small/big parts, streaming downloads, progress, atomic no-overwrite paths |
16
+ | `tl/parser.py`, `model.py`, `generator.py` | Source diagnostics, validation, deterministic typed definitions |
17
+ | `tl/codec.py`, `generated/` | Independent bounded TL binary codec and constructor registry |
18
+ | `mtproto/framing.py`, `probe.py` | Independently checked transport reference and native unencrypted handshake probe |
19
+ | `tools/schema.py`, `benchmark.py` | Explicit refresh, offline verify, diff, reproducible local measurements |
20
+
21
+ The live backend owns RSA/DH authorization-key creation, MTProto 2.0 encryption,
22
+ message IDs/seqnos/session salts, containers, acknowledgments, response correlation,
23
+ protocol resends, reconnects, migration and update pts/qts/seq recovery. GramFlux does
24
+ not claim to independently audit these merely by depending on them. SRP computation
25
+ uses backend primitives in a worker thread. Other backend CPU-heavy operations may
26
+ still block the event loop; benchmark/audit work is outstanding.
27
+
28
+ The client creates one child task per admitted operation. Timeout includes semaphore
29
+ admission, cancellation propagates to that operation, and disconnect cancels admitted
30
+ operations before closing the backend and persisting state. Waiting callers recheck
31
+ lifecycle state after admission. No broad application RPC retry is configured. At most
32
+ two additional attempts are allowed for explicit preauthorization code/bot/password
33
+ operations rejected with a migration response after the pinned backend switches DC.
34
+ Network ambiguity does not authorize creating another send-message request.
35
+
36
+ Dispatcher callbacks run one at a time in registration order. A failure is reported
37
+ without exception contents and later handlers still receive that event. Full queues
38
+ block producers. This does **not** bound Telethon's internal update queue; a slow
39
+ consumer can still accumulate upstream updates. End-to-end bounded update buffering,
40
+ durable event delivery and application-level deduplication are release blockers.
41
+
42
+ SQLite saves auth/DC and backend update-state snapshots. Entity/access-hash caches
43
+ are in-memory only. State is synchronized to disk on auth changes and clean disconnect;
44
+ there is no crash-consistent update cursor/durable callback transaction. SQLite methods
45
+ run off-loop; cancelled workers are joined before releasing their lifetime lock.
46
+
47
+ Independent generated declarations use the source page advertised as layer 225.
48
+ The backend's runtime uses layer 229. `Client.invoke` only accepts backend TLRequest
49
+ instances. Joining those two schema universes without negotiated-layer validation
50
+ would be unsafe. The native probe checks nonce and envelope structure but does not
51
+ authenticate Telegram; no keys or credentials are involved.
52
+
53
+ Dependencies were selected for a functional and reviewable vertical slice rather than
54
+ a new cryptographic implementation. There is no plugin framework, compiled extension,
55
+ or Pydantic dependency. Storage and the backend are injectable test boundaries; the
56
+ private `_backend` constructor argument is not a promised extension API. Native framing
57
+ and codec are currently independent test/tool subsystems, not the live wire stack.
@@ -0,0 +1,39 @@
1
+ # Compatibility and coverage
2
+
3
+ Actual local verification: CPython 3.12.3, Linux x86_64 (glibc 2.39). Python >=3.11
4
+ is the declared minimum. CI is configured for Ubuntu Python 3.11–3.14; configuration
5
+ is not evidence that these jobs have run. Persistent storage currently requires POSIX
6
+ flock; Windows persistent sessions and full cross-platform transfers are unsupported.
7
+ Memory-store use on Windows/macOS has not been verified here.
8
+
9
+ Pinned official source: `tl/data/api.tl`, official JSON, `mtproto.tl` and `metadata.json`.
10
+ Retrieved 2026-10-20. Advertised page layer: **225**. API TL SHA256:
11
+ `13d9c9f4a4ecc7282725b5a558f719cea5af0c3bafcf62531cac3a18bfaca046`.
12
+ Generated independent declarations: **1,573 constructors, 783 methods**, all IDs and
13
+ fields cross-checked against retained official JSON. The polymorphic vector constructor
14
+ has specialized codec semantics; 1,572 other constructor minimal shapes round-trip.
15
+ That is not exhaustive flag combinations, all possible objects or live method coverage.
16
+ Protocol parser verifies 46 explicit-ID declarations; primitive/vector preludes and
17
+ bare message records are special cases. Independent protocol object generation and
18
+ bare-type serialization are not advertised as supported runtime features.
19
+
20
+ Runtime: Telethon **1.45.0**, generated layer **229**, imported via `gramflux.raw`.
21
+ Different source provenance/layer from independent output is intentional and visible.
22
+ Neither runtime binding count nor generator count proves Telegram accepts every method.
23
+ Independent declarations cannot be passed to Client.invoke. No live account test has
24
+ run; the credential-free native initial handshake probe is the only Telegram wire
25
+ exchange verified in this environment.
26
+
27
+ | Area | Coverage boundary |
28
+ | --- | --- |
29
+ | High-level client | get_me, literal send_message, explicit code/password/bot auth, raw invoke, upload/send_file, document/photo download |
30
+ | Events | New/edited messages; text/direction/chat/sender/regex filters; serialized callbacks |
31
+ | State recovery | Backend pts/qts/seq handling; own snapshot persists clean-shutdown state, no durable event journal |
32
+ | Transports | Backend full/intermediate/abridged TCP; independent framing checked separately |
33
+ | Media | Seekable binary uploads up to 4000 512-KiB parts, empty upload rejected; explicit-size downloads; no CDN/parallel/resume/cross-DC file retry |
34
+ | Errors | GramFlux sanitized RPC/auth/wait/migration/transport/session/serialization errors; timeout and cancellation remain asyncio/Python exceptions |
35
+ | Session formats | GramFlux version-1 SQLite or MemoryStorage; no Telethon/Pyrogram/Hydrogram/Pyrofork file compatibility |
36
+ | Unsupported auth | Signup, QR, passkey, email verification, special official-app SMS/payment flows |
37
+
38
+ Migration guides map supported operations only. There is no drop-in compatibility
39
+ promise. Read `docs/guides/migration.md` for behavioral differences.
@@ -0,0 +1,37 @@
1
+ # Competitive research — 2026-10-20
2
+
3
+ Primary sources: official project repositories, package metadata, checked-out metadata
4
+ snapshots in `research/*-repository.json`, and `research/test-inventory.json`. File
5
+ counts include helpers and package files, so they do not measure quality or coverage.
6
+ No competitor performance claim is inferred from architecture. No source implementation
7
+ was copied. Repository metadata can change; the recorded date matters.
8
+
9
+ | Project | Observed maintenance | Architecture/API and dependencies | Compatibility/testing observations |
10
+ | --- | --- | --- | --- |
11
+ | [Telethon](https://pypi.org/project/Telethon/1.45.0/) | GitHub mirror archived; current package links to [Codeberg](https://codeberg.org/Lonami/Telethon), v1 described as maintenance mode. PyPI 1.45.0 released 2026-09-10 | asyncio TelegramClient, generated TL, Python MTProto, pyaes/rsa; optional acceleration. Familiar raw functions and high-level helpers | Package declares Python >=3.5; installed version tested here on 3.12. GitHub mirror test inventory includes crypto/RSA, helpers, events and client tests; not a current Codeberg CI audit |
12
+ | [Pyrogram](https://github.com/pyrogram/pyrogram) | Repository archived, pushed 2024-12-23 | Decorator Client API, generated raw layer, own sessions/dispatcher, pyaes 1.6.1/pysocks 1.7.1; optional TgCrypto | setup declares ~=3.7; classifiers through 3.11 are not modern-version verification. Tests inspected include commands/HTML/file IDs; GitHub Python workflow exists |
13
+ | [Hydrogram](https://github.com/hydrogram/hydrogram) | Not archived; pushed 2026-04-10 at inspection | Pyrogram-derived API; pyproject depends on pyaes, pysocks, aiosqlite; optional TgCrypto/uvloop | Python >=3.9, classifiers through 3.13; pytest/pytest-asyncio/Ruff development tools; API-update workflow; small test directory observed |
14
+ | [gotd/td](https://github.com/gotd/td) | Not archived; pushed 2026-10-19 | Go, generated TL, explicit contexts, modular transport/auth/storage; substantial Go dependency graph | go.mod declares Go 1.25; hundreds of *_test.go files, benchmark/e2e/nightly/schema-update workflows. Not a Python API substitute |
15
+
16
+ Limitations are contextual: Telethon's flexible high-level calls and backend retry/update
17
+ behavior require careful policy integration; archived Pyrogram is a maintenance risk;
18
+ Hydrogram and Pyrogram share an ecosystem/API heritage rather than GramFlux session
19
+ compatibility; gotd requires Go. None of these observations establish GramFlux superiority.
20
+
21
+ GramFlux's current differentiators are auditable official TL-vs-JSON verification,
22
+ fail-closed schema changes, explicit admission deadlines, value-free error diagnostics,
23
+ and a small streaming/persistence API. Their developer and performance benefits have
24
+ not been established in user studies or server workloads. The native codec is currently
25
+ slower on the recorded benchmark. Core networking is borrowed as a dependency, so it
26
+ cannot support a claim of a faster independent MTProto engine.
27
+
28
+ Official protocol research: [API](https://core.telegram.org/api),
29
+ [schema](https://core.telegram.org/schema), [MTProto schema](https://core.telegram.org/schema/mtproto),
30
+ [protocol](https://core.telegram.org/mtproto), [TL](https://core.telegram.org/mtproto/TL),
31
+ [serialization](https://core.telegram.org/mtproto/serialize),
32
+ [transports](https://core.telegram.org/mtproto/transports),
33
+ [authorization](https://core.telegram.org/api/auth),
34
+ [terms](https://core.telegram.org/api/terms),
35
+ [credentials](https://core.telegram.org/api/obtaining_api_id).
36
+ The official machine-readable JSON was retained as an independent check against HTML
37
+ TL extraction, rather than substituting a competitor's schema.
@@ -0,0 +1,27 @@
1
+ # Performance methodology
2
+
3
+ Run `python -m gramflux.tools.benchmark --iterations 5000 --rounds 5` on an otherwise
4
+ idle machine. JSON records Python/platform/processor, dependency versions, exact input
5
+ shape/size, each round, median and a separately sampled tracemalloc peak. Warm-up and
6
+ GC happen before timings. A correctness check compares bytes before measurement.
7
+
8
+ The current benchmark uses one identical 64-byte inputFile constructor for GramFlux's
9
+ independent codec and Telethon's generated codec. Both return normal objects; neither
10
+ performs network I/O. Bounds checking and type validation differ, so these timings
11
+ compare implemented behavior, not interchangeable security guarantees. Tracemalloc
12
+ peaks measure traced transient allocations over a short loop, not RSS per session or
13
+ retained heap. Results on a shared virtual machine are noisy.
14
+
15
+ `research/benchmark.json` is a measured baseline, not a hard-coded competitor table.
16
+ The independent codec is slower on this input. No optimization has been justified yet.
17
+ Profile representative nested messages/vectors and flags before specializing encoding.
18
+ Cache descriptors only if profiles show lookup cost, while preserving schema/version
19
+ validation and bounds. Do not add native extensions before measuring their benefit.
20
+
21
+ Not measured yet: RPC latency/throughput, multiple-session RSS, dispatch overhead,
22
+ SQLite latency, sustained file throughput/peak RSS, reconnect recovery or Telegram
23
+ server behavior. A fair future network comparison must use the same DC/account
24
+ permissions, operation payload, machine, transport, retries, concurrency and conditions,
25
+ record distributions and avoid load that violates Telegram terms. Controlled server
26
+ fault-injection results must be separated from actual Telegram tests. File benchmarks
27
+ must stream from disk at fixed part sizes and measure memory separately from latency.
@@ -0,0 +1,31 @@
1
+ # Security model
2
+
3
+ Assets: authorization keys, API hash, bot tokens, passwords/codes, session files,
4
+ private messages and user-provided file destinations. Boundaries: local filesystem,
5
+ Telegram MTProto backend, schema downloads, untrusted incoming binary objects, callbacks
6
+ and dependencies. MTProto cloud chats are not end-to-end encrypted secret chats.
7
+
8
+ | Threat | Protection | Residual risk |
9
+ | --- | --- | --- |
10
+ | Credential leakage | No credential repr in LoginChallenge/SessionData/native objects; sanitized RPC identifiers, backend log redaction, handler exceptions logged by type only | Python does not guarantee secret zeroization; callbacks and debuggers can expose objects; raw/backend objects may have value-bearing reprs |
11
+ | Local session theft | POSIX mode 0600, no-follow open, regular-file validation, exclusive ownership lock, transactional SQLite snapshot | Keys are plaintext at rest; machine compromise, backups, malicious parent directory or privilege escalation compromise accounts |
12
+ | Corrupt/foreign database | application_id and schema version checks; unrelated databases refused; version upgrades fail explicitly | No automatic repair or migration; untrusted SQLite input itself is not a sandbox |
13
+ | Malformed TL | Bounded lengths, vector counts, depth, ID registry; unknown flags and trailing input rejected | These bounds govern independent codec only; live decoding is backend policy |
14
+ | Resource exhaustion | Bounded admitted public RPCs and event dispatcher queue, chunked files | Backend update queues and some caches can grow; end-to-end memory bounds not established |
15
+ | Unsafe transfer paths | Only caller-supplied destination; secure temp in destination directory; atomic no-overwrite hard-link publication; cleanup on failure | Trusted local directory required; POSIX hard-link semantics; not durable resume; no CDN support; file references may expire |
16
+ | Event-loop blocking | SQLite/file I/O and SRP moved to threads; cancellation joins active workers | Backend key generation/other CPU code needs profiling; arbitrary user callbacks may block indefinitely |
17
+ | Schema supply chain | Explicit HTTPS fetch with normal certificate verification, exact source/hash/date, deterministic regeneration and JSON cross-check | Hash proves snapshot identity, not upstream authenticity; no signed schema publication verified |
18
+ | Network tampering | Established backend's MTProto implementation; native probe never accepts credentials or establishes trust | No new independent crypto audit; pinning a library is not proof of cryptographic correctness |
19
+ | Ambiguous request outcome | No broad application retry; bounded auth-only migration retries; explicit waits/errors | Backend retransmits protocol messages during reconnect; a timeout/cancellation cannot retract a server action |
20
+ | Interrupted shutdown | Shielded cleanup and worker joining; atomic session transaction, temporary download cleanup | SIGKILL/power loss can lose recent auth/update snapshots; callback delivery is not transactional |
21
+
22
+ No encryption-at-rest feature or secrets vault is invented. Use encrypted storage provided
23
+ by the OS and protect backups; adding application encryption requires external key
24
+ management and another dependency/security review. Session files must not be uploaded as
25
+ bug reports. No cross-library conversion or silent authenticated-session replacement.
26
+
27
+ Runtime dependency audit is recorded in `research/dependency-audit.txt`; results apply
28
+ only at scan time. The release still requires independent cryptographic review, live
29
+ fault injection, memory/soak testing, verified dependency artifacts, a private security
30
+ reporting channel, and a supported response policy. See SECURITY.md. No anti-abuse
31
+ bypass, spam tooling, flood evasion or unauthorized login functionality is implemented.