ferogram 0.5.1__tar.gz → 0.5.2__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 (110) hide show
  1. {ferogram-0.5.1 → ferogram-0.5.2}/.github/workflows/publish.yml +28 -12
  2. {ferogram-0.5.1 → ferogram-0.5.2}/CHANGELOG.md +6 -0
  3. {ferogram-0.5.1 → ferogram-0.5.2}/Cargo.lock +17 -17
  4. {ferogram-0.5.1 → ferogram-0.5.2}/Cargo.toml +6 -6
  5. {ferogram-0.5.1 → ferogram-0.5.2}/FEATURES.md +6 -0
  6. ferogram-0.5.2/PKG-INFO +162 -0
  7. ferogram-0.5.2/README.md +137 -0
  8. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/__init__.py +2 -1
  9. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/api.tl +58 -9
  10. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/client.py +512 -40
  11. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/_tl_schema.py +77 -15
  12. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/__init__.py +4 -0
  13. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/channels.py +7 -2
  14. ferogram-0.5.2/ferogram/raw/generated/functions/communities.py +375 -0
  15. ferogram-0.5.2/ferogram/raw/generated/functions/ephemeral.py +241 -0
  16. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/messages.py +173 -3
  17. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/__init__.py +2 -0
  18. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/_base.py +880 -11
  19. ferogram-0.5.2/ferogram/raw/generated/types/communities.py +120 -0
  20. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/messages.py +65 -11
  21. {ferogram-0.5.1 → ferogram-0.5.2}/pyproject.toml +2 -2
  22. {ferogram-0.5.1 → ferogram-0.5.2}/src/connection.rs +103 -10
  23. {ferogram-0.5.1 → ferogram-0.5.2}/src/lib.rs +3 -0
  24. ferogram-0.5.2/src/pipelined.rs +129 -0
  25. ferogram-0.5.1/PKG-INFO +0 -132
  26. ferogram-0.5.1/README.md +0 -107
  27. {ferogram-0.5.1 → ferogram-0.5.2}/.github/workflows/compile-check.yml +0 -0
  28. {ferogram-0.5.1 → ferogram-0.5.2}/.gitignore +0 -0
  29. {ferogram-0.5.1 → ferogram-0.5.2}/.readthedocs.yaml +0 -0
  30. {ferogram-0.5.1 → ferogram-0.5.2}/LICENSE-APACHE +0 -0
  31. {ferogram-0.5.1 → ferogram-0.5.2}/LICENSE-MIT +0 -0
  32. {ferogram-0.5.1 → ferogram-0.5.2}/Makefile +0 -0
  33. {ferogram-0.5.1 → ferogram-0.5.2}/assets/architecture.svg +0 -0
  34. {ferogram-0.5.1 → ferogram-0.5.2}/build.rs +0 -0
  35. {ferogram-0.5.1 → ferogram-0.5.2}/examples/admin_tools.py +0 -0
  36. {ferogram-0.5.1 → ferogram-0.5.2}/examples/command_bot.py +0 -0
  37. {ferogram-0.5.1 → ferogram-0.5.2}/examples/echo_bot.py +0 -0
  38. {ferogram-0.5.1 → ferogram-0.5.2}/examples/group_management.py +0 -0
  39. {ferogram-0.5.1 → ferogram-0.5.2}/examples/media_bot.py +0 -0
  40. {ferogram-0.5.1 → ferogram-0.5.2}/examples/raw_invoke.py +0 -0
  41. {ferogram-0.5.1 → ferogram-0.5.2}/examples/rich_message.py +0 -0
  42. {ferogram-0.5.1 → ferogram-0.5.2}/examples/search_bot.py +0 -0
  43. {ferogram-0.5.1 → ferogram-0.5.2}/examples/send_hi.py +0 -0
  44. {ferogram-0.5.1 → ferogram-0.5.2}/examples/send_media.py +0 -0
  45. {ferogram-0.5.1 → ferogram-0.5.2}/examples/send_message.py +0 -0
  46. {ferogram-0.5.1 → ferogram-0.5.2}/examples/update_handlers.py +0 -0
  47. {ferogram-0.5.1 → ferogram-0.5.2}/examples/user_management.py +0 -0
  48. {ferogram-0.5.1 → ferogram-0.5.2}/examples/userbot.py +0 -0
  49. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/filters.py +0 -0
  50. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/keyboards.py +0 -0
  51. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/logging.py +0 -0
  52. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/py.typed +0 -0
  53. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/__init__.py +0 -0
  54. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/api/__init__.py +0 -0
  55. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/api/functions.py +0 -0
  56. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/api/types.py +0 -0
  57. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/codegen.py +0 -0
  58. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/__init__.py +0 -0
  59. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/account.py +0 -0
  60. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/aicompose.py +0 -0
  61. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/auth.py +0 -0
  62. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/bots.py +0 -0
  63. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/chatlists.py +0 -0
  64. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/contacts.py +0 -0
  65. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/folders.py +0 -0
  66. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/fragment.py +0 -0
  67. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/help.py +0 -0
  68. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/langpack.py +0 -0
  69. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/payments.py +0 -0
  70. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/phone.py +0 -0
  71. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/photos.py +0 -0
  72. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/premium.py +0 -0
  73. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/smsjobs.py +0 -0
  74. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/stats.py +0 -0
  75. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/stickers.py +0 -0
  76. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/stories.py +0 -0
  77. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/updates.py +0 -0
  78. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/upload.py +0 -0
  79. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/functions/users.py +0 -0
  80. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/account.py +0 -0
  81. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/aicompose.py +0 -0
  82. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/auth.py +0 -0
  83. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/bots.py +0 -0
  84. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/channels.py +0 -0
  85. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/chatlists.py +0 -0
  86. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/contacts.py +0 -0
  87. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/fragment.py +0 -0
  88. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/help.py +0 -0
  89. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/payments.py +0 -0
  90. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/phone.py +0 -0
  91. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/photos.py +0 -0
  92. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/premium.py +0 -0
  93. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/smsjobs.py +0 -0
  94. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/stats.py +0 -0
  95. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/stickers.py +0 -0
  96. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/storage.py +0 -0
  97. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/stories.py +0 -0
  98. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/updates.py +0 -0
  99. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/upload.py +0 -0
  100. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/generated/types/users.py +0 -0
  101. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/proxy.py +0 -0
  102. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/raw/tl.py +0 -0
  103. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/rich.py +0 -0
  104. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/types.py +0 -0
  105. {ferogram-0.5.1 → ferogram-0.5.2}/ferogram/updates.py +0 -0
  106. {ferogram-0.5.1 → ferogram-0.5.2}/src/raw.rs +0 -0
  107. {ferogram-0.5.1 → ferogram-0.5.2}/src/session.rs +0 -0
  108. {ferogram-0.5.1 → ferogram-0.5.2}/src/srp.rs +0 -0
  109. {ferogram-0.5.1 → ferogram-0.5.2}/tests/test_rich.py +0 -0
  110. {ferogram-0.5.1 → ferogram-0.5.2}/tests/test_tl_roundtrip.py +0 -0
@@ -146,7 +146,7 @@ jobs:
146
146
  - name: Install maturin
147
147
  run: pip install maturin
148
148
 
149
- - name: Fetch Termux libpython3.13 for linking
149
+ - name: Fetch Termux libpython for linking
150
150
  run: |
151
151
  TARGET=${{ matrix.target }}
152
152
  case "$TARGET" in
@@ -166,21 +166,35 @@ jobs:
166
166
  curl -sL "https://packages.termux.dev/apt/termux-main/${DEB_PATH}" -o python.deb
167
167
  ar x python.deb
168
168
  # data archive may be .tar.xz or .tar.zst depending on Termux version
169
- tar xf data.tar.* --wildcards "*/libpython3.13*" 2>/dev/null || true
169
+ # Don't pin the minor version here - Termux's "python" package always
170
+ # tracks upstream latest, and older debs fall out of the Packages
171
+ # index once superseded, so a hardcoded "libpython3.13" wildcard
172
+ # breaks the moment Termux bumps its default Python.
173
+ tar xf data.tar.* --wildcards "*/libpython3.*" 2>/dev/null || true
170
174
 
171
175
  LIB_DIR=/tmp/termux-py/data/data/com.termux/files/usr/lib
172
- # Ensure the unversioned name exists for -lpython3.13
173
- if [ ! -f "$LIB_DIR/libpython3.13.so" ]; then
174
- ln -sf "$(basename $(ls $LIB_DIR/libpython3.13.so* | head -1))" \
175
- "$LIB_DIR/libpython3.13.so"
176
+ SO_FILE=$(ls "$LIB_DIR"/libpython3.*.so* 2>/dev/null | head -1)
177
+ if [ -z "$SO_FILE" ]; then
178
+ echo "::error::No libpython3.*.so found in Termux's python package ($DEB_PATH)"
179
+ exit 1
176
180
  fi
181
+
182
+ # Extract "3.14" out of ".../libpython3.14.so"
183
+ PYVER=$(basename "$SO_FILE" | sed -E 's/^libpython(3\.[0-9]+)\.so.*/\1/')
184
+ UNVERSIONED="$LIB_DIR/libpython${PYVER}.so"
185
+ if [ ! -f "$UNVERSIONED" ]; then
186
+ ln -sf "$(basename "$SO_FILE")" "$UNVERSIONED"
187
+ fi
188
+
177
189
  echo "TERMUX_LIBDIR=$LIB_DIR" >> $GITHUB_ENV
190
+ echo "TERMUX_PYVER=$PYVER" >> $GITHUB_ENV
191
+ echo "Linking against Termux libpython $PYVER ($SO_FILE)"
178
192
 
179
193
  - name: Build Android wheel
180
194
  env:
181
195
  ANDROID_NDK_HOME: ${{ steps.ndk.outputs.ndk-path }}
182
196
  ANDROID_API_LEVEL: ${{ matrix.api }}
183
- PYO3_CROSS_PYTHON_VERSION: "3.13"
197
+ PYO3_CROSS_PYTHON_VERSION: ${{ env.TERMUX_PYVER }}
184
198
  run: |
185
199
  NDK_BIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
186
200
  TARGET=${{ matrix.target }}
@@ -203,11 +217,13 @@ jobs:
203
217
  export AR_${TARGET_LOWER}=$NDK_BIN/llvm-ar
204
218
  export CARGO_TARGET_${TARGET_UPPER}_LINKER=$NDK_BIN/${CLANG_PREFIX}-clang
205
219
 
206
- # Link against Termux's real libpython3.13.so (not an empty stub).
207
- # This embeds DT_NEEDED: libpython3.13.so in the extension, so
208
- # bionic resolves all Python symbols explicitly at dlopen time via
209
- # Termux's LD_LIBRARY_PATH - instead of relying on global namespace
210
- # propagation, which Android's linker does not guarantee.
220
+ # Link against Termux's real libpython<version>.so (not an empty
221
+ # stub). This embeds DT_NEEDED: libpython<version>.so in the
222
+ # extension, so bionic resolves all Python symbols explicitly at
223
+ # dlopen time via Termux's LD_LIBRARY_PATH - instead of relying on
224
+ # global namespace propagation, which Android's linker does not
225
+ # guarantee. The version is whatever Termux's apt repo currently
226
+ # ships (see the fetch step above), not a fixed constant.
211
227
  export RUSTFLAGS="-L native=$TERMUX_LIBDIR"
212
228
 
213
229
  maturin build \
@@ -1,3 +1,9 @@
1
+ ## 0.5.2 (2026-07-17)
2
+
3
+ - Added `Client.get_chat_photos(peer, limit)`: photo/avatar history for groups and channels (`get_profile_photos` only ever worked for users). Current photo comes from the chat's full info, so it survives message deletion; older photos come from `messageActionChatEditPhoto` search history.
4
+ - Added fast re-auth support: `sign_out()` captures a `future_auth_token` when Telegram returns one and persists it via a new `DcConnection.get_future_auth_token`/`set_future_auth_token` pair (rides along in the existing session blob, no new session format code needed here). `request_login_code()` replays it automatically, so a returning session can skip code entry entirely (`auth.sentCodeSuccess`).
5
+ - MTProto handshake fix upstream (dc-tagged `p_q_inner_data` was being rejected by Telegram with RPC 444 outside DC2), pulled in transitively via `ferogram-mtsender`.
6
+ - Layer Upgrade to 228
1
7
  ## 0.5.1 (2026-06-29)
2
8
 
3
9
  ## What's Changed
@@ -392,9 +392,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
392
392
 
393
393
  [[package]]
394
394
  name = "ferogram-connect"
395
- version = "0.6.3"
395
+ version = "0.6.4"
396
396
  source = "registry+https://github.com/rust-lang/crates.io-index"
397
- checksum = "90734b153432187e49e05b3b79737b2ac69cd3647b1dc2f572dd63cdeeeea048"
397
+ checksum = "54211f9669f8bb7db8101d952514784311a1e135c01eb04d8732d465cdb2aa73"
398
398
  dependencies = [
399
399
  "ferogram-crypto",
400
400
  "ferogram-mtproto",
@@ -409,9 +409,9 @@ dependencies = [
409
409
 
410
410
  [[package]]
411
411
  name = "ferogram-crypto"
412
- version = "0.6.3"
412
+ version = "0.6.4"
413
413
  source = "registry+https://github.com/rust-lang/crates.io-index"
414
- checksum = "12bfa17a936160758b481d56f5674644290fa372165c2a416b21068ae484aed5"
414
+ checksum = "0e9b1bf8c53553a3fa8acbfdc0f9f9ede749f786a5d62c26c57a4dd20b793b4d"
415
415
  dependencies = [
416
416
  "aes",
417
417
  "ctr",
@@ -427,9 +427,9 @@ dependencies = [
427
427
 
428
428
  [[package]]
429
429
  name = "ferogram-mtproto"
430
- version = "0.6.3"
430
+ version = "0.6.4"
431
431
  source = "registry+https://github.com/rust-lang/crates.io-index"
432
- checksum = "eb92042988257514b90ed249214747225388bb38806f904c25c4659ec70f2051"
432
+ checksum = "007456e26302ca4a2f63019ed88c2055705ecf7752f823520d41aa2f8803b42e"
433
433
  dependencies = [
434
434
  "ferogram-crypto",
435
435
  "ferogram-tl-types",
@@ -441,9 +441,9 @@ dependencies = [
441
441
 
442
442
  [[package]]
443
443
  name = "ferogram-mtsender"
444
- version = "0.6.3"
444
+ version = "0.6.4"
445
445
  source = "registry+https://github.com/rust-lang/crates.io-index"
446
- checksum = "cde7ed2cd881032574626cda99d8fce73e32e4d884c843444d488fb608364e20"
446
+ checksum = "4fb2d34f025b0c6369d42f08317e3ded5bb8aa83bdec48fd443a4cc26fa4c9cf"
447
447
  dependencies = [
448
448
  "ferogram-connect",
449
449
  "ferogram-crypto",
@@ -457,7 +457,7 @@ dependencies = [
457
457
 
458
458
  [[package]]
459
459
  name = "ferogram-py"
460
- version = "0.5.1"
460
+ version = "0.5.2"
461
461
  dependencies = [
462
462
  "base64 0.22.1",
463
463
  "ferogram-connect",
@@ -474,9 +474,9 @@ dependencies = [
474
474
 
475
475
  [[package]]
476
476
  name = "ferogram-session"
477
- version = "0.6.3"
477
+ version = "0.6.4"
478
478
  source = "registry+https://github.com/rust-lang/crates.io-index"
479
- checksum = "307cfc80221fd742fa87af28bc629cb7acc9e6c89ceb7fa823068fb9df581989"
479
+ checksum = "c29506aee6e38e3f62623f28f17dfa470f347a87f65030313bf62f9b8dd12dd1"
480
480
  dependencies = [
481
481
  "base64 0.22.1",
482
482
  "libsql",
@@ -488,24 +488,24 @@ dependencies = [
488
488
 
489
489
  [[package]]
490
490
  name = "ferogram-tl-gen"
491
- version = "0.6.3"
491
+ version = "0.6.4"
492
492
  source = "registry+https://github.com/rust-lang/crates.io-index"
493
- checksum = "fe1bc77068bf406a6407dd9810fe80b70d9df18ce9069b2d5100b943f8caa638"
493
+ checksum = "501f1b96b5981e83d8328391dc6aa31df208dd8662f2b814117a345e570060ae"
494
494
  dependencies = [
495
495
  "ferogram-tl-parser",
496
496
  ]
497
497
 
498
498
  [[package]]
499
499
  name = "ferogram-tl-parser"
500
- version = "0.6.3"
500
+ version = "0.6.4"
501
501
  source = "registry+https://github.com/rust-lang/crates.io-index"
502
- checksum = "f092429c003263fa28e33f3090c41aedb2a7462fbc7b8f82172b0bf92ec1a205"
502
+ checksum = "d7337bdfb8be8eee3155a1af8ead1c34c2cfc2de738428574b1661d2094a7389"
503
503
 
504
504
  [[package]]
505
505
  name = "ferogram-tl-types"
506
- version = "0.6.3"
506
+ version = "0.6.4"
507
507
  source = "registry+https://github.com/rust-lang/crates.io-index"
508
- checksum = "ad3ec63abcbf0592390d400f73679d2149f9441c6c5ee8e9288b83ad32f76085"
508
+ checksum = "61d5a7ed4c2996730a9a35d06a33abaadc246dd828ba1ab5727bd5bbd8699a95"
509
509
  dependencies = [
510
510
  "ferogram-tl-gen",
511
511
  "ferogram-tl-parser",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ferogram-py"
3
- version = "0.5.1"
3
+ version = "0.5.2"
4
4
  edition = "2024"
5
5
  description = "Python MTProto client based on ferogram (Rust MTProto)"
6
6
  build = "build.rs"
@@ -12,11 +12,11 @@ name = "_ferogram"
12
12
  crate-type = ["cdylib"]
13
13
 
14
14
  [dependencies]
15
- ferogram-mtsender = { version = "0.6.3" }
16
- ferogram-session = { version = "0.6.3", features = ["sqlite-session", "libsql-session"] }
17
- ferogram-connect = { version = "0.6.3" }
18
- ferogram-tl-types = { version = "0.6.3" }
19
- ferogram-crypto = { version = "0.6.3" }
15
+ ferogram-mtsender = { version = "0.6.4" }
16
+ ferogram-session = { version = "0.6.4", features = ["sqlite-session", "libsql-session"] }
17
+ ferogram-connect = { version = "0.6.4" }
18
+ ferogram-tl-types = { version = "0.6.4" }
19
+ ferogram-crypto = { version = "0.6.4" }
20
20
  getrandom = "0.2"
21
21
  base64 = "0.22"
22
22
  pyo3 = { version = "0.24", features = ["extension-module", "abi3-py39"] }
@@ -387,6 +387,7 @@ await client.upload_with_progress(path, on_progress=None)
387
387
  await client.edit_chat_photo(peer, path)
388
388
  await client.delete_profile_photos()
389
389
  await client.get_profile_photos(peer, limit=100)
390
+ await client.get_chat_photos(peer, limit=100)
390
391
  ```
391
392
 
392
393
  Important current behavior:
@@ -642,6 +643,11 @@ await client.get_authorizations()
642
643
  await client.terminate_session(hash)
643
644
  ```
644
645
 
646
+ `sign_out()` captures a `future_auth_token` when Telegram provides one, and
647
+ `request_login_code()` replays it automatically on the next login. When
648
+ that succeeds, Telegram authorizes the session immediately, no code entry
649
+ needed - check for `"_": "auth.sentCodeSuccess"` on the returned dict.
650
+
645
651
  ## Bot management
646
652
 
647
653
  ```python
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: ferogram
3
+ Version: 0.5.2
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Rust
9
+ Classifier: Topic :: Communications :: Chat
10
+ Classifier: Topic :: Software Development :: Libraries
11
+ License-File: LICENSE-APACHE
12
+ License-File: LICENSE-MIT
13
+ Summary: A modern, elegant, asynchronous MTProto framework for building Telegram user clients and bots in Python.
14
+ Keywords: telegram,mtproto,rust,client,bot,ferogram
15
+ Author-email: Ankit Chaubey <ankitchaubey.dev@gmail.com>
16
+ License: MIT OR Apache-2.0
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
19
+ Project-URL: Author, https://github.com/ankit-chaubey
20
+ Project-URL: Documentation, https://github.com/ankit-chaubey/ferogram-py#readme
21
+ Project-URL: Homepage, https://github.com/ankit-chaubey/ferogram-py
22
+ Project-URL: Source, https://github.com/ankit-chaubey/ferogram-py
23
+ Project-URL: Tracker, https://github.com/ankit-chaubey/ferogram-py/issues
24
+
25
+ <div align="center">
26
+
27
+ # ferogram-py
28
+
29
+ ![PyPI](https://img.shields.io/pypi/v/ferogram?style=flat-square&logo=pypi&logoColor=white&color=7C3AED)
30
+ ![Python](https://img.shields.io/pypi/pyversions/ferogram?style=flat-square&logo=python&logoColor=FFD43B&color=3B82F6)
31
+ ![Downloads](https://img.shields.io/pepy/dt/ferogram?style=flat-square&color=14B8A6)
32
+ ![License](https://img.shields.io/badge/License-MIT%20%7C%20Apache--2.0-64748B?style=flat-square)
33
+ ![Telegram](https://img.shields.io/badge/Telegram-FerogramChat-06B6D4?style=flat-square&logo=telegram&logoColor=white)
34
+
35
+ **A modern, elegant, asynchronous MTProto framework for building Telegram user clients and bots in Python.**
36
+
37
+ </div>
38
+
39
+ Powered by a high-performance [Rust core](https://github.com/ankit-chaubey/ferogram) that takes care of networking, encryption, TL parsing, and session management so you can focus on writing clean, idiomatic Python.
40
+
41
+ ---
42
+
43
+ ## Why ferogram-py?
44
+
45
+ Most of the heavy lifting in an MTProto client happens behind the scenes; networking, encryption, TL parsing, and keeping up with updates. ferogram-py lets a Rust core handle all of that, while exposing a clean, Pythonic API.
46
+
47
+ For most applications, the high-level API is all you'll need. But if you want to use a brand-new Telegram feature or need something more advanced, you can always drop down to the raw MTProto API and invoke requests directly.
48
+
49
+ The goal is to stay out of your way: simple things should be simple, and advanced things should still be possible.
50
+
51
+ > Quick API reference: [FEATURES.md](./FEATURES.md)
52
+
53
+ ---
54
+
55
+ ## Install
56
+
57
+ ```bash
58
+ pip install ferogram
59
+ ```
60
+
61
+ <details>
62
+ <summary>Building from source</summary>
63
+
64
+ ```bash
65
+ make dev # editable install into .venv (builds the Rust extension)
66
+ make build # release wheel for this machine
67
+ make codegen # regenerate TL code without a Rust rebuild
68
+ make test # run tests
69
+ make clean # wipe .venv, target, dist, generated/
70
+ ```
71
+
72
+ On Termux: `pkg install rust clang python` first.
73
+ Rust-only change, don't want to wait on codegen: `FEROGRAM_SKIP_CODEGEN=1 maturin develop`
74
+
75
+ </details>
76
+
77
+ ---
78
+
79
+ ## Quick start
80
+
81
+ **Bot:**
82
+
83
+ ```python
84
+ from ferogram import Client, filters
85
+
86
+ app = Client("mybot", api_id=0, api_hash="", bot_token="123:TOKEN")
87
+
88
+ @app.on_message(filters.command("start"))
89
+ async def start(client, message):
90
+ await message.reply("Hello!")
91
+
92
+ app.run()
93
+ ```
94
+
95
+ **User:**
96
+
97
+ ```python
98
+ import asyncio
99
+ from ferogram import Client
100
+
101
+ app = Client("myaccount", api_id=0, api_hash="", phone="+1234567890")
102
+
103
+ async def main():
104
+ async with app as client:
105
+ await client.send_message("me", "logged in")
106
+
107
+ asyncio.run(main())
108
+ ```
109
+
110
+ Credentials also work from env vars: `API_ID`, `API_HASH`, `BOT_TOKEN`.
111
+
112
+ ## Logging
113
+
114
+ ```python
115
+ import ferogram.logging as fero_log
116
+
117
+ fero_log.setup() # INFO to stderr
118
+ fero_log.setup(level=10) # DEBUG
119
+ ```
120
+
121
+ ## Architecture
122
+
123
+ ![architecture](https://github.com/ankit-chaubey/ferogram-py/blob/main/assets/architecture.svg)
124
+
125
+ The compiled extension (`_ferogram.so`) stays deliberately small: networking, encryption, session storage, and MTProto internals live in Rust. Everything you touch day to day, the client, handlers, filters, is plain Python and can change without a recompile.
126
+
127
+ <details>
128
+ <summary>Prebuilt Wheels for your platform</summary>
129
+
130
+ Wheels ship prebuilt for Linux (x86_64, aarch64), macOS (x86_64, arm64), Windows (x86_64), and Android/Termux (aarch64, x86_64). `pip install ferogram` grabs the right one on its own.
131
+
132
+ </details>
133
+
134
+ ---
135
+
136
+ ## License
137
+
138
+ This project is dual-licensed under:
139
+
140
+ - MIT License
141
+ - Apache License 2.0
142
+
143
+ You may choose either license.
144
+
145
+ You are free to use, modify, and distribute this software, including for commercial use, provided the original license and copyright notice are included.
146
+
147
+ See [`LICENSE-MIT`](https://github.com/ankit-chaubey/ferogram-py/blob/main/LICENSE-MIT) and [`LICENSE-APACHE`](https://github.com/ankit-chaubey/ferogram-py/blob/main/LICENSE-APACHE) for full details.
148
+
149
+ ---
150
+
151
+ ## Developer
152
+
153
+ Developed by [Ankit Chaubey](https://github.com/ankit-chaubey)
154
+
155
+ Don't forget to explore the Rust engine powering ferogram-py: [`ferogram`](https://github.com/ankit-chaubey/ferogram). Thanks for being part of the journey.
156
+
157
+ Join the ferogram community! Questions, discussions, bugs report and feedback are always welcome. As the project grows, we'll eventually split Python and Rust discussions into dedicated spaces.
158
+
159
+ - Channel (releases & announcements): [@Ferogram](https://t.me/Ferogram)
160
+
161
+ - (questions & discussion): [@FerogramChat](https://t.me/FerogramChat)
162
+
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+
3
+ # ferogram-py
4
+
5
+ ![PyPI](https://img.shields.io/pypi/v/ferogram?style=flat-square&logo=pypi&logoColor=white&color=7C3AED)
6
+ ![Python](https://img.shields.io/pypi/pyversions/ferogram?style=flat-square&logo=python&logoColor=FFD43B&color=3B82F6)
7
+ ![Downloads](https://img.shields.io/pepy/dt/ferogram?style=flat-square&color=14B8A6)
8
+ ![License](https://img.shields.io/badge/License-MIT%20%7C%20Apache--2.0-64748B?style=flat-square)
9
+ ![Telegram](https://img.shields.io/badge/Telegram-FerogramChat-06B6D4?style=flat-square&logo=telegram&logoColor=white)
10
+
11
+ **A modern, elegant, asynchronous MTProto framework for building Telegram user clients and bots in Python.**
12
+
13
+ </div>
14
+
15
+ Powered by a high-performance [Rust core](https://github.com/ankit-chaubey/ferogram) that takes care of networking, encryption, TL parsing, and session management so you can focus on writing clean, idiomatic Python.
16
+
17
+ ---
18
+
19
+ ## Why ferogram-py?
20
+
21
+ Most of the heavy lifting in an MTProto client happens behind the scenes; networking, encryption, TL parsing, and keeping up with updates. ferogram-py lets a Rust core handle all of that, while exposing a clean, Pythonic API.
22
+
23
+ For most applications, the high-level API is all you'll need. But if you want to use a brand-new Telegram feature or need something more advanced, you can always drop down to the raw MTProto API and invoke requests directly.
24
+
25
+ The goal is to stay out of your way: simple things should be simple, and advanced things should still be possible.
26
+
27
+ > Quick API reference: [FEATURES.md](./FEATURES.md)
28
+
29
+ ---
30
+
31
+ ## Install
32
+
33
+ ```bash
34
+ pip install ferogram
35
+ ```
36
+
37
+ <details>
38
+ <summary>Building from source</summary>
39
+
40
+ ```bash
41
+ make dev # editable install into .venv (builds the Rust extension)
42
+ make build # release wheel for this machine
43
+ make codegen # regenerate TL code without a Rust rebuild
44
+ make test # run tests
45
+ make clean # wipe .venv, target, dist, generated/
46
+ ```
47
+
48
+ On Termux: `pkg install rust clang python` first.
49
+ Rust-only change, don't want to wait on codegen: `FEROGRAM_SKIP_CODEGEN=1 maturin develop`
50
+
51
+ </details>
52
+
53
+ ---
54
+
55
+ ## Quick start
56
+
57
+ **Bot:**
58
+
59
+ ```python
60
+ from ferogram import Client, filters
61
+
62
+ app = Client("mybot", api_id=0, api_hash="", bot_token="123:TOKEN")
63
+
64
+ @app.on_message(filters.command("start"))
65
+ async def start(client, message):
66
+ await message.reply("Hello!")
67
+
68
+ app.run()
69
+ ```
70
+
71
+ **User:**
72
+
73
+ ```python
74
+ import asyncio
75
+ from ferogram import Client
76
+
77
+ app = Client("myaccount", api_id=0, api_hash="", phone="+1234567890")
78
+
79
+ async def main():
80
+ async with app as client:
81
+ await client.send_message("me", "logged in")
82
+
83
+ asyncio.run(main())
84
+ ```
85
+
86
+ Credentials also work from env vars: `API_ID`, `API_HASH`, `BOT_TOKEN`.
87
+
88
+ ## Logging
89
+
90
+ ```python
91
+ import ferogram.logging as fero_log
92
+
93
+ fero_log.setup() # INFO to stderr
94
+ fero_log.setup(level=10) # DEBUG
95
+ ```
96
+
97
+ ## Architecture
98
+
99
+ ![architecture](https://github.com/ankit-chaubey/ferogram-py/blob/main/assets/architecture.svg)
100
+
101
+ The compiled extension (`_ferogram.so`) stays deliberately small: networking, encryption, session storage, and MTProto internals live in Rust. Everything you touch day to day, the client, handlers, filters, is plain Python and can change without a recompile.
102
+
103
+ <details>
104
+ <summary>Prebuilt Wheels for your platform</summary>
105
+
106
+ Wheels ship prebuilt for Linux (x86_64, aarch64), macOS (x86_64, arm64), Windows (x86_64), and Android/Termux (aarch64, x86_64). `pip install ferogram` grabs the right one on its own.
107
+
108
+ </details>
109
+
110
+ ---
111
+
112
+ ## License
113
+
114
+ This project is dual-licensed under:
115
+
116
+ - MIT License
117
+ - Apache License 2.0
118
+
119
+ You may choose either license.
120
+
121
+ You are free to use, modify, and distribute this software, including for commercial use, provided the original license and copyright notice are included.
122
+
123
+ See [`LICENSE-MIT`](https://github.com/ankit-chaubey/ferogram-py/blob/main/LICENSE-MIT) and [`LICENSE-APACHE`](https://github.com/ankit-chaubey/ferogram-py/blob/main/LICENSE-APACHE) for full details.
124
+
125
+ ---
126
+
127
+ ## Developer
128
+
129
+ Developed by [Ankit Chaubey](https://github.com/ankit-chaubey)
130
+
131
+ Don't forget to explore the Rust engine powering ferogram-py: [`ferogram`](https://github.com/ankit-chaubey/ferogram). Thanks for being part of the journey.
132
+
133
+ Join the ferogram community! Questions, discussions, bugs report and feedback are always welcome. As the project grows, we'll eventually split Python and Rust discussions into dedicated spaces.
134
+
135
+ - Channel (releases & announcements): [@Ferogram](https://t.me/Ferogram)
136
+
137
+ - (questions & discussion): [@FerogramChat](https://t.me/FerogramChat)
@@ -26,6 +26,7 @@ if _main_file:
26
26
  )
27
27
 
28
28
  from .client import Client, StopPropagation, ContinuePropagation, TransferHandle, TransferCancelled
29
+ from .client import TransferLimits, available_qualities
29
30
  from . import filters
30
31
 
31
32
  # Session classes stay in Rust
@@ -59,7 +60,7 @@ from .updates import (
59
60
  __all__ = [
60
61
  # Core
61
62
  "Client", "filters", "StopPropagation", "ContinuePropagation",
62
- "TransferHandle", "TransferCancelled",
63
+ "TransferHandle", "TransferCancelled", "TransferLimits", "available_qualities",
63
64
  # Session (Rust)
64
65
  "FileSession", "MemorySession", "StringSession",
65
66
  "SqliteSession", "LibSqlSession", "CustomSession",