disagreement 0.3.0b1__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- disagreement/__init__.py +2 -4
- disagreement/audio.py +25 -5
- disagreement/cache.py +12 -3
- disagreement/caching.py +15 -14
- disagreement/client.py +86 -52
- disagreement/enums.py +10 -3
- disagreement/error_handler.py +5 -1
- disagreement/errors.py +1341 -3
- disagreement/event_dispatcher.py +1 -3
- disagreement/ext/__init__.py +1 -0
- disagreement/ext/app_commands/__init__.py +0 -2
- disagreement/ext/app_commands/commands.py +0 -2
- disagreement/ext/app_commands/context.py +0 -2
- disagreement/ext/app_commands/converters.py +2 -4
- disagreement/ext/app_commands/decorators.py +5 -7
- disagreement/ext/app_commands/handler.py +1 -3
- disagreement/ext/app_commands/hybrid.py +0 -2
- disagreement/ext/commands/__init__.py +0 -2
- disagreement/ext/commands/cog.py +0 -2
- disagreement/ext/commands/converters.py +16 -5
- disagreement/ext/commands/core.py +52 -14
- disagreement/ext/commands/decorators.py +3 -7
- disagreement/ext/commands/errors.py +0 -2
- disagreement/ext/commands/help.py +0 -2
- disagreement/ext/commands/view.py +1 -3
- disagreement/gateway.py +27 -25
- disagreement/http.py +264 -22
- disagreement/interactions.py +0 -2
- disagreement/models.py +199 -105
- disagreement/shard_manager.py +0 -2
- disagreement/ui/view.py +2 -2
- disagreement/voice_client.py +20 -1
- {disagreement-0.3.0b1.dist-info → disagreement-0.4.0.dist-info}/METADATA +32 -6
- disagreement-0.4.0.dist-info/RECORD +55 -0
- disagreement-0.3.0b1.dist-info/RECORD +0 -55
- {disagreement-0.3.0b1.dist-info → disagreement-0.4.0.dist-info}/WHEEL +0 -0
- {disagreement-0.3.0b1.dist-info → disagreement-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {disagreement-0.3.0b1.dist-info → disagreement-0.4.0.dist-info}/top_level.txt +0 -0
disagreement/http.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# disagreement/http.py
|
2
|
-
|
3
1
|
"""
|
4
2
|
HTTP client for interacting with the Discord REST API.
|
5
3
|
"""
|
@@ -11,12 +9,7 @@ import json
|
|
11
9
|
from urllib.parse import quote
|
12
10
|
from typing import Optional, Dict, Any, Union, TYPE_CHECKING, List
|
13
11
|
|
14
|
-
from .errors import
|
15
|
-
HTTPException,
|
16
|
-
RateLimitError,
|
17
|
-
AuthenticationError,
|
18
|
-
DisagreementException,
|
19
|
-
)
|
12
|
+
from .errors import * # Import all custom exceptions
|
20
13
|
from . import __version__ # For User-Agent
|
21
14
|
from .rate_limiter import RateLimiter
|
22
15
|
from .interactions import InteractionResponsePayload
|
@@ -31,6 +24,232 @@ API_BASE_URL = "https://discord.com/api/v10" # Using API v10
|
|
31
24
|
|
32
25
|
logger = logging.getLogger(__name__)
|
33
26
|
|
27
|
+
DISCORD_ERROR_CODE_TO_EXCEPTION = {
|
28
|
+
0: GeneralError,
|
29
|
+
10001: UnknownAccount,
|
30
|
+
10002: UnknownApplication,
|
31
|
+
10003: UnknownChannel,
|
32
|
+
10004: UnknownGuild,
|
33
|
+
10005: UnknownIntegration,
|
34
|
+
10006: UnknownInvite,
|
35
|
+
10007: UnknownMember,
|
36
|
+
10008: UnknownMessage,
|
37
|
+
10009: UnknownPermissionOverwrite,
|
38
|
+
10010: UnknownProvider,
|
39
|
+
10011: UnknownRole,
|
40
|
+
10012: UnknownToken,
|
41
|
+
10013: UnknownUser,
|
42
|
+
10014: UnknownEmoji,
|
43
|
+
10015: UnknownWebhook,
|
44
|
+
10016: UnknownWebhookService,
|
45
|
+
10020: UnknownSession,
|
46
|
+
10021: UnknownAsset,
|
47
|
+
10026: UnknownBan,
|
48
|
+
10027: UnknownSKU,
|
49
|
+
10028: UnknownStoreListing,
|
50
|
+
10029: UnknownEntitlement,
|
51
|
+
10030: UnknownBuild,
|
52
|
+
10031: UnknownLobby,
|
53
|
+
10032: UnknownBranch,
|
54
|
+
10033: UnknownStoreDirectoryLayout,
|
55
|
+
10036: UnknownRedistributable,
|
56
|
+
10038: UnknownGiftCode,
|
57
|
+
10049: UnknownStream,
|
58
|
+
10050: UnknownPremiumServerSubscribeCooldown,
|
59
|
+
10057: UnknownGuildTemplate,
|
60
|
+
10059: UnknownDiscoverableServerCategory,
|
61
|
+
10060: UnknownSticker,
|
62
|
+
10061: UnknownStickerPack,
|
63
|
+
10062: UnknownInteraction,
|
64
|
+
10063: UnknownApplicationCommand,
|
65
|
+
10065: UnknownVoiceState,
|
66
|
+
10066: UnknownApplicationCommandPermissions,
|
67
|
+
10067: UnknownStageInstance,
|
68
|
+
10068: UnknownGuildMemberVerificationForm,
|
69
|
+
10069: UnknownGuildWelcomeScreen,
|
70
|
+
10070: UnknownGuildScheduledEvent,
|
71
|
+
10071: UnknownGuildScheduledEventUser,
|
72
|
+
10087: UnknownTag,
|
73
|
+
10097: UnknownSound,
|
74
|
+
20001: BotsCannotUseThisEndpoint,
|
75
|
+
20002: OnlyBotsCanUseThisEndpoint,
|
76
|
+
20009: ExplicitContentCannotBeSentToTheDesiredRecipients,
|
77
|
+
20012: NotAuthorizedToPerformThisActionOnThisApplication,
|
78
|
+
20016: ActionCannotBePerformedDueToSlowmodeRateLimit,
|
79
|
+
20018: OnlyTheOwnerOfThisAccountCanPerformThisAction,
|
80
|
+
20022: MessageCannotBeEditedDueToAnnouncementRateLimits,
|
81
|
+
20024: UnderMinimumAge,
|
82
|
+
20028: ChannelHitWriteRateLimit,
|
83
|
+
20029: ServerHitWriteRateLimit,
|
84
|
+
20031: DisallowedWordsInStageTopicOrNames,
|
85
|
+
20035: GuildPremiumSubscriptionLevelTooLow,
|
86
|
+
30001: MaximumNumberOfGuildsReached,
|
87
|
+
30002: MaximumNumberOfFriendsReached,
|
88
|
+
30003: MaximumNumberOfPinsReached,
|
89
|
+
30004: MaximumNumberOfRecipientsReached,
|
90
|
+
30005: MaximumNumberOfGuildRolesReached,
|
91
|
+
30007: MaximumNumberOfWebhooksReached,
|
92
|
+
30008: MaximumNumberOfEmojisReached,
|
93
|
+
30010: MaximumNumberOfReactionsReached,
|
94
|
+
30011: MaximumNumberOfGroupDMsReached,
|
95
|
+
30013: MaximumNumberOfGuildChannelsReached,
|
96
|
+
30015: MaximumNumberOfAttachmentsInAMessageReached,
|
97
|
+
30016: MaximumNumberOfInvitesReached,
|
98
|
+
30018: MaximumNumberOfAnimatedEmojisReached,
|
99
|
+
30019: MaximumNumberOfServerMembersReached,
|
100
|
+
30030: MaximumNumberOfServerCategoriesReached,
|
101
|
+
30031: GuildAlreadyHasATemplate,
|
102
|
+
30032: MaximumNumberOfApplicationCommandsReached,
|
103
|
+
30033: MaximumNumberOfThreadParticipantsReached,
|
104
|
+
30034: MaximumNumberOfDailyApplicationCommandCreatesReached,
|
105
|
+
30035: MaximumNumberOfBansForNonGuildMembersExceeded,
|
106
|
+
30037: MaximumNumberOfBansFetchesReached,
|
107
|
+
30038: MaximumNumberOfUncompletedGuildScheduledEventsReached,
|
108
|
+
30039: MaximumNumberOfStickersReached,
|
109
|
+
30040: MaximumNumberOfPruneRequestsReached,
|
110
|
+
30042: MaximumNumberOfGuildWidgetSettingsUpdatesReached,
|
111
|
+
30045: MaximumNumberOfSoundboardSoundsReached,
|
112
|
+
30046: MaximumNumberOfEditsToMessagesOlderThan1HourReached,
|
113
|
+
30047: MaximumNumberOfPinnedThreadsInAForumChannelReached,
|
114
|
+
30048: MaximumNumberOfTagsInAForumChannelReached,
|
115
|
+
30052: BitrateIsTooHighForChannelOfThisType,
|
116
|
+
30056: MaximumNumberOfPremiumEmojisReached,
|
117
|
+
30058: MaximumNumberOfWebhooksPerGuildReached,
|
118
|
+
30061: MaximumNumberOfChannelPermissionOverwritesReached,
|
119
|
+
30062: TheChannelsForThisGuildAreTooLarge,
|
120
|
+
40001: Unauthorized,
|
121
|
+
40002: YouNeedToVerifyYourAccount,
|
122
|
+
40003: YouAreOpeningDirectMessagesTooFast,
|
123
|
+
40004: SendMessagesHasBeenTemporarilyDisabled,
|
124
|
+
40005: RequestEntityTooLarge,
|
125
|
+
40006: ThisFeatureHasBeenTemporarilyDisabledServerSide,
|
126
|
+
40007: TheUserIsBannedFromThisGuild,
|
127
|
+
40012: ConnectionHasBeenRevoked,
|
128
|
+
40018: OnlyConsumableSKUsCanBeConsumed,
|
129
|
+
40019: YouCanOnlyDeleteSandboxEntitlements,
|
130
|
+
40032: TargetUserIsNotConnectedToVoice,
|
131
|
+
40033: ThisMessageHasAlreadyBeenCrossposted,
|
132
|
+
40041: AnApplicationCommandWithThatNameAlreadyExists,
|
133
|
+
40043: ApplicationInteractionFailedToSend,
|
134
|
+
40058: CannotSendAMessageInAForumChannel,
|
135
|
+
40060: InteractionHasAlreadyBeenAcknowledged,
|
136
|
+
40061: TagNamesMustBeUnique,
|
137
|
+
40062: ServiceResourceIsBeingRateLimited,
|
138
|
+
40066: ThereAreNoTagsAvailableThatCanBeSetByNonModerators,
|
139
|
+
40067: ATagIsRequiredToCreateAForumPostInThisChannel,
|
140
|
+
40074: AnEntitlementHasAlreadyBeenGrantedForThisResource,
|
141
|
+
40094: ThisInteractionHasHitTheMaximumNumberOfFollowUpMessages,
|
142
|
+
40333: CloudflareIsBlockingYourRequest,
|
143
|
+
50001: MissingAccess,
|
144
|
+
50002: InvalidAccountType,
|
145
|
+
50003: CannotExecuteActionOnADMChannel,
|
146
|
+
50004: GuildWidgetDisabled,
|
147
|
+
50005: CannotEditAMessageAuthoredByAnotherUser,
|
148
|
+
50006: CannotSendAnEmptyMessage,
|
149
|
+
50007: CannotSendMessagesToThisUser,
|
150
|
+
50008: CannotSendMessagesInANonTextChannel,
|
151
|
+
50009: ChannelVerificationLevelIsTooHighForYouToGainAccess,
|
152
|
+
50010: OAuth2ApplicationDoesNotHaveABot,
|
153
|
+
50011: OAuth2ApplicationLimitReached,
|
154
|
+
50012: InvalidOAuth2State,
|
155
|
+
50013: YouLackPermissionsToPerformThatAction,
|
156
|
+
50014: InvalidAuthenticationTokenProvided,
|
157
|
+
50015: NoteWasTooLong,
|
158
|
+
50016: ProvidedTooFewOrTooManyMessagesToDelete,
|
159
|
+
50017: InvalidMFALevel,
|
160
|
+
50019: AMessageCanOnlyBePinnedToTheChannelItWasSentIn,
|
161
|
+
50020: InviteCodeWasEitherInvalidOrTaken,
|
162
|
+
50021: CannotExecuteActionOnASystemMessage,
|
163
|
+
50024: CannotExecuteActionOnThisChannelType,
|
164
|
+
50025: InvalidOAuth2AccessTokenProvided,
|
165
|
+
50026: MissingRequiredOAuth2Scope,
|
166
|
+
50027: InvalidWebhookTokenProvided,
|
167
|
+
50028: InvalidRole,
|
168
|
+
50033: InvalidRecipients,
|
169
|
+
50034: AMessageProvidedWasTooOldToBulkDelete,
|
170
|
+
50035: InvalidFormBody,
|
171
|
+
50036: AnInviteWasAcceptedToAGuildTheApplicationBotIsNotIn,
|
172
|
+
50039: InvalidActivityAction,
|
173
|
+
50041: InvalidAPIVersionProvided,
|
174
|
+
50045: FileUploadedExceedsTheMaximumSize,
|
175
|
+
50046: InvalidFileUploaded,
|
176
|
+
50054: CannotSelfRedeemThisGift,
|
177
|
+
50055: InvalidGuild,
|
178
|
+
50057: InvalidSKU,
|
179
|
+
50067: InvalidRequestOrigin,
|
180
|
+
50068: InvalidMessageType,
|
181
|
+
50070: PaymentSourceRequiredToRedeemGift,
|
182
|
+
50073: CannotModifyASystemWebhook,
|
183
|
+
50074: CannotDeleteAChannelRequiredForCommunityGuilds,
|
184
|
+
50080: CannotEditStickersWithinAMessage,
|
185
|
+
50081: InvalidStickerSent,
|
186
|
+
50083: TriedToPerformAnOperationOnAnArchivedThread,
|
187
|
+
50085: InvalidThreadNotificationSettings,
|
188
|
+
50086: BeforeValueIsEarlierThanTheThreadCreationDate,
|
189
|
+
50087: CommunityServerChannelsMustBeTextChannels,
|
190
|
+
50091: TheEntityTypeOfTheEventIsDifferentFromTheEntityYouAreTryingToStartTheEventFor,
|
191
|
+
50095: ThisServerIsNotAvailableInYourLocation,
|
192
|
+
50097: ThisServerNeedsMonetizationEnabledInOrderToPerformThisAction,
|
193
|
+
50101: ThisServerNeedsMoreBoostsToPerformThisAction,
|
194
|
+
50109: TheRequestBodyContainsInvalidJSON,
|
195
|
+
50110: TheProvidedFileIsInvalid,
|
196
|
+
50123: TheProvidedFileTypeIsInvalid,
|
197
|
+
50124: TheProvidedFileDurationExceedsMaximumOf52Seconds,
|
198
|
+
50131: OwnerCannotBePendingMember,
|
199
|
+
50132: OwnershipCannotBeTransferredToABotUser,
|
200
|
+
50138: FailedToResizeAssetBelowTheMaximumSize,
|
201
|
+
50144: CannotMixSubscriptionAndNonSubscriptionRolesForAnEmoji,
|
202
|
+
50145: CannotConvertBetweenPremiumEmojiAndNormalEmoji,
|
203
|
+
50146: UploadedFileNotFound,
|
204
|
+
50151: TheSpecifiedEmojiIsInvalid,
|
205
|
+
50159: VoiceMessagesDoNotSupportAdditionalContent,
|
206
|
+
50160: VoiceMessagesMustHaveASingleAudioAttachment,
|
207
|
+
50161: VoiceMessagesMustHaveSupportingMetadata,
|
208
|
+
50162: VoiceMessagesCannotBeEdited,
|
209
|
+
50163: CannotDeleteGuildSubscriptionIntegration,
|
210
|
+
50173: YouCannotSendVoiceMessagesInThisChannel,
|
211
|
+
50178: TheUserAccountMustFirstBeVerified,
|
212
|
+
50192: TheProvidedFileDoesNotHaveAValidDuration,
|
213
|
+
50600: YouDoNotHavePermissionToSendThisSticker,
|
214
|
+
60003: TwoFactorIsRequiredForThisOperation,
|
215
|
+
80004: NoUsersWithDiscordTagExist,
|
216
|
+
90001: ReactionWasBlocked,
|
217
|
+
90002: UserCannotUseBurstReactions,
|
218
|
+
110001: ApplicationNotYetAvailable,
|
219
|
+
130000: APIResourceIsCurrentlyOverloaded,
|
220
|
+
150006: TheStageIsAlreadyOpen,
|
221
|
+
160002: CannotReplyWithoutPermissionToReadMessageHistory,
|
222
|
+
160004: AThreadHasAlreadyBeenCreatedForThisMessage,
|
223
|
+
160005: ThreadIsLocked,
|
224
|
+
160006: MaximumNumberOfActiveThreadsReached,
|
225
|
+
160007: MaximumNumberOfActiveAnnouncementThreadsReached,
|
226
|
+
170001: InvalidJSONForUploadedLottieFile,
|
227
|
+
170002: UploadedLottiesCannotContainRasterizedImages,
|
228
|
+
170003: StickerMaximumFramerateExceeded,
|
229
|
+
170004: StickerFrameCountExceedsMaximumOf1000Frames,
|
230
|
+
170005: LottieAnimationMaximumDimensionsExceeded,
|
231
|
+
170006: StickerFrameRateIsEitherTooSmallOrTooLarge,
|
232
|
+
170007: StickerAnimationDurationExceedsMaximumOf5Seconds,
|
233
|
+
180000: CannotUpdateAFinishedEvent,
|
234
|
+
180002: FailedToCreateStageNeededForStageEvent,
|
235
|
+
200000: MessageWasBlockedByAutomaticModeration,
|
236
|
+
200001: TitleWasBlockedByAutomaticModeration,
|
237
|
+
220001: WebhooksPostedToForumChannelsMustHaveAThreadNameOrThreadId,
|
238
|
+
220002: WebhooksPostedToForumChannelsCannotHaveBothAThreadNameAndThreadId,
|
239
|
+
220003: WebhooksCanOnlyCreateThreadsInForumChannels,
|
240
|
+
220004: WebhookServicesCannotBeUsedInForumChannels,
|
241
|
+
240000: MessageBlockedByHarmfulLinksFilter,
|
242
|
+
350000: CannotEnableOnboardingRequirementsAreNotMet,
|
243
|
+
350001: CannotUpdateOnboardingWhileBelowRequirements,
|
244
|
+
500000: FailedToBanUsers,
|
245
|
+
520000: PollVotingBlocked,
|
246
|
+
520001: PollExpired,
|
247
|
+
520002: InvalidChannelTypeForPollCreation,
|
248
|
+
520003: CannotEditAPollMessage,
|
249
|
+
520004: CannotUseAnEmojiIncludedWithThePoll,
|
250
|
+
520006: CannotExpireANonPollMessage,
|
251
|
+
}
|
252
|
+
|
34
253
|
|
35
254
|
class HTTPClient:
|
36
255
|
"""Handles HTTP requests to the Discord API."""
|
@@ -208,6 +427,17 @@ class HTTPClient:
|
|
208
427
|
discord_error_code = (
|
209
428
|
data.get("code") if isinstance(data, dict) else None
|
210
429
|
)
|
430
|
+
|
431
|
+
if discord_error_code in DISCORD_ERROR_CODE_TO_EXCEPTION:
|
432
|
+
exc_class = DISCORD_ERROR_CODE_TO_EXCEPTION[discord_error_code]
|
433
|
+
raise exc_class(
|
434
|
+
response,
|
435
|
+
f"API Error on {method} {endpoint}: {error_text}",
|
436
|
+
status=response.status,
|
437
|
+
text=error_text,
|
438
|
+
error_code=discord_error_code,
|
439
|
+
)
|
440
|
+
|
211
441
|
raise HTTPException(
|
212
442
|
response,
|
213
443
|
f"API Error on {method} {endpoint}: {error_text}",
|
@@ -215,8 +445,6 @@ class HTTPClient:
|
|
215
445
|
text=error_text,
|
216
446
|
error_code=discord_error_code,
|
217
447
|
)
|
218
|
-
|
219
|
-
# Should not be reached if retries are exhausted by RateLimitError
|
220
448
|
raise DisagreementException(
|
221
449
|
f"Failed request to {method} {endpoint} after multiple retries."
|
222
450
|
)
|
@@ -369,18 +597,18 @@ class HTTPClient:
|
|
369
597
|
)
|
370
598
|
|
371
599
|
async def delete_user_reaction(
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
600
|
+
self,
|
601
|
+
channel_id: "Snowflake",
|
602
|
+
message_id: "Snowflake",
|
603
|
+
emoji: str,
|
604
|
+
user_id: "Snowflake",
|
605
|
+
) -> None:
|
606
|
+
"""Removes another user's reaction from a message."""
|
607
|
+
encoded = quote(emoji)
|
608
|
+
await self.request(
|
609
|
+
"DELETE",
|
610
|
+
f"/channels/{channel_id}/messages/{message_id}/reactions/{encoded}/{user_id}",
|
611
|
+
)
|
384
612
|
|
385
613
|
async def get_reactions(
|
386
614
|
self, channel_id: "Snowflake", message_id: "Snowflake", emoji: str
|
@@ -678,6 +906,20 @@ class HTTPClient:
|
|
678
906
|
"""Fetches a guild object for a given guild ID."""
|
679
907
|
return await self.request("GET", f"/guilds/{guild_id}")
|
680
908
|
|
909
|
+
async def get_guild_widget(self, guild_id: "Snowflake") -> Dict[str, Any]:
|
910
|
+
"""Fetches the guild widget settings."""
|
911
|
+
|
912
|
+
return await self.request("GET", f"/guilds/{guild_id}/widget")
|
913
|
+
|
914
|
+
async def edit_guild_widget(
|
915
|
+
self, guild_id: "Snowflake", payload: Dict[str, Any]
|
916
|
+
) -> Dict[str, Any]:
|
917
|
+
"""Edits the guild widget settings."""
|
918
|
+
|
919
|
+
return await self.request(
|
920
|
+
"PATCH", f"/guilds/{guild_id}/widget", payload=payload
|
921
|
+
)
|
922
|
+
|
681
923
|
async def get_guild_templates(self, guild_id: "Snowflake") -> List[Dict[str, Any]]:
|
682
924
|
"""Fetches all templates for the given guild."""
|
683
925
|
return await self.request("GET", f"/guilds/{guild_id}/templates")
|