From 8077eb41303b07367d38e8eafa3c0884182274d0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:03:05 +0200 Subject: [PATCH] Update docs --- .gitignore | 2 + Makefile | 28 +- compiler/api/compiler.py | 104 ++++-- compiler/docs/template/bound-methods.rst | 4 - compiler/docs/template/methods.rst | 4 - compiler/docs/template/toctree.txt | 2 + compiler/docs/template/types.rst | 4 - docs/requirements.txt | 4 - docs/source/api/client.rst | 24 -- docs/source/api/decorators.rst | 68 ---- docs/source/api/enums/ChatAction.rst | 8 - docs/source/api/enums/ChatEventAction.rst | 8 - docs/source/api/enums/ChatMemberStatus.rst | 8 - docs/source/api/enums/ChatMembersFilter.rst | 8 - docs/source/api/enums/ChatType.rst | 8 - docs/source/api/enums/MessageEntityType.rst | 8 - docs/source/api/enums/MessageMediaType.rst | 8 - docs/source/api/enums/MessageServiceType.rst | 8 - docs/source/api/enums/MessagesFilter.rst | 8 - docs/source/api/enums/NextCodeType.rst | 8 - docs/source/api/enums/ParseMode.rst | 8 - docs/source/api/enums/PollType.rst | 8 - docs/source/api/enums/SentCodeType.rst | 8 - docs/source/api/enums/UserStatus.rst | 8 - docs/source/api/enums/cleanup.html | 9 - docs/source/api/enums/index.rst | 47 --- docs/source/api/errors/bad-request.rst | 7 - docs/source/api/errors/flood.rst | 7 - docs/source/api/errors/forbidden.rst | 7 - docs/source/api/errors/index.rst | 37 --- .../api/errors/internal-server-error.rst | 7 - docs/source/api/errors/not-acceptable.rst | 7 - docs/source/api/errors/see-other.rst | 7 - docs/source/api/errors/unauthorized.rst | 7 - docs/source/api/filters.rst | 11 - docs/source/api/handlers.rst | 66 ---- docs/source/conf.py | 91 ------ .../client-started-but-nothing-happens.rst | 11 - ...alling-stop-restart-add-remove-handler.rst | 12 - docs/source/faq/how-to-avoid-flood-waits.rst | 23 -- docs/source/faq/how-to-use-webhooks.rst | 9 - docs/source/faq/index.rst | 45 --- ...ing-the-account-to-another-data-center.rst | 10 - docs/source/faq/peer-id-invalid-error.rst | 14 - ...ror-timeouterror-connection-lost-reset.rst | 12 - ...interfaceerror-error-binding-parameter.rst | 13 - ...e3-operationalerror-database-is-locked.rst | 17 - ...e-account-has-been-limited-deactivated.rst | 16 - .../unicodeencodeerror-codec-cant-encode.rst | 7 - ...h-urls-gives-error-webpage-curl-failed.rst | 7 - ...le-clients-at-once-on-the-same-account.rst | 7 - ...same-file-id-across-different-accounts.rst | 6 - ...-ip-addresses-of-telegram-data-centers.rst | 30 -- .../why-is-the-api-key-needed-for-bots.rst | 12 - ...eacting-slowly-in-supergroups-channels.rst | 18 -- docs/source/index.rst | 172 ---------- docs/source/intro/install.rst | 50 --- docs/source/intro/quickstart.rst | 56 ---- docs/source/start/auth.rst | 93 ------ docs/source/start/errors.rst | 101 ------ docs/source/start/examples/bot_keyboards.rst | 68 ---- .../start/examples/callback_queries.rst | 21 -- docs/source/start/examples/echo_bot.rst | 21 -- .../start/examples/get_chat_history.rst | 20 -- .../start/examples/get_chat_members.rst | 22 -- docs/source/start/examples/get_dialogs.rst | 19 -- docs/source/start/examples/hello_world.rst | 20 -- docs/source/start/examples/index.rst | 46 --- docs/source/start/examples/inline_queries.rst | 59 ---- docs/source/start/examples/raw_updates.rst | 18 -- .../source/start/examples/use_inline_bots.rst | 25 -- docs/source/start/examples/welcome_bot.rst | 30 -- docs/source/start/invoking.rst | 110 ------- docs/source/start/setup.rst | 40 --- docs/source/start/updates.rst | 78 ----- docs/source/support.rst | 63 ---- docs/source/topics/advanced-usage.rst | 124 ------- docs/source/topics/client-settings.rst | 46 --- docs/source/topics/create-filters.rst | 109 ------- docs/source/topics/debugging.rst | 122 ------- docs/source/topics/more-on-updates.rst | 226 ------------- docs/source/topics/mtproto-vs-botapi.rst | 112 ------- docs/source/topics/proxy.rst | 34 -- docs/source/topics/scheduling.rst | 65 ---- docs/source/topics/serializing.rst | 56 ---- docs/source/topics/smart-plugins.rst | 306 ------------------ docs/source/topics/speedups.rst | 88 ----- docs/source/topics/storage-engines.rst | 90 ------ docs/source/topics/synchronous.rst | 88 ----- docs/source/topics/test-servers.rst | 41 --- docs/source/topics/text-formatting.rst | 243 -------------- docs/source/topics/use-filters.rst | 114 ------- docs/source/topics/voice-calls.rst | 19 -- 93 files changed, 85 insertions(+), 3865 deletions(-) delete mode 100644 docs/requirements.txt delete mode 100644 docs/source/api/client.rst delete mode 100644 docs/source/api/decorators.rst delete mode 100644 docs/source/api/enums/ChatAction.rst delete mode 100644 docs/source/api/enums/ChatEventAction.rst delete mode 100644 docs/source/api/enums/ChatMemberStatus.rst delete mode 100644 docs/source/api/enums/ChatMembersFilter.rst delete mode 100644 docs/source/api/enums/ChatType.rst delete mode 100644 docs/source/api/enums/MessageEntityType.rst delete mode 100644 docs/source/api/enums/MessageMediaType.rst delete mode 100644 docs/source/api/enums/MessageServiceType.rst delete mode 100644 docs/source/api/enums/MessagesFilter.rst delete mode 100644 docs/source/api/enums/NextCodeType.rst delete mode 100644 docs/source/api/enums/ParseMode.rst delete mode 100644 docs/source/api/enums/PollType.rst delete mode 100644 docs/source/api/enums/SentCodeType.rst delete mode 100644 docs/source/api/enums/UserStatus.rst delete mode 100644 docs/source/api/enums/cleanup.html delete mode 100644 docs/source/api/enums/index.rst delete mode 100644 docs/source/api/errors/bad-request.rst delete mode 100644 docs/source/api/errors/flood.rst delete mode 100644 docs/source/api/errors/forbidden.rst delete mode 100644 docs/source/api/errors/index.rst delete mode 100644 docs/source/api/errors/internal-server-error.rst delete mode 100644 docs/source/api/errors/not-acceptable.rst delete mode 100644 docs/source/api/errors/see-other.rst delete mode 100644 docs/source/api/errors/unauthorized.rst delete mode 100644 docs/source/api/filters.rst delete mode 100644 docs/source/api/handlers.rst delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/faq/client-started-but-nothing-happens.rst delete mode 100644 docs/source/faq/code-hangs-when-calling-stop-restart-add-remove-handler.rst delete mode 100644 docs/source/faq/how-to-avoid-flood-waits.rst delete mode 100644 docs/source/faq/how-to-use-webhooks.rst delete mode 100644 docs/source/faq/index.rst delete mode 100644 docs/source/faq/migrating-the-account-to-another-data-center.rst delete mode 100644 docs/source/faq/peer-id-invalid-error.rst delete mode 100644 docs/source/faq/socket-send-oserror-timeouterror-connection-lost-reset.rst delete mode 100644 docs/source/faq/sqlite3-interfaceerror-error-binding-parameter.rst delete mode 100644 docs/source/faq/sqlite3-operationalerror-database-is-locked.rst delete mode 100644 docs/source/faq/the-account-has-been-limited-deactivated.rst delete mode 100644 docs/source/faq/unicodeencodeerror-codec-cant-encode.rst delete mode 100644 docs/source/faq/uploading-with-urls-gives-error-webpage-curl-failed.rst delete mode 100644 docs/source/faq/using-multiple-clients-at-once-on-the-same-account.rst delete mode 100644 docs/source/faq/using-the-same-file-id-across-different-accounts.rst delete mode 100644 docs/source/faq/what-are-the-ip-addresses-of-telegram-data-centers.rst delete mode 100644 docs/source/faq/why-is-the-api-key-needed-for-bots.rst delete mode 100644 docs/source/faq/why-is-the-client-reacting-slowly-in-supergroups-channels.rst delete mode 100644 docs/source/index.rst delete mode 100644 docs/source/intro/install.rst delete mode 100644 docs/source/intro/quickstart.rst delete mode 100644 docs/source/start/auth.rst delete mode 100644 docs/source/start/errors.rst delete mode 100644 docs/source/start/examples/bot_keyboards.rst delete mode 100644 docs/source/start/examples/callback_queries.rst delete mode 100644 docs/source/start/examples/echo_bot.rst delete mode 100644 docs/source/start/examples/get_chat_history.rst delete mode 100644 docs/source/start/examples/get_chat_members.rst delete mode 100644 docs/source/start/examples/get_dialogs.rst delete mode 100644 docs/source/start/examples/hello_world.rst delete mode 100644 docs/source/start/examples/index.rst delete mode 100644 docs/source/start/examples/inline_queries.rst delete mode 100644 docs/source/start/examples/raw_updates.rst delete mode 100644 docs/source/start/examples/use_inline_bots.rst delete mode 100644 docs/source/start/examples/welcome_bot.rst delete mode 100644 docs/source/start/invoking.rst delete mode 100644 docs/source/start/setup.rst delete mode 100644 docs/source/start/updates.rst delete mode 100644 docs/source/support.rst delete mode 100644 docs/source/topics/advanced-usage.rst delete mode 100644 docs/source/topics/client-settings.rst delete mode 100644 docs/source/topics/create-filters.rst delete mode 100644 docs/source/topics/debugging.rst delete mode 100644 docs/source/topics/more-on-updates.rst delete mode 100644 docs/source/topics/mtproto-vs-botapi.rst delete mode 100644 docs/source/topics/proxy.rst delete mode 100644 docs/source/topics/scheduling.rst delete mode 100644 docs/source/topics/serializing.rst delete mode 100644 docs/source/topics/smart-plugins.rst delete mode 100644 docs/source/topics/speedups.rst delete mode 100644 docs/source/topics/storage-engines.rst delete mode 100644 docs/source/topics/synchronous.rst delete mode 100644 docs/source/topics/test-servers.rst delete mode 100644 docs/source/topics/text-formatting.rst delete mode 100644 docs/source/topics/use-filters.rst delete mode 100644 docs/source/topics/voice-calls.rst diff --git a/.gitignore b/.gitignore index ff9ee02406..7a99a5db85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ # Development +docs *.session config.ini main.py unknown_errors.txt +.DS_Store # Pyrogram generated code pyrogram/errors/exceptions/ diff --git a/Makefile b/Makefile index 0d19832945..81dfe6c901 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,33 @@ VENV := venv PYTHON := $(VENV)/bin/python +HOST = $(shell ifconfig | grep "inet " | tail -1 | cut -d\ -f2) RM := rm -rf -.PHONY: venv build docs +.PHONY: venv clean-build clean-api clean api build venv: $(RM) $(VENV) python3 -m venv $(VENV) $(PYTHON) -m pip install -U pip wheel setuptools - $(PYTHON) -m pip install -U -r requirements.txt -r dev-requirements.txt -r docs/requirements.txt + $(PYTHON) -m pip install -U -r requirements.txt -r dev-requirements.txt @echo "Created venv with $$($(PYTHON) --version)" clean-build: $(RM) *.egg-info build dist -clean-docs: - $(RM) docs/build - $(RM) docs/source/api/bound-methods docs/source/api/methods docs/source/api/types docs/source/telegram - clean-api: $(RM) pyrogram/errors/exceptions pyrogram/raw/all.py pyrogram/raw/base pyrogram/raw/functions pyrogram/raw/types clean: make clean-build - make clean-docs make clean-api api: cd compiler/api && ../../$(PYTHON) compiler.py cd compiler/errors && ../../$(PYTHON) compiler.py -docs-live: - make clean-docs - cd compiler/docs && ../../$(PYTHON) compiler.py - $(RM) docs/source/telegram - $(VENV)/bin/sphinx-autobuild \ - --host $(shell ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\ -f2) \ - --watch pyrogram --watch docs/resources \ - -b html "docs/source" "docs/build/html" -j auto - -docs: - make clean-docs - cd compiler/docs && ../../$(PYTHON) compiler.py - $(VENV)/bin/sphinx-build \ - -b html "docs/source" "docs/build/html" -j auto - build: - make clean-build - make clean-api + make clean $(PYTHON) setup.py sdist $(PYTHON) setup.py bdist_wheel \ No newline at end of file diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index c5372bff75..c29b7ed87f 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import json import os import re import shutil @@ -59,6 +60,16 @@ namespaces_to_constructors = {} namespaces_to_functions = {} +try: + with open("docs.json") as f: + docs = json.load(f) +except FileNotFoundError: + docs = { + "type": {}, + "constructor": {}, + "method": {} + } + class Combinator(NamedTuple): section: str @@ -149,7 +160,7 @@ def remove_whitespaces(source: str) -> str: return "\n".join(lines) -def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool = False): +def get_docstring_arg_type(t: str): if t in CORE_TYPES: if t == "long": return "``int`` ``64-bit``" @@ -167,9 +178,9 @@ def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool elif t == "TLObject" or t == "X": return "Any object from :obj:`~pyrogram.raw.types`" elif t == "!X": - return "Any method from :obj:`~pyrogram.raw.functions`" + return "Any function from :obj:`~pyrogram.raw.functions`" elif t.lower().startswith("vector"): - return "List of " + get_docstring_arg_type(t.split("<", 1)[1][:-1], True) + return "List of " + get_docstring_arg_type(t.split("<", 1)[1][:-1]) else: return f":obj:`{t} `" @@ -183,10 +194,7 @@ def get_references(t: str, kind: str): raise ValueError("Invalid kind") if t: - return "\n ".join( - f"- :obj:`{i} `" - for i in t - ), len(t) + return "\n ".join(t), len(t) return None, 0 @@ -315,17 +323,33 @@ def start(format: bool = False): constructors = sorted(types_to_constructors[qualtype]) constr_count = len(constructors) - items = "\n ".join([f"- :obj:`{c} `" for c in constructors]) + items = "\n ".join([f"{c}" for c in constructors]) + + type_docs = docs["type"].get(qualtype, None) + + if type_docs: + type_docs = type_docs["desc"] + else: + type_docs = "Telegram API base type." - docstring = f"This base type has {constr_count} constructor{'s' if constr_count > 1 else ''} available.\n\n" - docstring += f" Constructors:\n .. hlist::\n :columns: 2\n\n {items}" + docstring = type_docs + + docstring += f"\n\n Constructors:\n" \ + f" This base type has {constr_count} constructor{'s' if constr_count > 1 else ''} available.\n\n" \ + f" .. currentmodule:: pyrogram.raw.types\n\n" \ + f" .. autosummary::\n" \ + f" :nosignatures:\n\n" \ + f" {items}" references, ref_count = get_references(qualtype, "types") if references: - docstring += f"\n\n See Also:\n This object can be returned by " \ - f"{ref_count} method{'s' if ref_count > 1 else ''}:" \ - f"\n\n .. hlist::\n :columns: 2\n\n " + references + docstring += f"\n\n Functions:\n This object can be returned by " \ + f"{ref_count} function{'s' if ref_count > 1 else ''}.\n\n" \ + f" .. currentmodule:: pyrogram.raw.functions\n\n" \ + f" .. autosummary::\n" \ + f" :nosignatures:\n\n" \ + f" " + references with open(dir_path / f"{snake(module)}.py", "w") as f: f.write( @@ -359,41 +383,67 @@ def start(format: bool = False): docstring = "" docstring_args = [] + if c.section == "functions": + combinator_docs = docs["method"] + else: + combinator_docs = docs["constructor"] + for i, arg in enumerate(sorted_args): arg_name, arg_type = arg is_optional = FLAGS_RE.match(arg_type) flag_number = is_optional.group(1) if is_optional else -1 arg_type = arg_type.split("?")[-1] + arg_docs = combinator_docs.get(c.qualname, None) + + if arg_docs: + arg_docs = arg_docs["params"].get(arg_name, "N/A") + else: + arg_docs = "N/A" + docstring_args.append( - "{}{}: {}".format( + "{} ({}{}):\n {}\n".format( arg_name, - " (optional)".format(flag_number) if is_optional else "", - get_docstring_arg_type(arg_type, is_pyrogram_type=c.namespace == "pyrogram") + get_docstring_arg_type(arg_type), + ", *optional*".format(flag_number) if is_optional else "", + arg_docs ) ) if c.section == "types": - docstring += f"This object is a constructor of the base type :obj:`~pyrogram.raw.base.{c.qualtype}`.\n\n" - else: - docstring += f"Telegram API method.\n\n" + constructor_docs = docs["constructor"].get(c.qualname, None) - docstring += f" Details:\n - Layer: ``{layer}``\n - ID: ``{c.id[2:].upper()}``\n\n" + if constructor_docs: + constructor_docs = constructor_docs["desc"] + else: + constructor_docs = "Telegram API type." - if docstring_args: - docstring += " Parameters:\n " + "\n ".join(docstring_args) + docstring += constructor_docs + "\n" + docstring += f"\n Constructor of :obj:`~pyrogram.raw.base.{c.qualtype}`." else: - docstring += " **No parameters required.**" + function_docs = docs["method"].get(c.qualname, None) + + if function_docs: + docstring += function_docs["desc"] + "\n" + else: + docstring += f"Telegram API function." + + docstring += f"\n\n Details:\n - Layer: ``{layer}``\n - ID: ``{c.id[2:].upper()}``\n\n" + docstring += f" Parameters:\n " + \ + (f"\n ".join(docstring_args) if docstring_args else "No parameters required.\n") if c.section == "functions": - docstring += "\n\n Returns:\n " + get_docstring_arg_type(c.qualtype) + docstring += "\n Returns:\n " + get_docstring_arg_type(c.qualtype) else: references, count = get_references(c.qualname, "constructors") if references: - docstring += f"\n\n See Also:\n This object can be returned by " \ - f"{count} method{'s' if count > 1 else ''}:" \ - f"\n\n .. hlist::\n :columns: 2\n\n " + references + docstring += f"\n Functions:\n This object can be returned by " \ + f"{count} function{'s' if count > 1 else ''}.\n\n" \ + f" .. currentmodule:: pyrogram.raw.functions\n\n" \ + f" .. autosummary::\n" \ + f" :nosignatures:\n\n" \ + f" " + references write_types = read_types = "" if c.has_flags else "# No flags\n " diff --git a/compiler/docs/template/bound-methods.rst b/compiler/docs/template/bound-methods.rst index 33261d42b2..1e16e32ce9 100644 --- a/compiler/docs/template/bound-methods.rst +++ b/compiler/docs/template/bound-methods.rst @@ -19,10 +19,6 @@ some of the required arguments. app.run() -.. contents:: Contents - :backlinks: none - :local: - ----- .. currentmodule:: pyrogram.types diff --git a/compiler/docs/template/methods.rst b/compiler/docs/template/methods.rst index 1620350de8..f76e249def 100644 --- a/compiler/docs/template/methods.rst +++ b/compiler/docs/template/methods.rst @@ -14,10 +14,6 @@ the main package directly. with app: app.send_message("me", "hi") -.. contents:: Contents - :backlinks: none - :local: - ----- .. currentmodule:: pyrogram.Client diff --git a/compiler/docs/template/toctree.txt b/compiler/docs/template/toctree.txt index 717276c40e..7a36e4a592 100644 --- a/compiler/docs/template/toctree.txt +++ b/compiler/docs/template/toctree.txt @@ -4,4 +4,6 @@ .. module:: {module} .. toctree:: + :titlesonly: + {entities} \ No newline at end of file diff --git a/compiler/docs/template/types.rst b/compiler/docs/template/types.rst index 2011a61100..e404ad4cdf 100644 --- a/compiler/docs/template/types.rst +++ b/compiler/docs/template/types.rst @@ -17,10 +17,6 @@ are only returned by other methods. You also don't need to import them, unless y To tell whether a field is set or not, do a simple boolean check: ``if message.photo: ...``. -.. contents:: Contents - :backlinks: none - :local: - ----- .. currentmodule:: pyrogram.types diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 7283c8ba69..0000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -sphinx -sphinx_rtd_theme==1.0.0 -sphinx_copybutton -sphinx-autobuild \ No newline at end of file diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst deleted file mode 100644 index 3db28693dc..0000000000 --- a/docs/source/api/client.rst +++ /dev/null @@ -1,24 +0,0 @@ -Pyrogram Client -=============== - -You have entered the API Reference section where you can find detailed information about Pyrogram's API. The main Client -class, all available methods and types, filters, handlers, decorators and bound-methods detailed descriptions can be -found starting from this page. - -This page is about the Client class, which exposes high-level methods for an easy access to the API. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - with app: - app.send_message("me", "Hi!") - ------ - -Details -------- - -.. autoclass:: pyrogram.Client() diff --git a/docs/source/api/decorators.rst b/docs/source/api/decorators.rst deleted file mode 100644 index 2e7a04f263..0000000000 --- a/docs/source/api/decorators.rst +++ /dev/null @@ -1,68 +0,0 @@ -Decorators -========== - -Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to -:doc:`Handlers `; they do so by instantiating the correct handler and calling -:meth:`~pyrogram.Client.add_handler` automatically. All you need to do is adding the decorators on top of your -functions. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - @app.on_message() - def log(client, message): - print(message) - - - app.run() - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -.. currentmodule:: pyrogram - -Index ------ - -.. hlist:: - :columns: 3 - - - :meth:`~Client.on_message` - - :meth:`~Client.on_edited_message` - - :meth:`~Client.on_callback_query` - - :meth:`~Client.on_inline_query` - - :meth:`~Client.on_chosen_inline_result` - - :meth:`~Client.on_chat_member_updated` - - :meth:`~Client.on_chat_join_request` - - :meth:`~Client.on_deleted_messages` - - :meth:`~Client.on_user_status` - - :meth:`~Client.on_poll` - - :meth:`~Client.on_disconnect` - - :meth:`~Client.on_raw_update` - ------ - -Details -------- - -.. Decorators -.. autodecorator:: pyrogram.Client.on_message() -.. autodecorator:: pyrogram.Client.on_edited_message() -.. autodecorator:: pyrogram.Client.on_callback_query() -.. autodecorator:: pyrogram.Client.on_inline_query() -.. autodecorator:: pyrogram.Client.on_chosen_inline_result() -.. autodecorator:: pyrogram.Client.on_chat_member_updated() -.. autodecorator:: pyrogram.Client.on_chat_join_request() -.. autodecorator:: pyrogram.Client.on_deleted_messages() -.. autodecorator:: pyrogram.Client.on_user_status() -.. autodecorator:: pyrogram.Client.on_poll() -.. autodecorator:: pyrogram.Client.on_disconnect() -.. autodecorator:: pyrogram.Client.on_raw_update() diff --git a/docs/source/api/enums/ChatAction.rst b/docs/source/api/enums/ChatAction.rst deleted file mode 100644 index b66df5fd73..0000000000 --- a/docs/source/api/enums/ChatAction.rst +++ /dev/null @@ -1,8 +0,0 @@ -ChatAction -========== - -.. autoclass:: pyrogram.enums.ChatAction() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/ChatEventAction.rst b/docs/source/api/enums/ChatEventAction.rst deleted file mode 100644 index 0403e781db..0000000000 --- a/docs/source/api/enums/ChatEventAction.rst +++ /dev/null @@ -1,8 +0,0 @@ -ChatEventAction -=============== - -.. autoclass:: pyrogram.enums.ChatEventAction() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/ChatMemberStatus.rst b/docs/source/api/enums/ChatMemberStatus.rst deleted file mode 100644 index bff23eda66..0000000000 --- a/docs/source/api/enums/ChatMemberStatus.rst +++ /dev/null @@ -1,8 +0,0 @@ -ChatMemberStatus -================ - -.. autoclass:: pyrogram.enums.ChatMemberStatus() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/ChatMembersFilter.rst b/docs/source/api/enums/ChatMembersFilter.rst deleted file mode 100644 index 5a970ffc6e..0000000000 --- a/docs/source/api/enums/ChatMembersFilter.rst +++ /dev/null @@ -1,8 +0,0 @@ -ChatMembersFilter -================= - -.. autoclass:: pyrogram.enums.ChatMembersFilter() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/ChatType.rst b/docs/source/api/enums/ChatType.rst deleted file mode 100644 index dd653055fa..0000000000 --- a/docs/source/api/enums/ChatType.rst +++ /dev/null @@ -1,8 +0,0 @@ -ChatType -======== - -.. autoclass:: pyrogram.enums.ChatType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/MessageEntityType.rst b/docs/source/api/enums/MessageEntityType.rst deleted file mode 100644 index c7a8965f12..0000000000 --- a/docs/source/api/enums/MessageEntityType.rst +++ /dev/null @@ -1,8 +0,0 @@ -MessageEntityType -================= - -.. autoclass:: pyrogram.enums.MessageEntityType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/MessageMediaType.rst b/docs/source/api/enums/MessageMediaType.rst deleted file mode 100644 index 04e439d20e..0000000000 --- a/docs/source/api/enums/MessageMediaType.rst +++ /dev/null @@ -1,8 +0,0 @@ -MessageMediaType -================ - -.. autoclass:: pyrogram.enums.MessageMediaType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/MessageServiceType.rst b/docs/source/api/enums/MessageServiceType.rst deleted file mode 100644 index 2de56818d8..0000000000 --- a/docs/source/api/enums/MessageServiceType.rst +++ /dev/null @@ -1,8 +0,0 @@ -MessageServiceType -================== - -.. autoclass:: pyrogram.enums.MessageServiceType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/MessagesFilter.rst b/docs/source/api/enums/MessagesFilter.rst deleted file mode 100644 index 090907076a..0000000000 --- a/docs/source/api/enums/MessagesFilter.rst +++ /dev/null @@ -1,8 +0,0 @@ -MessagesFilter -============== - -.. autoclass:: pyrogram.enums.MessagesFilter() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/NextCodeType.rst b/docs/source/api/enums/NextCodeType.rst deleted file mode 100644 index 46164e47d6..0000000000 --- a/docs/source/api/enums/NextCodeType.rst +++ /dev/null @@ -1,8 +0,0 @@ -NextCodeType -============ - -.. autoclass:: pyrogram.enums.NextCodeType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/ParseMode.rst b/docs/source/api/enums/ParseMode.rst deleted file mode 100644 index 1bcc74da04..0000000000 --- a/docs/source/api/enums/ParseMode.rst +++ /dev/null @@ -1,8 +0,0 @@ -ParseMode -========= - -.. autoclass:: pyrogram.enums.ParseMode() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/PollType.rst b/docs/source/api/enums/PollType.rst deleted file mode 100644 index d00f9ce8a8..0000000000 --- a/docs/source/api/enums/PollType.rst +++ /dev/null @@ -1,8 +0,0 @@ -PollType -======== - -.. autoclass:: pyrogram.enums.PollType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/SentCodeType.rst b/docs/source/api/enums/SentCodeType.rst deleted file mode 100644 index d738b195b1..0000000000 --- a/docs/source/api/enums/SentCodeType.rst +++ /dev/null @@ -1,8 +0,0 @@ -SentCodeType -============ - -.. autoclass:: pyrogram.enums.SentCodeType() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/UserStatus.rst b/docs/source/api/enums/UserStatus.rst deleted file mode 100644 index c9a77e1bf9..0000000000 --- a/docs/source/api/enums/UserStatus.rst +++ /dev/null @@ -1,8 +0,0 @@ -UserStatus -========== - -.. autoclass:: pyrogram.enums.UserStatus() - :members: - -.. raw:: html - :file: ./cleanup.html \ No newline at end of file diff --git a/docs/source/api/enums/cleanup.html b/docs/source/api/enums/cleanup.html deleted file mode 100644 index bb9db7801a..0000000000 --- a/docs/source/api/enums/cleanup.html +++ /dev/null @@ -1,9 +0,0 @@ - \ No newline at end of file diff --git a/docs/source/api/enums/index.rst b/docs/source/api/enums/index.rst deleted file mode 100644 index bd9f8b1da7..0000000000 --- a/docs/source/api/enums/index.rst +++ /dev/null @@ -1,47 +0,0 @@ -Enumerations -============ - -This page is about Pyrogram enumerations. -Enumerations are types that hold a group of related values to be used whenever a constant value is required. -They will help you deal with those values in a type-safe way and also enable code completion so that you can be sure -to apply only a valid value among the expected ones. - ------ - -.. currentmodule:: pyrogram.enums - -.. autosummary:: - :nosignatures: - - ChatAction - ChatEventAction - ChatMemberStatus - ChatMembersFilter - ChatType - MessageEntityType - MessageMediaType - MessageServiceType - MessagesFilter - ParseMode - PollType - SentCodeType - NextCodeType - UserStatus - -.. toctree:: - :hidden: - - ChatAction - ChatEventAction - ChatMemberStatus - ChatMembersFilter - ChatType - MessageEntityType - MessageMediaType - MessageServiceType - MessagesFilter - ParseMode - PollType - SentCodeType - NextCodeType - UserStatus \ No newline at end of file diff --git a/docs/source/api/errors/bad-request.rst b/docs/source/api/errors/bad-request.rst deleted file mode 100644 index ab13fdabb2..0000000000 --- a/docs/source/api/errors/bad-request.rst +++ /dev/null @@ -1,7 +0,0 @@ -400 - BadRequest ----------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/400_BAD_REQUEST.tsv - :delim: tab - :header-rows: 1 diff --git a/docs/source/api/errors/flood.rst b/docs/source/api/errors/flood.rst deleted file mode 100644 index e01e012274..0000000000 --- a/docs/source/api/errors/flood.rst +++ /dev/null @@ -1,7 +0,0 @@ -420 - Flood ------------ - -.. csv-table:: - :file: ../../../../compiler/errors/source/420_FLOOD.tsv - :delim: tab - :header-rows: 1 \ No newline at end of file diff --git a/docs/source/api/errors/forbidden.rst b/docs/source/api/errors/forbidden.rst deleted file mode 100644 index c2a8dcb80b..0000000000 --- a/docs/source/api/errors/forbidden.rst +++ /dev/null @@ -1,7 +0,0 @@ -403 - Forbidden ---------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/403_FORBIDDEN.tsv - :delim: tab - :header-rows: 1 \ No newline at end of file diff --git a/docs/source/api/errors/index.rst b/docs/source/api/errors/index.rst deleted file mode 100644 index be2b80d46a..0000000000 --- a/docs/source/api/errors/index.rst +++ /dev/null @@ -1,37 +0,0 @@ -RPC Errors -========== - -All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.errors``. -The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram -follow the usual *PascalCase* convention. - -.. code-block:: python - - from pyrogram.errors import FloodWait - - try: - ... - except FloodWait as e: - ... - -.. hlist:: - :columns: 1 - - - :doc:`see-other` - - :doc:`bad-request` - - :doc:`unauthorized` - - :doc:`forbidden` - - :doc:`not-acceptable` - - :doc:`flood` - - :doc:`internal-server-error` - -.. toctree:: - :hidden: - - see-other - bad-request - unauthorized - forbidden - not-acceptable - flood - internal-server-error \ No newline at end of file diff --git a/docs/source/api/errors/internal-server-error.rst b/docs/source/api/errors/internal-server-error.rst deleted file mode 100644 index 996d77eba5..0000000000 --- a/docs/source/api/errors/internal-server-error.rst +++ /dev/null @@ -1,7 +0,0 @@ -500 - InternalServerError -------------------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv - :delim: tab - :header-rows: 1 \ No newline at end of file diff --git a/docs/source/api/errors/not-acceptable.rst b/docs/source/api/errors/not-acceptable.rst deleted file mode 100644 index 79cfa8bcaf..0000000000 --- a/docs/source/api/errors/not-acceptable.rst +++ /dev/null @@ -1,7 +0,0 @@ -406 - NotAcceptable -------------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/406_NOT_ACCEPTABLE.tsv - :delim: tab - :header-rows: 1 \ No newline at end of file diff --git a/docs/source/api/errors/see-other.rst b/docs/source/api/errors/see-other.rst deleted file mode 100644 index 629b955764..0000000000 --- a/docs/source/api/errors/see-other.rst +++ /dev/null @@ -1,7 +0,0 @@ -303 - SeeOther --------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/303_SEE_OTHER.tsv - :delim: tab - :header-rows: 1 \ No newline at end of file diff --git a/docs/source/api/errors/unauthorized.rst b/docs/source/api/errors/unauthorized.rst deleted file mode 100644 index c56abeecc3..0000000000 --- a/docs/source/api/errors/unauthorized.rst +++ /dev/null @@ -1,7 +0,0 @@ -401 - Unauthorized ------------------- - -.. csv-table:: - :file: ../../../../compiler/errors/source/401_UNAUTHORIZED.tsv - :delim: tab - :header-rows: 1 diff --git a/docs/source/api/filters.rst b/docs/source/api/filters.rst deleted file mode 100644 index eb3c9522b3..0000000000 --- a/docs/source/api/filters.rst +++ /dev/null @@ -1,11 +0,0 @@ -Update Filters -============== - -Filters are objects that can be used to filter the content of incoming updates. -:doc:`Read more about how filters work <../topics/use-filters>`. - -Details -------- - -.. automodule:: pyrogram.filters - :members: diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst deleted file mode 100644 index 8a8ac71477..0000000000 --- a/docs/source/api/handlers.rst +++ /dev/null @@ -1,66 +0,0 @@ -Update Handlers -=============== - -Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions. -For a much more convenient way of registering callback functions have a look at :doc:`Decorators ` instead. - -.. code-block:: python - - from pyrogram import Client - from pyrogram.handlers import MessageHandler - - app = Client("my_account") - - - def dump(client, message): - print(message) - - - app.add_handler(MessageHandler(dump)) - - app.run() - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -.. currentmodule:: pyrogram.handlers - -Index ------ - -.. hlist:: - :columns: 3 - - - :class:`MessageHandler` - - :class:`EditedMessageHandler` - - :class:`DeletedMessagesHandler` - - :class:`CallbackQueryHandler` - - :class:`InlineQueryHandler` - - :class:`ChosenInlineResultHandler` - - :class:`ChatMemberUpdatedHandler` - - :class:`UserStatusHandler` - - :class:`PollHandler` - - :class:`DisconnectHandler` - - :class:`RawUpdateHandler` - ------ - -Details -------- - -.. Handlers -.. autoclass:: MessageHandler() -.. autoclass:: EditedMessageHandler() -.. autoclass:: DeletedMessagesHandler() -.. autoclass:: CallbackQueryHandler() -.. autoclass:: InlineQueryHandler() -.. autoclass:: ChosenInlineResultHandler() -.. autoclass:: ChatMemberUpdatedHandler() -.. autoclass:: UserStatusHandler() -.. autoclass:: PollHandler() -.. autoclass:: DisconnectHandler() -.. autoclass:: RawUpdateHandler() diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 3071cdc17b..0000000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,91 +0,0 @@ -# Pyrogram - Telegram MTProto API Client Library for Python -# Copyright (C) 2017-present Dan -# -# This file is part of Pyrogram. -# -# Pyrogram is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Pyrogram is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with Pyrogram. If not, see . - -import os -import sys - -sys.path.insert(0, os.path.abspath("../..")) - -from pyrogram import __version__ - -from pygments.styles.friendly import FriendlyStyle - -FriendlyStyle.background_color = "#f3f2f1" - -project = "Pyrogram" -copyright = f"2017-present, Dan" -author = "Dan" - -version = ".".join(__version__.split(".")[:-1]) - -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.napoleon", - "sphinx.ext.autosummary", - "sphinx.ext.intersphinx", - "sphinx_copybutton" -] - -intersphinx_mapping = { - "python": ("https://docs.python.org/3", None) -} - -master_doc = "index" -source_suffix = ".rst" -autodoc_member_order = "bysource" - -templates_path = ["../resources/templates"] -html_copy_source = False - -napoleon_use_rtype = False -napoleon_use_param = False - -pygments_style = "friendly" - -copybutton_prompt_text = "$ " - -suppress_warnings = ["image.not_readable"] - -html_title = "Pyrogram Documentation" -html_theme = "sphinx_rtd_theme" -html_static_path = ["../resources/static"] -html_show_sourcelink = True -html_show_copyright = False -html_theme_options = { - "canonical_url": "https://docs.pyrogram.org/", - "collapse_navigation": True, - "sticky_navigation": False, - "logo_only": True, - "display_version": False, - "style_external_links": True -} - -html_logo = "../resources/static/img/pyrogram.png" -html_favicon = "../resources/static/img/favicon.ico" - -latex_engine = "xelatex" -latex_logo = "../resources/static/img/pyrogram.png" - -latex_elements = { - "pointsize": "12pt", - "fontpkg": r""" - \setmainfont{Open Sans} - \setsansfont{Bitter} - \setmonofont{Ubuntu Mono} - """ -} diff --git a/docs/source/faq/client-started-but-nothing-happens.rst b/docs/source/faq/client-started-but-nothing-happens.rst deleted file mode 100644 index ab85f51832..0000000000 --- a/docs/source/faq/client-started-but-nothing-happens.rst +++ /dev/null @@ -1,11 +0,0 @@ -Client started, but nothing happens -=================================== - -A possible cause might be network issues, either yours or Telegram's. To check this, add the following code at -the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable -network: - -.. code-block:: python - - import logging - logging.basicConfig(level=logging.INFO) \ No newline at end of file diff --git a/docs/source/faq/code-hangs-when-calling-stop-restart-add-remove-handler.rst b/docs/source/faq/code-hangs-when-calling-stop-restart-add-remove-handler.rst deleted file mode 100644 index 37d47a6444..0000000000 --- a/docs/source/faq/code-hangs-when-calling-stop-restart-add-remove-handler.rst +++ /dev/null @@ -1,12 +0,0 @@ -Code hangs when calling stop, restart, add/remove_handler -========================================================= - -You tried to ``.stop()``, ``.restart()``, ``.add_handler()`` or ``.remove_handler()`` inside a running handler, but -that can't be done because the way Pyrogram deals with handlers would make it hang. - -When calling one of the methods above inside an event handler, Pyrogram needs to wait for all running handlers to finish -in order to continue. Since your handler is blocking the execution by waiting for the called method to finish -and since Pyrogram needs to wait for your handler to finish, you are left with a deadlock. - -The solution to this problem is to pass ``block=False`` to such methods so that they return immediately and the actual -code called asynchronously. \ No newline at end of file diff --git a/docs/source/faq/how-to-avoid-flood-waits.rst b/docs/source/faq/how-to-avoid-flood-waits.rst deleted file mode 100644 index 06d1cdc2a9..0000000000 --- a/docs/source/faq/how-to-avoid-flood-waits.rst +++ /dev/null @@ -1,23 +0,0 @@ -How to avoid Flood Waits? -========================= - -Slow things down and make less requests. Moreover, exact limits are unknown and can change anytime based on normal -usages. - -When a flood wait happens the server will tell you how much time to wait before continuing. -The following shows how to catch the exception in your code and wait the required seconds. - -.. code-block:: python - - import asyncio - from pyrogram.errors import FloodWait - - ... - try: - ... # Your code - except FloodWait as e: - await asyncio.sleep(e.value) # Wait "value" seconds before continuing - ... - - -More info about error handling can be found :doc:`here <../start/errors>`. diff --git a/docs/source/faq/how-to-use-webhooks.rst b/docs/source/faq/how-to-use-webhooks.rst deleted file mode 100644 index b0dd4008cd..0000000000 --- a/docs/source/faq/how-to-use-webhooks.rst +++ /dev/null @@ -1,9 +0,0 @@ -How to use webhooks? -==================== - -There is no webhook in Pyrogram, simply because there is no HTTP involved. However, a similar technique is -being used to make receiving updates efficient. - -Pyrogram uses persistent connections via TCP sockets to interact with the server and instead of actively asking for -updates every time (polling), Pyrogram will sit down and wait for the server to send updates by itself the very moment -they are available (server push). diff --git a/docs/source/faq/index.rst b/docs/source/faq/index.rst deleted file mode 100644 index 3d4a00362b..0000000000 --- a/docs/source/faq/index.rst +++ /dev/null @@ -1,45 +0,0 @@ -Frequently Asked Questions -========================== - -This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general. - -**Contents** - -- :doc:`why-is-the-api-key-needed-for-bots` -- :doc:`how-to-use-webhooks` -- :doc:`using-the-same-file-id-across-different-accounts` -- :doc:`using-multiple-clients-at-once-on-the-same-account` -- :doc:`client-started-but-nothing-happens` -- :doc:`what-are-the-ip-addresses-of-telegram-data-centers` -- :doc:`migrating-the-account-to-another-data-center` -- :doc:`why-is-the-client-reacting-slowly-in-supergroups-channels` -- :doc:`peer-id-invalid-error` -- :doc:`code-hangs-when-calling-stop-restart-add-remove-handler` -- :doc:`unicodeencodeerror-codec-cant-encode` -- :doc:`uploading-with-urls-gives-error-webpage-curl-failed` -- :doc:`sqlite3-operationalerror-database-is-locked` -- :doc:`sqlite3-interfaceerror-error-binding-parameter` -- :doc:`socket-send-oserror-timeouterror-connection-lost-reset` -- :doc:`how-to-avoid-flood-waits` -- :doc:`the-account-has-been-limited-deactivated` - -.. toctree:: - :hidden: - - why-is-the-api-key-needed-for-bots - how-to-use-webhooks - using-the-same-file-id-across-different-accounts - using-multiple-clients-at-once-on-the-same-account - client-started-but-nothing-happens - what-are-the-ip-addresses-of-telegram-data-centers - migrating-the-account-to-another-data-center - why-is-the-client-reacting-slowly-in-supergroups-channels - peer-id-invalid-error - code-hangs-when-calling-stop-restart-add-remove-handler - unicodeencodeerror-codec-cant-encode - uploading-with-urls-gives-error-webpage-curl-failed - sqlite3-operationalerror-database-is-locked - sqlite3-interfaceerror-error-binding-parameter - socket-send-oserror-timeouterror-connection-lost-reset - how-to-avoid-flood-waits - the-account-has-been-limited-deactivated \ No newline at end of file diff --git a/docs/source/faq/migrating-the-account-to-another-data-center.rst b/docs/source/faq/migrating-the-account-to-another-data-center.rst deleted file mode 100644 index 7ae76a1e36..0000000000 --- a/docs/source/faq/migrating-the-account-to-another-data-center.rst +++ /dev/null @@ -1,10 +0,0 @@ -Migrating the account to another data center -============================================ - -This question is asked by people who find their account always being connected to one DC (data center), but are -connecting from a place far away, thus resulting in slower interactions when using the API because of the greater -physical distance between the user and the associated DC. - -When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be -created in. It's also up to the server to decide whether to automatically migrate a user in case of prolonged usages -from a distant location. \ No newline at end of file diff --git a/docs/source/faq/peer-id-invalid-error.rst b/docs/source/faq/peer-id-invalid-error.rst deleted file mode 100644 index 197ea8374d..0000000000 --- a/docs/source/faq/peer-id-invalid-error.rst +++ /dev/null @@ -1,14 +0,0 @@ -PEER_ID_INVALID error -===================== - -This error could mean several things: - -- The chat id you tried to use is simply wrong, check it again. -- The chat id refers to a group or channel you are not a member of. -- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``. -- The chat id refers to a user or chat your current session hasn't met yet. - -About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to -contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching -for usernames, meeting them in a common group, having their phone contacts saved, getting a message mentioning them -or obtaining the dialogs list. \ No newline at end of file diff --git a/docs/source/faq/socket-send-oserror-timeouterror-connection-lost-reset.rst b/docs/source/faq/socket-send-oserror-timeouterror-connection-lost-reset.rst deleted file mode 100644 index 85c5065015..0000000000 --- a/docs/source/faq/socket-send-oserror-timeouterror-connection-lost-reset.rst +++ /dev/null @@ -1,12 +0,0 @@ -socket.send(), OSError(), TimeoutError(), Connection lost/reset -=============================================================== - -If you get any of these errors chances are you ended up with a slow or inconsistent network connection. -Another reason could be because you are blocking the event loop for too long. - -You can consider the following: - -- Use Pyrogram asynchronously in its intended way. -- Use shorter non-asynchronous processing loops. -- Use ``asyncio.sleep()`` instead of ``time.sleep()``. -- Use a stable network connection. diff --git a/docs/source/faq/sqlite3-interfaceerror-error-binding-parameter.rst b/docs/source/faq/sqlite3-interfaceerror-error-binding-parameter.rst deleted file mode 100644 index 5d148186b6..0000000000 --- a/docs/source/faq/sqlite3-interfaceerror-error-binding-parameter.rst +++ /dev/null @@ -1,13 +0,0 @@ -sqlite3.InterfaceError: Error binding parameter -=============================================== - -This error occurs when you pass a chat id value of the wrong type when trying to call a method. Most likely, you -accidentally passed the whole user or chat object instead of the id or username. - -.. code-block:: python - - # Wrong. You passed the whole Chat instance - app.send_message(chat, "text") - - # Correct - app.send_message(chat.id, "text") \ No newline at end of file diff --git a/docs/source/faq/sqlite3-operationalerror-database-is-locked.rst b/docs/source/faq/sqlite3-operationalerror-database-is-locked.rst deleted file mode 100644 index b5cb2d8293..0000000000 --- a/docs/source/faq/sqlite3-operationalerror-database-is-locked.rst +++ /dev/null @@ -1,17 +0,0 @@ -sqlite3.OperationalError: database is locked -============================================ - -This error occurs when more than one process is using the same session file, that is, when you run two or more clients -at the same time using the same session name or in case another program has accessed the file. - -For example, it could occur when a background script is still running and you forgot about it. In this case, you either -restart your system or find and kill the process that is locking the database. On Unix based systems, you can try the -following: - -#. ``cd`` into your session file directory. -#. ``fuser my_account.session`` to find the process id. -#. ``kill 1234`` to gracefully stop the process. -#. If the last command doesn't help, use ``kill -9 1234`` instead. - -If you want to run multiple clients on the same account, you must authorize your account (either user or bot) -from the beginning every time, and use different session names for each parallel client you are going to use. \ No newline at end of file diff --git a/docs/source/faq/the-account-has-been-limited-deactivated.rst b/docs/source/faq/the-account-has-been-limited-deactivated.rst deleted file mode 100644 index 79d589eaf8..0000000000 --- a/docs/source/faq/the-account-has-been-limited-deactivated.rst +++ /dev/null @@ -1,16 +0,0 @@ -The account has been limited/deactivated -======================================== - -Pyrogram is a framework that interfaces with Telegram; it is at your commands, meaning it only does what you tell it to -do, the rest is up to you and Telegram (see `Telegram's ToS`_). - -If you found your account being limited/deactivated, it could be due spam/flood/abuse of the API or the usage of certain -virtual/VoIP numbers. - -If you think your account was limited/deactivated by mistake, you can write to recover@telegram.org, contact -`@SpamBot`_ or use `this form`_. - -.. _@SpamBot: https://t.me/spambot -.. _this form: https://telegram.org/support -.. _Telegram's ToS: https://telegram.org/tos - diff --git a/docs/source/faq/unicodeencodeerror-codec-cant-encode.rst b/docs/source/faq/unicodeencodeerror-codec-cant-encode.rst deleted file mode 100644 index a4511ce5d1..0000000000 --- a/docs/source/faq/unicodeencodeerror-codec-cant-encode.rst +++ /dev/null @@ -1,7 +0,0 @@ -UnicodeEncodeError: '...' codec can't encode ... -================================================ - -Where ```` might be *ascii*, *cp932*, *charmap* or anything else other than *utf-8*. This error usually -shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to -your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to -another terminal altogether. diff --git a/docs/source/faq/uploading-with-urls-gives-error-webpage-curl-failed.rst b/docs/source/faq/uploading-with-urls-gives-error-webpage-curl-failed.rst deleted file mode 100644 index 2b7c5a7e9f..0000000000 --- a/docs/source/faq/uploading-with-urls-gives-error-webpage-curl-failed.rst +++ /dev/null @@ -1,7 +0,0 @@ -Uploading with URLs gives error WEBPAGE_CURL_FAILED -=================================================== - -When uploading media files using an URL, the server automatically tries to download the media and uploads it to the -Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the -media file is too large. In such cases, your only option is to download the media yourself and upload it from your -local machine. \ No newline at end of file diff --git a/docs/source/faq/using-multiple-clients-at-once-on-the-same-account.rst b/docs/source/faq/using-multiple-clients-at-once-on-the-same-account.rst deleted file mode 100644 index ab73b29c1d..0000000000 --- a/docs/source/faq/using-multiple-clients-at-once-on-the-same-account.rst +++ /dev/null @@ -1,7 +0,0 @@ -Using multiple clients at once on the same account -================================================== - -Both user and bot accounts are able to run multiple sessions in parallel. However, you must not use the same session -in more than one client at the same time. The correct way to run multiple clients on the same account is by authorizing -your account (either user or bot) from the beginning each time, and use one separate session for each parallel client. - diff --git a/docs/source/faq/using-the-same-file-id-across-different-accounts.rst b/docs/source/faq/using-the-same-file-id-across-different-accounts.rst deleted file mode 100644 index 00305ef12d..0000000000 --- a/docs/source/faq/using-the-same-file-id-across-different-accounts.rst +++ /dev/null @@ -1,6 +0,0 @@ -Using the same file_id across different accounts -================================================ - -Telegram file_id strings are bound to the account which generated them. An attempt in using a foreign file id will -result in errors such as ``[400 MEDIA_EMPTY]``. The only exception are stickers' file ids; you can use them across -different accounts without any problem. \ No newline at end of file diff --git a/docs/source/faq/what-are-the-ip-addresses-of-telegram-data-centers.rst b/docs/source/faq/what-are-the-ip-addresses-of-telegram-data-centers.rst deleted file mode 100644 index c951230ba6..0000000000 --- a/docs/source/faq/what-are-the-ip-addresses-of-telegram-data-centers.rst +++ /dev/null @@ -1,30 +0,0 @@ -What are the IP addresses of Telegram Data Centers? -=================================================== - -Telegram is currently composed by a decentralized, multi-DC infrastructure (currently 5 DCs, each of which can -work independently) spread across different locations worldwide. However, some of the less busy DCs have been lately -dismissed and their IP addresses are now kept as aliases to the nearest one. - -.. csv-table:: Production Environment - :header: ID, Location, IPv4, IPv6 - :widths: auto - :align: center - - DC1, "MIA, Miami FL, USA", ``149.154.175.53``, ``2001:b28:f23d:f001::a`` - DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a`` - DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a`` - DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a`` - DC5, "SIN, Singapore, SG", ``91.108.56.130``, ``2001:b28:f23f:f005::a`` - -.. csv-table:: Test Environment - :header: ID, Location, IPv4, IPv6 - :widths: auto - :align: center - - DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e`` - DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e`` - DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e`` - -.. centered:: More info about the Test Environment can be found :doc:`here <../topics/test-servers>`. - -***** Alias DC \ No newline at end of file diff --git a/docs/source/faq/why-is-the-api-key-needed-for-bots.rst b/docs/source/faq/why-is-the-api-key-needed-for-bots.rst deleted file mode 100644 index 2e062d405d..0000000000 --- a/docs/source/faq/why-is-the-api-key-needed-for-bots.rst +++ /dev/null @@ -1,12 +0,0 @@ -Why is the API key needed for bots? -=================================== - -Requests against the official bot API endpoints are made via JSON/HTTP and are handled by an intermediate server -application that implements the MTProto protocol and uses its own API key to communicate with the MTProto servers. - -.. figure:: //_static/img/mtproto-vs-bot-api.png - :align: center - -Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to -identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone -number only. \ No newline at end of file diff --git a/docs/source/faq/why-is-the-client-reacting-slowly-in-supergroups-channels.rst b/docs/source/faq/why-is-the-client-reacting-slowly-in-supergroups-channels.rst deleted file mode 100644 index 4d19616469..0000000000 --- a/docs/source/faq/why-is-the-client-reacting-slowly-in-supergroups-channels.rst +++ /dev/null @@ -1,18 +0,0 @@ -Why is the client reacting slowly in supergroups/channels? -========================================================== - -Because of how Telegram works internally, every message you receive and send must pass through the creator's DC, and in -the worst case where you, the creator and another member all belong to three different DCs, the other member messages -have to go through from their DC to the creator's DC and finally to your DC. This is applied to each message and member -of a supergroup/channel and the process will inevitably take its time. - -Another reason that makes responses come slowly is that messages are dispatched by priority. Depending on the kind -of member, some users receive messages faster than others and for big and busy supergroups the delay might become -noticeable, especially if you are among the lower end of the priority list: - -1. Creator. -2. Administrators. -3. Bots. -4. Mentioned users. -5. Recent online users. -6. Everyone else. \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index d96223cb13..0000000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,172 +0,0 @@ -Welcome to Pyrogram -=================== - -.. raw:: html - - - -

- Telegram MTProto API Framework for Python - -
- - Homepage - - • - - Development - - • - - Releases - - • - - News - -

- -.. code-block:: python - - from pyrogram import Client, filters - - app = Client("my_account") - - - @app.on_message(filters.private) - async def hello(client, message): - await message.reply("Hello from Pyrogram!") - - - app.run() - -**Pyrogram** is a modern, elegant and asynchronous :doc:`MTProto API ` framework. -It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot identity -(bot API alternative) using Python. - -Support -------- - -If you'd like to support Pyrogram, you can consider: - -- `Become a GitHub sponsor `_. -- `Become a LiberaPay patron `_. -- `Become an OpenCollective backer `_. - -How the Documentation is Organized ----------------------------------- - -Contents are organized into sections composed of self-contained topics which can be all accessed from the sidebar, or by -following them in order using the :guilabel:`Next` button at the end of each page. -You can also switch to Dark or Light theme or leave on Auto (follows system preferences) by using the dedicated button -in the top left corner. - -Here below you can, instead, find a list of the most relevant pages for a quick access. - -First Steps -^^^^^^^^^^^ - -.. hlist:: - :columns: 1 - - - :doc:`Quick Start `: Overview to get you started quickly. - - :doc:`Invoking Methods `: How to call Pyrogram's methods. - - :doc:`Handling Updates `: How to handle Telegram updates. - - :doc:`Error Handling `: How to handle API errors correctly. - -API Reference -^^^^^^^^^^^^^ - -.. hlist:: - :columns: 1 - - - :doc:`Pyrogram Client `: Reference details about the Client class. - - :doc:`Available Methods `: List of available high-level methods. - - :doc:`Available Types `: List of available high-level types. - - :doc:`Enumerations `: List of available enumerations. - - :doc:`Bound Methods `: List of convenient bound methods. - -Meta -^^^^ - -.. hlist:: - :columns: 1 - - - :doc:`Pyrogram FAQ `: Answers to common Pyrogram questions. - - :doc:`Support Pyrogram `: Ways to show your appreciation. - - :doc:`Release Notes `: Release notes for Pyrogram releases. - -.. toctree:: - :hidden: - :caption: Introduction - - intro/quickstart - intro/install - -.. toctree:: - :hidden: - :caption: Getting Started - - start/setup - start/auth - start/invoking - start/updates - start/errors - start/examples/index - -.. toctree:: - :hidden: - :caption: API Reference - - api/client - api/methods/index - api/types/index - api/bound-methods/index - api/enums/index - api/handlers - api/decorators - api/errors/index - api/filters - -.. toctree:: - :hidden: - :caption: Topic Guides - - topics/use-filters - topics/create-filters - topics/more-on-updates - topics/client-settings - topics/speedups - topics/text-formatting - topics/synchronous - topics/smart-plugins - topics/storage-engines - topics/serializing - topics/proxy - topics/scheduling - topics/mtproto-vs-botapi - topics/debugging - topics/test-servers - topics/advanced-usage - topics/voice-calls - -.. toctree:: - :hidden: - :caption: Meta - - faq/index - support - releases/index - -.. toctree:: - :hidden: - :caption: Telegram Raw API - - telegram/functions/index - telegram/types/index - telegram/base/index \ No newline at end of file diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst deleted file mode 100644 index c45c384489..0000000000 --- a/docs/source/intro/install.rst +++ /dev/null @@ -1,50 +0,0 @@ -Install Guide -============= - -Being a modern Python framework, Pyrogram requires an up to date version of Python to be installed in your system. -We recommend using the latest versions of both Python 3 and pip. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Install Pyrogram ----------------- - -- The easiest way to install and upgrade Pyrogram to its latest stable version is by using **pip**: - - .. code-block:: text - - $ pip3 install -U pyrogram - -- or, with :doc:`TgCrypto <../topics/speedups>` as extra requirement (recommended): - - .. code-block:: text - - $ pip3 install -U pyrogram tgcrypto - -Bleeding Edge -------------- - -You can install the development version from the git ``master`` branch using this command: - -.. code-block:: text - - $ pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip - -Verifying ---------- - -To verify that Pyrogram is correctly installed, open a Python shell and import it. -If no error shows up you are good to go. - -.. parsed-literal:: - - >>> import pyrogram - >>> pyrogram.__version__ - 'x.y.z' - -.. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/intro/quickstart.rst b/docs/source/intro/quickstart.rst deleted file mode 100644 index 29c355e7c7..0000000000 --- a/docs/source/intro/quickstart.rst +++ /dev/null @@ -1,56 +0,0 @@ -Quick Start -=========== - -The next few steps serve as a quick start to see Pyrogram in action as fast as possible. - -Get Pyrogram Real Fast ----------------------- - -.. admonition :: Cloud Credits - :class: tip - - If you need a cloud server to host your applications, try Hetzner Cloud. You can sign up with - `this link `_ to get €20 in cloud credits. - -1. Install Pyrogram with ``pip3 install -U pyrogram``. - -2. Get your own Telegram API key from https://my.telegram.org/apps. - -3. Open the text editor of your choice and paste the following: - - .. code-block:: python - - import asyncio - from pyrogram import Client - - api_id = 12345 - api_hash = "0123456789abcdef0123456789abcdef" - - - async def main(): - async with Client("my_account", api_id, api_hash) as app: - await app.send_message("me", "Greetings from **Pyrogram**!") - - - asyncio.run(main()) - -4. Replace *api_id* and *api_hash* values with your own. - -5. Save the file as ``hello.py``. - -6. Run the script with ``python3 hello.py`` - -7. Follow the instructions on your terminal to login. - -8. Watch Pyrogram send a message to yourself. - -Enjoy the API -------------- - -That was just a quick overview. In the next few pages of the introduction, we'll take a much more in-depth look of what -we have just done above. - -If you are feeling eager to continue you can take a shortcut to :doc:`../start/invoking` and come back -later to learn some more details. - -.. _community: https://t.me/Pyrogram diff --git a/docs/source/start/auth.rst b/docs/source/start/auth.rst deleted file mode 100644 index ba28ac69b7..0000000000 --- a/docs/source/start/auth.rst +++ /dev/null @@ -1,93 +0,0 @@ -Authorization -============= - -Once a :doc:`project is set up `, you will still have to follow a few steps before you can actually use Pyrogram to make -API calls. This section provides all the information you need in order to authorize yourself as user or bot. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -User Authorization ------------------- - -In order to use the API, Telegram requires that users be authorized via their phone numbers. -Pyrogram automatically manages this process, all you need to do is create an instance of the -:class:`~pyrogram.Client` class by passing to it a ``name`` of your choice (e.g.: "my_account") and call -the :meth:`~pyrogram.Client.run` method: - -.. code-block:: python - - from pyrogram import Client - - api_id = 12345 - api_hash = "0123456789abcdef0123456789abcdef" - - app = Client("my_account", api_id=api_id, api_hash=api_hash) - - app.run() - -This starts an interactive shell asking you to input your **phone number**, including your `Country Code`_ (the plus -``+`` and minus ``-`` symbols can be omitted) and the **phone code** you will receive in your devices that are already -authorized or via SMS: - -.. code-block:: text - - Enter phone number: +1-123-456-7890 - Is "+1-123-456-7890" correct? (y/n): y - Enter phone code: 12345 - Logged in successfully - -After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram to -execute API calls with your identity. This file is personal and will be loaded again when you restart your app. -You can now remove the api_id and api_hash values from the code as they are not needed anymore. - -.. note:: - - The code above does nothing except asking for credentials and keeping the client online, hit :guilabel:`CTRL+C` now - to stop your application and keep reading. - -Bot Authorization ------------------ - -Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by -the `Bot Father`_. Bot tokens replace the users' phone numbers only — you still need to -:doc:`configure a Telegram API key <../start/setup>` with Pyrogram, even when using bots. - -The authorization process is automatically managed. All you need to do is choose a ``name`` (can be anything, -usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named -after the session name, which will be ``my_bot.session`` for the example below. - -.. code-block:: python - - from pyrogram import Client - - api_id = 12345 - api_hash = "0123456789abcdef0123456789abcdef" - bot_token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" - - app = Client( - "my_bot", - api_id=api_id, api_hash=api_hash, - bot_token=bot_token - ) - - app.run() - -.. _Country Code: https://en.wikipedia.org/wiki/List_of_country_calling_codes -.. _Bot Father: https://t.me/botfather - -.. note:: - - The API key (api_id and api_hash) and the bot_token are not required anymore after a successful authorization. - This means you can now simply use the following: - - .. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - app.run() \ No newline at end of file diff --git a/docs/source/start/errors.rst b/docs/source/start/errors.rst deleted file mode 100644 index 402fea8b7c..0000000000 --- a/docs/source/start/errors.rst +++ /dev/null @@ -1,101 +0,0 @@ -Error Handling -============== - -Errors can be correctly handled with ``try...except`` blocks in order to control the behaviour of your application. -Pyrogram errors all live inside the ``errors`` package: - -.. code-block:: python - - from pyrogram import errors - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -RPCError --------- - -The father of all errors is named ``RPCError`` and is able to catch all Telegram API related errors. -This error is raised every time a method call against Telegram's API was unsuccessful. - -.. code-block:: python - - from pyrogram.errors import RPCError - -.. warning:: - - Avoid catching this error everywhere, especially when no feedback is given (i.e. by logging/printing the full error - traceback), because it makes it impossible to understand what went wrong. - -Error Categories ----------------- - -The ``RPCError`` packs together all the possible errors Telegram could raise, but to make things tidier, Pyrogram -provides categories of errors, which are named after the common HTTP errors and are subclass-ed from the ``RPCError``: - -.. code-block:: python - - from pyrogram.errors import BadRequest, Forbidden, ... - -- :doc:`303 - SeeOther <../api/errors/see-other>` -- :doc:`400 - BadRequest <../api/errors/bad-request>` -- :doc:`401 - Unauthorized <../api/errors/unauthorized>` -- :doc:`403 - Forbidden <../api/errors/forbidden>` -- :doc:`406 - NotAcceptable <../api/errors/not-acceptable>` -- :doc:`420 - Flood <../api/errors/flood>` -- :doc:`500 - InternalServerError <../api/errors/internal-server-error>` - -Single Errors -------------- - -For a fine-grained control over every single error, Pyrogram does also expose errors that deal each with a specific -issue. For example: - -.. code-block:: python - - from pyrogram.errors import FloodWait - -These errors subclass directly from the category of errors they belong to, which in turn subclass from the father -``RPCError``, thus building a class of error hierarchy such as this: - -- RPCError - - BadRequest - - ``MessageEmpty`` - - ``UsernameOccupied`` - - ``...`` - - InternalServerError - - ``RpcCallFail`` - - ``InterDcCallError`` - - ``...`` - - ``...`` - -.. _Errors: api/errors - -Unknown Errors --------------- - -In case Pyrogram does not know anything about a specific error yet, it raises a generic error from its known category, -for example, an unknown error with error code ``400``, will be raised as a ``BadRequest``. This way you can catch the -whole category of errors and be sure to also handle these unknown errors. - -Errors with Values ------------------- - -Exception objects may also contain some informative values. For example, ``FloodWait`` holds the amount of seconds you -have to wait before you can try again, some other errors contain the DC number on which the request must be repeated on. -The value is stored in the ``value`` attribute of the exception object: - -.. code-block:: python - - import asyncio - from pyrogram.errors import FloodWait - - ... - try: - ... # Your code - except FloodWait as e: - await asyncio.sleep(e.value) # Wait N seconds before continuing - ... \ No newline at end of file diff --git a/docs/source/start/examples/bot_keyboards.rst b/docs/source/start/examples/bot_keyboards.rst deleted file mode 100644 index b774a80e7e..0000000000 --- a/docs/source/start/examples/bot_keyboards.rst +++ /dev/null @@ -1,68 +0,0 @@ -bot_keyboards -============= - -This example will show you how to send normal and inline keyboards (as bot). - -You must log-in as a regular bot in order to send keyboards (use the token from @BotFather). -Any attempt in sending keyboards with a user account will be simply ignored by the server. - -send_message() is used as example, but a keyboard can be sent with any other send_* methods, -like send_audio(), send_document(), send_location(), etc... - -.. code-block:: python - - from pyrogram import Client - from pyrogram.types import (ReplyKeyboardMarkup, InlineKeyboardMarkup, - InlineKeyboardButton) - - # Create a client using your bot token - app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") - - - async def main(): - async with app: - await app.send_message( - "me", # Edit this - "This is a ReplyKeyboardMarkup example", - reply_markup=ReplyKeyboardMarkup( - [ - ["A", "B", "C", "D"], # First row - ["E", "F", "G"], # Second row - ["H", "I"], # Third row - ["J"] # Fourth row - ], - resize_keyboard=True # Make the keyboard smaller - ) - ) - - await app.send_message( - "me", # Edit this - "This is a InlineKeyboardMarkup example", - reply_markup=InlineKeyboardMarkup( - [ - [ # First row - InlineKeyboardButton( # Generates a callback query when pressed - "Button", - callback_data="data" - ), - InlineKeyboardButton( # Opens a web URL - "URL", - url="https://docs.pyrogram.org" - ), - ], - [ # Second row - InlineKeyboardButton( # Opens the inline interface - "Choose chat", - switch_inline_query="pyrogram" - ), - InlineKeyboardButton( # Opens the inline interface in the current chat - "Inline here", - switch_inline_query_current_chat="pyrogram" - ) - ] - ] - ) - ) - - - app.run(main()) \ No newline at end of file diff --git a/docs/source/start/examples/callback_queries.rst b/docs/source/start/examples/callback_queries.rst deleted file mode 100644 index 64da57b39a..0000000000 --- a/docs/source/start/examples/callback_queries.rst +++ /dev/null @@ -1,21 +0,0 @@ -callback_queries -================ - -This example shows how to handle callback queries, i.e.: queries coming from inline button presses. -It uses the @on_callback_query decorator to register a CallbackQueryHandler. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") - - - @app.on_callback_query() - async def answer(client, callback_query): - await callback_query.answer( - f"Button contains: '{callback_query.data}'", - show_alert=True) - - - app.run() # Automatically start() and idle() \ No newline at end of file diff --git a/docs/source/start/examples/echo_bot.rst b/docs/source/start/examples/echo_bot.rst deleted file mode 100644 index de8288b5e4..0000000000 --- a/docs/source/start/examples/echo_bot.rst +++ /dev/null @@ -1,21 +0,0 @@ -echo_bot -======== - -This simple echo bot replies to every private text message. - -It uses the ``@on_message`` decorator to register a ``MessageHandler`` and applies two filters on it: -``filters.text`` and ``filters.private`` to make sure it will reply to private text messages only. - -.. code-block:: python - - from pyrogram import Client, filters - - app = Client("my_account") - - - @app.on_message(filters.text & filters.private) - async def echo(client, message): - await message.reply(message.text) - - - app.run() # Automatically start() and idle() \ No newline at end of file diff --git a/docs/source/start/examples/get_chat_history.rst b/docs/source/start/examples/get_chat_history.rst deleted file mode 100644 index 59939948b3..0000000000 --- a/docs/source/start/examples/get_chat_history.rst +++ /dev/null @@ -1,20 +0,0 @@ -get_history -=========== - -This example shows how to get the full message history of a chat, starting from the latest message. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - async def main(): - async with app: - # "me" refers to your own chat (Saved Messages) - async for message in app.get_chat_history("me"): - print(message) - - - app.run(main()) \ No newline at end of file diff --git a/docs/source/start/examples/get_chat_members.rst b/docs/source/start/examples/get_chat_members.rst deleted file mode 100644 index 26636ca344..0000000000 --- a/docs/source/start/examples/get_chat_members.rst +++ /dev/null @@ -1,22 +0,0 @@ -get_chat_members -================ - -This example shows how to get all the members of a chat. - -.. code-block:: python - - from pyrogram import Client - - # Target channel/supergroup - TARGET = -100123456789 - - app = Client("my_account") - - - async def main(): - async with app: - async for member in app.get_chat_members(TARGET): - print(member) - - - app.run(main()) \ No newline at end of file diff --git a/docs/source/start/examples/get_dialogs.rst b/docs/source/start/examples/get_dialogs.rst deleted file mode 100644 index e5b1060966..0000000000 --- a/docs/source/start/examples/get_dialogs.rst +++ /dev/null @@ -1,19 +0,0 @@ -get_dialogs -=========== - -This example shows how to get the full dialogs list (as user). - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - async def main(): - async with app: - async for dialog in app.get_dialogs(): - print(dialog.chat.title or dialog.chat.first_name) - - - app.run(main()) \ No newline at end of file diff --git a/docs/source/start/examples/hello_world.rst b/docs/source/start/examples/hello_world.rst deleted file mode 100644 index 2902241e8c..0000000000 --- a/docs/source/start/examples/hello_world.rst +++ /dev/null @@ -1,20 +0,0 @@ -hello_world -=========== - -This example demonstrates a basic API usage - -.. code-block:: python - - from pyrogram import Client - - # Create a new Client instance - app = Client("my_account") - - - async def main(): - async with app: - # Send a message, Markdown is enabled by default - await app.send_message("me", "Hi there! I'm using **Pyrogram**") - - - app.run(main()) diff --git a/docs/source/start/examples/index.rst b/docs/source/start/examples/index.rst deleted file mode 100644 index d47b60e80d..0000000000 --- a/docs/source/start/examples/index.rst +++ /dev/null @@ -1,46 +0,0 @@ -Examples -======== - -This page contains example scripts to show you how Pyrogram looks like. - -Every script is working right away (provided you correctly set up your credentials), meaning you can simply copy-paste -and run. The only things you have to change are session names and target chats, where applicable. - -The examples listed below can be treated as building blocks for your own applications and are meant to be simple enough -to give you a basic idea. - ------ - -.. csv-table:: - :header: Example, Description - :widths: auto - :align: center - - :doc:`hello_world`, "Demonstration of basic API usage" - :doc:`echo_bot`, "Echo every private text message" - :doc:`welcome_bot`, "The Welcome Bot in @PyrogramChat" - :doc:`get_chat_history`, "Get the full message history of a chat" - :doc:`get_chat_members`, "Get all the members of a chat" - :doc:`get_dialogs`, "Get all of your dialog chats" - :doc:`callback_queries`, "Handle callback queries (as bot) coming from inline button presses" - :doc:`inline_queries`, "Handle inline queries (as bot) and answer with results" - :doc:`use_inline_bots`, "Query an inline bot (as user) and send a result to a chat" - :doc:`bot_keyboards`, "Send normal and inline keyboards using regular bots" - :doc:`raw_updates`, "Handle raw updates (old, should be avoided)" - -For more advanced examples, see https://snippets.pyrogram.org. - -.. toctree:: - :hidden: - - hello_world - echo_bot - welcome_bot - get_chat_history - get_chat_members - get_dialogs - callback_queries - inline_queries - use_inline_bots - bot_keyboards - raw_updates diff --git a/docs/source/start/examples/inline_queries.rst b/docs/source/start/examples/inline_queries.rst deleted file mode 100644 index b78c6e1cb8..0000000000 --- a/docs/source/start/examples/inline_queries.rst +++ /dev/null @@ -1,59 +0,0 @@ -inline_queries -============== - -This example shows how to handle inline queries. - -Two results are generated when users invoke the bot inline mode, e.g.: @pyrogrambot hi. -It uses the @on_inline_query decorator to register an InlineQueryHandler. - -.. code-block:: python - - from pyrogram import Client - from pyrogram.types import (InlineQueryResultArticle, InputTextMessageContent, - InlineKeyboardMarkup, InlineKeyboardButton) - - app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") - - - @app.on_inline_query() - async def answer(client, inline_query): - await inline_query.answer( - results=[ - InlineQueryResultArticle( - title="Installation", - input_message_content=InputTextMessageContent( - "Here's how to install **Pyrogram**" - ), - url="https://docs.pyrogram.org/intro/install", - description="How to install Pyrogram", - reply_markup=InlineKeyboardMarkup( - [ - [InlineKeyboardButton( - "Open website", - url="https://docs.pyrogram.org/intro/install" - )] - ] - ) - ), - InlineQueryResultArticle( - title="Usage", - input_message_content=InputTextMessageContent( - "Here's how to use **Pyrogram**" - ), - url="https://docs.pyrogram.org/start/invoking", - description="How to use Pyrogram", - reply_markup=InlineKeyboardMarkup( - [ - [InlineKeyboardButton( - "Open website", - url="https://docs.pyrogram.org/start/invoking" - )] - ] - ) - ) - ], - cache_time=1 - ) - - - app.run() # Automatically start() and idle() \ No newline at end of file diff --git a/docs/source/start/examples/raw_updates.rst b/docs/source/start/examples/raw_updates.rst deleted file mode 100644 index 463a45a80b..0000000000 --- a/docs/source/start/examples/raw_updates.rst +++ /dev/null @@ -1,18 +0,0 @@ -raw_updates -=========== - -This example shows how to handle raw updates. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - @app.on_raw_update() - async def raw(client, update, users, chats): - print(update) - - - app.run() # Automatically start() and idle() diff --git a/docs/source/start/examples/use_inline_bots.rst b/docs/source/start/examples/use_inline_bots.rst deleted file mode 100644 index 8a2a72acc4..0000000000 --- a/docs/source/start/examples/use_inline_bots.rst +++ /dev/null @@ -1,25 +0,0 @@ -use_inline_bots -=============== - -This example shows how to query an inline bot (as user). - -.. code-block:: python - - from pyrogram import Client - - # Create a new Client - app = Client("my_account") - - - async def main(): - async with app: - # Get bot results for "hello" from the inline bot @vid - bot_results = await app.get_inline_bot_results("vid", "hello") - - # Send the first result to your own chat (Saved Messages) - await app.send_inline_bot_result( - "me", bot_results.query_id, - bot_results.results[0].id) - - - app.run(main()) \ No newline at end of file diff --git a/docs/source/start/examples/welcome_bot.rst b/docs/source/start/examples/welcome_bot.rst deleted file mode 100644 index 4e30ea7f0a..0000000000 --- a/docs/source/start/examples/welcome_bot.rst +++ /dev/null @@ -1,30 +0,0 @@ -welcome_bot -=========== - -This example uses the ``emoji`` module to easily add emoji in your text messages and ``filters`` -to make it only work for specific messages in a specific chat. - -.. code-block:: python - - from pyrogram import Client, emoji, filters - - # Target chat. Can also be a list of multiple chat ids/usernames - TARGET = -100123456789 - # Welcome message template - MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!" - - app = Client("my_account") - - - # Filter in only new_chat_members updates generated in TARGET chat - @app.on_message(filters.chat(TARGET) & filters.new_chat_members) - async def welcome(client, message): - # Build the new members list (with mentions) by using their first_name - new_members = [u.mention for u in message.new_chat_members] - # Build the welcome message by using an emoji and the list we built above - text = MESSAGE.format(emoji.SPARKLES, ", ".join(new_members)) - # Send the welcome message, without the web page preview - await message.reply_text(text, disable_web_page_preview=True) - - - app.run() # Automatically start() and idle() \ No newline at end of file diff --git a/docs/source/start/invoking.rst b/docs/source/start/invoking.rst deleted file mode 100644 index 415ef848b4..0000000000 --- a/docs/source/start/invoking.rst +++ /dev/null @@ -1,110 +0,0 @@ -Invoking Methods -================ - -At this point, we have successfully :doc:`installed Pyrogram <../intro/install>` and :doc:`authorized ` our -account; we are now aiming towards the core of the framework. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Basic Usage ------------ - -Making API calls with Pyrogram is very simple. Here's a basic example we are going to examine step by step: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - async def main(): - async with app: - await app.send_message("me", "Hi!") - - - app.run(main()) - -Step-by-step -^^^^^^^^^^^^ - -#. Let's begin by importing the Client class. - - .. code-block:: python - - from pyrogram import Client - -#. Now instantiate a new Client object, "my_account" is a session name of your choice. - - .. code-block:: python - - app = Client("my_account") - -#. Async methods must be invoked within an async context. - Here we define an async function and put our code inside. Also notice the ``await`` keyword in front of the method - call; this is required for all asynchronous methods. - - .. code-block:: python - - async def main(): - async with app: - await app.send_message("me", "Hi!") - -#. Finally, we tell Python to schedule our ``main()`` async function by using Pyrogram's :meth:`~pyrogram.Client.run` - method. - - .. code-block:: python - - app.run(main()) - -Context Manager ---------------- - -The ``async with`` statement starts a context manager, which is used as a shortcut for starting, executing and stopping -the Client, asynchronously. It does so by automatically calling :meth:`~pyrogram.Client.start` and -:meth:`~pyrogram.Client.stop` in a more convenient way which also gracefully stops the client, even in case of -unhandled exceptions in your code. - -Below there's the same example as above, but without the use of the context manager: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - async def main(): - await app.start() - await app.send_message("me", "Hi!") - await app.stop() - - - app.run(main()) - -Using asyncio.run() -------------------- - -Alternatively to the :meth:`~pyrogram.Client.run` method, you can use Python's ``asyncio.run()`` to execute the main -function, with one little caveat: the Client instance (and possibly other asyncio resources you are going to use) must -be instantiated inside the main function. - -.. code-block:: python - - import asyncio - from pyrogram import Client - - - async def main(): - app = Client("my_account") - - async with app: - await app.send_message("me", "Hi!") - - - asyncio.run(main()) \ No newline at end of file diff --git a/docs/source/start/setup.rst b/docs/source/start/setup.rst deleted file mode 100644 index b8fd6effd7..0000000000 --- a/docs/source/start/setup.rst +++ /dev/null @@ -1,40 +0,0 @@ -Project Setup -============= - -We have just :doc:`installed Pyrogram <../intro/install>`. In this page we'll discuss what you need to do in order to set up a -project with the framework. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -API Key -------- - -The first step requires you to obtain a valid Telegram API key (api_id and api_hash pair): - -#. Visit https://my.telegram.org/apps and log in with your Telegram account. -#. Fill out the form with your details and register a new Telegram application. -#. Done. The API key consists of two parts: **api_id** and **api_hash**. Keep it secret. - -.. note:: - - The API key defines a token for a Telegram *application* you are going to build. - This means that you are able to authorize multiple users or bots with a single API key. - -Configuration -------------- - -Having the API key from the previous step in handy, we can now begin to configure a Pyrogram project: pass your API key to Pyrogram by using the *api_id* and *api_hash* parameters of the Client class: - -.. code-block:: python - - from pyrogram import Client - - api_id = 12345 - api_hash = "0123456789abcdef0123456789abcdef" - - app = Client("my_account", api_id=api_id, api_hash=api_hash) \ No newline at end of file diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst deleted file mode 100644 index 685128c21c..0000000000 --- a/docs/source/start/updates.rst +++ /dev/null @@ -1,78 +0,0 @@ -Handling Updates -================ - -:doc:`Invoking API methods ` sequentially is one way to use Pyrogram. This page deals with Telegram updates -and how to handle new incoming messages or other events in Pyrogram. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Defining Updates ----------------- - -Updates are events that happen in your Telegram account (incoming messages, new members join, -bot button presses, etc.), which are meant to notify you about a new specific state that has changed. These updates are -handled by registering one or more callback functions in your app using :doc:`Handlers <../api/handlers>`. - -Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback -function will be called back by the framework and its body executed. - -Registering a Handler ---------------------- - -To explain how handlers work let's examine the one which will be in charge for handling :class:`~pyrogram.types.Message` -updates coming from all around your chats. Every other kind of handler shares the same setup logic and you should not -have troubles settings them up once you learn from this section. - -Using Decorators -^^^^^^^^^^^^^^^^ - -The most elegant way to register a message handler is by using the :meth:`~pyrogram.Client.on_message` decorator: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - @app.on_message() - async def my_handler(client, message): - await message.forward("me") - - - app.run() - -The defined function ``my_handler``, which accepts the two arguments *(client, message)*, will be the function that gets -executed every time a new message arrives. - -In the last line we see again the :meth:`~pyrogram.Client.run` method, this time used without any argument. -Its purpose here is simply to automatically :meth:`~pyrogram.Client.start`, keep the Client online so that it can listen -for updates and :meth:`~pyrogram.Client.stop` it once you hit ``CTRL+C``. - -Using add_handler() -^^^^^^^^^^^^^^^^^^^ - -The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback -function and registers it in your Client. It is useful in case you want to programmatically add handlers. - -.. code-block:: python - - from pyrogram import Client - from pyrogram.handlers import MessageHandler - - - async def my_function(client, message): - await message.forward("me") - - - app = Client("my_account") - - my_handler = MessageHandler(my_function) - app.add_handler(my_handler) - - app.run() diff --git a/docs/source/support.rst b/docs/source/support.rst deleted file mode 100644 index 8efa4bc19f..0000000000 --- a/docs/source/support.rst +++ /dev/null @@ -1,63 +0,0 @@ -Support Pyrogram -================ - -.. raw:: html - - - -
- Star - - Fork -
- -
- -Pyrogram is a free and open source project. -If you enjoy Pyrogram and would like to show your appreciation, consider donating or becoming -a sponsor of the project. You can support Pyrogram via the ways shown below: - ------ - -GitHub Sponsor --------------- - -`Become a GitHub sponsor `_. - -.. raw:: html - - Sponsor - ------ - -LiberaPay Patron ----------------- - -`Become a LiberaPay patron `_. - -.. raw:: html - - - ------ - -OpenCollective Backer ---------------------- - -`Become an OpenCollective backer `_ - -.. raw:: html - - \ No newline at end of file diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst deleted file mode 100644 index df99042d1b..0000000000 --- a/docs/source/topics/advanced-usage.rst +++ /dev/null @@ -1,124 +0,0 @@ -Advanced Usage -============== - -Pyrogram's API -- which consists of well documented :doc:`methods <../api/methods/index>` and -:doc:`types <../api/types/index>` -- exists to provide an easier interface to the more complex Telegram API. - -In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main "raw" -Telegram API with its functions and types. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Telegram Raw API ----------------- - -If you can't find a high-level method for your needs or if you want complete, low-level access to the whole -Telegram API, you have to use the raw :mod:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`. - -As already hinted, raw functions and types can be less convenient. This section will therefore explain some pitfalls to -take into consideration when working with the raw API. - -.. tip:: - - Every available high-level method in Pyrogram is built on top of these raw functions. - -Invoking Functions ------------------- - -Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which can be called in the usual simple way, -functions to be invoked from the raw Telegram API have a different way of usage. - -First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>` -live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist -as Python classes, meaning you need to create an instance of each every time you need them and fill them in with the -correct values using named arguments. - -Next, to actually invoke the raw function you have to use the :meth:`~pyrogram.Client.invoke` method provided by the -Client class and pass the function object you created. - -Here's some examples: - -- Update first name, last name and bio: - - .. code-block:: python - - from pyrogram import Client - from pyrogram.raw import functions - - async with Client("my_account") as app: - await app.invoke( - functions.account.UpdateProfile( - first_name="First Name", last_name="Last Name", - about="New bio text" - ) - ) - -- Set online/offline status: - - .. code-block:: python - - from pyrogram import Client - from pyrogram.raw import functions, types - - async with Client("my_account") as app: - # Set online status - await app.invoke(functions.account.UpdateStatus(offline=False)) - - # Set offline status - await app.invoke(functions.account.UpdateStatus(offline=True)) - -- Get chat info: - - .. code-block:: python - - from pyrogram import Client - from pyrogram.raw import functions, types - - async with Client("my_account") as app: - r = await app.invoke( - functions.channels.GetFullChannel( - channel=app.resolve_peer("username") - ) - ) - - print(r) - -Chat IDs --------- - -The way Telegram works makes it not possible to directly send a message to a user or a chat by using their IDs only. -Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed. Pyrogram allows -sending messages with IDs only thanks to cached access hashes. - -There are three different InputPeer types, one for each kind of Telegram entity. -Whenever an InputPeer is needed you must pass one of these: - -- :class:`~pyrogram.raw.types.InputPeerUser` - Users -- :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats -- :class:`~pyrogram.raw.types.InputPeerChannel` - Channels & Supergroups - -But you don't necessarily have to manually instantiate each object because Pyrogram already provides -:meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer -by accepting a peer ID only. - -Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and -all positive within their respective raw types. - -Things are different when working with Pyrogram's API because having them in the same space could lead to -collisions, and that's why Pyrogram uses a slightly different representation for each kind of ID. - -For example, given the ID *123456789*, here's how Pyrogram can tell entities apart: - -- ``+ID`` User: *123456789* -- ``-ID`` Chat: *-123456789* -- ``-100ID`` Channel or Supergroup: *-100123456789* - -So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an -high-level method. - -.. _Community: https://t.me/Pyrogram \ No newline at end of file diff --git a/docs/source/topics/client-settings.rst b/docs/source/topics/client-settings.rst deleted file mode 100644 index 02dce71375..0000000000 --- a/docs/source/topics/client-settings.rst +++ /dev/null @@ -1,46 +0,0 @@ -Client Settings -=============== - -You can control the way your client appears in the Active Sessions menu of an official client by changing some client -settings. By default you will see something like the following: - -- Device Model: ``CPython x.y.z`` -- Application: ``Pyrogram x.y.z`` -- System Version: ``Linux x.y.z`` - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Set Custom Values ------------------ - -To set custom values, you can pass the arguments directly in the Client's constructor. - -.. code-block:: python - - app = Client( - "my_account", - app_version="1.2.3", - device_model="PC", - system_version="Linux" - ) - -Set Custom Languages --------------------- - -To tell Telegram in which language should speak to you (terms of service, bots, service messages, ...) you can -set ``lang_code`` in `ISO 639-1 `_ standard (defaults to "en", -English). - -With the following code we make Telegram know we want it to speak in Italian (it): - -.. code-block:: python - - app = Client( - "my_account", - lang_code="it", - ) \ No newline at end of file diff --git a/docs/source/topics/create-filters.rst b/docs/source/topics/create-filters.rst deleted file mode 100644 index f8c05af620..0000000000 --- a/docs/source/topics/create-filters.rst +++ /dev/null @@ -1,109 +0,0 @@ -Creating Filters -================ - -Pyrogram already provides lots of built-in :class:`~pyrogram.filters` to work with, but in case you can't find a -specific one for your needs or want to build a custom filter by yourself you can use -:meth:`filters.create() `. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Custom Filters --------------- - -An example to demonstrate how custom filters work is to show how to create and use one for the -:class:`~pyrogram.handlers.CallbackQueryHandler`. Note that callback queries updates are only received by bots as result -of a user pressing an inline button attached to the bot's message; create and :doc:`authorize your bot <../start/auth>`, -then send a message with an inline keyboard to yourself. This allows you to test your filter by pressing the inline -button: - -.. code-block:: python - - from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton - - await app.send_message( - "username", # Change this to your username or id - "Pyrogram custom filter test", - reply_markup=InlineKeyboardMarkup( - [[InlineKeyboardButton("Press me", "pyrogram")]] - ) - ) - -Basic Filters -------------- - -For this basic filter we will be using only the first parameter of :meth:`~pyrogram.filters.create`. - -The heart of a filter is its callback function, which accepts three arguments *(self, client, update)* and returns -either ``True``, in case you want the update to pass the filter or ``False`` otherwise. - -In this example we are matching the query data to "pyrogram", which means that the filter will only allow callback -queries containing "pyrogram" as data: - -.. code-block:: python - - from pyrogram import filters - - async def func(_, __, query): - return query.data == "pyrogram" - - static_data_filter = filters.create(func) - - -The first two arguments of the callback function are unused here and because of this we named them using underscores. - -Finally, the filter usage remains the same: - -.. code-block:: python - - @app.on_callback_query(static_data_filter) - async def pyrogram_data(_, query): - query.answer("it works!") - -Filters with Arguments ----------------------- - -A more flexible filter would be one that accepts "pyrogram" or any other string as argument at usage time. -A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method and the -first argument of the callback function, which is a reference to the filter object itself holding the extra data passed -via named arguments. - -This is how a dynamic custom filter looks like: - -.. code-block:: python - - from pyrogram import filters - - def dynamic_data_filter(data): - async def func(flt, _, query): - return flt.data == query.data - - # "data" kwarg is accessed with "flt.data" above - return filters.create(func, data=data) - -And finally its usage: - -.. code-block:: python - - @app.on_callback_query(dynamic_data_filter("pyrogram")) - async def pyrogram_data(_, query): - query.answer("it works!") - - -Method Calls Inside Filters ---------------------------- - -The missing piece we haven't covered yet is the second argument of a filter callback function, namely, the ``client`` -argument. This is a reference to the :obj:`~pyrogram.Client` instance that is running the filter and it is useful in -case you would like to make some API calls before deciding whether the filter should allow the update or not: - -.. code-block:: python - - async def func(_, client, query): - # r = await client.some_api_method() - # check response "r" and decide to return True or False - ... \ No newline at end of file diff --git a/docs/source/topics/debugging.rst b/docs/source/topics/debugging.rst deleted file mode 100644 index 1c0ac069f9..0000000000 --- a/docs/source/topics/debugging.rst +++ /dev/null @@ -1,122 +0,0 @@ -Debugging -========= - -When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing -to actually worry about since Pyrogram provides some commodities to help you in this. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Caveman Debugging ------------------ - - *The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.* - - -- Brian Kernighan, "Unix for Beginners" (1979) - -Adding ``print()`` statements in crucial parts of your code is by far the most ancient, yet efficient technique for -debugging programs, especially considering the concurrent nature of the framework itself. Pyrogram goodness in this -respect comes with the fact that any object can be nicely printed just by calling ``print(obj)``, thus giving to you -an insight of all its inner details. - -Consider the following code: - -.. code-block:: python - - me = await app.get_users("me") - print(me) # User - -This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a -:class:`~pyrogram.types.User` instance, in this case. The output on your terminal will be something similar to this: - -.. code-block:: json - - { - "_": "User", - "id": 123456789, - "is_self": true, - "is_contact": false, - "is_mutual_contact": false, - "is_deleted": false, - "is_bot": false, - "is_verified": false, - "is_restricted": false, - "is_support": false, - "first_name": "Pyrogram", - "photo": { - "_": "ChatPhoto", - "small_file_id": "AbCdE...EdCbA", - "small_photo_unique_id": "VwXyZ...ZyXwV", - "big_file_id": "AbCdE...EdCbA", - "big_photo_unique_id": "VwXyZ...ZyXwV" - } - } - -As you've probably guessed already, Pyrogram objects can be nested. That's how compound data are built, and nesting -keeps going until we are left with base data types only, such as ``str``, ``int``, ``bool``, etc. - -Accessing Attributes --------------------- - -Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are -fully-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``: - -.. code-block:: python - - photo = me.photo - print(photo) # ChatPhoto - -.. code-block:: json - - { - "_": "ChatPhoto", - "small_file_id": "AbCdE...EdCbA", - "small_photo_unique_id": "VwXyZ...ZyXwV", - "big_file_id": "AbCdE...EdCbA", - "big_photo_unique_id": "VwXyZ...ZyXwV" - } - -Checking an Object's Type -------------------------- - -Another thing worth talking about is how to tell and check for an object's type. - -As you noticed already, when printing an object you'll see the special attribute ``"_"``. This is just a visual thing -useful to show humans the object type, but doesn't really exist anywhere; any attempt in accessing it will lead to an -error. The correct way to get the object type is by using the built-in function ``type()``: - -.. code-block:: python - - status = me.status - print(type(status)) - -.. code-block:: text - - - -And to check if an object is an instance of a given class, you use the built-in function ``isinstance()``: - -.. code-block:: python - :name: this-py - - from pyrogram.types import UserStatus - - status = me.status - print(isinstance(status, UserStatus)) - -.. code-block:: text - - True - -.. raw:: html - - \ No newline at end of file diff --git a/docs/source/topics/more-on-updates.rst b/docs/source/topics/more-on-updates.rst deleted file mode 100644 index 18c1a68af3..0000000000 --- a/docs/source/topics/more-on-updates.rst +++ /dev/null @@ -1,226 +0,0 @@ -More on Updates -=============== - -Here we'll show some advanced usages when working with :doc:`update handlers <../start/updates>` and -:doc:`filters `. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Handler Groups --------------- - -If you register handlers with overlapping (conflicting) filters, only the first one is executed and any other handler -will be ignored. This is intended by design. - -In order to handle the very same update more than once, you have to register your handler in a different dispatching -group. Dispatching groups hold one or more handlers and are processed sequentially, they are identified by a number -(number 0 being the default) and sorted, that is, a lower group number has a higher priority: - -For example, take these two handlers: - -.. code-block:: python - - @app.on_message(filters.text | filters.sticker) - async def text_or_sticker(client, message): - print("Text or Sticker") - - - @app.on_message(filters.text) - async def just_text(client, message): - print("Just Text") - -Here, ``just_text`` is never executed because ``text_or_sticker``, which has been registered first, already handles -texts (``filters.text`` is shared and conflicting). To enable it, register the handler using a different group: - -.. code-block:: python - - @app.on_message(filters.text, group=1) - async def just_text(client, message): - print("Just Text") - -Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``): - -.. code-block:: python - - @app.on_message(filters.text, group=-1) - async def just_text(client, message): - print("Just Text") - -With :meth:`~pyrogram.Client.add_handler` (without decorators) the same can be achieved with: - -.. code-block:: python - - app.add_handler(MessageHandler(just_text, filters.text), -1) - -Update propagation ------------------- - -Registering multiple handlers, each in a different group, becomes useful when you want to handle the same update more -than once. Any incoming update will be sequentially processed by all of your registered functions by respecting the -groups priority policy described above. Even in case any handler raises an unhandled exception, Pyrogram will still -continue to propagate the same update to the next groups until all the handlers are done. Example: - -.. code-block:: python - - @app.on_message(filters.private) - async def _(client, message): - print(0) - - - @app.on_message(filters.private, group=1) - async def _(client, message): - raise Exception("Unhandled exception!") # Simulate an unhandled exception - - - @app.on_message(filters.private, group=2) - async def _(client, message): - print(2) - -All these handlers will handle the same kind of messages, that are, messages sent or received in private chats. -The output for each incoming update will therefore be: - -.. code-block:: text - - 0 - Exception: Unhandled exception! - 2 - -Stop Propagation -^^^^^^^^^^^^^^^^ - -In order to prevent further propagation of an update in the dispatching phase, you can do *one* of the following: - -- Call the update's bound-method ``.stop_propagation()`` (preferred way). -- Manually ``raise StopPropagation`` exception (more suitable for raw updates only). - -.. note:: - - Internally, the propagation is stopped by handling a custom exception. ``.stop_propagation()`` is just an elegant - and intuitive way to ``raise StopPropagation``; this also means that any code coming *after* calling the method - won't be executed as your function just raised an exception to signal the dispatcher not to propagate the - update anymore. - -Example with ``stop_propagation()``: - -.. code-block:: python - - @app.on_message(filters.private) - async def _(client, message): - print(0) - - - @app.on_message(filters.private, group=1) - async def _(client, message): - print(1) - message.stop_propagation() - - - @app.on_message(filters.private, group=2) - async def _(client, message): - print(2) - -Example with ``raise StopPropagation``: - -.. code-block:: python - - from pyrogram import StopPropagation - - @app.on_message(filters.private) - async def _(client, message): - print(0) - - - @app.on_message(filters.private, group=1) - async ef _(client, message): - print(1) - raise StopPropagation - - - @app.on_message(filters.private, group=2) - async def _(client, message): - print(2) - -Each handler is registered in a different group, but the handler in group number 2 will never be executed because the -propagation was stopped earlier. The output of both (equivalent) examples will be: - -.. code-block:: text - - 0 - 1 - -Continue Propagation -^^^^^^^^^^^^^^^^^^^^ - -As opposed to `stopping the update propagation <#stop-propagation>`_ and also as an alternative to the -`handler groups <#handler-groups>`_, you can signal the internal dispatcher to continue the update propagation within -**the same group** despite having conflicting filters in the next registered handler. This allows you to register -multiple handlers with overlapping filters in the same group; to let the dispatcher process the next handler you can do -*one* of the following in each handler you want to grant permission to continue: - -- Call the update's bound-method ``.continue_propagation()`` (preferred way). -- Manually ``raise ContinuePropagation`` exception (more suitable for raw updates only). - -.. note:: - - Internally, the propagation is continued by handling a custom exception. ``.continue_propagation()`` is just an - elegant and intuitive way to ``raise ContinuePropagation``; this also means that any code coming *after* calling the - method won't be executed as your function just raised an exception to signal the dispatcher to continue with the - next available handler. - - -Example with ``continue_propagation()``: - -.. code-block:: python - - @app.on_message(filters.private) - async def _(client, message): - print(0) - message.continue_propagation() - - - @app.on_message(filters.private) - async def _(client, message): - print(1) - message.continue_propagation() - - - @app.on_message(filters.private) - async def _(client, message): - print(2) - -Example with ``raise ContinuePropagation``: - -.. code-block:: python - - from pyrogram import ContinuePropagation - - @app.on_message(filters.private) - async def _(client, message): - print(0) - raise ContinuePropagation - - - @app.on_message(filters.private) - async def _(client, message): - print(1) - raise ContinuePropagation - - - @app.on_message(filters.private) - async def _(client, message): - print(2) - -Three handlers are registered in the same group, and all of them will be executed because the propagation was continued -in each handler (except in the last one, where is useless to do so since there is no more handlers after). -The output of both (equivalent) examples will be: - -.. code-block:: text - - 0 - 1 - 2 diff --git a/docs/source/topics/mtproto-vs-botapi.rst b/docs/source/topics/mtproto-vs-botapi.rst deleted file mode 100644 index 9681c1eb65..0000000000 --- a/docs/source/topics/mtproto-vs-botapi.rst +++ /dev/null @@ -1,112 +0,0 @@ -MTProto vs. Bot API -=================== - -Pyrogram is a framework written from the ground up that acts as a fully-fledged Telegram client based on the MTProto -API. This means that Pyrogram is able to execute any official client and bot API action and more. This page will -therefore show you why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's -make it clear what actually is the MTProto and the Bot API. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -What is the MTProto API? ------------------------- - -`MTProto`_, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram -itself --- it's the only protocol used to exchange information between a client and the actual Telegram servers. - -The MTProto API on the other hand, is what people for convenience call the main Telegram API in order to distinguish it -from the Bot API. The main Telegram API is able to authorize both users and bots and is built on top of the MTProto -encryption protocol by means of `binary data serialized`_ in a specific way, as described by the `TL language`_, and -delivered using UDP, TCP or even HTTP as transport-layer protocol. Clients that make use of Telegram's main API, such as -Pyrogram, implement all these details. - -.. _MTProto: https://core.telegram.org/mtproto -.. _binary data serialized: https://core.telegram.org/mtproto/serialize -.. _TL language: https://core.telegram.org/mtproto/TL - -What is the Bot API? --------------------- - -The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main Telegram API. Bots are -special accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the -main Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram -servers using MTProto. - -.. figure:: //_static/img/mtproto-vs-bot-api.png - :align: center - -.. _Bot API: https://core.telegram.org/bots/api - -Advantages of the MTProto API ------------------------------ - -Here is a non-exhaustive list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of -the official HTTP Bot API. Using Pyrogram you can: - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Authorize both user and bot identities** - - :guilabel:`--` The Bot API only allows bot accounts - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Upload & download any file, up to 2000 MiB each (~2 GB)** - - :guilabel:`--` The Bot API allows uploads and downloads of files only up to 50 MB / 20 MB in size (respectively). - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Has less overhead due to direct connections to Telegram** - - :guilabel:`--` The Bot API uses an intermediate server to handle HTTP requests before they are sent to the actual - Telegram servers. - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Run multiple sessions at once (for both user and bot identities)** - - :guilabel:`--` The Bot API intermediate server will terminate any other session in case you try to use the same - bot again in a parallel connection. - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Has much more detailed types and powerful methods** - - :guilabel:`--` The Bot API types often miss some useful information about Telegram entities and some of the - methods are limited as well. - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Obtain information about any message existing in a chat using their ids** - - :guilabel:`--` The Bot API simply doesn't support this - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Retrieve the whole chat members list of either public or private chats** - - :guilabel:`--` The Bot API simply doesn't support this - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Receive extra updates, such as the one about a user name change** - - :guilabel:`--` The Bot API simply doesn't support this - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Has more meaningful errors in case something went wrong** - - :guilabel:`--` The Bot API reports less detailed errors - -.. hlist:: - :columns: 1 - - - :guilabel:`+` **Get API version updates, and thus new features, sooner** - - :guilabel:`--` The Bot API is simply slower in implementing new features diff --git a/docs/source/topics/proxy.rst b/docs/source/topics/proxy.rst deleted file mode 100644 index 286743493d..0000000000 --- a/docs/source/topics/proxy.rst +++ /dev/null @@ -1,34 +0,0 @@ -Proxy Settings -============== - -Pyrogram supports proxies with and without authentication. This feature allows Pyrogram to exchange data with Telegram -through an intermediate SOCKS 4/5 or HTTP (CONNECT) proxy server. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Usage ------ - -To use Pyrogram with a proxy, use the *proxy* parameter in the Client class. If your proxy doesn't require authorization -you can omit ``username`` and ``password``. - -.. code-block:: python - - from pyrogram import Client - - proxy = { - "scheme": "socks5", # "socks4", "socks5" and "http" are supported - "hostname": "11.22.33.44", - "port": 1234, - "username": "username", - "password": "password" - } - - app = Client("my_account", proxy=proxy) - - app.run() diff --git a/docs/source/topics/scheduling.rst b/docs/source/topics/scheduling.rst deleted file mode 100644 index a67a92548a..0000000000 --- a/docs/source/topics/scheduling.rst +++ /dev/null @@ -1,65 +0,0 @@ -Scheduling Tasks -================ - -Scheduling tasks means executing one or more functions periodically at pre-defined intervals or after a delay. This is -useful, for example, to send recurring messages to specific chats or users. - -This page will show examples on how to integrate Pyrogram with ``apscheduler`` in both asynchronous and -non-asynchronous contexts. For more detailed information, you can visit and learn from the library documentation. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Using apscheduler ------------------ - -- Install with ``pip3 install apscheduler`` -- Documentation: https://apscheduler.readthedocs.io - -Asynchronously -^^^^^^^^^^^^^^ - -.. code-block:: python - - from apscheduler.schedulers.asyncio import AsyncIOScheduler - - from pyrogram import Client - - app = Client("my_account") - - - async def job(): - await app.send_message("me", "Hi!") - - - scheduler = AsyncIOScheduler() - scheduler.add_job(job, "interval", seconds=3) - - scheduler.start() - app.run() - -Non-Asynchronously -^^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - from apscheduler.schedulers.background import BackgroundScheduler - - from pyrogram import Client - - app = Client("my_account") - - - def job(): - app.send_message("me", "Hi!") - - - scheduler = BackgroundScheduler() - scheduler.add_job(job, "interval", seconds=3) - - scheduler.start() - app.run() diff --git a/docs/source/topics/serializing.rst b/docs/source/topics/serializing.rst deleted file mode 100644 index 3dc644f880..0000000000 --- a/docs/source/topics/serializing.rst +++ /dev/null @@ -1,56 +0,0 @@ -Object Serialization -==================== - -Serializing means converting a Pyrogram object, which exists as Python class instance, to a text string that can be -easily shared and stored anywhere. Pyrogram provides two formats for serializing its objects: one good looking for -humans and another more compact for machines that is able to recover the original structures. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -For Humans - str(obj) ---------------------- - -If you want a nicely formatted, human readable JSON representation of any object in the API you can use ``str(obj)``. - -.. code-block:: python - - ... - - async with app: - r = await app.get_chat("me") - print(str(r)) - -.. tip:: - - When using ``print()`` you don't actually need to use ``str()`` on the object because it is called automatically, we - have done that above just to show you how to explicitly convert a Pyrogram object to JSON. - -For Machines - repr(obj) ------------------------- - -If you want to share or store objects for future references in a more compact way, you can use ``repr(obj)``. While -still pretty much readable, this format is not intended for humans. The advantage of this format is that once you -serialize your object, you can use ``eval()`` to get back the original structure; just make sure to ``import pyrogram``, -as the process requires the package to be in scope. - -.. code-block:: python - - import pyrogram - - ... - - async with app: - r = await app.get_chat("me") - - print(repr(r)) - print(eval(repr(r)) == r) # True - -.. note:: - - Type definitions are subject to changes between versions. You should make sure to store and load objects using the - same Pyrogram version. \ No newline at end of file diff --git a/docs/source/topics/smart-plugins.rst b/docs/source/topics/smart-plugins.rst deleted file mode 100644 index c378c9d81f..0000000000 --- a/docs/source/topics/smart-plugins.rst +++ /dev/null @@ -1,306 +0,0 @@ -Smart Plugins -============= - -Pyrogram embeds a smart, lightweight yet powerful plugin system that is meant to further simplify the organization -of large projects and to provide a way for creating pluggable (modular) components that can be easily shared across -different Pyrogram applications with minimal boilerplate code. - -.. tip:: - - Smart Plugins are completely optional and disabled by default. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Introduction ------------- - -Prior to the Smart Plugin system, pluggable handlers were already possible. For example, if you wanted to modularize -your applications, you had to put your function definitions in separate files and register them inside your main script -after importing your modules, like this: - -.. note:: - - This is an example application that replies in private chats with two messages: one containing the same - text message you sent and the other containing the reversed text message. - - Example: *"Pyrogram"* replies with *"Pyrogram"* and *"margoryP"* - -.. code-block:: text - - myproject/ - handlers.py - main.py - -- ``handlers.py`` - - .. code-block:: python - - async def echo(client, message): - await message.reply(message.text) - - - async def echo_reversed(client, message): - await message.reply(message.text[::-1]) - -- ``main.py`` - - .. code-block:: python - - from pyrogram import Client, filters - from pyrogram.handlers import MessageHandler - - from handlers import echo, echo_reversed - - app = Client("my_account") - - app.add_handler( - MessageHandler( - echo, - filters.text & filters.private)) - - app.add_handler( - MessageHandler( - echo_reversed, - filters.text & filters.private), - group=1) - - app.run() - -This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to -manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each -:class:`~pyrogram.handlers.MessageHandler` object because you can't use decorators for your functions. -So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically. - -Using Smart Plugins -------------------- - -Setting up your Pyrogram project to accommodate Smart Plugins is pretty straightforward: - -#. Create a new folder to store all the plugins (e.g.: "plugins", "handlers", ...). -#. Put your python files full of plugins inside. Organize them as you wish. -#. Enable plugins in your Client. - -.. note:: - - This is the same example application as shown above, written using the Smart Plugin system. - -.. code-block:: text - - myproject/ - plugins/ - handlers.py - main.py - -- ``plugins/handlers.py`` - - .. code-block:: python - - from pyrogram import Client, filters - - - @Client.on_message(filters.text & filters.private) - async def echo(client, message): - await message.reply(message.text) - - - @Client.on_message(filters.text & filters.private, group=1) - async def echo_reversed(client, message): - await message.reply(message.text[::-1]) - -- ``main.py`` - - .. code-block:: python - - from pyrogram import Client - - plugins = dict(root="plugins") - - Client("my_account", plugins=plugins).run() - - -The first important thing to note is the new ``plugins`` folder. You can put *any python file* in *any subfolder* and -each file can contain *any decorated function* (handlers) with one limitation: within a single module (file) you must -use different names for each decorated function. - -The second thing is telling Pyrogram where to look for your plugins: you can use the Client parameter "plugins"; -the *root* value must match the name of your plugins root folder. Your Pyrogram Client instance will **automatically** -scan the folder upon starting to search for valid handlers and register them for you. - -Then you'll notice you can now use decorators. That's right, you can apply the usual decorators to your callback -functions in a static way, i.e. **without having the Client instance around**: simply use ``@Client`` (Client class) -instead of the usual ``@app`` (Client instance) and things will work just the same. - -Specifying the Plugins to include ---------------------------------- - -By default, if you don't explicitly supply a list of plugins, every valid one found inside your plugins root folder will -be included by following the alphabetical order of the directory structure (files and subfolders); the single handlers -found inside each module will be, instead, loaded in the order they are defined, from top to bottom. - -.. note:: - - Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping - filters included a second time will not work, by design. Learn more at :doc:`More on Updates `. - -This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or -exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude`` -directives in the dictionary passed as Client argument. Here's how they work: - -- If both ``include`` and ``exclude`` are omitted, all plugins are loaded as described above. -- If ``include`` is given, only the specified plugins will be loaded, in the order they are passed. -- If ``exclude`` is given, the plugins specified here will be unloaded. - -The ``include`` and ``exclude`` value is a **list of strings**. Each string containing the path of the module relative -to the plugins root folder, in Python notation (dots instead of slashes). - - E.g.: ``subfolder.module`` refers to ``plugins/subfolder/module.py``, with ``root="plugins"``. - -You can also choose the order in which the single handlers inside a module are loaded, thus overriding the default -top-to-bottom loading policy. You can do this by appending the name of the functions to the module path, each one -separated by a blank space. - - E.g.: ``subfolder.module fn2 fn1 fn3`` will load *fn2*, *fn1* and *fn3* from *subfolder.module*, in this order. - -Examples -^^^^^^^^ - -Given this plugins folder structure with three modules, each containing their own handlers (fn1, fn2, etc...), which are -also organized in subfolders: - -.. code-block:: text - - myproject/ - plugins/ - subfolder1/ - plugins1.py - - fn1 - - fn2 - - fn3 - subfolder2/ - plugins2.py - ... - plugins0.py - ... - ... - -- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order - (files) and definition order (handlers inside files): - - .. code-block:: python - - plugins = dict(root="plugins") - - Client("my_account", plugins=plugins).run() - -- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order: - - .. code-block:: python - - plugins = dict( - root="plugins", - include=[ - "subfolder2.plugins2", - "plugins0" - ] - ) - - Client("my_account", plugins=plugins).run() - -- Load everything except the handlers inside *plugins2.py*: - - .. code-block:: python - - plugins = dict( - root="plugins", - exclude=["subfolder2.plugins2"] - ) - - Client("my_account", plugins=plugins).run() - -- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*: - - .. code-block:: python - - plugins = dict( - root="plugins", - include=["subfolder1.plugins1 fn3 fn1 fn2"] - ) - - Client("my_account", plugins=plugins).run() - -Load/Unload Plugins at Runtime ------------------------------- - -In the previous section we've explained how to specify which plugins to load and which to ignore before your Client -starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime. - -Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram -updates) will be modified in such a way that a special ``handlers`` attribute pointing to a list of tuples of -*(handler: Handler, group: int)* is attached to the function object itself. - -- ``plugins/handlers.py`` - - .. code-block:: python - - @Client.on_message(filters.text & filters.private) - async def echo(client, message): - await message.reply(message.text) - - print(echo) - print(echo.handlers) - -- Printing ``echo`` will show something like ````. - -- Printing ``echo.handlers`` will reveal the handlers, that is, a list of tuples containing the actual handlers and - the groups they were registered on ``[(, 0)]``. - -Unloading -^^^^^^^^^ - -In order to unload a plugin, all you need to do is obtain a reference to it by importing the relevant module and call -:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* instance: - -- ``main.py`` - - .. code-block:: python - - from plugins.handlers import echo - - handlers = echo.handlers - - for h in handlers: - app.remove_handler(*h) - -The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive -exactly what is needed. The same could have been achieved with: - -.. code-block:: python - - handlers = echo.handlers - handler, group = handlers[0] - - app.remove_handler(handler, group) - -Loading -^^^^^^^ - -Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time -using :meth:`~pyrogram.Client.add_handler` instead. Example: - -- ``main.py`` - - .. code-block:: python - - from plugins.handlers import echo - - ... - - handlers = echo.handlers - - for h in handlers: - app.add_handler(*h) \ No newline at end of file diff --git a/docs/source/topics/speedups.rst b/docs/source/topics/speedups.rst deleted file mode 100644 index 821b26f4df..0000000000 --- a/docs/source/topics/speedups.rst +++ /dev/null @@ -1,88 +0,0 @@ -Speedups -======== - -Pyrogram's speed can be boosted up by using TgCrypto and uvloop. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -TgCrypto --------- - -TgCrypto_ is a high-performance, easy-to-install cryptography library specifically written in C for Pyrogram as a Python -extension. It is a replacement for a slower Python-only alternative and implements the cryptographic algorithms Telegram -requires, namely: AES-256-IGE, AES-256-CTR and AES-256-CBC. - -Installation -^^^^^^^^^^^^ - -.. code-block:: bash - - $ pip3 install -U tgcrypto - -Usage -^^^^^ - -Pyrogram will automatically make use of TgCrypto when detected, all you need to do is to install it. - -uvloop ------- - -uvloop_ is a fast, drop-in replacement of the built-in asyncio event loop. uvloop is implemented in Cython and uses -libuv under the hood. It makes asyncio 2-4x faster. - -Installation -^^^^^^^^^^^^ - -.. code-block:: bash - - $ pip3 install -U uvloop - -Usage -^^^^^ - -Call ``uvloop.install()`` before calling ``asyncio.run()`` or ``app.run()``. - -.. code-block:: python - - import asyncio - import uvloop - - from pyrogram import Client - - - async def main(): - app = Client("my_account") - - async with app: - print(await app.get_me()) - - - uvloop.install() - asyncio.run(main()) - -The ``uvloop.install()`` call also needs to be placed before creating a Client instance. - -.. code-block:: python - - import uvloop - from pyrogram import Client - - uvloop.install() - - app = Client("my_account") - - - @app.on_message() - async def hello(client, message): - print(await client.get_me()) - - - app.run() - -.. _TgCrypto: https://github.com/pyrogram/tgcrypto -.. _uvloop: https://github.com/MagicStack/uvloop diff --git a/docs/source/topics/storage-engines.rst b/docs/source/topics/storage-engines.rst deleted file mode 100644 index 34147917ee..0000000000 --- a/docs/source/topics/storage-engines.rst +++ /dev/null @@ -1,90 +0,0 @@ -Storage Engines -=============== - -Every time you login to Telegram, some personal piece of data are created and held by both parties (the client, Pyrogram -and the server, Telegram). This session data is uniquely bound to your own account, indefinitely (until you logout or -decide to manually terminate it) and is used to authorize a client to execute API calls on behalf of your identity. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Persisting Sessions -------------------- - -In order to make a client reconnect successfully between restarts, that is, without having to start a new -authorization process from scratch each time, Pyrogram needs to store the generated session data somewhere. - -Different Storage Engines -------------------------- - -Pyrogram offers two different types of storage engines: a **File Storage** and a **Memory Storage**. -These engines are well integrated in the framework and require a minimal effort to set up. Here's how they work: - -File Storage -^^^^^^^^^^^^ - -This is the most common storage engine. It is implemented by using **SQLite**, which will store the session details. -The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve -data whenever they are needed. - -To use this type of engine, simply pass any name of your choice to the ``name`` parameter of the -:obj:`~pyrogram.Client` constructor, as usual: - -.. code-block:: python - - from pyrogram import Client - - async with Client("my_account") as app: - print(await app.get_me()) - -Once you successfully log in (either with a user or a bot identity), a session file will be created and saved to disk as -``my_account.session``. Any subsequent client restart will make Pyrogram search for a file named that way and the -session database will be automatically loaded. - -Memory Storage -^^^^^^^^^^^^^^ - -In case you don't want to have any session file saved to disk, you can use an in-memory storage by passing True to the -``in_memory`` parameter of the :obj:`~pyrogram.Client` constructor: - -.. code-block:: python - - from pyrogram import Client - - async with Client("my_account", in_memory=True) as app: - print(await app.get_me()) - -This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop -a client, the entire database is discarded and the session details used for logging in again will be lost forever. - -Session Strings ---------------- - -In case you want to use an in-memory storage, but also want to keep access to the session you created, call -:meth:`~pyrogram.Client.export_session_string` anytime before stopping the client... - -.. code-block:: python - - from pyrogram import Client - - async with Client("my_account", in_memory=True) as app: - print(await app.export_session_string()) - -...and save the resulting string. You can use this string by passing it as Client argument the next time you want to -login using the same session; the storage used will still be in-memory: - -.. code-block:: python - - from pyrogram import Client - - session_string = "...ZnUIFD8jsjXTb8g_vpxx48k1zkov9sapD-tzjz-S4WZv70M..." - - async with Client("my_account", session_string=session_string) as app: - print(await app.get_me()) - -Session strings are useful when you want to run authorized Pyrogram clients on platforms where their ephemeral -filesystems makes it harder for a file-based storage engine to properly work as intended. diff --git a/docs/source/topics/synchronous.rst b/docs/source/topics/synchronous.rst deleted file mode 100644 index 0a677b0e50..0000000000 --- a/docs/source/topics/synchronous.rst +++ /dev/null @@ -1,88 +0,0 @@ -Synchronous Usage -================= - -Pyrogram is an asynchronous framework and as such is subject to the asynchronous rules. It can, however, run in -synchronous mode (also known as non-asynchronous or sync/non-async for short). This mode exists mainly as a convenience -way for invoking methods without the need of ``async``/``await`` keywords and the extra boilerplate, but **it's not the -intended way to use the framework**. - -You can use Pyrogram in this synchronous mode when you want to write something short and contained without the -async boilerplate or in case you want to combine Pyrogram with other libraries that are not async. - -.. warning:: - - You have to be very careful when using the framework in its synchronous, non-native form, especially when combined - with other non-async libraries because thread blocking operations that clog the asynchronous event loop underneath - will make the program run erratically. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Synchronous Invocations ------------------------ - -The following is a standard example of running asynchronous functions with Python's asyncio. -Pyrogram is being used inside the main function with its asynchronous interface. - -.. code-block:: python - - import asyncio - from pyrogram import Client - - - async def main(): - app = Client("my_account") - - async with app: - await app.send_message("me", "Hi!") - - - asyncio.run(main()) - -To run Pyrogram synchronously, use the non-async context manager as shown in the following example. -As you can see, the non-async example becomes less cluttered. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - with app: - app.send_message("me", "Hi!") - -Synchronous handlers --------------------- - -You can also have synchronous handlers; you only need to define the callback function without using ``async def`` and -invoke API methods by not placing ``await`` in front of them. Mixing ``def`` and ``async def`` handlers together is also -possible. - -.. code-block:: python - - @app.on_message() - async def handler1(client, message): - await message.forward("me") - - @app.on_edited_message() - def handler2(client, message): - message.forward("me") - -uvloop usage ------------- - -When using Pyrogram in its synchronous mode combined with uvloop, you need to call ``uvloop.install()`` before importing -Pyrogram. - -.. code-block:: python - - import uvloop - uvloop.install() - - from pyrogram import Client - - ... \ No newline at end of file diff --git a/docs/source/topics/test-servers.rst b/docs/source/topics/test-servers.rst deleted file mode 100644 index 1ccfe286c8..0000000000 --- a/docs/source/topics/test-servers.rst +++ /dev/null @@ -1,41 +0,0 @@ -Test Servers -============ - -If you wish to test your application in a separate environment, Pyrogram is able to authorize your account into -Telegram's test servers without hassle. All you need to do is start a new session (e.g.: "my_account_test") using -``test_mode=True``: - -.. code-block:: python - - from pyrogram import Client - - async with Client("my_account_test", test_mode=True) as app: - print(await app.get_me()) - -.. note:: - - If this is the first time you login into test servers, you will be asked to register your account first. - Accounts registered on test servers reside in a different, parallel instance of a Telegram server. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Test Mode in Official Apps --------------------------- - -You can also login yourself into test servers using official desktop apps, such as Telegram Web and Telegram Desktop: - -- **Telegram Web**: Login here: https://web.telegram.org/?test=1 -- **Telegram Desktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server". - -Test Numbers ------------- - -Beside normal numbers, the test environment allows you to login with reserved test numbers. -Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random -numbers. Users with such numbers always get ``XXXXX`` or ``XXXXXX`` as the confirmation code (the DC number, repeated -five or six times). \ No newline at end of file diff --git a/docs/source/topics/text-formatting.rst b/docs/source/topics/text-formatting.rst deleted file mode 100644 index 00aa0cf8c8..0000000000 --- a/docs/source/topics/text-formatting.rst +++ /dev/null @@ -1,243 +0,0 @@ -Text Formatting -=============== - -.. role:: strike - :class: strike - -.. role:: underline - :class: underline - -.. role:: bold-underline - :class: bold-underline - -.. role:: strike-italic - :class: strike-italic - -Pyrogram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled -texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a -variety of decorations that can also be nested in order to combine multiple styles together. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Basic Styles ------------- - -When formatting your messages, you can choose between Markdown-style, HTML-style or both (default). The following is a -list of the basic styles currently supported by Pyrogram. - -- **bold** -- *italic* -- :strike:`strike` -- :underline:`underline` -- spoiler -- `text URL `_ -- `user text mention `_ -- ``inline fixed-width code`` -- .. code-block:: text - - pre-formatted - fixed-width - code block - -Markdown Style --------------- - -To strictly use this mode, pass :obj:`~pyrogram.enums.ParseMode.MARKDOWN` to the *parse_mode* parameter when using -:meth:`~pyrogram.Client.send_message`. Use the following syntax in your message: - -.. code-block:: text - - **bold** - - __italic__ - - --underline-- - - ~~strike~~ - - ||spoiler|| - - [text URL](https://pyrogram.org/) - - [text user mention](tg://user?id=123456789) - - `inline fixed-width code` - - ``` - pre-formatted - fixed-width - code block - ``` - -**Example**: - -.. code-block:: python - - from pyrogram import enums - - await app.send_message( - "me", - ( - "**bold**, " - "__italic__, " - "--underline--, " - "~~strike~~, " - "||spoiler||, " - "[URL](https://pyrogram.org), " - "`code`, " - "```" - "for i in range(10):\n" - " print(i)" - "```" - ), - parse_mode=enums.ParseMode.MARKDOWN - ) - -HTML Style ----------- - -To strictly use this mode, pass :obj:`~pyrogram.enums.HTML` to the *parse_mode* parameter when using -:meth:`~pyrogram.Client.send_message`. The following tags are currently supported: - -.. code-block:: text - - bold, bold - - italic, italic - - underline - - strike, strike, strike - - spoiler - - text URL - - inline mention - - inline fixed-width code - - 🔥 - -
-    pre-formatted
-      fixed-width
-        code block
-    
- -**Example**: - -.. code-block:: python - - from pyrogram import enums - - await app.send_message( - "me", - ( - "bold, " - "italic, " - "underline, " - "strike, " - "spoiler, " - "URL, " - "code\n\n" - "
"
-            "for i in range(10):\n"
-            "    print(i)"
-            "
" - ), - parse_mode=enums.ParseMode.HTML - ) - -.. note:: - - All ``<``, ``>`` and ``&`` symbols that are not a part of a tag or an HTML entity must be replaced with the - corresponding HTML entities (``<`` with ``<``, ``>`` with ``>`` and ``&`` with ``&``). You can use this - snippet to quickly escape those characters: - - .. code-block:: python - - import html - - text = "" - text = html.escape(text) - - print(text) - - .. code-block:: text - - <my text> - -Different Styles ----------------- - -By default, when ignoring the *parse_mode* parameter, both Markdown and HTML styles are enabled together. -This means you can combine together both syntaxes in the same text: - -.. code-block:: python - - await app.send_message("me", "**bold**, italic") - -Result: - - **bold**, *italic* - -If you don't like this behaviour you can always choose to only enable either Markdown or HTML in strict mode by passing -:obj:`~pyrogram.enums.MARKDOWN` or :obj:`~pyrogram.enums.HTML` as argument to the *parse_mode* parameter. - -.. code-block:: python - - from pyrogram import enums - - await app.send_message("me", "**bold**, italic", parse_mode=enums.ParseMode.MARKDOWN) - await app.send_message("me", "**bold**, italic", parse_mode=enums.ParseMode.HTML) - -Result: - - **bold**, italic - - \*\*bold**, *italic* - -In case you want to completely turn off the style parser, simply pass :obj:`~pyrogram.enums.DISABLED` to *parse_mode*. -The text will be sent as-is. - -.. code-block:: python - - from pyrogram import enums - - await app.send_message("me", "**bold**, italic", parse_mode=enums.ParseMode.DISABLED) - -Result: - - \*\*bold**, italic - -Nested and Overlapping Entities -------------------------------- - -You can also style texts with more than one decoration at once by nesting entities together. For example, you can send -a text message with both :bold-underline:`bold and underline` styles, or a text that has both :strike-italic:`italic and -strike` styles, and you can still combine both Markdown and HTML together. - -Here there are some example texts you can try sending: - -**Markdown**: - -- ``**bold, --underline--**`` -- ``**bold __italic --underline ~~strike~~--__**`` -- ``**bold __and** italic__`` - -**HTML**: - -- ``bold, underline`` -- ``bold italic underline strike`` -- ``bold and italic`` - -**Combined**: - -- ``--you can combine HTML with **Markdown**--`` -- ``**and also overlap** --entities this way--`` diff --git a/docs/source/topics/use-filters.rst b/docs/source/topics/use-filters.rst deleted file mode 100644 index ab7296af85..0000000000 --- a/docs/source/topics/use-filters.rst +++ /dev/null @@ -1,114 +0,0 @@ -Using Filters -============= - -So far we've seen :doc:`how to register a callback function <../start/updates>` that executes every time an update comes -from the server, but there's much more than that to come. - -Here we'll discuss about :obj:`~pyrogram.filters`. Filters enable a fine-grain control over what kind of -updates are allowed or not to be passed in your callback functions, based on their inner details. - -.. contents:: Contents - :backlinks: none - :depth: 1 - :local: - ------ - -Single Filters --------------- - -Let's start right away with a simple example: - -- This example will show you how to **only** handle messages containing a :class:`~pyrogram.types.Sticker` object and - ignore any other message. Filters are passed as the first argument of the decorator: - - .. code-block:: python - - from pyrogram import filters - - - @app.on_message(filters.sticker) - async def my_handler(client, message): - print(message) - -- or, without decorators. Here filters are passed as the second argument of the handler constructor; the first is the - callback function itself: - - .. code-block:: python - - from pyrogram import filters - from pyrogram.handlers import MessageHandler - - - async def my_handler(client, message): - print(message) - - - app.add_handler(MessageHandler(my_handler, filters.sticker)) - -Combining Filters ------------------ - -Filters can be used in a more advanced way by inverting and combining more filters together using bitwise -operators ``~``, ``&`` and ``|``: - -- Use ``~`` to invert a filter (behaves like the ``not`` operator). -- Use ``&`` and ``|`` to merge two filters (behave like ``and``, ``or`` operators respectively). - -Here are some examples: - -- Message is a **text** message **or** a **photo**. - - .. code-block:: python - - @app.on_message(filters.text | filters.photo) - async def my_handler(client, message): - print(message) - -- Message is a **sticker** **and** is coming from a **channel or** a **private** chat. - - .. code-block:: python - - @app.on_message(filters.sticker & (filters.channel | filters.private)) - async def my_handler(client, message): - print(message) - -Advanced Filters ----------------- - -Some filters, like :meth:`~pyrogram.filters.command` or :meth:`~pyrogram.filters.regex` -can also accept arguments: - -- Message is either a */start* or */help* **command**. - - .. code-block:: python - - @app.on_message(filters.command(["start", "help"])) - async def my_handler(client, message): - print(message) - -- Message is a **text** message or a media **caption** matching the given **regex** pattern. - - .. code-block:: python - - @app.on_message(filters.regex("pyrogram")) - async def my_handler(client, message): - print(message) - -More handlers using different filters can also live together. - -.. code-block:: python - - @app.on_message(filters.command("start")) - async def start_command(client, message): - print("This is the /start command") - - - @app.on_message(filters.command("help")) - async def help_command(client, message): - print("This is the /help command") - - - @app.on_message(filters.chat("PyrogramChat")) - async def from_pyrogramchat(client, message): - print("New message in @PyrogramChat") diff --git a/docs/source/topics/voice-calls.rst b/docs/source/topics/voice-calls.rst deleted file mode 100644 index aef4030ca8..0000000000 --- a/docs/source/topics/voice-calls.rst +++ /dev/null @@ -1,19 +0,0 @@ -Voice Calls -=========== - -Both private voice calls and group voice calls are currently supported by third-party, external libraries that integrate -with Pyrogram. - -Libraries ---------- - -There are currently two main libraries (with very similar names) you can use: - -1. https://github.com/pytgcalls/pytgcalls -2. https://github.com/MarshalX/tgcalls - -Older implementations ---------------------- - -An older implementation of Telegram voice calls can be found at https://github.com/bakatrouble/pylibtgvoip (currently -outdated due to the deprecation of the Telegram VoIP library used underneath). \ No newline at end of file