├── .flake8 ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── SECURITY.md └── dependabot.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── REWRITE_OVERVIEW.md ├── changes ├── ctx.feature.md ├── routes.127.feature.md └── towncrier.148.feature.md ├── docs ├── Makefile ├── api │ ├── core.rst │ └── extensions │ │ └── gears.rst ├── assets │ └── pycord-v3.png ├── conf.py ├── extensions │ └── resourcelinks.py ├── index.rst └── make.bat ├── examples ├── bot.py ├── cluster.py ├── interactions │ ├── commands │ │ └── application_commands.py │ └── components │ │ ├── button.py │ │ └── text_input.py └── superspeed_rate_limiting.py ├── pycord ├── __init__.py ├── __main__.py ├── _about.py ├── api │ ├── __init__.py │ ├── execution │ │ ├── __init__.py │ │ └── executer.py │ ├── route.py │ └── routers │ │ ├── __init__.py │ │ ├── application_commands.py │ │ ├── application_role_connection_metadata.py │ │ ├── audit_logs.py │ │ ├── auto_moderation.py │ │ ├── base.py │ │ ├── channels.py │ │ ├── emojis.py │ │ ├── guilds.py │ │ ├── messages.py │ │ ├── scheduled_events.py │ │ └── user.py ├── application.py ├── application_role_connection_metadata.py ├── audit_log.py ├── auto_moderation.py ├── banner.txt ├── bot.py ├── channel.py ├── color.py ├── commands │ ├── __init__.py │ ├── application │ │ ├── __init__.py │ │ ├── command.py │ │ ├── context.py │ │ └── errors.py │ ├── command.py │ └── group.py ├── connection.py ├── embed.py ├── enums.py ├── errors.py ├── events │ ├── __init__.py │ ├── channels.py │ ├── event_manager.py │ ├── guilds.py │ └── other.py ├── ext │ ├── __init__.py │ └── gears │ │ ├── __init__.py │ │ └── gear.py ├── file.py ├── flags.py ├── gateway │ ├── __init__.py │ ├── cluster.py │ ├── manager.py │ ├── notifier.py │ ├── passthrough.py │ └── shard.py ├── guild.py ├── guild_template.py ├── http.py ├── ibanner.txt ├── integration.py ├── interaction.py ├── interface.py ├── invite.py ├── media.py ├── member.py ├── message.py ├── message_iterator.py ├── missing.py ├── pages │ ├── __init__.py │ ├── errors.py │ └── paginator.py ├── py.typed ├── role.py ├── scheduled_event.py ├── snowflake.py ├── stage_instance.py ├── state │ ├── __init__.py │ ├── core.py │ ├── grouped_store.py │ └── store.py ├── team.py ├── types │ ├── __init__.py │ ├── application.py │ ├── application_commands.py │ ├── application_role_connection_metadata.py │ ├── audit_log.py │ ├── auto_moderation.py │ ├── channel.py │ ├── component.py │ ├── embed.py │ ├── guild.py │ ├── guild_scheduled_event.py │ ├── guild_template.py │ ├── integration.py │ ├── interaction.py │ ├── invite.py │ ├── media.py │ ├── message.py │ ├── role.py │ ├── snowflake.py │ ├── stage_instance.py │ ├── user.py │ ├── voice_state.py │ ├── webhook.py │ └── welcome_screen.py ├── typing.py ├── ui │ ├── __init__.py │ ├── button.py │ ├── component.py │ ├── house.py │ ├── interactive_component.py │ ├── select_menu.py │ └── text_input.py ├── user.py ├── utils.py ├── voice.py ├── webhook.py └── welcome_screen.py ├── pyproject.toml ├── requirements.txt ├── requirements ├── _.txt ├── dev.txt └── docs.txt ├── setup.cfg ├── setup.py ├── templates └── towncrier.jinja └── tests └── __init__.py /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | min_python_version = 3.10 3 | count = true 4 | max-line-length = 120 5 | show_source = True 6 | statistics = True 7 | 8 | # Mostly taken from the flake8 documentation 9 | ignore = 10 | # F812: list comprehension redefines ... 11 | F812, 12 | # H101: Use TODO(NAME) 13 | H101, 14 | # H202: assertRaises Exception too broad 15 | H202, 16 | # H233: Python 3.x incompatible use of print operator 17 | H233, 18 | # H301: one import per line 19 | H301, 20 | # H306: imports not in alphabetical order (time, os) 21 | H306, 22 | # H401: docstring should not start with a space 23 | H401, 24 | # H403: multi line docstrings should end on a new line 25 | H403, 26 | # H404: multi line docstring should start without a leading new line 27 | H404, 28 | # H405: multi line docstring summary not separated with an empty line 29 | H405, 30 | # H501: Do not use self.__dict__ for string formatting 31 | H501 32 | # T101: Fix todos 33 | T101 34 | # E402: module level import not at top of file 35 | E402 36 | # CFQ002: Function has 7 arguments that exceeds max allowed 6 37 | CFQ002 38 | # CFQ004: Function has 8 returns that exceeds max allowed 3 39 | CFQ004 40 | # E722: do not use bare 'except' 41 | E722 42 | # W503: line break before binary operator 43 | W503 44 | # E203: whitespace before ':' 45 | E203 46 | 47 | per-file-ignores = 48 | # imported but unused 49 | __init__.py: F401, F403, W291 50 | 51 | exclude = 52 | .git, 53 | .idea, 54 | .vs, 55 | .vscode, 56 | __pycache__, 57 | docs, 58 | build, 59 | dist, 60 | venv, 61 | breaking, 62 | .github, 63 | tests-dev, 64 | 65 | accept-encodings = utf-8 66 | max-complexity = 19 67 | docstring-convention = numpy 68 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report broken or incorrect behavior caused by the library. 3 | labels: unconfirmed bug 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: > 8 | Please ensure this is actually a bug with the library, and not with your own code. 9 | 10 | If you discover this is a bug with your code, come ask for help in [our Discord server](https://discord.gg/pycord). 11 | - type: input 12 | attributes: 13 | label: Summary 14 | description: A short summary of the bug encountered. 15 | validations: 16 | required: true 17 | - type: textarea 18 | attributes: 19 | label: Reproduction Steps 20 | description: What steps lead to this bug's occurrence. 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Minimal Reproducible Code 26 | description: > 27 | If code that causes the bug can be given, please provide it here. 28 | render: python 29 | - type: textarea 30 | attributes: 31 | label: Expectations vs. Actual 32 | description: What were your expectations of the code, and what actually happened. 33 | validations: 34 | required: true 35 | - type: input 36 | attributes: 37 | label: Version 38 | description: Please provide the version on which you are running the code. 39 | validations: 40 | required: true 41 | - type: checkboxes 42 | attributes: 43 | label: Issue Checklist 44 | options: 45 | - label: I have searched all issues for duplicates. 46 | required: true 47 | - label: I have shown the entire traceback, if available. 48 | required: true 49 | - label: I have removed my token from any given code, if visible. 50 | required: true 51 | - type: textarea 52 | attributes: 53 | label: More Information 54 | description: Please provide any extra information you have here, including system information. 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a question 4 | about: Ask questions and discuss with other users of the library. 5 | url: https://github.com/Pycord-Development/pycord-v3/discussions 6 | - name: Discord Server 7 | about: Use our official Discord server to ask for help and questions as well. 8 | url: https://pycord.dev/discord 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest a feature implementation for a section of the library. 3 | labels: feature request 4 | body: 5 | - type: input 6 | attributes: 7 | label: Summary 8 | description: A short summary of what your feature request is. 9 | validations: 10 | required: true 11 | - type: dropdown 12 | attributes: 13 | multiple: false 14 | label: What section of the library should this be implemented in? 15 | options: 16 | - pycord [core library] 17 | - pycord.ext.gears 18 | - pycord.ext.pager 19 | - docs 20 | validations: 21 | required: true 22 | - type: textarea 23 | attributes: 24 | label: Purpose 25 | description: > 26 | What is the general purpose of this feature request? What exactly becomes easier or 27 | possible when this feature is implemented? 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Ideal Solution 33 | description: > 34 | Is there a specific way this should be implemented? 35 | Is there anything particular this feature should do? 36 | - type: textarea 37 | attributes: 38 | label: Current Solution 39 | description: What is the current solution to this problem, if any? 40 | - type: textarea 41 | attributes: 42 | label: More Information 43 | description: If there is anything else you'd like to add, please do so here. 44 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | If you find a vulnerability you have two ways to report it: 6 | 7 | - Write a dm to one of our core developers on https://pycord.dev/discord 8 | - Write an email to admin@pycord.dev 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *build/ 2 | dist/ 3 | parts/ 4 | sdist/ 5 | *.egg-info/ 6 | *.egg 7 | .vscode/* 8 | .vs/* 9 | .idea/* 10 | out/* 11 | __pycache__/ 12 | test.py 13 | .pytest_cache/ 14 | .mypy_cache/ 15 | .nox/ 16 | *.inv 17 | ci.py 18 | .env 19 | testing/ -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.3.0 4 | hooks: 5 | - id: trailing-whitespace 6 | - id: end-of-file-fixer 7 | - repo: https://github.com/PyCQA/isort 8 | rev: 5.10.1 9 | hooks: 10 | - id: isort 11 | - repo: https://github.com/odwyersoftware/brunette 12 | rev: 0.2.7 13 | hooks: 14 | - id: brunette 15 | args: [--safe, --quiet, --single-quotes] 16 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | formats: [] 3 | 4 | build: 5 | os: ubuntu-20.04 6 | tools: 7 | python: "3.10" 8 | 9 | python: 10 | install: 11 | - method: pip 12 | path: . 13 | extra_requirements: 14 | - docs 15 | 16 | sphinx: 17 | configuration: docs/conf.py 18 | fail_on_warning: false 19 | builder: html 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | This project uses [*towncrier*](https://towncrier.readthedocs.io/) for upkeep of our new changelog. 8 | 9 | 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Pycord v3 Contribution Guide 2 | 3 | This is an extremely basic guide for contributing to the repo. 4 | 5 | ## Steps for Every Contribution 6 | 7 | ***There is only 1.*** 8 | 9 | 1. Make sure your contribution is not a duplicate before opening (i.e., search all open contributions and ensure it doesn't closely relate to yours). 10 | 11 | ## Steps for Opening Issues 12 | 13 | Thanks for taking the time to open an issue, this helps us make a more stable and usable library. 14 | 15 | 1. Fill out the template. If the template is not filled out properly, your issue will most likely be closed. 16 | 1. If you include a traceback when creating a bug report, or if you include bits of code in your feature request, please place it in a [code block](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks). 17 | 2. Be as detailed as possible when creating your issue. In most scenarios, the fewer details that we are given, the longer it will take for your issue to be resolved. 18 | 19 | ## Steps for Opening Pull Requests 20 | 21 | Considering that we are in a pre-alpha state right now, thank you very much for your contribution. It is deeply appreciated. 22 | 23 | However, before you create your PR, please ensure you've done a couple of things: 24 | 25 | 1. Your PR needs to have a clear purpose. PRs that edit multiple files are more than welcome, but make sure it accomplishes a single goal. This could be fixing a bug, refactoring, or even adding new material. 26 | 2. Follow the style of the library. This implies two separate points: 27 | 1. Make sure your code is as clean as possible and looks similar to the rest of the codebase. This includes spacing, function signatures/definitions, and commenting/documentation format. 28 | 2. Ensure that your opened pull request follows the [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/#summary) styling guide. This helps people understand the purpose of the PR, and how it should be reviewed. 29 | 3. If possible, try to use our pre-commit hooks to format your code. These hooks format the code before you push it to GitHub, and could vastly improve your own experience by not needing to use other formatting commands. 30 | 31 | ## Appending to the Changelog 32 | 33 | Pycord tries to keep an up-to-date changelog of every change to ensure easy tracking of breaking or non-breaking changes. 34 | 35 | This does mean however that you need to changelog every pull request you make. 36 | We try to make this as easy as possible to ensure *you* the developer can easily make and get a pull request merged. 37 | 38 | Firstly, if you haven't already, download Towncrier (the tool we use for changelog upkeep): 39 | 40 | ```sh 41 | pip install -U towncrier 42 | ``` 43 | 44 | Now, you are ready to create the house of your change, its file. To start: 45 | 46 | ```sh 47 | towncrier create {pull_request_shortname}.{pull_request_number}.{pull_request_type} 48 | ``` 49 | 50 | This command means multiple things, in which: 51 | 52 | - `pull_request_shortname`: the name of your PR lowercased and in the shortest form possible. 53 | - `pull_request_number`: the pull request your making this for. i.e.: #178 54 | - `pull_request_type`: the type of pull request (doc, feature, removal, bug, trivial, etc). 55 | 56 | Once you've formed that, you can make the content of your changelog. There's are not too much rules about what you *can* and *can't* 57 | put in this. Of course, they have to be relevant to the pull request, however, they do have to have one general form: 58 | 59 | ```md 60 | [#{pull_request_number}](https://github.com/pycord/pycord-v3/issues/{pull_request_number}): {pull_request_name} 61 | 62 | {Details on what this pull request does, and why} 63 | 64 | - {An exact} 65 | - {List of} 66 | - {Changes} 67 | ``` 68 | 69 | This only introduces one notable variable: `{pull_request_name}`. 70 | 71 | This variable is simply a version of your pull request name without Conventional Commits. Such as: 72 | 73 | - "Adds Towncrier" 74 | - "Implement Modals" 75 | - "Switch to Ruff," etc.. 76 | 77 | ## Where can I get more help with my issue/PR? 78 | 79 | Docs are somewhat chaotic at the moment, so your best bet is [our Discord server](https://discord.gg/pycord). 80 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-present Pycord Development 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | include LICENSE 3 | include requirements.txt 4 | include pycord/bin/*.dll 5 | include pycord/py.typed 6 | include pycord/banner.txt 7 | include pycord/ibanner.txt 8 | 9 | prune .github 10 | prune docs 11 | prune examples 12 | prune tests 13 | prune news 14 | prune templates 15 | exclude pycord/bin/COPYING 16 | exclude .flake8 17 | exclude .gitignore 18 | exclude .pre-commit-config.yaml 19 | exclude .prettierrc 20 | exclude .readthedocs.yml 21 | exclude FUNDING.yml 22 | exclude requirements-dev.txt 23 | -------------------------------------------------------------------------------- /REWRITE_OVERVIEW.md: -------------------------------------------------------------------------------- 1 | # Rewrite Overview 2 | 3 | Complete overview of every breaking change 4 | made in v3, and why we made them. 5 | 6 | ## Namespace 7 | 8 | By far one of the smallest yet most significant 9 | changes is our namespace. 10 | While v2 used to have the discord namespace 11 | for v3 to signify we're not a fork anymore 12 | we changed it to pycord. 13 | 14 | So instead of `import discord` its just 15 | `import pycord` now. 16 | 17 | ## Generalized Commands 18 | 19 | In v3, commands have been restructured 20 | into one system to allow the easy creation 21 | of new ones. 22 | 23 | Instead of having `bot.slash_command` and the other types 24 | like in v2, you instead use our one decorator `bot.command`. 25 | 26 | Expansibility has been made a priority 27 | for v3, so we also made Commands easy to customize. 28 | Command creators provide a `cls` field to 29 | show which Command class they want to use. 30 | This is required and is not set to any default 31 | 32 | An example Slash Command could be the following: 33 | 34 | ```py 35 | import pycord 36 | 37 | bot = pycord.Bot(...) 38 | 39 | @bot.command('echo', pycord.ApplicationCommand, description='Command to echo a message') 40 | async def echo(inter: pycord.Interaction, msg: str = pycord.Option(name='message', description='The message to echo')): 41 | await inter.resp.send(msg) 42 | 43 | bot.run(...) 44 | ``` 45 | 46 | ## Extensible Cache 47 | 48 | Caching has been rebuilt to allow 49 | higher levels of extensibility. 50 | 51 | Do you want to cache on redis? Now you can! 52 | It's extremely easy, just subclass our 53 | Store class and rebuild it for your cacher. 54 | 55 | ## Extensions 56 | 57 | ### Cogs 58 | 59 | Cogs have been completely reformed from the 60 | ground up to build a brand new and better 61 | experience. 62 | 63 | To show that difference, we have renamed Cogs 64 | to Gears, also because it's particularly a better name. 65 | 66 | - Basic Cog with Slash Command 67 | ```py 68 | from discord.cogs import Cog 69 | from discord.commands import slash_command 70 | 71 | class MyCog(Cog): 72 | @slash_command 73 | async def dunce(self) -> None: 74 | ... 75 | ``` 76 | 77 | - Basic Gear with Slash Command 78 | ```py 79 | import pycord 80 | from pycord.ext.gears import Gear 81 | 82 | gear = Gear(__name__) 83 | 84 | @gear.command('dunce', pycord.ApplicationCommand, type=1, description='duncy command') 85 | async def dunce(inter: pycord.Interaction) -> None: 86 | ... 87 | ``` 88 | -------------------------------------------------------------------------------- /changes/ctx.feature.md: -------------------------------------------------------------------------------- 1 | #[main]: Adds Context-like functionality back to v3. 2 | 3 | Introducing Prelude: the new Context. 4 | -------------------------------------------------------------------------------- /changes/routes.127.feature.md: -------------------------------------------------------------------------------- 1 | #[127](https://github.com/pycord/pycord-v3/issues/127): Routes 2 | 3 | Adds a bunch of new routes. This also increases memory efficiency and speed by heavily making use of 4 | `__slots__` where it wasn't before. 5 | 6 | A full list of new routes cannot be provided, though you can always parse through the diff and see. 7 | 8 | This is not a complete implementation, yet it is the start. Future PRs will be categorized for specific route topics. 9 | -------------------------------------------------------------------------------- /changes/towncrier.148.feature.md: -------------------------------------------------------------------------------- 1 | #[148](https://github.com/pycord/pycord-v3/issues/148): Towncrier 2 | 3 | As Pycord v3 grows as a library, a dedicated changelog must be upkept. 4 | Unlike v2, we decided to go down the route of a more advanced tool for v3, that being 5 | to use Towncrier. 6 | 7 | Notable changes are: 8 | 9 | - Simply adding towncrier config 10 | - Creation of `changes` and `template` directories 11 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/api/core.rst: -------------------------------------------------------------------------------- 1 | .. currentmodule:: pycord 2 | 3 | API Reference 4 | ============= 5 | 6 | Main Classes 7 | ------------ 8 | 9 | Bot 10 | ~~~ 11 | 12 | .. autoclass:: Bot() 13 | :members: 14 | 15 | 16 | Application Commands 17 | -------------------- 18 | 19 | Application Command 20 | ~~~~~~~~~~~~~~~~~~~ 21 | 22 | .. autoclass:: ApplicationCommand() 23 | :members: 24 | 25 | Option 26 | ~~~~~~ 27 | 28 | .. autoclass:: Option() 29 | :members: 30 | 31 | Choice 32 | ~~~~~~ 33 | 34 | .. autoclass:: CommandChoice() 35 | :members: 36 | 37 | 38 | Discord Models 39 | -------------- 40 | 41 | Application 42 | ~~~~~~~~~~~ 43 | 44 | .. autoclass:: Application() 45 | :members: 46 | 47 | Audit Log 48 | ~~~~~~~~~ 49 | 50 | .. autoclass:: AuditLog() 51 | :members: 52 | 53 | 54 | Etcetera Classes 55 | ---------------- 56 | 57 | Missing 58 | ~~~~~~~ 59 | 60 | .. autoclass:: MISSING 61 | -------------------------------------------------------------------------------- /docs/api/extensions/gears.rst: -------------------------------------------------------------------------------- 1 | .. currentmodule:: pycord.ext.gears 2 | 3 | Gears API Reference 4 | =================== 5 | Gear's Represent Pycord's ambitious path for a new modernisitic library, scrapping the old system for a new 6 | rethought and remade one. 7 | 8 | API 9 | --- 10 | 11 | Gear 12 | ~~~~ 13 | 14 | .. autoclass:: Gear 15 | :members: 16 | -------------------------------------------------------------------------------- /docs/assets/pycord-v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pycord-Development/pycord-next/3b94ae3f1ed951930e53a105c9be985c5ae5d7e1/docs/assets/pycord-v3.png -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | import os 7 | import sys 8 | 9 | # -- Project information ----------------------------------------------------- 10 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 11 | 12 | project = 'Pycord' 13 | 14 | copyright = '2021-present, Pycord Development' 15 | author = 'Pycord Development' 16 | release = '3.0.0' 17 | 18 | # -- General configuration --------------------------------------------------- 19 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 20 | 21 | sys.path.insert(0, os.path.abspath('..')) 22 | sys.path.append(os.path.abspath('extensions')) 23 | 24 | extensions = [ 25 | 'resourcelinks', 26 | 'sphinx.ext.autodoc', 27 | 'sphinx.ext.napoleon', 28 | 'sphinx.ext.intersphinx', 29 | ] 30 | 31 | templates_path = ['_templates'] 32 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 33 | 34 | autodoc_member_order = 'bysource' 35 | autodoc_typehints = 'none' 36 | 37 | # -- Options for HTML output ------------------------------------------------- 38 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 39 | 40 | html_theme = 'pydata_sphinx_theme' 41 | 42 | # Add any paths that contain custom static files (such as style sheets) here, 43 | # relative to this directory. They are copied after the builtin static files, 44 | # so a file named 'default.css' will overwrite the builtin 'default.css'. 45 | html_static_path = ['_static'] 46 | 47 | html_logo = 'https://raw.githubusercontent.com/Pycord-Development/pycord-v3/main/docs/assets/pycord-v3.png' 48 | 49 | # Any option(s) added to your certain theme. 50 | # in this case, Pydata 51 | html_theme_options = { 52 | 'footer_items': ['copyright', 'sphinx-version'], 53 | } 54 | 55 | html_sidebars = {'**': ['sidebar-nav-bs']} 56 | 57 | resource_links = { 58 | 'guide': 'https://guide.pycord.dev', 59 | 'repository': 'https://github.com/pycord-development/pycord-v3', 60 | } 61 | 62 | # Links used for cross-referencing stuff in other documentation 63 | intersphinx_mapping = { 64 | 'py': ('https://docs.python.org/3', None), 65 | 'aio': ('https://docs.aiohttp.org/en/stable/', None), 66 | } 67 | -------------------------------------------------------------------------------- /docs/extensions/resourcelinks.py: -------------------------------------------------------------------------------- 1 | # Credit to sphinx.ext.extlinks for being a good starter 2 | # Copyright 2007-2020 by the Sphinx team 3 | # Licensed under BSD. 4 | 5 | from typing import Any, Dict, List, Tuple 6 | 7 | import sphinx 8 | from docutils import nodes, utils 9 | from docutils.nodes import Node, system_message 10 | from docutils.parsers.rst.states import Inliner 11 | from sphinx.application import Sphinx 12 | from sphinx.util.nodes import split_explicit_title 13 | from sphinx.util.typing import RoleFunction 14 | 15 | 16 | def make_link_role(resource_links: Dict[str, str]) -> RoleFunction: 17 | def role( 18 | typ: str, 19 | rawtext: str, 20 | text: str, 21 | lineno: int, 22 | inliner: Inliner, 23 | options: Dict = {}, 24 | content: List[str] = [], 25 | ) -> Tuple[List[Node], List[system_message]]: 26 | text = utils.unescape(text) 27 | has_explicit_title, title, key = split_explicit_title(text) 28 | full_url = resource_links[key] 29 | if not has_explicit_title: 30 | title = full_url 31 | pnode = nodes.reference(title, title, internal=False, refuri=full_url) 32 | return [pnode], [] 33 | 34 | return role 35 | 36 | 37 | def add_link_role(app: Sphinx) -> None: 38 | app.add_role('resource', make_link_role(app.config.resource_links)) 39 | 40 | 41 | def setup(app: Sphinx) -> Dict[str, Any]: 42 | app.add_config_value('resource_links', {}, 'env') 43 | app.connect('builder-inited', add_link_role) 44 | return {'version': sphinx.__display_version__, 'parallel_read_safe': True} 45 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. Pycord documentation master file, created by 2 | sphinx-quickstart on Thu Nov 17 21:56:36 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Pycord's documentation! 7 | ================================== 8 | 9 | This is the documentation for Pycord, a library made for modern discord bots. 10 | 11 | **Features:** 12 | 13 | * Advanced and Fast 429 handling 14 | * Modern and Easy-to-use user interface 15 | * Optimized for memory, speed, and expandability 16 | 17 | Getting started 18 | --------------- 19 | 20 | For Guides on such things like installations, to Gateway Intents, please go to our :resource:`specialized guide ` instead. 21 | 22 | For examples, we'd recommend checking out the ones in our :resource:`repository `. 23 | 24 | .. toctree:: 25 | :maxdepth: 2 26 | :caption: Contents: 27 | 28 | Manuals 29 | ------- 30 | 31 | These go into great internal detail about what and how something does something. 32 | 33 | Core API 34 | -------- 35 | 36 | .. toctree:: 37 | :maxdepth: 1 38 | 39 | api/core.rst 40 | 41 | Extension API 42 | ------------- 43 | 44 | .. toctree:: 45 | :maxdepth: 1 46 | 47 | api/extensions/gears.rst 48 | api/extensions/pager.rst 49 | 50 | 51 | Indices and tables 52 | ================== 53 | 54 | * :ref:`genindex` 55 | * :ref:`modindex` 56 | * :ref:`search` 57 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /examples/bot.py: -------------------------------------------------------------------------------- 1 | import pycord 2 | 3 | bot = pycord.Bot(intents=pycord.Intents.all()) 4 | 5 | 6 | @bot.listen('on_guild_available') 7 | async def on_ready(guild: pycord.Guild) -> None: 8 | print(f' In Guild: {guild.name}') 9 | 10 | 11 | bot.run('token') 12 | -------------------------------------------------------------------------------- /examples/cluster.py: -------------------------------------------------------------------------------- 1 | import pycord 2 | 3 | bot = pycord.Bot(intents=pycord.Intents.all(), shards=6) 4 | 5 | 6 | @bot.listen('on_guild_create') 7 | async def on_ready(guild: pycord.Guild) -> None: 8 | print(f' In Guild: {guild.name}') 9 | 10 | 11 | bot.cluster('token', 2) 12 | -------------------------------------------------------------------------------- /examples/interactions/commands/application_commands.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | import pycord 4 | 5 | # start the bot with no intents, and with default config 6 | bot = pycord.Bot(intents=pycord.Intents()) 7 | 8 | # the guild id to deploy on. Often used for developing to 9 | # avoid having to wait the extraneous amount of time Discord has for global 10 | # commands 11 | GUILD_ID: int | pycord.MissingEnum = pycord.MISSING 12 | 13 | 14 | # make a chat input command which 15 | # is named favorite and that displays 16 | # an autocompleted list of animes to pick from 17 | @bot.command(guild_id=GUILD_ID) 18 | # make a function for what to do once the user 19 | # has completed their input. 20 | # this has the option anime, displayed as a Parameter, 21 | # which is parsed by Pycord to give you the information the user gave. 22 | async def favorite( 23 | ctx: pycord.Context, 24 | # The name of this option, 25 | # can be set to anything but 26 | # try to keep it short 27 | anime: Annotated[ 28 | str, 29 | pycord.Option( 30 | # The description for this option, 31 | # this is a longer version of name displaying 32 | # more detail and technicalities 33 | description='Your favorite Anime Show', 34 | # this just sets it so the user cannot proceed without 35 | # entering this option 36 | required=True, 37 | # enables autocomplete on Discord's side 38 | autocomplete=True, 39 | # these are the choices the user can pick. 40 | # the first value is the name, which is what 41 | # the user will see. The second is the value, which is what 42 | # you, or the bot, will see. 43 | choices=[ 44 | pycord.CommandChoice('Attack on Titan'), 45 | pycord.CommandChoice("JoJo's Bizzare Adventure"), 46 | pycord.CommandChoice('Cowboy Bebop'), 47 | pycord.CommandChoice('Hunter x Hunter'), 48 | pycord.CommandChoice('Spy x Family'), 49 | ], 50 | ), 51 | ], 52 | ): 53 | """Pick which one is your favorite anime""" 54 | 55 | # checks the value of the int 56 | # and if it matches up to an anime, 57 | # it responds with a custom response. 58 | match anime: 59 | case 'Attack on Titan': 60 | await ctx.send('It seems like you like Attack on Titan, Nice!') 61 | case "JoJo's Bizzare Adventure": 62 | await ctx.send("おにいちゃんありがとう. You like JoJo's Bizzare Adventure. Nice!") 63 | case 'Cowboy Bebop': 64 | await ctx.send('良い!あなたはカウボーイビバップが好きです') 65 | case 'Hunter x Hunter': 66 | await ctx.send( 67 | 'I ran out of responses... Well anyway, you like Hunter x Hunter which is Nice!' 68 | ) 69 | case 'Spy x Family': 70 | await ctx.send( 71 | 'I have a friend which really likes this anime, ' 72 | "it's good seeing you like it too. Of course, Spy x Family!" 73 | ) 74 | 75 | 76 | # run the bot with the token. 77 | # PLEASE REMEMBER TO CHANGE! 78 | bot.run('token') 79 | -------------------------------------------------------------------------------- /examples/interactions/components/button.py: -------------------------------------------------------------------------------- 1 | import pycord 2 | 3 | # initiate a bot with 0 intents 4 | bot = pycord.Bot(intents=pycord.Intents()) 5 | 6 | # create a house to store our components 7 | house = pycord.House() 8 | 9 | # add a button to our house 10 | # as well as add a callback for when its interacted with 11 | @house.button(pycord.ButtonStyle.GREEN, 'yes') 12 | async def yes_button(inter: pycord.Interaction) -> None: 13 | await inter.resp.send('you said yes!') 14 | 15 | 16 | # add a "no" button in direct reply to 17 | # our "yes" button 18 | # responds the same as yes but with a touch of no 19 | @house.button(pycord.ButtonStyle.RED, 'no') 20 | async def no_button(inter: pycord.Interaction) -> None: 21 | await inter.resp.send('you said no :(') 22 | 23 | 24 | # listen for the on_message event 25 | @bot.listen('on_message') 26 | async def on_message(message: pycord.Message) -> None: 27 | # check if the content in this message aligns 28 | # with the wanted content of our command 29 | if message.content == '!!yesorno': 30 | # send the house singularly 31 | # if you want to send multiple, just do houses= and set the value as a list 32 | await message.channel.send('Heres your house mate', house=house) 33 | 34 | 35 | # run the bot with the token. 36 | # PLEASE REMEMBER TO CHANGE! 37 | bot.run('token') 38 | -------------------------------------------------------------------------------- /examples/interactions/components/text_input.py: -------------------------------------------------------------------------------- 1 | import pycord 2 | from pycord.ui import text_input 3 | 4 | # initiate a bot with 0 intents 5 | bot = pycord.Bot(intents=pycord.Intents()) 6 | 7 | # make a modal which holds our text inputs 8 | favorite_friend_modal = text_input.Modal("Who's your favorite friend?") 9 | # add a text input into this modal 10 | favorite_friend_modal.add_text_input( 11 | # instantiate a TextInput class 12 | text_input.TextInput( 13 | # the name of the text input 14 | # in this case "Friend Name" 15 | 'Friend Name', 16 | # should this be styled as a paragraph 17 | # or shortened? In this case short since it's only names 18 | pycord.TextInputStyle.SHORT, 19 | # makes this TextInput required to proceed 20 | required=True, 21 | # the placeholder (or example) value set 22 | placeholder='Michael.. Bob.. Emre..', 23 | ) 24 | ) 25 | 26 | 27 | # a function which runs every time 28 | # a favorite_friend_modal is finished 29 | @favorite_friend_modal.on_call 30 | async def on_favorite_friend_call(inter: pycord.Interaction, name: str) -> None: 31 | # sends the friends name in chat 32 | await inter.resp.send(f"{inter.user.name}'s favorite friend is {name}!") 33 | 34 | 35 | # create an app command to send the modal in 36 | @bot.command( 37 | # names the app command "favorite_friend" 38 | 'favorite_friend', 39 | # sets the command type to Application 40 | pycord.ApplicationCommand, 41 | # specifies this should be a chat input (slash) command 42 | type=pycord.ApplicationCommandType.CHAT_INPUT, 43 | # the command description 44 | description='Describe your favorite friend within a modal', 45 | # a test guild to append this command to 46 | guild_id=None, 47 | ) 48 | async def favorite_friend(inter: pycord.Interaction) -> None: 49 | # send the modal to the user 50 | await inter.resp.send_modal(modal=favorite_friend_modal) 51 | 52 | 53 | # run the bot with the token 54 | # PLEASE REMEMBER TO CHANGE! 55 | bot.run('token') 56 | -------------------------------------------------------------------------------- /examples/superspeed_rate_limiting.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import logging 3 | from typing import Any 4 | 5 | import pycord 6 | 7 | logging.basicConfig(level=logging.DEBUG) 8 | api = pycord.HTTPClient('token') 9 | GUILD_ID = 0 10 | 11 | 12 | async def spam_channels() -> None: 13 | channels: list[dict[str, Any]] = [] 14 | 15 | tasks: list[asyncio.Task] = [ 16 | api.request( 17 | 'POST', 18 | pycord.Route('/guilds/{guild_id}/channels', guild_id=GUILD_ID), 19 | {'name': 'rate-limit-test'}, 20 | ) 21 | for _ in range(50) 22 | ] 23 | 24 | channels = await asyncio.gather(*tasks) 25 | tasks.clear() 26 | 27 | tasks.extend( 28 | api.request( 29 | 'DELETE', pycord.Route('/channels/{channel_id}', channel_id=channel['id']) 30 | ) 31 | for channel in channels 32 | ) 33 | 34 | await asyncio.gather(*tasks) 35 | await api.close_session() 36 | 37 | 38 | asyncio.run(spam_channels()) 39 | -------------------------------------------------------------------------------- /pycord/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pycord 3 | ~~~~~~ 4 | Making Bots Happen. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from ._about import * 10 | from .api import * 11 | from .application import * 12 | from .audit_log import * 13 | from .auto_moderation import * 14 | from .bot import * 15 | from .channel import * 16 | from .color import * 17 | from .commands import * 18 | from .connection import * 19 | from .embed import * 20 | from .enums import * 21 | from .events import * 22 | from .flags import * 23 | from .gateway import * 24 | from .guild import * 25 | from .guild_template import * 26 | from .http import * 27 | from .integration import * 28 | from .interaction import * 29 | from .interface import * 30 | from .invite import * 31 | from .media import * 32 | from .member import * 33 | from .message import * 34 | from .role import * 35 | from .snowflake import * 36 | from .stage_instance import * 37 | from .state import * 38 | from .team import * 39 | from .user import * 40 | from .utils import * 41 | from .voice import * 42 | from .webhook import * 43 | from .welcome_screen import * 44 | -------------------------------------------------------------------------------- /pycord/__main__.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | """Cli processes.""" 22 | import platform 23 | import sys 24 | 25 | import pycord 26 | 27 | 28 | def main() -> None: 29 | version = pycord.__version__ 30 | python_version = platform.python_version() 31 | sys.stderr.write(f'Running on Pycord Version {version},') 32 | sys.stderr.write(f' with Python version {python_version}.') 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /pycord/_about.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | import logging 23 | import typing 24 | 25 | __title__: str = 'pycord' 26 | __author__: str = 'Pycord Development' 27 | __license__: str = 'MIT' 28 | __copyright__: str = 'Copyright 2021-present Pycord Development' 29 | __version__: str = '3.0.0' 30 | __git_sha1__: str = 'HEAD' 31 | 32 | 33 | class VersionInfo(typing.NamedTuple): 34 | major: int 35 | minor: int 36 | micro: int 37 | releaselevel: typing.Literal['alpha', 'beta', 'candidate', 'final'] 38 | serial: int 39 | 40 | 41 | version_info: VersionInfo = VersionInfo( 42 | major=3, minor=0, micro=0, releaselevel='alpha', serial=0 43 | ) 44 | 45 | logging.getLogger(__name__).addHandler(logging.NullHandler()) 46 | 47 | __all__: typing.Sequence[str] = ( 48 | '__title__', 49 | '__author__', 50 | '__license__', 51 | '__copyright__', 52 | '__version__', 53 | 'VersionInfo', 54 | 'version_info', 55 | ) 56 | -------------------------------------------------------------------------------- /pycord/api/execution/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.execution 3 | ~~~~~~~~~~~~~~~~ 4 | Rate Limit execution for the Discord API 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .executer import * 10 | -------------------------------------------------------------------------------- /pycord/api/execution/executer.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | import asyncio 22 | 23 | from ..route import BaseRoute 24 | 25 | 26 | class Executer: 27 | def __init__(self, route: BaseRoute) -> None: 28 | self.route = route 29 | self.is_global: bool | None = None 30 | self._request_queue: asyncio.Queue[asyncio.Event] | None = None 31 | self.rate_limited: bool = False 32 | 33 | async def executed( 34 | self, reset_after: int | float, limit: int, is_global: bool 35 | ) -> None: 36 | self.rate_limited = True 37 | self.is_global = is_global 38 | self._reset_after = reset_after 39 | self._request_queue = asyncio.Queue() 40 | 41 | await asyncio.sleep(reset_after) 42 | 43 | self.is_global = False 44 | 45 | # NOTE: This could break if someone did a second global rate limit somehow 46 | requests_passed: int = 0 47 | for _ in range(self._request_queue.qsize() - 1): 48 | if requests_passed == limit: 49 | requests_passed = 0 50 | if not is_global: 51 | await asyncio.sleep(reset_after) 52 | else: 53 | await asyncio.sleep(5) 54 | 55 | requests_passed += 1 56 | e = await self._request_queue.get() 57 | e.set() 58 | 59 | async def wait(self) -> None: 60 | if not self.rate_limited: 61 | return 62 | 63 | event = asyncio.Event() 64 | 65 | if self._request_queue: 66 | self._request_queue.put_nowait(event) 67 | else: 68 | raise ValueError( 69 | 'Request queue does not exist, rate limit may have been solved.' 70 | ) 71 | await event.wait() 72 | -------------------------------------------------------------------------------- /pycord/api/route.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Sequence 22 | 23 | from pycord.types import Snowflake 24 | 25 | __all__: Sequence[str] = ('Route', 'BaseRoute') 26 | 27 | 28 | class BaseRoute: 29 | guild_id: int | None 30 | channel_id: int | None 31 | webhook_id: int | None 32 | webhook_token: str | None 33 | 34 | def __init__( 35 | self, 36 | path: str, 37 | guild_id: Snowflake | None = None, 38 | channel_id: Snowflake | None = None, 39 | webhook_id: Snowflake | None = None, 40 | webhook_token: str | None = None, 41 | **parameters: str | int, 42 | ) -> None: 43 | ... 44 | 45 | def merge(self, url: str) -> str: 46 | pass 47 | 48 | 49 | class Route(BaseRoute): 50 | def __init__( 51 | self, 52 | path: str, 53 | guild_id: Snowflake | None = None, 54 | channel_id: Snowflake | None = None, 55 | webhook_id: Snowflake | None = None, 56 | webhook_token: str | None = None, 57 | **parameters: str | int, 58 | ): 59 | self.path = path 60 | 61 | # major parameters 62 | self.guild_id = guild_id 63 | self.channel_id = channel_id 64 | self.webhook_id = webhook_id 65 | self.webhook_token = webhook_token 66 | 67 | self.parameters = parameters 68 | 69 | def merge(self, url: str): 70 | return url + self.path.format( 71 | guild_id=self.guild_id, 72 | channel_id=self.channel_id, 73 | webhook_id=self.webhook_id, 74 | webhook_token=self.webhook_token, 75 | **self.parameters, 76 | ) 77 | 78 | def __eq__(self, route: 'Route') -> bool: 79 | return ( 80 | route.channel_id == self.channel_id 81 | or route.guild_id == self.guild_id 82 | or route.webhook_id == self.webhook_id 83 | or route.webhook_token == self.webhook_token 84 | ) 85 | -------------------------------------------------------------------------------- /pycord/api/routers/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.api.routers 3 | ~~~~~~~~~~~~~~~~~~ 4 | Implementation of Discord API Routes 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .application_commands import * 10 | from .application_role_connection_metadata import * 11 | from .audit_logs import * 12 | from .auto_moderation import * 13 | from .base import * 14 | from .channels import * 15 | from .emojis import * 16 | from .guilds import * 17 | from .messages import * 18 | -------------------------------------------------------------------------------- /pycord/api/routers/application_role_connection_metadata.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from ...snowflake import Snowflake 22 | from ...types import ApplicationRoleConnectionMetadata 23 | from ..route import Route 24 | from .base import BaseRouter 25 | 26 | 27 | class ApplicationRoleConnections(BaseRouter): 28 | async def get_application_role_connection_metadata_records( 29 | self, 30 | application_id: Snowflake, 31 | ) -> list[ApplicationRoleConnectionMetadata]: 32 | return await self.request( 33 | 'GET', 34 | Route( 35 | '/applications/{application_id}/role-connections/metadata', 36 | application_id=application_id, 37 | ), 38 | ) 39 | 40 | async def update_application_role_connection_metadata_records( 41 | self, 42 | application_id: Snowflake, 43 | records: list[ApplicationRoleConnectionMetadata], 44 | ) -> list[ApplicationRoleConnectionMetadata]: 45 | return self.request( 46 | 'PUT', 47 | Route( 48 | '/applications/{application_id}/role-connections/metadata', 49 | application_id=application_id, 50 | ), 51 | records, 52 | ) 53 | -------------------------------------------------------------------------------- /pycord/api/routers/audit_logs.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from ...missing import MISSING, MissingEnum 22 | from ...snowflake import Snowflake 23 | from ...types import AUDIT_LOG_EVENT_TYPE, AuditLog 24 | from ...utils import remove_undefined 25 | from ..route import Route 26 | from .base import BaseRouter 27 | 28 | 29 | class AuditLogs(BaseRouter): 30 | async def get_guild_audit_log( 31 | self, 32 | guild_id: Snowflake, 33 | *, 34 | user_id: Snowflake | MissingEnum = MISSING, 35 | action_type: AUDIT_LOG_EVENT_TYPE | MissingEnum = MISSING, 36 | before: Snowflake | MissingEnum = MISSING, 37 | after: Snowflake | MissingEnum = MISSING, 38 | limit: int | MissingEnum = MISSING, 39 | ) -> AuditLog: 40 | params = { 41 | 'user_id': user_id, 42 | 'action_type': action_type, 43 | 'before': before, 44 | 'after': after, 45 | 'limit': limit, 46 | } 47 | return await self.request( 48 | 'GET', 49 | Route( 50 | '/guilds/{guild_id}/audit-logs', 51 | guild_id=guild_id, 52 | ), 53 | query_params=remove_undefined(params), 54 | ) 55 | -------------------------------------------------------------------------------- /pycord/api/routers/base.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Any 22 | 23 | from ...file import File 24 | from ..route import BaseRoute 25 | 26 | REQUEST_RETURN = str | dict[str, Any] | list[Any] | bytes 27 | 28 | 29 | class BaseRouter: 30 | async def request( 31 | self, 32 | method: str, 33 | route: BaseRoute, 34 | data: dict[str, Any] | None = None, 35 | files: list[File] | None = None, 36 | form: list[dict[str, Any]] | None = None, 37 | *, 38 | reason: str | None = None, 39 | query_params: dict[str, str] | None = None, 40 | ) -> REQUEST_RETURN: 41 | ... 42 | -------------------------------------------------------------------------------- /pycord/api/routers/emojis.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from ...missing import MISSING, MissingEnum 22 | from ...snowflake import Snowflake 23 | from ...types import Emoji 24 | from ...utils import remove_undefined 25 | from ..route import Route 26 | from .base import BaseRouter 27 | 28 | 29 | class Emojis(BaseRouter): 30 | async def list_guild_emojis(self, guild_id: Snowflake) -> list[Emoji]: 31 | return await self.request( 32 | 'GET', Route('/guilds/{guild_id}/emojis', guild_id=guild_id) 33 | ) 34 | 35 | async def get_guild_emoji(self, guild_id: Snowflake, emoji_id: Snowflake) -> Emoji: 36 | return await self.request( 37 | 'GET', 38 | Route( 39 | '/guilds/{guild_id}/emojis/{emoji_id}', 40 | guild_id=guild_id, 41 | emoji_id=emoji_id, 42 | ), 43 | ) 44 | 45 | async def create_guild_emoji( 46 | self, 47 | guild_id: Snowflake, 48 | *, 49 | name: str, 50 | image: bytes, # TODO 51 | roles: list[Snowflake] | MissingEnum = MISSING, 52 | reason: str | None = None, 53 | ) -> Emoji: 54 | payload = { 55 | 'name': name, 56 | 'image': image, 57 | 'roles': roles, 58 | } 59 | return await self.request( 60 | 'POST', 61 | Route('POST', '/guilds/{guild_id}/emojis', guild_id=guild_id), 62 | remove_undefined(**payload), 63 | reason=reason, 64 | ) 65 | 66 | async def modify_guild_emoji( 67 | self, 68 | guild_id: Snowflake, 69 | emoji_id: Snowflake, 70 | *, 71 | name: str | MissingEnum = MISSING, 72 | roles: list[Snowflake] | MissingEnum = MISSING, 73 | reason: str | None = None, 74 | ) -> Emoji: 75 | payload = { 76 | 'name': name, 77 | 'roles': roles, 78 | } 79 | return await self.request( 80 | 'PATCH', 81 | Route( 82 | '/guilds/{guild_id}/emojis/{emoji_id}', 83 | guild_id=guild_id, 84 | emoji_id=emoji_id, 85 | ), 86 | remove_undefined(**payload), 87 | reason=reason, 88 | ) 89 | 90 | async def delete_guild_emoji( 91 | self, 92 | guild_id: Snowflake, 93 | emoji_id: Snowflake, 94 | *, 95 | reason: str | None = None, 96 | ) -> None: 97 | await self.request( 98 | 'DELETE', 99 | Route( 100 | '/guilds/{guild_id}/emojis/{emoji_id}', 101 | guild_id=guild_id, 102 | emoji_id=emoji_id, 103 | ), 104 | reason=reason, 105 | ) 106 | -------------------------------------------------------------------------------- /pycord/api/routers/scheduled_events.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from ...file import File 24 | from ...missing import MISSING, MissingEnum 25 | from ...snowflake import Snowflake 26 | from ...types import PRIVACY_LEVEL, EntityMetadata, GuildScheduledEvent 27 | from ...utils import remove_undefined, to_datauri 28 | from ..route import Route 29 | from .base import BaseRouter 30 | 31 | 32 | class ScheduledEvents(BaseRouter): 33 | async def list_scheduled_events( 34 | self, guild_id: Snowflake, with_user_count: bool | MissingEnum = MISSING 35 | ) -> list[GuildScheduledEvent]: 36 | return await self.request( 37 | 'GET', 38 | Route('/guilds/{guild_id}/scheduled-events', guild_id=guild_id), 39 | remove_undefined(with_user_count=with_user_count), 40 | ) 41 | 42 | async def create_guild_scheduled_event( 43 | self, 44 | guild_id: Snowflake, 45 | name: str, 46 | scheduled_start_time: str, 47 | entity_type: Literal[1, 2, 3], 48 | channel_id: Snowflake | MissingEnum = MISSING, 49 | entity_metadata: EntityMetadata | MissingEnum = MISSING, 50 | privacy_level: PRIVACY_LEVEL | MissingEnum = MISSING, 51 | scheduled_end_time: str | MissingEnum = MISSING, 52 | description: str | MissingEnum = MISSING, 53 | image: File | MissingEnum = MISSING, 54 | ) -> GuildScheduledEvent: 55 | fields = remove_undefined( 56 | name=name, 57 | scheduled_start_time=scheduled_start_time, 58 | entity_type=entity_type, 59 | channel_id=channel_id, 60 | entity_metadata=entity_metadata, 61 | privacy_level=privacy_level, 62 | scheduled_end_time=scheduled_end_time, 63 | description=description, 64 | image=image, 65 | ) 66 | 67 | if fields.get('image'): 68 | fields['image'] = to_datauri(fields['image']) 69 | 70 | # TODO 71 | await self.request( 72 | 'POST', 73 | ) 74 | -------------------------------------------------------------------------------- /pycord/api/routers/user.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | 23 | from ...types import User 24 | from ..route import Route 25 | from .base import BaseRouter 26 | 27 | 28 | class Users(BaseRouter): 29 | async def get_current_user(self) -> User: 30 | return await self.request('GET', Route('/users/@me')) 31 | -------------------------------------------------------------------------------- /pycord/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ${bold_white} ${reset} ${blue} ````'````````````````````````'` 4 | ${bold_white} ${reset} ${bold_blue} `. `- 5 | ${bold_white} O88888${reset} ${yellow}'' _ 6 | ${bold_white}u@@@@@@@@@@@BG! O@@@@8${reset} ${bold_yellow}_ ${reset}${bold_white}:oQ@@@@@@#Rr${reset}${bold_yellow} `- 7 | ${bold_white}u@@@@@@@@@@@@@@O. O@@@@8${reset} ${red}- ${reset}${bold_white}k@@@@#dWQ@@@@D`${reset}${red} . 8 | ${bold_white}u@@@@@` 'I@@@@@a`O9999r V6996u ,LaEQQQDUv. :}P$QQ8OI?. V9999L_H8Qc !y0QQRY.O@@@@8${reset} ${bold_red}- ${reset}${bold_white}Vkkk} E@@@@:${reset}${bold_red} . 9 | ${bold_white}u@@@@@` :@@@@@R I@@@@Q` ^@@@@@" -M@@@@@@@@@@@q ,Q@@@@@@@@@@@V` O@@@@Q#@@@G-0@@@@@@@##@@@@8${reset} ${purple}- ${reset}${bold_white}-m3HQ@@@0r${reset}${purple} . 10 | ${bold_white}u@@@@@}iYz#@@@@@) `$@@@@} O@@@@j -B@@@@Q \@@@T ,#@@@@K_`=#@@@@q O@@@@@8]*);E@@@@@V::V@@@@@8${reset} ${bold_purple}- ${reset}${bold_white}:@@@@@#$z;${reset}${bold_purple} . 11 | ${bold_white}u@@@@@@@@@@@@@O! ,#@@@B.*@@@@0` L@@@@@ T@@@@@` y@@@@@: O@@@@Q` @@@@@H G@@@@8${reset} ${black}- ${reset}${bold_white}```=D@@@@P${reset}${black} . 12 | ${bold_white}u@@@@@6OOOMj]! x@@@@}9@@@#! x@@@@@ }@@@@@. U@@@@@, O@@@@$ #@@@@b d@@@@8${reset} ${bold_black}- ${reset}${bold_white},####0~` :6@@@@8${reset}${bold_black} . 13 | ${bold_white}u@@@@@` K@@@#@@@@x `0@@@@# /@@| .Q@@@@0r~Y@@@@@w O@@@@$ P@@@@@OxxO@@@@@8${reset} ${blue}- ${reset}${bold_white}c#@@@@@@@@@@@Q=${reset}${blue} . 14 | ${bold_white}u@@@@@` `#@@@@@@g `c@@@@@@@@@@#T `M@@@@@@@@@@#) O@@@@$ `z@@@@@@@QQ@@@@8${reset} ${bold_blue}_ ${reset}${bold_white}`rz0QBBB8bV:${reset}${bold_blue} `- 15 | ${bold_white}=yyyyV x@@@@@#: `~YI5MWIx! `^}m5MGwx: |yyyyv `*w33y~ )yyyyx${reset} ${yellow}.` - 16 | ${bold_white}=gEB@@@@#r ${reset} ${bold_yellow} '. .` 17 | ${bold_white}`g@@@@@#X_ ${reset} ${blue} '`````'''''''''''''''''''````'` 18 | ${bold_white}`-":_` 19 | -------------------------------------------------------------------------------- /pycord/commands/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.commands 3 | ~~~~~~~~~~~~~~~ 4 | Flexible and Versatile command system for Pycord. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .application import * 10 | from .command import * 11 | from .group import * 12 | -------------------------------------------------------------------------------- /pycord/commands/application/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.commands.application 3 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | Implementation of Application Commands 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .command import * 10 | from .context import * 11 | from .errors import * 12 | -------------------------------------------------------------------------------- /pycord/commands/application/errors.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from ...errors import PycordException 23 | 24 | 25 | class ApplicationCommandException(PycordException): 26 | ... 27 | -------------------------------------------------------------------------------- /pycord/commands/command.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from typing import TYPE_CHECKING, Type 24 | 25 | from ..events.event_manager import Event 26 | 27 | if TYPE_CHECKING: 28 | from ..state import State 29 | from ..types import AsyncFunc 30 | from .group import Group 31 | 32 | 33 | class Command: 34 | _processor_event: Type[Event] | Event 35 | 36 | def __init__( 37 | self, callback: AsyncFunc, name: str, state: State, group: Group | None = None 38 | ) -> None: 39 | self._callback = callback 40 | 41 | self.name = name 42 | self.group = group 43 | self._state = state 44 | 45 | async def instantiate(self) -> None: 46 | ... 47 | 48 | async def _invoke(self, *args, **kwargs) -> None: 49 | pass 50 | -------------------------------------------------------------------------------- /pycord/commands/group.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from typing import TYPE_CHECKING, TypeVar 24 | 25 | from .command import Command 26 | 27 | if TYPE_CHECKING: 28 | from ..state import State 29 | from ..types import AsyncFunc 30 | 31 | T = TypeVar('T') 32 | 33 | 34 | class Group: 35 | def __init__(self, func: AsyncFunc | None, name: str, state: State) -> None: 36 | self.commands: list[Command] = [] 37 | # nested groups 38 | self.groups: list['Group'] = [] 39 | 40 | self.name = name 41 | self._callback = func 42 | self.__state = state 43 | self._pending_commands: list[Command] = [] 44 | 45 | @property 46 | def _state(self) -> State: 47 | return self.__state 48 | 49 | @_state.setter 50 | def _state(self, state: State) -> None: 51 | self.__state = state 52 | 53 | for command in self._pending_commands: 54 | self._state.commands.append(command) 55 | 56 | def command(self, name: str) -> T: 57 | def wrapper(func: T) -> T: 58 | command = Command(func, name=name, state=self._state, group=self) 59 | if self._state: 60 | self._state.commands.append(command) 61 | else: 62 | self._pending_commands.append(command) 63 | return func 64 | 65 | return wrapper 66 | -------------------------------------------------------------------------------- /pycord/connection.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from typing import TYPE_CHECKING 25 | 26 | from .enums import VisibilityType 27 | from .missing import MISSING, Maybe, MissingEnum 28 | from .snowflake import Snowflake 29 | from .types import ( 30 | SERVICE, 31 | Connection as DiscordConnection, 32 | Integration as DiscordIntegration, 33 | ) 34 | 35 | if TYPE_CHECKING: 36 | from .state import State 37 | 38 | 39 | class Connection: 40 | def __init__(self, data: DiscordConnection, state: State) -> None: 41 | self.id: Snowflake = Snowflake(data['id']) 42 | self.name: str = data['name'] 43 | self.type: SERVICE = data['type'] 44 | self.revoked: bool | MissingEnum = data.get('revoked', MISSING) 45 | self._integrations: list[DiscordIntegration] | MissingEnum = data.get( 46 | 'integrations', MISSING 47 | ) 48 | self.verified: bool = data['verified'] 49 | self.friend_sync: bool = data['friend_sync'] 50 | self.show_activity: bool = data['show_activity'] 51 | self.two_way_linked: bool = data['two_way_link'] 52 | self.visibility: VisibilityType = VisibilityType(data['visibility']) 53 | -------------------------------------------------------------------------------- /pycord/errors.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Any 22 | 23 | from aiohttp import ClientResponse 24 | 25 | from .utils import parse_errors 26 | 27 | 28 | class PycordException(Exception): 29 | pass 30 | 31 | 32 | class BotException(PycordException): 33 | pass 34 | 35 | 36 | class InteractionException(BotException): 37 | pass 38 | 39 | 40 | class GatewayException(PycordException): 41 | pass 42 | 43 | 44 | class NoIdentifiesLeft(GatewayException): 45 | pass 46 | 47 | 48 | class DisallowedIntents(GatewayException): 49 | pass 50 | 51 | 52 | class ShardingRequired(GatewayException): 53 | pass 54 | 55 | 56 | class InvalidAuth(GatewayException): 57 | pass 58 | 59 | 60 | class HTTPException(PycordException): 61 | def __init__(self, resp: ClientResponse, data: dict[str, Any] | None) -> None: 62 | self._response = resp 63 | self.status = resp.status 64 | 65 | if data: 66 | self.code = data.get('code', 0) 67 | self.error_message = data.get('message', '') 68 | 69 | if errors := data.get('errors'): 70 | self.errors = parse_errors(errors) 71 | message = self.error_message + '\n'.join( 72 | f'In {key}: {err}' for key, err in self.errors.items() 73 | ) 74 | else: 75 | message = self.error_message 76 | 77 | super().__init__(f'{resp.status} {resp.reason} (code: {self.code}): {message}') 78 | 79 | 80 | class Forbidden(HTTPException): 81 | pass 82 | 83 | 84 | class NotFound(HTTPException): 85 | pass 86 | 87 | 88 | class InternalError(HTTPException): 89 | pass 90 | 91 | 92 | class OverfilledShardsException(BotException): 93 | pass 94 | 95 | 96 | class FlagException(BotException): 97 | pass 98 | 99 | 100 | class ComponentException(BotException): 101 | pass 102 | 103 | 104 | class NoFetchOrGet(BotException): 105 | pass 106 | -------------------------------------------------------------------------------- /pycord/events/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.events 3 | ~~~~~~~~~~~~~ 4 | Basic Implementation of Discord Events 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .channels import * 10 | from .event_manager import * 11 | from .guilds import * 12 | from .other import * 13 | -------------------------------------------------------------------------------- /pycord/events/event_manager.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | 23 | import asyncio 24 | from asyncio import Future 25 | from typing import TYPE_CHECKING, Any, Type, TypeVar 26 | 27 | from ..types import AsyncFunc 28 | 29 | if TYPE_CHECKING: 30 | from ..state import State 31 | 32 | 33 | T = TypeVar('T', bound='Event') 34 | 35 | 36 | class Event: 37 | _name: str 38 | _state: 'State' 39 | 40 | async def _is_publishable(self, data: dict[str, Any], state: 'State') -> bool: 41 | return True 42 | 43 | async def _async_load(self, data: dict[str, Any], state: 'State') -> None: 44 | ... 45 | 46 | 47 | class EventManager: 48 | def __init__(self, base_events: list[Type[Event]], state: 'State') -> None: 49 | self._base_events = base_events 50 | self._state = state 51 | 52 | # structured like: 53 | # EventClass: [childrenfuncs] 54 | self.events: dict[Type[Event], list[AsyncFunc]] = {} 55 | 56 | for event in self._base_events: 57 | # base_events is used for caching purposes 58 | self.events[event] = [] 59 | 60 | self.wait_fors: dict[Type[Event], list[Future]] = {} 61 | 62 | def add_event(self, event: Type[Event], func: AsyncFunc) -> None: 63 | try: 64 | self.events[event].append(func) 65 | except KeyError: 66 | self.events[event] = [func] 67 | 68 | def wait_for(self, event: Type[T]) -> Future[T]: 69 | fut = Future() 70 | 71 | try: 72 | self.wait_fors[event].append(fut) 73 | except KeyError: 74 | self.wait_fors[event] = [fut] 75 | 76 | return fut 77 | 78 | async def publish(self, event_str: str, data: dict[str, Any]) -> None: 79 | # in certain cases, events may be inserted during runtime which breaks dispatching 80 | items = list(self.events.items()) 81 | 82 | for event, funcs in items: 83 | if event._name == event_str: 84 | eve = event() 85 | dispatch = await eve._is_publishable(data, self._state) 86 | 87 | # used in cases like GUILD_AVAILABLE 88 | if dispatch is False: 89 | continue 90 | else: 91 | await eve._async_load(data, self._state) 92 | 93 | eve._state = self._state 94 | 95 | for func in funcs: 96 | asyncio.create_task(func(eve)) 97 | 98 | wait_fors = self.wait_fors.get(event) 99 | 100 | if wait_fors is not None: 101 | for wait_for in wait_fors: 102 | wait_for.set_result(eve) 103 | self.wait_fors.pop(event) 104 | -------------------------------------------------------------------------------- /pycord/ext/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.ext 3 | ~~~~~~~~~~ 4 | A variety of Pycord extensions to make your bot development experience easier 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | -------------------------------------------------------------------------------- /pycord/ext/gears/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.ext.gears 3 | ~~~~~~~~~~~~~~~~ 4 | Extension to add a way to extend your bot easily throughout multiple files. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .gear import * 10 | -------------------------------------------------------------------------------- /pycord/file.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | 23 | import asyncio 24 | import pathlib 25 | from io import BytesIO 26 | from typing import BinaryIO, Protocol 27 | 28 | 29 | def _open_file(path: pathlib.Path) -> BinaryIO: 30 | return path.expanduser().open('rb') 31 | 32 | 33 | class File(Protocol): 34 | path: pathlib.Path | None 35 | filename: str 36 | file: BinaryIO 37 | spoiler: bool 38 | 39 | def reset(self, seek: int | bool = True) -> None: 40 | ... 41 | 42 | def close(self) -> None: 43 | ... 44 | 45 | 46 | class SysFile(File): 47 | def __init__( 48 | self, path: str, filename: str | None = None, spoiler: bool = False 49 | ) -> None: 50 | self.path = pathlib.Path(path) 51 | self.filename = filename 52 | # assumes the event loop has already started 53 | self.spoiler = spoiler 54 | asyncio.create_task(self._hook_file()) 55 | 56 | async def _hook_file(self) -> None: 57 | loop = asyncio.get_running_loop() 58 | 59 | self.file = await loop.run_in_executor(None, _open_file, _open_file, self._path) 60 | 61 | # assure we have control over closures 62 | self._closer = self.file.close 63 | self.file.close = lambda: None 64 | 65 | if self.filename is None: 66 | self.filename = self.path.name 67 | 68 | if self.spoiler and not self.filename.startswith('SPOILER_'): 69 | self.filename = f'SPOILER_{self.filename}' 70 | 71 | self._original_position = self.file.tell() 72 | 73 | def reset(self, seek: int | bool = True) -> None: 74 | if seek: 75 | self.file.seek(self._original_position) 76 | 77 | def close(self) -> None: 78 | self.file.close = self._closer 79 | self._closer() 80 | 81 | 82 | class BytesFile(File): 83 | def __init__(self, filename: str, io: bytes | BytesIO) -> None: 84 | self.filename = filename 85 | self.file = BytesIO(io) 86 | 87 | # assure we have control over closures 88 | self._closer = self.file.close 89 | self.file.close = lambda: None 90 | 91 | if self.spoiler and not self.filename.startswith('SPOILER_'): 92 | self.filename = f'SPOILER_{self.filename}' 93 | 94 | self._original_position = self.file.tell() 95 | 96 | def reset(self, seek: int | bool = True) -> None: 97 | if seek: 98 | self.file.seek(self._original_position) 99 | 100 | def close(self) -> None: 101 | self.file.close = self._closer 102 | self._closer() 103 | -------------------------------------------------------------------------------- /pycord/gateway/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.gateway 3 | ~~~~~~~~~~~~~~ 4 | Advanced Implementation of the Discord Gateway 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from ..events.event_manager import * 10 | from .cluster import * 11 | from .manager import * 12 | from .notifier import * 13 | from .passthrough import * 14 | from .shard import * 15 | -------------------------------------------------------------------------------- /pycord/gateway/cluster.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | import asyncio 24 | from multiprocessing import Process 25 | from typing import TYPE_CHECKING 26 | 27 | from aiohttp import BasicAuth 28 | 29 | from ..utils import chunk 30 | from .manager import ShardManager 31 | 32 | if TYPE_CHECKING: 33 | from ..state import State 34 | 35 | 36 | class ShardCluster(Process): 37 | def __init__( 38 | self, 39 | state: State, 40 | shards: list[int], 41 | amount: int, 42 | managers: int, 43 | proxy: str | None = None, 44 | proxy_auth: BasicAuth | None = None, 45 | ) -> None: 46 | self.shard_managers: list[ShardManager] = [] 47 | self._state = state 48 | self._shards = shards 49 | self._amount = amount 50 | self._managers = managers 51 | self._proxy = proxy 52 | self._proxy_auth = proxy_auth 53 | super().__init__() 54 | 55 | async def _run(self) -> None: 56 | await self._state._cluster_lock.acquire() 57 | # this is guessing that `i` is a shard manager 58 | tasks = [] 59 | for sharder in list(chunk(self._shards, self._managers)): 60 | manager = ShardManager( 61 | self._state, sharder, self._amount, self._proxy, self._proxy_auth 62 | ) 63 | tasks.append(manager.start()) 64 | self.shard_managers.append(manager) 65 | asyncio.create_task(manager.start()) 66 | self._state._cluster_lock.release() 67 | self.keep_alive = asyncio.Future() 68 | await self.keep_alive 69 | 70 | def run(self) -> None: 71 | asyncio.create_task(self._run()) 72 | -------------------------------------------------------------------------------- /pycord/gateway/manager.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | import asyncio 24 | from typing import TYPE_CHECKING 25 | 26 | from aiohttp import BasicAuth, ClientSession 27 | 28 | from ..errors import NoIdentifiesLeft 29 | 30 | if TYPE_CHECKING: 31 | from ..state import State 32 | 33 | from .notifier import Notifier 34 | from .passthrough import PassThrough 35 | from .shard import Shard 36 | 37 | 38 | class ShardManager: 39 | def __init__( 40 | self, 41 | state: State, 42 | shards: list[int], 43 | amount: int, 44 | proxy: str | None = None, 45 | proxy_auth: BasicAuth | None = None, 46 | ) -> None: 47 | self.shards: list[Shard] = [] 48 | self.amount = amount 49 | self._shards = shards 50 | self._state = state 51 | self.proxy = proxy 52 | self.proxy_auth = proxy_auth 53 | 54 | def add_shard(self, shard: Shard) -> None: 55 | self.shards.insert(shard.id, shard) 56 | 57 | def remove_shard(self, shard: Shard) -> None: 58 | self.shards.remove(shard) 59 | 60 | def remove_shards(self) -> None: 61 | self.shards.clear() 62 | 63 | async def delete_shard(self, shard: Shard) -> None: 64 | shard._receive_task.cancel() 65 | shard._hb_task.cancel() 66 | 67 | await shard._ws.close() 68 | self.remove_shard(shard) 69 | 70 | async def delete_shards(self) -> None: 71 | for shard in self.shards: 72 | await self.delete_shard(shard=shard) 73 | 74 | async def start(self) -> None: 75 | self.session = ClientSession() 76 | notifier = Notifier(self) 77 | 78 | if not self._state.shard_concurrency: 79 | info = await self._state.http.get_gateway_bot() 80 | session_start_limit = info['session_start_limit'] 81 | 82 | if session_start_limit['remaining'] == 0: 83 | raise NoIdentifiesLeft('session_start_limit has been exhausted') 84 | 85 | self._state.shard_concurrency = PassThrough( 86 | session_start_limit['max_concurrency'], 7 87 | ) 88 | self._state._session_start_limit = session_start_limit 89 | 90 | tasks = [] 91 | 92 | for shard_id in self._shards: 93 | shard = Shard( 94 | id=shard_id, state=self._state, session=self.session, notifier=notifier 95 | ) 96 | 97 | tasks.append(shard.connect(token=self._state.token)) 98 | 99 | self.shards.append(shard) 100 | 101 | await asyncio.gather(*tasks) 102 | 103 | async def shutdown(self) -> None: 104 | await self.delete_shards() 105 | -------------------------------------------------------------------------------- /pycord/gateway/notifier.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | import logging 24 | from typing import TYPE_CHECKING 25 | 26 | from .shard import Shard 27 | 28 | if TYPE_CHECKING: 29 | from .manager import ShardManager 30 | 31 | _log = logging.getLogger(__name__) 32 | 33 | 34 | class Notifier: 35 | def __init__(self, manager: ShardManager) -> None: 36 | self.manager = manager 37 | 38 | async def shard_died(self, shard: Shard) -> None: 39 | _log.debug(f'Shard {shard.id} died, restarting it') 40 | shard_id = shard.id 41 | self.manager.remove_shard(shard) 42 | del shard 43 | 44 | new_shard = Shard( 45 | id=shard_id, 46 | state=self.manager._state, 47 | session=self.manager.session, 48 | notifier=self, 49 | ) 50 | await new_shard.connect(token=self.manager._state.token) 51 | self.manager.add_shard(new_shard) 52 | -------------------------------------------------------------------------------- /pycord/gateway/passthrough.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | import time 22 | from asyncio import AbstractEventLoop, Future, get_running_loop 23 | 24 | 25 | class PassThrough: 26 | def __init__(self, concurrency: int, per: float | int) -> None: 27 | self.concurrency: int = concurrency 28 | self.per: float | int = per 29 | 30 | self.current: int = self.concurrency 31 | self._reserved: list[Future] = [] 32 | self.loop: AbstractEventLoop = get_running_loop() 33 | self.pending_reset: bool = False 34 | 35 | async def __aenter__(self) -> 'PassThrough': 36 | while self.current == 0: 37 | future = self.loop.create_future() 38 | self._reserved.append(future) 39 | await future 40 | 41 | self.current -= 1 42 | 43 | if not self.pending_reset: 44 | self.pending_reset = True 45 | self.loop.call_later(self.per, self.reset) 46 | 47 | return self 48 | 49 | async def __aexit__(self, *_) -> None: 50 | ... 51 | 52 | def reset(self) -> None: 53 | current_time = time.time() 54 | self.reset_at = current_time + self.per 55 | self.current = self.concurrency 56 | 57 | for _ in range(self.concurrency): 58 | try: 59 | self._reserved.pop().set_result(None) 60 | except IndexError: 61 | break 62 | 63 | if len(self._reserved): 64 | self.pending_reset = True 65 | self.loop.call_later(self.per, self.reset) 66 | else: 67 | self.pending_reset = False 68 | -------------------------------------------------------------------------------- /pycord/guild_template.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from datetime import datetime 24 | from typing import TYPE_CHECKING 25 | 26 | from .snowflake import Snowflake 27 | from .types import GuildTemplate as DiscordGuildTemplate 28 | from .user import User 29 | 30 | if TYPE_CHECKING: 31 | from .state import State 32 | 33 | 34 | class GuildTemplate: 35 | __slots__ = ( 36 | 'code', 37 | 'name', 38 | 'description', 39 | 'usage_count', 40 | 'creator_id', 41 | 'creator', 42 | 'created_at', 43 | 'updated_at', 44 | 'source_guild_id', 45 | 'serialized_source_guild', 46 | 'is_dirty', 47 | ) 48 | 49 | def __init__(self, data: DiscordGuildTemplate, state: State) -> None: 50 | self.code: str = data['code'] 51 | self.name: str = data['name'] 52 | self.description: str | None = data['description'] 53 | self.usage_count: int = data['usage_count'] 54 | self.creator_id: Snowflake = Snowflake(data['creator_id']) 55 | self.creator: User = User(data['creator'], state) 56 | self.created_at: datetime = datetime.fromisoformat(data['created_at']) 57 | self.updated_at: datetime = datetime.fromisoformat(data['updated_at']) 58 | self.source_guild_id: Snowflake = Snowflake(data['source_guild_id']) 59 | # TODO: maybe make this a Guild object? 60 | self.serialized_source_guild: dict = data['serialized_source_guild'] 61 | self.is_dirty: bool | None = data['is_dirty'] 62 | -------------------------------------------------------------------------------- /pycord/ibanner.txt: -------------------------------------------------------------------------------- 1 | ${bold_red}Wel${reset}${blue}come${reset} ${bold_blue}to${reset} ${yellow}Pycord v${version}${reset} 2 | ${bold_white}It's currently ${current_time}, running on Python ${py_version}${reset} 3 | 4 | ${bold_yellow}${botname}${reset} currently has ${red}${concurrency}${reset} connects left and will be running ${bold_blue}${shardcount}${reset} shard${sp}. 5 | -------------------------------------------------------------------------------- /pycord/integration.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from datetime import datetime 25 | from typing import TYPE_CHECKING 26 | 27 | from .application import Application 28 | from .missing import MISSING, Maybe, MissingEnum 29 | from .snowflake import Snowflake 30 | from .types import ( 31 | INTEGRATION_EXPIRE_BEHAVIOR, 32 | INTEGRATION_TYPE, 33 | SCOPE, 34 | Account as DiscordAccount, 35 | Integration as DiscordIntegration, 36 | IntegrationApplication as DiscordIntegrationApplication, 37 | ) 38 | from .user import User 39 | 40 | if TYPE_CHECKING: 41 | from .state import State 42 | 43 | 44 | class Account: 45 | def __init__(self, data: DiscordAccount) -> None: 46 | self.id: str = data['id'] 47 | self.name: str = data['name'] 48 | 49 | 50 | class IntegrationApplication: 51 | def __init__(self, data: DiscordIntegrationApplication, state: State) -> None: 52 | self.id: Snowflake = Snowflake(data['id']) 53 | self.name: str = data['name'] 54 | self.icon: str | None = data['icon'] 55 | self.description: str | None = data['description'] 56 | self.bot: User | MissingEnum = ( 57 | User(data['bot'], state) if data.get('bot') is not None else MISSING 58 | ) 59 | 60 | 61 | class Integration: 62 | def __init__(self, data: DiscordIntegration, state: State) -> None: 63 | self.id: Snowflake = Snowflake(data['id']) 64 | self.name: str = data['name'] 65 | self.type: INTEGRATION_TYPE = data['type'] 66 | self.enabled: bool | MissingEnum = data.get('enabled', MISSING) 67 | self.syncing: bool | MissingEnum = data.get('syncing', MISSING) 68 | self.role_id: Snowflake | MissingEnum = ( 69 | Snowflake(data['role_id']) if data.get('role_id') else MISSING 70 | ) 71 | self.enable_emoticons: bool | MissingEnum = data.get( 72 | 'enable_emoticons', MISSING 73 | ) 74 | self.expire_behavior: INTEGRATION_EXPIRE_BEHAVIOR | MissingEnum = data.get( 75 | 'expire_behavior', MISSING 76 | ) 77 | self.expire_grace_period: int | MissingEnum = data.get( 78 | 'expire_grace_period', MISSING 79 | ) 80 | self.user: User | MissingEnum = ( 81 | User(data['user'], state) if data.get('user') is not None else MISSING 82 | ) 83 | self.account: Account = Account(data['account']) 84 | self.synced_at: MissingEnum | datetime = ( 85 | datetime.fromisoformat(data['synced_at']) 86 | if data.get('synced_at') is not None 87 | else MISSING 88 | ) 89 | self.subscriber_count: int | MissingEnum = data.get('subscriber_count', MISSING) 90 | self.revoked: bool | MissingEnum = data.get('revoked', MISSING) 91 | self.application: Application | MissingEnum = ( 92 | IntegrationApplication(data['application'], state) 93 | if data.get('application') is not None 94 | else MISSING 95 | ) 96 | self.scopes: list[SCOPE] | MissingEnum = data.get('scopes', MISSING) 97 | -------------------------------------------------------------------------------- /pycord/invite.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from datetime import datetime 24 | from typing import TYPE_CHECKING 25 | 26 | from .application import Application 27 | from .channel import Channel 28 | from .enums import InviteTargetType 29 | from .guild import Guild 30 | from .missing import MISSING, Maybe, MissingEnum 31 | from .scheduled_event import ScheduledEvent 32 | from .types import Invite as DiscordInvite, InviteMetadata as DiscordInviteMetadata 33 | from .user import User 34 | 35 | if TYPE_CHECKING: 36 | from .state import State 37 | 38 | 39 | class InviteMetadata: 40 | def __init__(self, data: DiscordInviteMetadata) -> None: 41 | self.uses: int = data['uses'] 42 | self.max_uses: int = data['max_uses'] 43 | self.max_age: int = data['max_age'] 44 | self.temporary: bool = data['temporary'] 45 | self.created_at: datetime = datetime.fromisoformat(data['created_at']) 46 | 47 | 48 | class Invite: 49 | def __init__(self, data: DiscordInvite, state: State) -> None: 50 | self.code: str = data['code'] 51 | self.guild: Guild | MissingEnum = ( 52 | Guild(data['guild'], state) if data.get('guild') is not None else MISSING 53 | ) 54 | self.channel: Channel | None = ( 55 | Channel(data['channel'], state) if data.get('channel') is not None else None 56 | ) 57 | self.inviter: User | MissingEnum = ( 58 | User(data['inviter'], state) if data.get('inviter') is not None else MISSING 59 | ) 60 | self.target_type: int | MissingEnum = ( 61 | InviteTargetType(data['target_type']) 62 | if data.get('target_type') is not None 63 | else MISSING 64 | ) 65 | self.target_user: User | MissingEnum = ( 66 | User(data['target_user'], state) 67 | if data.get('target_user') is not None 68 | else MISSING 69 | ) 70 | self.target_application: Application | MissingEnum = ( 71 | Application(data['target_application'], state) 72 | if data.get('target_application') is not None 73 | else MISSING 74 | ) 75 | self.approximate_presence_count: int | MissingEnum = data.get( 76 | 'approximate_presence_count', MISSING 77 | ) 78 | self.approximate_member_count: int | MissingEnum = data.get( 79 | 'approximate_member_count', MISSING 80 | ) 81 | self.expires_at: datetime | None = ( 82 | datetime.fromisoformat(data['expires_at']) 83 | if data.get('expires_at') is not None 84 | else data.get('expires_at', MISSING) 85 | ) 86 | self.guild_scheduled_event: ScheduledEvent | MissingEnum = ( 87 | ScheduledEvent(data['guild_scheduled_event'], state) 88 | if data.get('guild_scheduled_event') is not None 89 | else MISSING 90 | ) 91 | -------------------------------------------------------------------------------- /pycord/message_iterator.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from .message import Message 22 | from .pages import Page 23 | from .pages.paginator import Paginator 24 | 25 | 26 | class MessagePage(Page[Message]): 27 | def __init__(self, message: Message) -> None: 28 | self.value = message 29 | 30 | 31 | # Paginator but typed for MessagePage 32 | class MessagePaginator(Paginator[MessagePage]): 33 | ... 34 | -------------------------------------------------------------------------------- /pycord/missing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=3 3 | # Copyright (c) 2021-present VincentRPS 4 | # Copyright (c) 2022-present Pycord Development 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE 23 | 24 | from enum import Enum, auto 25 | from typing import Literal, TypeVar, Union 26 | 27 | T = TypeVar('T') 28 | 29 | 30 | class MissingEnum(Enum): 31 | MISSING = auto() 32 | 33 | def __bool__(self) -> Literal[False]: 34 | return False 35 | 36 | 37 | MISSING: Literal[MissingEnum.MISSING] = MissingEnum.MISSING 38 | """ 39 | An instance of `.missing.MissingEnum` for purposes of code use. 40 | """ 41 | 42 | 43 | Maybe = Union[T, Literal[MissingEnum.MISSING]] 44 | -------------------------------------------------------------------------------- /pycord/pages/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.ext.pager 3 | ~~~~~~~~~~~~~~~~ 4 | The form of paginating through pages in Pycord. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .errors import * 10 | from .paginator import * 11 | -------------------------------------------------------------------------------- /pycord/pages/errors.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Sequence 22 | 23 | from ..errors import PycordException 24 | 25 | __all__: Sequence[str] = ('PagerException', 'NoMorePages') 26 | 27 | 28 | class PagerException(PycordException): 29 | ... 30 | 31 | 32 | class NoMorePages(PagerException): 33 | ... 34 | -------------------------------------------------------------------------------- /pycord/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pycord-Development/pycord-next/3b94ae3f1ed951930e53a105c9be985c5ae5d7e1/pycord/py.typed -------------------------------------------------------------------------------- /pycord/role.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from typing import TYPE_CHECKING 24 | 25 | from .color import Color 26 | from .flags import Permissions 27 | from .snowflake import Snowflake 28 | 29 | if TYPE_CHECKING: 30 | from .state import State 31 | 32 | from .missing import MISSING, Maybe, MissingEnum 33 | from .types import Role as DiscordRole, RoleTags as DiscordRoleTags 34 | 35 | 36 | class RoleTags: 37 | __slots__ = ('bot_id', 'integration_id', 'premium_subscriber') 38 | 39 | def __init__(self, data: DiscordRoleTags) -> None: 40 | self.bot_id: MissingEnum | Snowflake = ( 41 | Snowflake(data.get('bot_id')) 42 | if data.get('bot_id', MISSING) is not MISSING 43 | else MISSING 44 | ) 45 | self.integration_id: MissingEnum | Snowflake = ( 46 | Snowflake(data.get('integration_id')) 47 | if data.get('integration_id', MISSING) is not MISSING 48 | else MISSING 49 | ) 50 | self.premium_subscriber: MissingEnum | None = data.get( 51 | 'premium_subscriber', MISSING 52 | ) 53 | 54 | 55 | class Role: 56 | __slots__ = ( 57 | '_state', 58 | '_tags', 59 | 'id', 60 | 'name', 61 | 'color', 62 | 'hoist', 63 | 'icon', 64 | 'unicode_emoji', 65 | 'position', 66 | 'permissions', 67 | 'managed', 68 | 'mentionable', 69 | 'tags', 70 | ) 71 | 72 | def __init__(self, data: DiscordRole, state: State) -> None: 73 | self._state = state 74 | self.id: Snowflake = Snowflake(data['id']) 75 | self.name: str = data['name'] 76 | self.color: Color = Color(data['color']) 77 | self.hoist: bool = data['hoist'] 78 | self.icon: str | None | MissingEnum = data.get('icon', MISSING) 79 | self.unicode_emoji: str | None | MissingEnum = data.get( 80 | 'unicode_emoji', MISSING 81 | ) 82 | self.position: int = data['position'] 83 | self.permissions: Permissions = Permissions.from_value(data['permissions']) 84 | self.managed: bool = data['managed'] 85 | self.mentionable: bool = data['mentionable'] 86 | self._tags: dict[str, str | None] | MissingEnum = data.get('tags', MISSING) 87 | self.tags: RoleTags | MissingEnum = ( 88 | RoleTags(self._tags) if self._tags is not MISSING else MISSING 89 | ) 90 | -------------------------------------------------------------------------------- /pycord/snowflake.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | """Implementation of Discord's Snowflake ID""" 22 | 23 | from __future__ import annotations 24 | 25 | from datetime import datetime, timezone 26 | 27 | from .utils import DISCORD_EPOCH 28 | 29 | 30 | class Snowflake(int): 31 | @property 32 | def timestamp(self) -> datetime: 33 | return datetime.fromtimestamp( 34 | ((self >> 22) + DISCORD_EPOCH) / 1000, tz=timezone.utc 35 | ) 36 | 37 | @property 38 | def worker_id(self) -> int: 39 | return (self & 0x3E0000) >> 17 40 | 41 | @property 42 | def process_id(self) -> int: 43 | return (self & 0x1F000) >> 12 44 | 45 | @property 46 | def increment(self) -> int: 47 | return self & 0xFFF 48 | 49 | def __hash__(self) -> int: 50 | return self >> 22 51 | 52 | @classmethod 53 | def from_datetime(cls, dt: datetime) -> Snowflake: 54 | return cls((int(dt.timestamp()) - DISCORD_EPOCH) << 22) 55 | -------------------------------------------------------------------------------- /pycord/stage_instance.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from typing import TYPE_CHECKING 24 | 25 | from .enums import StageInstancePrivacyLevel 26 | from .missing import MISSING, Maybe, MissingEnum 27 | from .snowflake import Snowflake 28 | from .types import StageInstance as DiscordStageInstance 29 | 30 | if TYPE_CHECKING: 31 | from .state import State 32 | 33 | 34 | class StageInstance: 35 | def __init__(self, data: DiscordStageInstance, state: State) -> None: 36 | self.id: Snowflake = Snowflake(data['id']) 37 | self.guild_id: Snowflake = Snowflake(data['guild_id']) 38 | self.channel_id: Snowflake = Snowflake(data['channel_id']) 39 | self.topic: str = data['topic'] 40 | self.privacy_level: StageInstancePrivacyLevel = StageInstancePrivacyLevel( 41 | data['privacy_level'] 42 | ) 43 | self.guild_scheduled_event_id: MissingEnum | Snowflake = ( 44 | Snowflake(data['guild_scheduled_event_id']) 45 | if data.get('guild_scheduled_event_id') is not None 46 | else MISSING 47 | ) 48 | -------------------------------------------------------------------------------- /pycord/state/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.state 3 | ~~~~~~~~~~~~ 4 | Pycord's State, keeps track of everything. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .core import * 10 | from .grouped_store import * 11 | from .store import * 12 | -------------------------------------------------------------------------------- /pycord/state/grouped_store.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | 23 | from .store import Store 24 | 25 | 26 | class GroupedStore: 27 | __slots__ = ('_stores', '_stores_dict', '_kwargs') 28 | 29 | def __init__(self, **max_items) -> None: 30 | self._stores = [] 31 | self._stores_dict = {} 32 | self._kwargs = max_items 33 | 34 | def get_stores(self) -> list[Store]: 35 | return self._stores 36 | 37 | def get_store(self, name: str) -> Store: 38 | return self._stores[name] 39 | 40 | def discard(self, name: str) -> None: 41 | d = self._stores_dict.get(name) 42 | if d is not None: 43 | self._stores_dict.pop(name) 44 | self._stores.remove(d) 45 | 46 | def sift(self, name: str) -> Store: 47 | s = self._stores_dict.get(name) 48 | if s is not None: 49 | return s 50 | 51 | for k, v in self._kwargs.items(): 52 | if k == (name + '_max_items'): 53 | store = Store(v) 54 | else: 55 | store = Store() 56 | 57 | self._stores.append(store) 58 | self._stores_dict[name] = store 59 | return store 60 | -------------------------------------------------------------------------------- /pycord/state/store.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Any, Type, TypeVar 23 | 24 | 25 | class _stored: 26 | __slots__ = ('parents', 'id', 'storing') 27 | 28 | def __init__(self, parents: set[Any], self_id: Any, storing: Any) -> None: 29 | self.parents = parents 30 | self.id = self_id 31 | self.storing = storing 32 | 33 | 34 | T = TypeVar('T') 35 | 36 | 37 | class Store: 38 | __slots__ = ('_store', 'max_items') 39 | 40 | _store: set[_stored] 41 | 42 | def __init__(self, max_items: int | None = None) -> None: 43 | self._store = set() 44 | self.max_items = max_items 45 | 46 | async def get_one(self, parents: list[Any], id: Any) -> Any | None: 47 | ps = set(parents) 48 | 49 | for store in self._store: 50 | if store.parents & ps and store.id == id: 51 | return store.storing 52 | 53 | async def get_without_parents(self, id: Any) -> tuple[set[Any], Any] | None: 54 | for store in self._store: 55 | if store.id == id: 56 | return store.parents, store.storing 57 | 58 | async def insert(self, parents: list[Any], id: Any, data: Any) -> None: 59 | if self.max_items and len(self._store) == self.max_items: 60 | self._store = set() 61 | 62 | self._store.add(_stored(set(parents), id, data)) 63 | 64 | async def save(self, parents: list[Any], id: Any, data: Any) -> Any | None: 65 | ps = set(parents) 66 | 67 | for store in self._store: 68 | if store.parents & ps and store.id == id: 69 | old_data = store.storing 70 | self._store.discard(store) 71 | store.storing = data 72 | self._store.add(store) 73 | return old_data 74 | else: 75 | if self.max_items and len(self._store) == self.max_items: 76 | self._store = {} 77 | 78 | store = _stored(set(parents), id, data) 79 | self._store.add(store) 80 | 81 | async def discard( 82 | self, parents: list[Any], id: Any, type: Type[T] | T = Any 83 | ) -> T | None: 84 | ps = set(parents) 85 | 86 | for store in self._store: 87 | if store.parents & ps or store.id == id: 88 | self._store.remove(store) 89 | return store 90 | 91 | async def get_all(self): 92 | for store in self._store: 93 | yield store.storing 94 | 95 | async def get_all_parent(self, parents: list[Any]): 96 | ps = set(parents) 97 | 98 | for store in self._store: 99 | if store.parents & ps: 100 | yield store.storing 101 | 102 | async def delete_all(self) -> None: 103 | self._store.clear() 104 | 105 | async def delete_all_parent(self, parents: list[Any]) -> None: 106 | ps = set(parents) 107 | 108 | for store in self._store: 109 | if store.parents & ps: 110 | self._store.remove(store) 111 | -------------------------------------------------------------------------------- /pycord/team.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from .enums import MembershipState 22 | from .snowflake import Snowflake 23 | from .types import Team as DiscordTeam, TeamMember as DiscordTeamMember 24 | from .user import User 25 | 26 | 27 | class TeamMember: 28 | def __init__(self, data: DiscordTeamMember) -> None: 29 | self.team_id: Snowflake = Snowflake(data['team_id']) 30 | self.user = User(data['user']) 31 | self.permissions: list[str] = data['permissions'] 32 | self.membership_state: MembershipState = MembershipState( 33 | data['membership_state'] 34 | ) 35 | 36 | 37 | class Team: 38 | def __init__(self, data: DiscordTeam) -> None: 39 | self.id: Snowflake = Snowflake(data['id']) 40 | self.icon: str | None = data['icon'] 41 | self.members: list[TeamMember] = [TeamMember(d) for d in data['members']] 42 | self.name: str = data['name'] 43 | self.owner_id: Snowflake = Snowflake(data['owner_user_id']) 44 | -------------------------------------------------------------------------------- /pycord/types/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.types 3 | ~~~~~~~~~~~~ 4 | Typing's for the Discord API. 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from typing import Any, Callable, Coroutine 10 | 11 | from .application import * 12 | from .application_commands import * 13 | from .application_role_connection_metadata import * 14 | from .audit_log import * 15 | from .auto_moderation import * 16 | from .channel import * 17 | from .component import * 18 | from .embed import * 19 | from .guild import * 20 | from .guild_scheduled_event import * 21 | from .guild_template import * 22 | from .integration import * 23 | from .interaction import * 24 | from .invite import * 25 | from .media import * 26 | from .message import * 27 | from .role import * 28 | from .snowflake import * 29 | from .stage_instance import * 30 | from .user import * 31 | from .voice_state import * 32 | from .webhook import * 33 | from .welcome_screen import * 34 | 35 | AsyncFunc = Callable[..., Coroutine[Any, Any, Any]] 36 | -------------------------------------------------------------------------------- /pycord/types/application.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .integration import SCOPE 27 | from .snowflake import Snowflake 28 | from .user import User 29 | 30 | 31 | class TeamMember(TypedDict): 32 | membership_state: Literal[1, 2] 33 | permissions: list[str] 34 | team_id: Snowflake 35 | user: User 36 | 37 | 38 | class Team(TypedDict): 39 | icon: str | None 40 | id: Snowflake 41 | members: list[TeamMember] 42 | name: str 43 | owner_user_id: Snowflake 44 | 45 | 46 | class InstallParams(TypedDict): 47 | scopes: list[SCOPE] 48 | permissions: str 49 | 50 | 51 | class Application(TypedDict): 52 | id: Snowflake 53 | name: str 54 | icon: str | None 55 | description: str 56 | rpc_origins: NotRequired[list[str]] 57 | bot_public: bool 58 | bot_require_code_grant: bool 59 | terms_of_service_url: NotRequired[str] 60 | privacy_policy_url: NotRequired[str] 61 | owner: NotRequired[User] 62 | summary: NotRequired[str] 63 | verify_key: str 64 | team: Team | None 65 | guild_id: NotRequired[Snowflake] 66 | primary_sku_id: NotRequired[Snowflake] 67 | slug: NotRequired[str] 68 | cover_image: NotRequired[str] 69 | flags: NotRequired[int] 70 | tags: NotRequired[list[str]] 71 | install_params: InstallParams 72 | custom_install_url: NotRequired[str] 73 | role_connections_verification_url: NotRequired[str] 74 | -------------------------------------------------------------------------------- /pycord/types/application_commands.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .channel import CTYPE 27 | from .snowflake import Snowflake 28 | from .user import LOCALE 29 | 30 | ATYPE = Literal[ 31 | 1, 32 | 2, 33 | 3, 34 | ] 35 | AOTYPE = Literal[ 36 | 1, 37 | 2, 38 | 3, 39 | 4, 40 | 5, 41 | 6, 42 | 7, 43 | 8, 44 | 9, 45 | 10, 46 | 11, 47 | ] 48 | 49 | 50 | class ApplicationCommandOptionChoice(TypedDict): 51 | name: str 52 | name_localizations: NotRequired[dict[LOCALE] | None] 53 | value: str | int | float 54 | 55 | 56 | class ApplicationCommandOption(TypedDict): 57 | type: ATYPE 58 | name: str 59 | name_localizations: NotRequired[dict[LOCALE, str] | None] 60 | description: str 61 | description_localizations: NotRequired[dict[LOCALE, str] | None] 62 | required: NotRequired[bool] 63 | choices: NotRequired[ApplicationCommandOptionChoice] 64 | options: NotRequired[list['ApplicationCommandOption']] 65 | channel_types: NotRequired[list[CTYPE]] 66 | min_value: NotRequired[int] 67 | max_value: NotRequired[int] 68 | min_length: NotRequired[int] 69 | max_length: NotRequired[int] 70 | autocomplete: NotRequired[bool] 71 | 72 | 73 | class ApplicationCommand(TypedDict): 74 | id: Snowflake 75 | type: NotRequired[ATYPE] 76 | application_id: Snowflake 77 | guild_id: NotRequired[Snowflake] 78 | name: str 79 | name_localizations: NotRequired[dict[LOCALE, str] | None] 80 | description: str 81 | description_localizations: NotRequired[dict[LOCALE, str] | None] 82 | options: NotRequired[list[ApplicationCommandOption]] 83 | default_member_permissions: str | None 84 | dm_permission: NotRequired[bool] 85 | default_permission: NotRequired[bool | None] 86 | version: Snowflake 87 | 88 | 89 | class ApplicationCommandPermissions(TypedDict): 90 | id: Snowflake 91 | type: Literal[1, 2, 3] 92 | permission: bool 93 | 94 | 95 | class GuildApplicationCommandPermissions(TypedDict): 96 | id: Snowflake 97 | application_id: Snowflake 98 | guild_id: Snowflake 99 | permissions: list[ApplicationCommandPermissions] 100 | -------------------------------------------------------------------------------- /pycord/types/application_role_connection_metadata.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .user import LOCALE 27 | 28 | RCMTYPE = Literal[ 29 | 1, 30 | 2, 31 | 3, 32 | 4, 33 | 5, 34 | 6, 35 | 7, 36 | 8, 37 | ] 38 | 39 | 40 | class ApplicationRoleConnectionMetadata(TypedDict): 41 | type: RCMTYPE 42 | key: str 43 | name: str 44 | name_localizations: NotRequired[dict[LOCALE, str]] 45 | description: str 46 | description_localizations: NotRequired[dict[LOCALE, str]] 47 | -------------------------------------------------------------------------------- /pycord/types/audit_log.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Any, Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .application_commands import ApplicationCommand 27 | from .auto_moderation import AutoModerationRule 28 | from .channel import Channel 29 | from .guild_scheduled_event import GuildScheduledEvent 30 | from .integration import Integration 31 | from .snowflake import Snowflake 32 | from .user import User 33 | from .webhook import Webhook 34 | 35 | AUDIT_LOG_EVENT_TYPE = Literal[ 36 | 1, 37 | 10, 38 | 11, 39 | 12, 40 | 13, 41 | 14, 42 | 15, 43 | 20, 44 | 21, 45 | 22, 46 | 23, 47 | 24, 48 | 25, 49 | 26, 50 | 27, 51 | 28, 52 | 30, 53 | 31, 54 | 32, 55 | 40, 56 | 41, 57 | 42, 58 | 50, 59 | 51, 60 | 52, 61 | 60, 62 | 61, 63 | 62, 64 | 72, 65 | 73, 66 | 74, 67 | 75, 68 | 80, 69 | 81, 70 | 82, 71 | 83, 72 | 84, 73 | 85, 74 | 90, 75 | 91, 76 | 92, 77 | 100, 78 | 101, 79 | 102, 80 | 110, 81 | 111, 82 | 112, 83 | 121, 84 | 140, 85 | 141, 86 | 142, 87 | 143, 88 | 144, 89 | 145, 90 | ] 91 | 92 | 93 | class AuditLogChange(TypedDict): 94 | new_value: NotRequired[Any] 95 | old_value: NotRequired[Any] 96 | key: str 97 | 98 | 99 | class OptionalAuditEntryInfo(TypedDict): 100 | application_id: Snowflake 101 | auto_moderation_rule_name: str 102 | auto_moderation_rule_trigger_type: str 103 | channel_id: Snowflake 104 | count: str 105 | delete_member_days: str 106 | id: Snowflake 107 | members_removed: str 108 | message_id: Snowflake 109 | role_name: str 110 | type: str 111 | 112 | 113 | class AuditLogEntry(TypedDict): 114 | target_id: str | None 115 | changes: NotRequired[AuditLogChange] 116 | user_id: Snowflake | None 117 | id: Snowflake 118 | action_type: AUDIT_LOG_EVENT_TYPE 119 | options: NotRequired[OptionalAuditEntryInfo] 120 | reason: NotRequired[str] 121 | 122 | 123 | class AuditLog(TypedDict): 124 | application_commands: list[ApplicationCommand] 125 | audit_log_entries: list[AuditLogEntry] 126 | auto_moderation_rules: list[AutoModerationRule] 127 | guild_scheduled_events: list[GuildScheduledEvent] 128 | integrations: list[Integration] 129 | threads: list[Channel] 130 | users: list[User] 131 | webhooks: list[Webhook] 132 | -------------------------------------------------------------------------------- /pycord/types/auto_moderation.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import TypedDict 25 | 26 | from .snowflake import Snowflake 27 | 28 | AUTO_MODERATION_TRIGGER_TYPES = Literal[1, 3, 4, 5] 29 | AUTO_MODERATION_KEYWORD_PRESET_TYPES = Literal[1, 2, 3] 30 | AUTO_MODERATION_EVENT_TYPES = Literal[1] 31 | AUTO_MODERATION_ACTION_TYPES = Literal[1, 2, 3] 32 | 33 | 34 | class AutoModerationActionMetadata(TypedDict): 35 | channel_id: Snowflake 36 | duration_seconds: int 37 | 38 | 39 | class AutoModerationAction(TypedDict): 40 | type: AUTO_MODERATION_ACTION_TYPES 41 | metadata: AutoModerationActionMetadata 42 | 43 | 44 | class AutoModerationTriggerMetadata(TypedDict): 45 | keyword_filter: list[str] 46 | regex_patterns: list[str] 47 | presets: list[AUTO_MODERATION_KEYWORD_PRESET_TYPES] 48 | allow_list: list[str] 49 | mention_total_limit: int 50 | 51 | 52 | class AutoModerationRule(TypedDict): 53 | id: Snowflake 54 | guild_id: Snowflake 55 | name: str 56 | creator_id: Snowflake 57 | event_type: AUTO_MODERATION_EVENT_TYPES 58 | trigger_type: AUTO_MODERATION_TRIGGER_TYPES 59 | trigger_metadata: AutoModerationTriggerMetadata 60 | actions: list[AutoModerationAction] 61 | enabled: bool 62 | exempt_roles: list[Snowflake] 63 | exempt_channels: list[Snowflake] 64 | -------------------------------------------------------------------------------- /pycord/types/channel.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import TYPE_CHECKING, Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .snowflake import Snowflake 26 | from .user import User 27 | 28 | if TYPE_CHECKING: 29 | from .guild import GuildMember 30 | 31 | CTYPE = Literal[0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15] 32 | 33 | 34 | class Overwrite(TypedDict): 35 | id: Snowflake 36 | type: int 37 | allow: str 38 | deny: str 39 | 40 | 41 | class ThreadMetadata(TypedDict): 42 | archived: bool 43 | auto_archive_duration: int 44 | archive_timestamp: str 45 | locked: bool 46 | invitable: NotRequired[bool] 47 | create_timestamp: NotRequired[str | None] 48 | 49 | 50 | class ThreadMember(TypedDict): 51 | id: NotRequired[Snowflake] 52 | user_id: NotRequired[Snowflake] 53 | join_timestamp: str 54 | flags: int 55 | member: NotRequired['GuildMember'] 56 | 57 | 58 | class ForumTag(TypedDict): 59 | id: Snowflake 60 | name: str 61 | moderated: bool 62 | emoji_id: Snowflake 63 | emoji_name: str | None 64 | 65 | 66 | class DefaultReaction(TypedDict): 67 | emoji_id: str | None 68 | emoji_name: str | None 69 | 70 | 71 | class Channel(TypedDict): 72 | id: Snowflake 73 | type: CTYPE 74 | guild_id: NotRequired[Snowflake] 75 | position: NotRequired[Snowflake] 76 | permission_overwrites: NotRequired[list[Overwrite]] 77 | name: NotRequired[str | None] 78 | topic: NotRequired[str | None] 79 | nsfw: NotRequired[bool] 80 | last_message_id: NotRequired[Snowflake | None] 81 | bitrate: NotRequired[int] 82 | user_limit: NotRequired[int] 83 | rate_limit_per_user: NotRequired[int] 84 | recipients: NotRequired[list[User]] 85 | icon: NotRequired[str | None] 86 | owner_id: NotRequired[Snowflake] 87 | application_id: NotRequired[Snowflake] 88 | parent_id: NotRequired[Snowflake | None] 89 | last_pin_timestamp: NotRequired[str | None] 90 | rtc_region: NotRequired[str | None] 91 | video_quality_mode: NotRequired[Literal[1, 2]] 92 | message_count: NotRequired[int] 93 | member_count: NotRequired[int] 94 | thread_metadata: NotRequired[ThreadMetadata] 95 | member: NotRequired[ThreadMember] 96 | default_auto_archive_duration: NotRequired[int] 97 | permissions: NotRequired[int] 98 | flags: NotRequired[int] 99 | total_messages_sent: NotRequired[int] 100 | available_tags: list[ForumTag] 101 | applied_tags: list[Snowflake] 102 | default_reaction_emoji: NotRequired[DefaultReaction] 103 | default_thread_rate_limit_per_user: NotRequired[int] 104 | default_sort_order: NotRequired[int | None] 105 | 106 | 107 | AMTYPE = Literal['roles', 'users', 'everyone'] 108 | 109 | 110 | class AllowedMentions(TypedDict): 111 | parse: list[AMTYPE] 112 | roles: list[Snowflake] 113 | users: list[Snowflake] 114 | replied_user: bool 115 | 116 | 117 | class FollowedChannel(TypedDict): 118 | channel_id: Snowflake 119 | webhook_id: Snowflake 120 | 121 | 122 | class ListThreadsResponse(TypedDict): 123 | threads: list[Channel] 124 | members: list[ThreadMember] 125 | has_more: bool 126 | -------------------------------------------------------------------------------- /pycord/types/component.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from typing import Literal 25 | 26 | from typing_extensions import NotRequired, TypedDict 27 | 28 | from .channel import CTYPE 29 | from .media import Emoji 30 | 31 | COTYPE = Literal[1, 2, 3, 4, 5, 6, 7, 8] 32 | BSTYLE = Literal[1, 2, 3, 4, 5] 33 | 34 | 35 | class ActionRow(TypedDict): 36 | components: list[Button | SelectMenu | TextInput] 37 | 38 | 39 | class Button(TypedDict): 40 | type: Literal[2] 41 | style: BSTYLE 42 | label: NotRequired[str] 43 | emoji: NotRequired[Emoji] 44 | custom_id: NotRequired[str] 45 | url: NotRequired[str] 46 | disabled: NotRequired[bool] 47 | 48 | 49 | class SelectOption(TypedDict): 50 | label: str 51 | value: str 52 | description: NotRequired[str] 53 | emoji: NotRequired[Emoji] 54 | default: NotRequired[bool] 55 | 56 | 57 | class SelectMenu(TypedDict): 58 | type: Literal[3, 5, 6, 7, 8] 59 | custom_id: str 60 | options: NotRequired[list[SelectOption]] 61 | channel_types: list[CTYPE] 62 | placeholder: NotRequired[str] 63 | min_values: NotRequired[int] 64 | mazx_values: NotRequired[int] 65 | disabled: NotRequired[bool] 66 | 67 | 68 | class TextInput(TypedDict): 69 | type: Literal[4] 70 | custom_id: str 71 | style: Literal[1, 2] 72 | label: str 73 | min_length: NotRequired[int] 74 | max_length: NotRequired[int] 75 | required: NotRequired[bool] 76 | value: NotRequired[str] 77 | placeholder: NotRequired[str] 78 | 79 | 80 | Component = ActionRow | SelectMenu | TextInput | Button 81 | -------------------------------------------------------------------------------- /pycord/types/embed.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | ETYPES = Literal['rich', 'image', 'video', 'gifv', 'article', 'link'] 26 | 27 | 28 | class Thumbnail(TypedDict): 29 | url: str 30 | proxy_url: NotRequired[str] 31 | height: NotRequired[int] 32 | width: NotRequired[int] 33 | 34 | 35 | class Video(TypedDict): 36 | url: str 37 | proxy_url: NotRequired[str] 38 | height: NotRequired[int] 39 | width: NotRequired[int] 40 | 41 | 42 | class Image(TypedDict): 43 | url: str 44 | proxy_url: NotRequired[str] 45 | height: NotRequired[int] 46 | width: NotRequired[int] 47 | 48 | 49 | class Author(TypedDict): 50 | name: str 51 | url: NotRequired[str] 52 | icon_url: NotRequired[str] 53 | proxy_icon_url: NotRequired[str] 54 | 55 | 56 | class Provider(TypedDict): 57 | name: NotRequired[str] 58 | url: NotRequired[str] 59 | 60 | 61 | class Footer(TypedDict): 62 | text: str 63 | icon_url: NotRequired[str] 64 | proxy_icon_url: NotRequired[str] 65 | 66 | 67 | class Field(TypedDict): 68 | name: str 69 | value: str 70 | inline: NotRequired[bool] 71 | 72 | 73 | class Embed(TypedDict): 74 | title: NotRequired[str] 75 | type: NotRequired[ETYPES] 76 | description: NotRequired[str] 77 | url: NotRequired[str] 78 | timestamp: NotRequired[str] 79 | color: NotRequired[int] 80 | footer: NotRequired[Footer] 81 | image: NotRequired[Image] 82 | thumbnail: NotRequired[Thumbnail] 83 | video: NotRequired[Video] 84 | provider: NotRequired[Provider] 85 | author: NotRequired[Author] 86 | fields: NotRequired[list[Field]] 87 | -------------------------------------------------------------------------------- /pycord/types/guild_scheduled_event.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .guild import GuildMember 26 | from .snowflake import Snowflake 27 | from .user import User 28 | 29 | 30 | class EntityMetadata(TypedDict): 31 | location: str | None 32 | 33 | 34 | class EventUser(TypedDict): 35 | guild_scheduled_event_id: Snowflake 36 | user: User 37 | member: GuildMember 38 | 39 | 40 | class GuildScheduledEvent(TypedDict): 41 | id: Snowflake 42 | guild_id: Snowflake 43 | channel_id: Snowflake | None 44 | creator_id: NotRequired[Snowflake] 45 | name: str 46 | description: NotRequired[str | None] 47 | scheduled_start_time: str 48 | scheduled_end_time: str | None 49 | privacy_level: Literal[2] 50 | status: Literal[1, 2, 3, 4] 51 | entity_type: Literal[1, 2, 3] 52 | entity_id: Snowflake | None 53 | entity_metadata: EntityMetadata | None 54 | creator: NotRequired[User] 55 | user_count: NotRequired[int] 56 | image: NotRequired[str | None] 57 | -------------------------------------------------------------------------------- /pycord/types/guild_template.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing_extensions import TypedDict 22 | 23 | from .guild import Guild 24 | from .snowflake import Snowflake 25 | from .user import User 26 | 27 | 28 | class GuildTemplate(TypedDict): 29 | code: str 30 | name: str 31 | description: str | None 32 | usage_count: int 33 | creator_id: Snowflake 34 | creator: User 35 | created_at: str 36 | updated_at: str 37 | source_guild_id: Snowflake 38 | serialized_source_guild: Guild 39 | is_dirty: bool | None 40 | -------------------------------------------------------------------------------- /pycord/types/integration.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .snowflake import Snowflake 27 | from .user import User 28 | 29 | SCOPE = Literal[ 30 | 'activities.read', 31 | 'activities.write', 32 | 'applications.builds.read', 33 | 'applications.builds.upload', 34 | 'applications.commands', 35 | 'applications.commands.update', 36 | 'applications.commands.permissions.update', 37 | 'applications.entitlements', 38 | 'applications.store.update', 39 | 'bot', 40 | 'connections', 41 | 'dm_channels.read', 42 | 'email', 43 | 'guilds', 44 | 'guilds.join', 45 | 'guilds.members.read', 46 | 'identify', 47 | 'messages.send', 48 | 'relationships.read', 49 | 'rpc', 50 | 'rpc.activities.write', 51 | 'rpc.notifications.read', 52 | 'rpc.voice.read', 53 | 'rpc.voice.write', 54 | 'voice', 55 | 'webhook.incoming', 56 | ] 57 | INTEGRATION_TYPE = Literal['twitch', 'youtube', 'discord'] 58 | INTEGRATION_EXPIRE_BEHAVIOR = Literal[0, 1] 59 | 60 | 61 | class Account(TypedDict): 62 | id: str 63 | name: str 64 | 65 | 66 | class IntegrationApplication(TypedDict): 67 | id: Snowflake 68 | name: str 69 | icon: str | None 70 | description: str 71 | bot: NotRequired[User] 72 | 73 | 74 | class Integration(TypedDict): 75 | id: Snowflake 76 | name: str 77 | type: INTEGRATION_TYPE 78 | enabled: NotRequired[bool] 79 | syncing: NotRequired[bool] 80 | role_id: NotRequired[Snowflake] 81 | enable_emoticons: NotRequired[bool] 82 | expire_behavior: NotRequired[INTEGRATION_EXPIRE_BEHAVIOR] 83 | expire_grace_period: NotRequired[int] 84 | user: NotRequired[User] 85 | account: Account 86 | synced_at: NotRequired[str] 87 | subscriber_count: NotRequired[int] 88 | revoked: NotRequired[bool] 89 | application: NotRequired[IntegrationApplication] 90 | scopes: list[SCOPE] 91 | -------------------------------------------------------------------------------- /pycord/types/interaction.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .application_commands import ATYPE, ApplicationCommandOptionChoice 26 | from .channel import AllowedMentions, Channel 27 | from .component import Component, SelectOption 28 | from .embed import Embed 29 | from .guild import GuildMember 30 | from .media import Attachment 31 | from .message import Message 32 | from .role import Role 33 | from .snowflake import Snowflake 34 | from .user import LOCALE, User 35 | 36 | ITYPE = Literal[ 37 | 1, 38 | 2, 39 | 3, 40 | 4, 41 | 5, 42 | ] 43 | 44 | 45 | class ResolvedData(TypedDict): 46 | users: NotRequired[list[User]] 47 | members: NotRequired[list[GuildMember]] 48 | roles: NotRequired[list[Role]] 49 | channels: NotRequired[list[Channel]] 50 | messages: NotRequired[list[Message]] 51 | attachments: NotRequired[list[Attachment]] 52 | 53 | 54 | class ApplicationCommandInteractionDataOption(TypedDict): 55 | name: str 56 | type: ATYPE 57 | value: NotRequired[str | int | float] 58 | options: NotRequired[list['ApplicationCommandInteractionDataOption']] 59 | focused: NotRequired[bool] 60 | 61 | 62 | class ApplicationCommandData(TypedDict): 63 | id: Snowflake 64 | name: str 65 | type: ATYPE 66 | resolved: NotRequired[ResolvedData] 67 | options: NotRequired[list[ApplicationCommandInteractionDataOption]] 68 | guild_id: NotRequired[Snowflake] 69 | target_id: NotRequired[Snowflake] 70 | 71 | 72 | class MessageComponentData(TypedDict): 73 | custom_id: str 74 | component_type: int 75 | values: NotRequired[list[SelectOption]] 76 | 77 | 78 | class ModalSubmitData(TypedDict): 79 | custom_id: str 80 | components: list[Component] 81 | 82 | 83 | INTERACTION_DATA = ( 84 | ApplicationCommandData 85 | | ApplicationCommandInteractionDataOption 86 | | ResolvedData 87 | | ApplicationCommandData 88 | | MessageComponentData 89 | | ModalSubmitData 90 | ) 91 | 92 | 93 | class Interaction(TypedDict): 94 | id: Snowflake 95 | application_id: Snowflake 96 | type: ITYPE 97 | data: INTERACTION_DATA 98 | guild_id: NotRequired[Snowflake] 99 | channel_id: NotRequired[Snowflake] 100 | member: NotRequired[GuildMember] 101 | user: NotRequired[User] 102 | token: str 103 | version: int 104 | message: NotRequired[Message] 105 | app_permissions: str 106 | locale: LOCALE 107 | guild_locale: LOCALE 108 | 109 | 110 | class ICDMessages(TypedDict): 111 | tts: NotRequired[bool] 112 | content: NotRequired[str] 113 | embeds: NotRequired[list[Embed]] 114 | allowed_mentions: NotRequired[AllowedMentions] 115 | flags: NotRequired[int] 116 | components: NotRequired[list[Component]] 117 | attachments: NotRequired[list[Attachment]] 118 | 119 | 120 | class ICDAutocomplete(TypedDict): 121 | choices: list[ApplicationCommandOptionChoice] 122 | 123 | 124 | class ICDModal(TypedDict): 125 | custom_id: str 126 | title: str 127 | components: list[Component] 128 | 129 | 130 | ICD = ICDMessages | ICDAutocomplete | ICDModal 131 | 132 | 133 | class InteractionResponse(TypedDict): 134 | type: Literal[1, 4, 5, 6, 7, 8, 9] 135 | data: ICD 136 | -------------------------------------------------------------------------------- /pycord/types/invite.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing_extensions import NotRequired, TypedDict 22 | 23 | from .application import Application 24 | from .channel import Channel 25 | from .guild import Guild 26 | from .guild_scheduled_event import GuildScheduledEvent 27 | from .user import User 28 | 29 | 30 | class InviteMetadata(TypedDict): 31 | uses: int 32 | max_uses: int 33 | max_age: int 34 | temporary: bool 35 | created_at: str 36 | 37 | 38 | class Invite(TypedDict): 39 | code: str 40 | guild: NotRequired[Guild] 41 | channel: Channel | None 42 | inviter: NotRequired[User] 43 | target_type: NotRequired[int] 44 | target_user: NotRequired[User] 45 | target_application: NotRequired[Application] 46 | approximate_presence_count: NotRequired[int] 47 | approximate_member_count: NotRequired[int] 48 | expires_at: NotRequired[str] 49 | guild_scheduled_event: NotRequired[GuildScheduledEvent] 50 | 51 | 52 | class PartialInvite(TypedDict): 53 | code: str | None 54 | uses: int 55 | -------------------------------------------------------------------------------- /pycord/types/media.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .snowflake import Snowflake 26 | from .user import User 27 | 28 | 29 | class Emoji(TypedDict): 30 | id: Snowflake | None 31 | name: str 32 | roles: NotRequired[list[Snowflake]] 33 | user: NotRequired[User] 34 | require_colons: NotRequired[bool] 35 | managed: NotRequired[bool] 36 | animated: NotRequired[bool] 37 | available: NotRequired[bool] 38 | 39 | 40 | class StickerItem(TypedDict): 41 | id: Snowflake 42 | name: str 43 | format_type: Literal[1, 2, 3] 44 | 45 | 46 | class Sticker(StickerItem): 47 | pack_id: NotRequired[Snowflake] 48 | description: str | None 49 | tags: str 50 | asset: NotRequired[str] 51 | type: Literal[1, 2] 52 | available: NotRequired[bool] 53 | guild_id: NotRequired[Snowflake] 54 | user: NotRequired[User] 55 | sort_value: NotRequired[int] 56 | 57 | 58 | class StickerPack(TypedDict): 59 | id: Snowflake 60 | stickers: list[Sticker] 61 | name: str 62 | sku_id: Snowflake 63 | cover_sticker_id: NotRequired[Snowflake] 64 | description: str 65 | banner_asset_id: NotRequired[Snowflake] 66 | 67 | 68 | class Attachment(TypedDict): 69 | id: Snowflake 70 | filename: str 71 | description: NotRequired[str] 72 | content_type: NotRequired[str] 73 | size: int 74 | url: str 75 | proxy_url: str 76 | height: NotRequired[int | None] 77 | width: NotRequired[int | None] 78 | ephemeral: NotRequired[bool] 79 | -------------------------------------------------------------------------------- /pycord/types/message.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .application import Application 26 | from .channel import CTYPE, AllowedMentions, Channel 27 | from .component import Component 28 | from .embed import Embed 29 | from .guild import GuildMember 30 | from .media import Attachment, Emoji, Sticker, StickerItem 31 | from .role import Role 32 | from .snowflake import Snowflake 33 | from .user import User 34 | 35 | MTYPE = Literal[ 36 | 0, 37 | 1, 38 | 2, 39 | 3, 40 | 4, 41 | 5, 42 | 6, 43 | 7, 44 | 8, 45 | 9, 46 | 10, 47 | 11, 48 | 12, 49 | 13, 50 | 14, 51 | 15, 52 | 16, 53 | 17, 54 | 18, 55 | 19, 56 | 20, 57 | 21, 58 | 22, 59 | 23, 60 | 24, 61 | ] 62 | 63 | 64 | class ChannelMention(TypedDict): 65 | id: Snowflake 66 | guild_id: Snowflake 67 | type: CTYPE 68 | name: str 69 | 70 | 71 | class Reaction(TypedDict): 72 | count: int 73 | me: bool 74 | emoji: Emoji 75 | 76 | 77 | class MessageActivity(TypedDict): 78 | type: Literal[1, 2, 3, 5] 79 | party_id: str 80 | 81 | 82 | class MessageReference(TypedDict): 83 | message_id: NotRequired[Snowflake] 84 | channel_id: NotRequired[Snowflake] 85 | guild_id: NotRequired[Snowflake] 86 | fail_if_not_exists: NotRequired[bool] 87 | 88 | 89 | class MessageInteraction(TypedDict): 90 | id: Snowflake 91 | type: Literal[1, 2, 3, 4, 5] 92 | name: str 93 | user: User 94 | member: NotRequired[GuildMember] 95 | 96 | 97 | class Message(TypedDict): 98 | id: Snowflake 99 | channel_id: Snowflake 100 | author: NotRequired[User] 101 | content: NotRequired[str] 102 | timestamp: str 103 | edited_timestamp: str | None 104 | tts: bool 105 | mention_everyone: bool 106 | mentions: list[User] 107 | mention_roles: list[Role] 108 | mention_channels: NotRequired[list[ChannelMention]] 109 | attachments: list[Attachment] 110 | embeds: list[Embed] 111 | reactions: list[Reaction] 112 | nonce: NotRequired[int | str] 113 | pinned: bool 114 | webhook_id: Snowflake 115 | type: int 116 | activity: NotRequired[MessageActivity] 117 | application: NotRequired[Application] 118 | application_id: NotRequired[Snowflake] 119 | message_reference: NotRequired[MessageReference] 120 | flags: NotRequired[int] 121 | referenced_message: NotRequired['Message'] 122 | interaction: NotRequired[MessageInteraction] 123 | thread: NotRequired[Channel] 124 | components: NotRequired[list[Component]] 125 | sticker_items: NotRequired[list[StickerItem]] 126 | stickers: NotRequired[list[Sticker]] 127 | position: NotRequired[int] 128 | 129 | 130 | class ForumThreadMessageParams(TypedDict): 131 | content: NotRequired[str] 132 | embeds: NotRequired[list[Embed]] 133 | allowed_mentions: NotRequired[AllowedMentions] 134 | components: NotRequired[list[Component]] 135 | sticker_ids: NotRequired[list[Snowflake]] 136 | payload_json: NotRequired[str] 137 | attachments: NotRequired[list[Attachment]] 138 | flags: NotRequired[int] 139 | -------------------------------------------------------------------------------- /pycord/types/role.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import Literal 22 | 23 | from typing_extensions import NotRequired, TypedDict 24 | 25 | from .snowflake import Snowflake 26 | 27 | 28 | class RoleTags(TypedDict): 29 | bot_id: NotRequired[Snowflake] 30 | integration_id: NotRequired[Snowflake] 31 | premium_subscriber: NotRequired[Literal[None]] 32 | 33 | 34 | class Role(TypedDict): 35 | id: Snowflake 36 | name: str 37 | color: int 38 | hoist: bool 39 | icon: NotRequired[str | None] 40 | unicode_emoji: NotRequired[str | None] 41 | position: int 42 | permissions: str 43 | managed: bool 44 | mentionable: bool 45 | tags: NotRequired[RoleTags] 46 | -------------------------------------------------------------------------------- /pycord/types/snowflake.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from typing import Sequence, TypeVar, Union 25 | 26 | __all__: Sequence[str] = ('Snowflake', 'SnowflakeL', 'SnowflakeOr') 27 | 28 | T = TypeVar('T', covariant=True) 29 | 30 | Snowflake = Union[int, str] 31 | SnowflakeL = list[Snowflake] 32 | SnowflakeOr = Union[T, Snowflake] 33 | -------------------------------------------------------------------------------- /pycord/types/stage_instance.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing import Literal 23 | 24 | from typing_extensions import TypedDict 25 | 26 | from .snowflake import Snowflake 27 | 28 | PRIVACY_LEVEL = Literal[1, 2] 29 | 30 | 31 | class StageInstance(TypedDict): 32 | id: Snowflake 33 | guild_id: Snowflake 34 | channel_id: Snowflake 35 | topic: str 36 | privacy_level: PRIVACY_LEVEL 37 | discoverable_disabled: bool 38 | guild_scheduled_event_id: Snowflake | None 39 | -------------------------------------------------------------------------------- /pycord/types/user.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from typing import TYPE_CHECKING, Literal 24 | 25 | from typing_extensions import NotRequired, TypedDict 26 | 27 | if TYPE_CHECKING: 28 | from .integration import Integration 29 | 30 | from .snowflake import Snowflake 31 | 32 | PREMIUM_TYPE = Literal[0, 1, 2, 3] 33 | LOCALE = Literal[ 34 | 'da', 35 | 'de', 36 | 'en-GB', 37 | 'en-US', 38 | 'en-ES', 39 | 'fr', 40 | 'hr', 41 | 'it', 42 | 'lt', 43 | 'hu', 44 | 'nl', 45 | 'no', 46 | 'pl', 47 | 'pt-BR', 48 | 'ro', 49 | 'fi', 50 | 'sv-SE', 51 | 'vi', 52 | 'tr', 53 | 'cs', 54 | 'el', 55 | 'bg', 56 | 'ru', 57 | 'uk', 58 | 'hi', 59 | 'th', 60 | 'zh-CN', 61 | 'ja', 62 | 'zh-TW', 63 | 'ko', 64 | ] 65 | 66 | 67 | class User(TypedDict): 68 | id: Snowflake 69 | username: str 70 | discriminator: str 71 | avatar: str | None 72 | bot: NotRequired[bool] 73 | system: NotRequired[bool] 74 | mfa_enabled: NotRequired[bool] 75 | banner: NotRequired[str | None] 76 | accent_color: NotRequired[int | None] 77 | locale: NotRequired[LOCALE] 78 | verified: NotRequired[bool] 79 | email: NotRequired[str | None] 80 | flags: NotRequired[int] 81 | premium_type: NotRequired[PREMIUM_TYPE] 82 | public_flags: NotRequired[int] 83 | 84 | 85 | SERVICE = Literal[ 86 | 'battlenet', 87 | 'ebay', 88 | 'epicgames', 89 | 'facebook', 90 | 'github', 91 | 'leagueoflegends', 92 | 'paypal', 93 | 'playstation', 94 | 'reddit', 95 | 'riotgames', 96 | 'spotify', 97 | 'skype', 98 | 'steam', 99 | 'twitch', 100 | 'twitter', 101 | 'xbox', 102 | 'youtuve', 103 | ] 104 | VISIBILITY = Literal[0, 1] 105 | 106 | 107 | class Connection(TypedDict): 108 | id: str 109 | name: str 110 | type: SERVICE 111 | revoked: NotRequired[bool] 112 | integrations: NotRequired[list[Integration]] 113 | verified: bool 114 | friend_sync: bool 115 | show_activity: bool 116 | two_way_link: bool 117 | visibility: int 118 | -------------------------------------------------------------------------------- /pycord/types/voice_state.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from typing_extensions import NotRequired, TypedDict 23 | 24 | from .guild import GuildMember 25 | from .snowflake import Snowflake 26 | 27 | 28 | class VoiceState(TypedDict): 29 | guild_id: NotRequired[Snowflake] 30 | channel_id: Snowflake | None 31 | user_id: Snowflake 32 | member: NotRequired[GuildMember] 33 | session_id: str 34 | deaf: bool 35 | mute: bool 36 | self_deaf: bool 37 | self_mute: bool 38 | self_stream: NotRequired[bool] 39 | self_video: bool 40 | suppress: bool 41 | request_to_speak_timestamp: str | None 42 | 43 | 44 | class VoiceRegion(TypedDict): 45 | id: str 46 | name: str 47 | optimal: bool 48 | deprecated: bool 49 | custom: bool 50 | -------------------------------------------------------------------------------- /pycord/types/webhook.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | 3 | # Copyright (c) 2022-present Pycord Development 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE 22 | from typing import Literal 23 | 24 | from typing_extensions import NotRequired, TypedDict 25 | 26 | from .channel import Channel 27 | from .guild import Guild 28 | from .snowflake import Snowflake 29 | from .user import User 30 | 31 | WTYPE = Literal[1, 2, 3] 32 | 33 | 34 | class Webhook(TypedDict): 35 | id: Snowflake 36 | type: WTYPE 37 | guild_id: NotRequired[Snowflake | None] 38 | channel_id: NotRequired[Snowflake | None] 39 | user: NotRequired[User] 40 | name: str | None 41 | avatar: str | None 42 | token: NotRequired[str] 43 | application_id: str | None 44 | source_guild: NotRequired[Guild] 45 | source_channel: NotRequired[Channel] 46 | url: NotRequired[str] 47 | -------------------------------------------------------------------------------- /pycord/types/welcome_screen.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2022-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from typing import TypedDict 22 | 23 | from .snowflake import Snowflake 24 | 25 | 26 | class WelcomeScreenChannel(TypedDict): 27 | channel_id: Snowflake 28 | description: str 29 | emoji_id: Snowflake | None 30 | emoji_name: str | None 31 | 32 | 33 | class WelcomeScreen(TypedDict): 34 | description: str | None 35 | welcome_channels: list[WelcomeScreenChannel] 36 | -------------------------------------------------------------------------------- /pycord/typing.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | 23 | import typing 24 | from typing import TYPE_CHECKING, Any 25 | 26 | from .types.snowflake import Snowflake 27 | 28 | if TYPE_CHECKING: 29 | from .state import State 30 | 31 | 32 | class Typing: 33 | __slots__ = ('_state', '__channel_id') 34 | 35 | def __init__(self, channel_id: Snowflake, state: 'State') -> None: 36 | self._state = state 37 | self.__channel_id = channel_id 38 | 39 | async def trigger(self) -> None: 40 | await self._state.http.trigger_typing_indicator(self.__channel_id) 41 | 42 | async def __aenter__(self) -> typing.Self: 43 | await self.trigger() 44 | return self 45 | 46 | async def __aexit__(self, exc_t: Any, exc_v: Any, exc_tb: Any) -> None: 47 | await self.trigger() 48 | -------------------------------------------------------------------------------- /pycord/ui/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pycord.ui 3 | ~~~~~~~~~ 4 | Implementation of Discord's UI-based Component Features 5 | 6 | :copyright: 2021-present Pycord Development 7 | :license: MIT 8 | """ 9 | from .button import * 10 | from .component import * 11 | from .house import * 12 | from .interactive_component import * 13 | from .select_menu import * 14 | from .text_input import * 15 | -------------------------------------------------------------------------------- /pycord/ui/button.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from typing import TYPE_CHECKING, Any 25 | 26 | from ..enums import ButtonStyle 27 | from ..errors import ComponentException 28 | from ..media import Emoji 29 | from ..missing import MISSING, MissingEnum 30 | from ..types import AsyncFunc 31 | from ..utils import remove_undefined 32 | from .interactive_component import InteractiveComponent 33 | 34 | if TYPE_CHECKING: 35 | from ..interaction import Interaction 36 | 37 | 38 | class Button(InteractiveComponent): 39 | """ 40 | Represents a Discord Button 41 | """ 42 | 43 | def __init__( 44 | self, 45 | callback: AsyncFunc, 46 | # button-based values 47 | style: ButtonStyle | int, 48 | label: str | MissingEnum = MISSING, 49 | custom_id: str | MissingEnum = MISSING, 50 | emoji: str | Emoji | MissingEnum = MISSING, 51 | url: str | MissingEnum = MISSING, 52 | disabled: bool = False, 53 | ) -> None: 54 | super().__init__(callback, custom_id) 55 | if isinstance(style, ButtonStyle): 56 | self._style = style.value 57 | else: 58 | self._style = style 59 | self.style = style 60 | self.label: str | None | MissingEnum = label 61 | self.url = url 62 | 63 | if label is None and url is None: 64 | raise ComponentException('label and url cannot both be None') 65 | 66 | if url and custom_id: 67 | raise ComponentException('Cannot have custom_id and url at the same time') 68 | 69 | if label is None: 70 | self.label = MISSING 71 | 72 | if isinstance(emoji, str): 73 | self.emoji = Emoji._from_str(emoji, None) 74 | else: 75 | self.emoji = emoji 76 | 77 | self.disabled = disabled 78 | 79 | def _to_dict(self) -> dict[str, Any]: 80 | return remove_undefined( 81 | **{ 82 | 'style': self._style, 83 | 'label': self.label, 84 | 'url': self.url, 85 | 'custom_id': self.id, 86 | 'emoji': self.emoji._partial() if self.emoji else MISSING, 87 | 'disabled': self.disabled, 88 | 'type': 2, 89 | } 90 | ) 91 | 92 | def disable(self) -> None: 93 | """ 94 | Disables this Button 95 | """ 96 | self.disabled = True 97 | 98 | async def _internal_invocation(self, inter: Interaction) -> None: 99 | await self._callback(inter) 100 | -------------------------------------------------------------------------------- /pycord/ui/component.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from copy import copy 25 | from dataclasses import dataclass, field 26 | from typing import Any, Literal 27 | 28 | 29 | class Component: 30 | """ 31 | The base component type which every other component 32 | subclasses and bases off of 33 | """ 34 | 35 | id: str 36 | type: int 37 | disabled: bool 38 | 39 | def copy(self) -> Component: 40 | return copy(self) 41 | 42 | def _to_dict(self) -> dict[str, Any]: 43 | ... 44 | 45 | def disable(self) -> None: 46 | ... 47 | 48 | 49 | @dataclass 50 | class ActionRow: 51 | """ 52 | Represents a Discord Action Row 53 | """ 54 | 55 | type: Literal[1] = field(default=1) 56 | components: list[Component] = field(default=list) 57 | 58 | def _to_dict(self) -> dict[str, Any]: 59 | return {'type': self.type, 'components': self.components} 60 | -------------------------------------------------------------------------------- /pycord/ui/interactive_component.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | 22 | from __future__ import annotations 23 | 24 | from typing import TYPE_CHECKING 25 | 26 | from .component import Component 27 | 28 | if TYPE_CHECKING: 29 | from ..interaction import Interaction 30 | from ..state import State 31 | from ..types import AsyncFunc 32 | 33 | 34 | class InteractiveComponent(Component): 35 | """ 36 | The base set of a component which can be interacted with. 37 | 38 | .. WARNING:: 39 | This is a **base class** which means we don't 40 | recommend usage of it unless you're making your 41 | own component class. 42 | """ 43 | 44 | def __init__( 45 | self, 46 | callback: AsyncFunc, 47 | custom_id: str | None, 48 | ) -> None: 49 | self._callback = callback 50 | self.id = custom_id 51 | self._state: State | None = None 52 | 53 | def _set_state(self, state: State) -> None: 54 | self._state = state 55 | 56 | async def _internal_invocation(self, inter: Interaction) -> None: 57 | ... 58 | 59 | async def _invoke(self, inter: Interaction) -> None: 60 | if inter.type not in (3, 5): 61 | return 62 | 63 | custom_id = inter.data['custom_id'] 64 | 65 | if custom_id == self.id: 66 | await self._internal_invocation(inter) 67 | -------------------------------------------------------------------------------- /pycord/user.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from functools import cached_property 24 | from typing import TYPE_CHECKING 25 | 26 | from .color import Color 27 | from .enums import PremiumType 28 | from .flags import UserFlags 29 | from .missing import MISSING, Maybe, MissingEnum 30 | from .snowflake import Snowflake 31 | from .types import LOCALE, User as DiscordUser 32 | 33 | if TYPE_CHECKING: 34 | from .state import State 35 | 36 | 37 | class User: 38 | def __init__(self, data: DiscordUser, state: State) -> None: 39 | self.id: Snowflake = Snowflake(data['id']) 40 | self.name: str = data['username'] 41 | self.discriminator: str = data['discriminator'] 42 | self._avatar: str | None = data['avatar'] 43 | self.bot: bool | MissingEnum = data.get('bot', MISSING) 44 | self.system: bool | MissingEnum = data.get('system', MISSING) 45 | self.mfa_enabled: bool | MissingEnum = data.get('mfa_enabled', MISSING) 46 | self._banner: MissingEnum | str | None = data.get('banner', MISSING) 47 | self._accent_color: MissingEnum | int | None = data.get('accent_color', MISSING) 48 | self.accent_color: MissingEnum | Color | None = ( 49 | Color(self._accent_color) 50 | if self._accent_color not in [MISSING, None] 51 | else self._accent_color 52 | ) 53 | self.locale: MissingEnum | LOCALE = data.get('locale', MISSING) 54 | self.verified: MissingEnum | bool = data.get('verified', MISSING) 55 | self.email: str | None | MissingEnum = data.get('email', MISSING) 56 | self._flags: MissingEnum | int = data.get('flags', MISSING) 57 | self.flags: MissingEnum | UserFlags = ( 58 | UserFlags.from_value(self._flags) if self._flags is not MISSING else MISSING 59 | ) 60 | self._premium_type: MissingEnum | int = data.get('premium_type', MISSING) 61 | self.premium_type: PremiumType | MissingEnum = ( 62 | PremiumType(self._premium_type) 63 | if self._premium_type is not MISSING 64 | else MISSING 65 | ) 66 | self._public_flags: MissingEnum | int = data.get('public_flags', MISSING) 67 | self.public_flags: MissingEnum | UserFlags = ( 68 | UserFlags.from_value(self._public_flags) 69 | if self._public_flags is not MISSING 70 | else MISSING 71 | ) 72 | 73 | @cached_property 74 | def mention(self) -> str: 75 | return f'<@{self.id}>' 76 | -------------------------------------------------------------------------------- /pycord/voice.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from __future__ import annotations 22 | 23 | from datetime import datetime 24 | from typing import TYPE_CHECKING 25 | 26 | from .member import Member 27 | from .missing import MISSING, Maybe, MissingEnum 28 | from .snowflake import Snowflake 29 | from .types import VoiceState as DiscordVoiceState 30 | 31 | if TYPE_CHECKING: 32 | from .state import State 33 | 34 | 35 | class VoiceState: 36 | def __init__(self, data: DiscordVoiceState, state: State) -> None: 37 | self.guild_id: Snowflake | MissingEnum = ( 38 | Snowflake(data['guild_id']) if data.get('guild_id') is not None else MISSING 39 | ) 40 | self.channel_id: Snowflake | None = ( 41 | Snowflake(data['channel_id']) 42 | if data.get('channel_id') is not None 43 | else None 44 | ) 45 | self.user_id: Snowflake = Snowflake(data['user_id']) 46 | self.member: Member | MissingEnum = ( 47 | Member(data['member'], state, guild_id=self.guild_id) 48 | if data.get('member') is not None 49 | else MISSING 50 | ) 51 | self.session_id: str = data['session_id'] 52 | self.deaf: bool = data['deaf'] 53 | self.mute: bool = data['mute'] 54 | self.self_deaf: bool = data['self_deaf'] 55 | self.self_mute: bool = data['self_mute'] 56 | self.self_stream: bool | MissingEnum = data.get('self_stream', MISSING) 57 | self.self_video: bool = data['self_video'] 58 | self.suppress: bool = data['suppress'] 59 | self.request_to_speak: datetime | MissingEnum = ( 60 | datetime.fromisoformat(data['request_to_speak_timestamp']) 61 | if data.get('request_to_speak_timestamp') is not None 62 | else None 63 | ) 64 | -------------------------------------------------------------------------------- /pycord/welcome_screen.py: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | # Copyright (c) 2021-present Pycord Development 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE 21 | from .snowflake import Snowflake 22 | from .types import ( 23 | WelcomeScreen as DiscordWelcomeScreen, 24 | WelcomeScreenChannel as DiscordWelcomeScreenChannel, 25 | ) 26 | 27 | 28 | class WelcomeScreenChannel: 29 | def __init__(self, data: DiscordWelcomeScreenChannel) -> None: 30 | self.channel_id: Snowflake = Snowflake(data['channel_id']) 31 | self.description: str = data['description'] 32 | self.emoji_id: Snowflake | None = ( 33 | Snowflake(data['emoji_id']) if data['emoji_id'] is not None else None 34 | ) 35 | self.emoji_name: str | None = data['emoji_name'] 36 | 37 | 38 | class WelcomeScreen: 39 | def __init__(self, data: DiscordWelcomeScreen) -> None: 40 | self.description: str | None = data['description'] 41 | self.welcome_channels: list[WelcomeScreenChannel] = [] 42 | self.welcome_channels.extend( 43 | WelcomeScreenChannel(welcome_channel) 44 | for welcome_channel in data['welcome_channels'] 45 | ) 46 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.brunette] 2 | target-version = ["py310", "py311"] 3 | single-quotes = true 4 | 5 | [tool.isort] 6 | profile = "black" 7 | combine_as_imports = true 8 | combine_star = true 9 | 10 | [tool.coverage.report] 11 | exclude_lines = [ 12 | "if TYPE_CHECKING:", 13 | ] 14 | 15 | [tool.towncrier] 16 | # For finding the __version__ 17 | package = "pycord" 18 | package_dir = "pycord" 19 | # For writing into the correct file 20 | filename = "CHANGELOG.md" 21 | start_string = "\n" 22 | # For finding the news fragments 23 | directory = "changes/" 24 | 25 | # For rendering properly for this project 26 | title_format = "## [{version}](https://github.com/pycord/pycord-v3/tree/{version}) ({project_date})" 27 | underlines = ["", "", ""] 28 | template = "templates/towncrier.jinja" 29 | 30 | # Grouping of entries, within our changelog 31 | type = [ 32 | { name = "Deprecations and Removals", directory = "removal", showcontent = true }, 33 | { name = "Features", directory = "feature", showcontent = true }, 34 | { name = "Bug Fixes", directory = "bug", showcontent = true }, 35 | { name = "Documentation", directory = "doc", showcontent = true }, 36 | { name = "Etcetera", directory = "etc", showcontent = false }, 37 | { name = "Trivial Changes", directory = "trivial", showcontent = false }, 38 | ] 39 | 40 | [tool.mypy] 41 | strict = false 42 | check_untyped_defs = false 43 | incremental = true 44 | namespace_packages = true 45 | no_implicit_optional = true 46 | pretty = true 47 | python_version = 3.11 48 | show_column_numbers = true 49 | show_error_codes = true 50 | show_error_context = true 51 | 52 | # allowed 53 | allow_untyped_globals = false 54 | allow_redefinition = true 55 | 56 | # disallowed 57 | disallow_untyped_decorators = true 58 | disallow_incomplete_defs = true 59 | disallow_untyped_defs = true 60 | 61 | # warnings 62 | warn_redundant_casts = true 63 | warn_return_any = true 64 | warn_unreachable = true 65 | warn_unused_configs = true 66 | warn_unused_ignores = true 67 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # used to communicate to Discord's REST and Gateway API via HTTP & WebSockets 2 | aiohttp~=3.9 3 | # used for colored logging and the colored banner 4 | colorlog~=6.8 5 | # used for enumerate objects 6 | fastenum~=1.0.4 7 | # extensions for the typing module 8 | typing-extensions~=4.10.0 9 | -------------------------------------------------------------------------------- /requirements/_.txt: -------------------------------------------------------------------------------- 1 | # used to communicate to Discord's REST and Gateway API via HTTP & WebSockets 2 | aiohttp~=3.9 3 | # used for colored logging and the colored banner 4 | colorlog~=6.8 5 | # used for enumerate objects 6 | fastenum~=1.0.4 7 | # extensions for the typing module 8 | typing-extensions~=4.10.0 9 | -------------------------------------------------------------------------------- /requirements/dev.txt: -------------------------------------------------------------------------------- 1 | -r _.txt 2 | pytest~=8.0.2 3 | pytest-asyncio~=0.21.0 4 | coverage~=7.2 5 | flake8==7.0.0 6 | -------------------------------------------------------------------------------- /requirements/docs.txt: -------------------------------------------------------------------------------- 1 | sphinx==7.2.6 2 | pydata-sphinx-theme~=0.13 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:brunette] 2 | target-version = py310 3 | single-quotes = true -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | # Copyright (c) 2021-present Pycord Development 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | import setuptools 23 | 24 | __version__ = '3.0.0' 25 | 26 | with open('requirements.txt') as f: 27 | requirements = f.read().splitlines() 28 | 29 | packages = [ 30 | 'pycord', 31 | 'pycord.ui', 32 | 'pycord.types', 33 | 'pycord.events', 34 | 'pycord.state', 35 | 'pycord.pages', 36 | 'pycord.api', 37 | 'pycord.api.execution', 38 | 'pycord.gateway', 39 | 'pycord.commands', 40 | 'pycord.commands.application', 41 | 'pycord.api.routers', 42 | 'pycord.ext', 43 | 'pycord.ext.gears', 44 | ] 45 | 46 | extra_requires = { 47 | 'speed': [ 48 | 'msgspec~=0.9.1', # Faster alternative to the normal json module. 49 | 'aiodns~=3.0', # included in aiohttp speed. 50 | 'Brotli~=1.0.9', # included in aiohttp speed. 51 | 'ciso8601~=2.2.0', # Faster datetime parsing. 52 | 'faust-cchardet~=2.1.16', # cchardet for python 3.11+ 53 | ], 54 | 'docs': [ 55 | 'sphinx==6.1.3', 56 | 'pydata-sphinx-theme~=0.13', 57 | ], 58 | } 59 | 60 | setuptools.setup( 61 | name='py-cord', 62 | version=__version__, 63 | packages=packages, 64 | package_data={ 65 | 'pycord': ['banner.txt', 'ibanner.txt', 'bin/*.dll'], 66 | }, 67 | project_urls={ 68 | 'Documentation': 'https://docs.pycord.dev', 69 | 'Issue Tracker': 'https://github.com/pycord/pycord-v3/issues', 70 | 'Pull Request Tracker': 'https://github.com/pycord/pycord-v3/pulls', 71 | }, 72 | url='https://github.com/pycord/pycord-v3', 73 | license='MIT', 74 | author='Pycord Development', 75 | long_description=open('README.md').read(), 76 | long_description_content_type='text/markdown', 77 | install_requires=requirements, 78 | extras_require=extra_requires, 79 | description='A modern Discord API wrapper for Python', 80 | python_requires='>=3.10', 81 | classifiers=[ 82 | 'Development Status :: 2 - Pre-Alpha', 83 | 'License :: OSI Approved :: MIT License', 84 | 'Intended Audience :: Developers', 85 | 'Natural Language :: English', 86 | 'Operating System :: OS Independent', 87 | 'Programming Language :: Python :: 3.11', 88 | 'Programming Language :: Python :: 3.10', 89 | 'Programming Language :: Python :: Implementation :: CPython', 90 | 'Framework :: AsyncIO', 91 | 'Framework :: aiohttp', 92 | 'Topic :: Communications :: Chat', 93 | 'Topic :: Internet :: WWW/HTTP', 94 | 'Topic :: Internet', 95 | 'Topic :: Software Development :: Libraries', 96 | 'Topic :: Software Development :: Libraries :: Python Modules', 97 | 'Topic :: Utilities', 98 | ], 99 | ) 100 | -------------------------------------------------------------------------------- /templates/towncrier.jinja: -------------------------------------------------------------------------------- 1 | {% if sections[""] %} 2 | {% for category, val in definitions.items() if category in sections[""] %} 3 | 4 | ### {{ definitions[category]['name'] }} 5 | 6 | {% for text, values in sections[""][category].items() %} 7 | - {{ text }} {{ values|join(', ') }} 8 | {% endfor %} 9 | 10 | {% endfor %} 11 | {% else %} 12 | No significant changes. 13 | 14 | 15 | {% endif %} -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import pycord 2 | 3 | 4 | def version(): 5 | assert pycord.__version__ != '2.0.0' 6 | --------------------------------------------------------------------------------