[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"readme-html:EDM115\u002Fminiproto:codex\u002Fv1":3},"\u003Ch1 id=\"miniproto\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"miniproto\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#miniproto\">miniproto\u003C\u002Fa>\u003C\u002Fh1>\n\u003Cp align=\"center\">\n   \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002FEDM115\u002Fminiproto\u002Fcodex\u002Fv1\u002Fdocs-site\u002Fsrc\u002Fassets\u002Fbrand\u002Fmark.svg\" width=\"176\" height=\"176\" alt=\"miniproto Packet Loom mark\"> \n\u003C\u002Fp>\n\u003Cp>\u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">miniproto\u003C\u002Fspan>\u003C\u002Fcode> is a fast, async-first Telegram MTProto client core for Python. It owns protocol correctness, authorization, encrypted sessions, raw Layer 228 bindings, updates, peers, messages, and bounded media transfers while a bundled Rust\u002FPyO3 extension accelerates measured hot paths.\u003Cbr>\n\u003Cbr>\n\u003C\u002Fp>\n\u003Cp>The first public line is \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">0\u003C\u002Fspan>.\u003Cspan class=\"hljs-number\">1\u003C\u002Fspan>.x\u003C\u002Fcode> Alpha: the implementation is substantial, but breaking changes remain possible while the API and operational defaults settle. Start with the \u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">documentation website\u003C\u002Fa> or the \u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fstart\u002Fquickstart\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">five-minute quickstart\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"install\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"install\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#install\">Install\u003C\u002Fa>\u003C\u002Fh2>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>console\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs console'>python -m pip install miniproto\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>The package requires Python 3.13 or newer. Release automation targets normal CPython 3.13 and 3.14 plus free-threaded CPython 3.14t, with native wheels for Linux glibc\u002Fmusl, Windows, and macOS on x86-64 and ARM64. CPython 3.13t and ARMv7 are not supported. Until the first Alpha artifacts are published, contributors can install the checkout with \u003Ccode class=\"hljs\">uv \u003Cspan class=\"hljs-keyword\">sync \u003C\u002Fspan>--\u003Cspan class=\"hljs-keyword\">extra \u003C\u002Fspan>dev,docs\u003C\u002Fcode> and \u003Ccode class=\"hljs\">uv \u003Cspan class=\"hljs-built_in\">run\u003C\u002Fspan> maturin develop\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"secure-minimal-quickstart\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"secure-minimal-quickstart\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#secure-minimal-quickstart\">Secure minimal quickstart\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>This deliberately uses in-memory storage, so it contacts Telegram but does not retain an authorization credential on disk:\u003C\u002Fp>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>\u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> os\n\n\u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> miniproto \u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> Client, ClientConfig, InMemorySessionStorage, event_loop\n\n\n\u003Cspan class=\"hljs-keyword\">async\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">def\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">main\u003C\u002Fspan>() -&gt; \u003Cspan class=\"hljs-literal\">None\u003C\u002Fspan>:\n    config = ClientConfig(\n        api_id=\u003Cspan class=\"hljs-built_in\">int\u003C\u002Fspan>(os.environ[\u003Cspan class=\"hljs-string\">&quot;MINIPROTO_API_ID&quot;\u003C\u002Fspan>]),\n        api_hash=os.environ[\u003Cspan class=\"hljs-string\">&quot;MINIPROTO_API_HASH&quot;\u003C\u002Fspan>],\n        session_storage=InMemorySessionStorage(),\n    )\n    \u003Cspan class=\"hljs-keyword\">async\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">with\u003C\u002Fspan> Client(config) \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> client:\n        \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.sign_in_bot(os.environ[\u003Cspan class=\"hljs-string\">&quot;MINIPROTO_BOT_TOKEN&quot;\u003C\u002Fspan>])\n        me = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.get_me()\n        \u003Cspan class=\"hljs-built_in\">print\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">f&quot;authorized bot ID: \u003Cspan class=\"hljs-subst\">{me.\u003Cspan class=\"hljs-built_in\">id\u003C\u002Fspan>}\u003C\u002Fspan>&quot;\u003C\u002Fspan>)\n\n\nevent_loop.run(main())\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>For a durable client, omit \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">session_storage\u003C\u002Fspan>\u003C\u002Fcode>, provide \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">MINIPROTO_SESSION_KEY\u003C\u002Fspan>\u003C\u002Fcode> through a secret manager, and use a distinct \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">session_path\u003C\u002Fspan>\u003C\u002Fcode> for each account. The default encrypted SQLite storage refuses to initialize without adequate key material; \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-title class_\">InMemorySessionStorage\u003C\u002Fspan>\u003C\u002Fcode> is intentionally ephemeral. See \u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fguides\u002Fsession-security\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Session Security\u003C\u002Fa> before persisting or moving authorization state.\u003C\u002Fp>\n\u003Ch2 id=\"authorization-and-identity\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"authorization-and-identity\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#authorization-and-identity\">Authorization and identity\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Phone authorization accepts sync or async callbacks for the login code and optional two-step-verification password:\u003C\u002Fp>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>\u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> getpass\n\n\u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.sign_in_phone(\n    \u003Cspan class=\"hljs-string\">&quot;+12025550123&quot;\u003C\u002Fspan>,\n    code_callback=\u003Cspan class=\"hljs-keyword\">lambda\u003C\u002Fspan>: getpass.getpass(\u003Cspan class=\"hljs-string\">&quot;Telegram login code: &quot;\u003C\u002Fspan>),\n    password_callback=\u003Cspan class=\"hljs-keyword\">lambda\u003C\u002Fspan>: getpass.getpass(\u003Cspan class=\"hljs-string\">&quot;Two-step password: &quot;\u003C\u002Fspan>),\n)\nme = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.get_me()\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>Bots use \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.\u003Cspan class=\"hljs-title function_\">sign_in_bot\u003C\u002Fspan>(token)\u003C\u002Fcode>. Neither flow grants permissions Telegram has not assigned to the account, and no credentialed example is part of the offline test suite.\u003C\u002Fp>\n\u003Ch2 id=\"raw-layer-228-calls\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"raw-layer-228-calls\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#raw-layer-228-calls\">Raw Layer 228 calls\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The generated raw API exposes every pinned Telegram function and constructor while \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-built_in\">Client\u003C\u002Fspan>.\u003Cspan class=\"hljs-built_in\">invoke\u003C\u002Fspan>()\u003C\u002Fcode> owns request wrapping, result validation, datacenter migration, eligible retries, flood-wait handling, and optional quick acknowledgements:\u003C\u002Fp>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>\u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> miniproto.raw \u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> functions\n\ntelegram_config = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.invoke(functions.HelpGetConfig())\n\u003Cspan class=\"hljs-built_in\">print\u003C\u002Fspan>(telegram_config.this_dc)\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>The \u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Freference\u002Ftelegram\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">generated Telegram reference\u003C\u002Fa> cross-links functions, parameters, result families, constructors, known RPC errors, and Python import names. For a non-idempotent request, do not force \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attr\">retry\u003C\u002Fspan>\u003Cspan class=\"hljs-operator\">=\u003C\u002Fspan>\u003Cspan class=\"hljs-literal\">True\u003C\u002Fspan>\u003C\u002Fcode> unless the operation has an application-owned deduplication guarantee.\u003C\u002Fp>\n\u003Ch2 id=\"messages-and-files\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"messages-and-files\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#messages-and-files\">Messages and files\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The convenience surface stays intentionally small:\u003C\u002Fp>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>message = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.send_message(\u003Cspan class=\"hljs-string\">&quot;@your_test_chat&quot;\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">&quot;Hello from miniproto&quot;\u003C\u002Fspan>)\nedited = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.edit_message(\u003Cspan class=\"hljs-string\">&quot;@your_test_chat&quot;\u003C\u002Fspan>, message.\u003Cspan class=\"hljs-built_in\">id\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">&quot;Updated text&quot;\u003C\u002Fspan>)\n\u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.delete_messages(\u003Cspan class=\"hljs-string\">&quot;@your_test_chat&quot;\u003C\u002Fspan>, [edited.\u003Cspan class=\"hljs-built_in\">id\u003C\u002Fspan>], revoke=\u003Cspan class=\"hljs-literal\">True\u003C\u002Fspan>)\n\nuploaded = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.send_file(\u003Cspan class=\"hljs-string\">&quot;@your_test_chat&quot;\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">&quot;report.pdf&quot;\u003C\u002Fspan>, caption=\u003Cspan class=\"hljs-string\">&quot;Nightly report&quot;\u003C\u002Fspan>)\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>\u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">send_message\u003C\u002Fspan>\u003Cspan class=\"hljs-params\">()\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode> and the final send step of \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">send_file\u003C\u002Fspan>\u003Cspan class=\"hljs-params\">()\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode> can request a transport quick acknowledgement. That receipt means Telegram accepted the encrypted packet for processing; the awaited RPC result remains the operation’s completion signal.\u003C\u002Fp>\n\u003Ch2 id=\"ordered-updates\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"ordered-updates\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#ordered-updates\">Ordered updates\u003C\u002Fa>\u003C\u002Fh2>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>\u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> miniproto \u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> Update\n\n\n\u003Cspan class=\"hljs-keyword\">async\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">def\u003C\u002Fspan> \u003Cspan class=\"hljs-title function_\">consume_updates\u003C\u002Fspan>() -&gt; \u003Cspan class=\"hljs-literal\">None\u003C\u002Fspan>:\n    \u003Cspan class=\"hljs-keyword\">async\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">for\u003C\u002Fspan> update \u003Cspan class=\"hljs-keyword\">in\u003C\u002Fspan> client.iter_updates():\n        \u003Cspan class=\"hljs-keyword\">if\u003C\u002Fspan> \u003Cspan class=\"hljs-built_in\">isinstance\u003C\u002Fspan>(update, Update):\n            \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> process(update)\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>Update recovery persists MTProto state before public delivery, handles difference recovery, and preserves FIFO order for the normalized events it emits. It is not an application-level exactly-once guarantee: durable side effects still need application-owned idempotency, and a blocked iterator task must be cancelled during shutdown.\u003C\u002Fp>\n\u003Ch2 id=\"bounded-media-transfers\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"bounded-media-transfers\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#bounded-media-transfers\">Bounded media transfers\u003C\u002Fa>\u003C\u002Fh2>\n\n          \u003Cdiv class='code-block'>\n            \u003Cdiv class='code-block-header'>\n              \u003Cspan class='code-block-lang'>python\u003C\u002Fspan>\n              \u003Cbutton class='copy-code-button' type='button'>\n                Copy\n              \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n            \u003Cpre>\u003Ccode class='hljs python'>\u003Cspan class=\"hljs-keyword\">from\u003C\u002Fspan> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C\u002Fspan> Path\n\nresult = \u003Cspan class=\"hljs-keyword\">await\u003C\u002Fspan> client.download_media(message.media, Path(\u003Cspan class=\"hljs-string\">&quot;download.bin&quot;\u003C\u002Fspan>), concurrency=\u003Cspan class=\"hljs-number\">4\u003C\u002Fspan>, verify_plain_hashes=\u003Cspan class=\"hljs-literal\">True\u003C\u002Fspan>)\n\n\u003Cspan class=\"hljs-keyword\">with\u003C\u002Fspan> Path(\u003Cspan class=\"hljs-string\">&quot;stream.bin&quot;\u003C\u002Fspan>).\u003Cspan class=\"hljs-built_in\">open\u003C\u002Fspan>(\u003Cspan class=\"hljs-string\">&quot;wb&quot;\u003C\u002Fspan>) \u003Cspan class=\"hljs-keyword\">as\u003C\u002Fspan> output:\n    \u003Cspan class=\"hljs-keyword\">async\u003C\u002Fspan> \u003Cspan class=\"hljs-keyword\">for\u003C\u002Fspan> chunk \u003Cspan class=\"hljs-keyword\">in\u003C\u002Fspan> client.iter_download(message.media, concurrency=\u003Cspan class=\"hljs-number\">2\u003C\u002Fspan>, max_in_flight_bytes=\u003Cspan class=\"hljs-number\">4\u003C\u002Fspan> * \u003Cspan class=\"hljs-number\">1024\u003C\u002Fspan> * \u003Cspan class=\"hljs-number\">1024\u003C\u002Fspan>):\n        output.write(chunk)\n\u003C\u002Fcode>\u003C\u002Fpre>\n          \u003C\u002Fdiv>\n        \u003Cp>Uploads and downloads use bounded request windows, shared byte-weighted per-DC schedulers, dedicated media lanes, migration-aware pools, file-reference refresh, cancellation cleanup, mandatory CDN integrity checks, and optional ordinary \u003Ccode class=\"hljs\">upload.getFileHashes\u003C\u002Fcode> verification. \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">iter_download\u003C\u002Fspan>\u003Cspan class=\"hljs-params\">()\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode> yields ordered chunks without materializing the whole file; \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">download_media\u003C\u002Fspan>\u003Cspan class=\"hljs-params\">()\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode> additionally supports memory, paths, caller-owned destinations, ranges, resuming, caching, and eligible bot multi-session downloads.\u003C\u002Fp>\n\u003Ch2 id=\"sessions-native-code-and-fallbacks\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"sessions-native-code-and-fallbacks\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#sessions-native-code-and-fallbacks\">Sessions, native code, and fallbacks\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Native miniproto session strings can be exported as a checksummed bearer value or protected with Scrypt and AES-256-GCM. Telethon v1 and Pyrogram compatibility formats are supported with explicitly lossy field mappings. Every session string is a bearer credential, even when encrypted at rest.\u003Cbr>\n\u003Cbr>\n\u003C\u002Fp>\n\u003Cp>The private \u003Ccode class=\"hljs\">miniproto._native\u003C\u002Fcode> extension provides crypto, MTProto envelope, transport framing, TL, and session hot paths. Public wrappers select capabilities rather than assuming that one successful import implements everything; supported Python\u002F\u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">cryptography\u003C\u002Fspan>\u003C\u002Fcode> paths remain available when a native capability cannot load. Reproducible benchmark commands and result interpretation are documented in \u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fguides\u002Fperformance-and-benchmarks\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Performance and benchmarks\u003C\u002Fa>; no local timing is presented as a universal Telegram throughput claim.\u003C\u002Fp>\n\u003Ch2 id=\"miniproto-versus-mpgram\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"miniproto-versus-mpgram\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#miniproto-versus-mpgram\">\u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">miniproto\u003C\u002Fspan>\u003C\u002Fcode> versus \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">mpgram\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">miniproto\u003C\u002Fspan>\u003C\u002Fcode> is the reusable protocol SDK: transports, authorization, sessions, DC migration, raw invocation, generated bindings, updates, peers, core message helpers, and media primitives. The future \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">mpgram\u003C\u002Fspan>\u003C\u002Fcode> package is the application-framework boundary for routers, filters, decorators, middleware, commands, plugins, dependency\u002Fcontext helpers, conversations, bound message methods, and broad high-level Telegram ergonomics.\u003C\u002Fp>\n\u003Ch2 id=\"documentation-and-project-links\" tabindex=\"-1\">\u003Cspan\n                class=\"header-copy-icon\"\n                role=\"button\"\n                data-slug=\"documentation-and-project-links\"\n              >\n                \u003Csvg>\u003Cpath fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42c-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0a5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.98 2.98 0 0 0 0-4.24a2.98 2.98 0 0 0-4.24 0l-3.53 3.53a2.98 2.98 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0a5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.98 2.98 0 0 0 0 4.24a2.98 2.98 0 0 0 4.24 0l3.53-3.53a2.98 2.98 0 0 0 0-4.24a.973.973 0 0 1 0-1.42\"\u002F>\u003C\u002Fsvg>\n              \u003C\u002Fspan>\u003Ca class=\"header-anchor\" href=\"#documentation-and-project-links\">Documentation and project links\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation\u003C\u002Fa> — authored guides plus searchable generated Python, Telegram, and Rust reference pages.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fedm115.github.io\u002Fminiproto\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation backup\u003C\u002Fa> — in case the main site is down, always reflect the latest changes on the \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-literal\">master\u003C\u002Fspan>\u003C\u002Fcode> branch.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fconcepts\u002Farchitecture\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Architecture\u003C\u002Fa> — ownership boundaries and the Python\u002Fschema\u002FRust execution model.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fproject\u002Fdevelopment\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Development commands\u003C\u002Fa> — schema, docs, quality, tests, benchmarks, builds, and release diagnostics.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fminiproto.edm115.dev\u002Fproject\u002Frelease\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Release guide\u003C\u002Fa> — attested build artifacts, OIDC publishing, immutable releases, and recovery boundaries.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FEDM115\u002Fminiproto\u002Fblob\u002Fcodex\u002Fv1\u002FCONTRIBUTING.md\" target=\"_blank\" rel=\"noopener noreferrer\">Contributing\u003C\u002Fa> — local setup and verification expectations.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FEDM115\u002Fminiproto\u002Fblob\u002Fcodex\u002Fv1\u002FSECURITY.md\" target=\"_blank\" rel=\"noopener noreferrer\">Security policy\u003C\u002Fa> — supported Alpha line, secret handling, and private vulnerability reporting.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FEDM115\u002Fminiproto\u002Fblob\u002Fcodex\u002Fv1\u002FCHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\">Changelog\u003C\u002Fa> — complete \u003Ccode class=\"hljs\">\u003Cspan class=\"hljs-attribute\">0\u003C\u002Fspan>.\u003Cspan class=\"hljs-number\">1\u003C\u002Fspan>.\u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>\u003C\u002Fcode> Alpha capability and limitation summary.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The project takes API-design inspiration from Telethon, Pyrogram and its forks, Grammers, TDLib, GramJS, mtcute, Telegram Web K\u002Ftweb, and Telegram’s official MTProto documentation without copying copyleft implementation code. Telegram controls account permissions, limits, and service behavior; users remain responsible for Telegram’s Terms of Service, API rules, account consent, and lawful data handling.\u003C\u002Fp>\n",1787264275865]