Skip to content

Commit f4170eb

Browse files
committed
🎨 Add guidelines and reorganize
1 parent 2069a4b commit f4170eb

File tree

12 files changed

+124
-20
lines changed

12 files changed

+124
-20
lines changed

discord/guild.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
overload,
4141
)
4242

43-
from . import abc, utils
43+
from . import abc, models, utils
4444
from .asset import Asset
4545
from .automod import AutoModAction, AutoModRule, AutoModTriggerMetadata
4646
from .channel import *
@@ -2114,9 +2114,9 @@ async def fetch_ban(self, user: Snowflake) -> BanEntry:
21142114
HTTPException
21152115
An error occurred while fetching the information.
21162116
"""
2117-
data: BanPayload = await self._state.http.get_ban(user.id, self.id)
2117+
data: models.Ban = await self._state.http.get_ban(user.id, self.id)
21182118
return BanEntry(
2119-
user=User(state=self._state, data=data["user"]), reason=data["reason"]
2119+
user=User(state=self._state, data=data.user), reason=data.reason
21202120
)
21212121

21222122
async def fetch_channel(self, channel_id: int, /) -> GuildChannel | Thread:

discord/http.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1648,14 +1648,15 @@ def get_bans(
16481648
Route("GET", "/guilds/{guild_id}/bans", guild_id=guild_id), params=params
16491649
)
16501650

1651-
def get_ban(self, user_id: Snowflake, guild_id: Snowflake) -> Response[guild.Ban]:
1651+
def get_ban(self, user_id: Snowflake, guild_id: Snowflake) -> Response[models.Ban]:
16521652
return self.request(
16531653
Route(
16541654
"GET",
16551655
"/guilds/{guild_id}/bans/{user_id}",
16561656
guild_id=guild_id,
16571657
user_id=user_id,
1658-
)
1658+
),
1659+
model=models.Ban,
16591660
)
16601661

16611662
def get_vanity_code(self, guild_id: Snowflake) -> Response[invite.VanityInvite]:

discord/models/README.md

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Py-cord Models
2+
3+
This directory contains the pydantic models and types used by py-cord.
4+
5+
## Structure
6+
7+
The models are structured in a way that they mirror the structure of the Discord API.
8+
They are subdivided into the following submodules:
9+
10+
> [!IMPORTANT] Each of the submodules is defined below in order. Submodules may only
11+
> reference in their code classes from the same or lower level submodules. For example,
12+
> `api` may reference classes from `api`, `base` and `types`, but `base` may not
13+
> reference classes from `api`. This is to prevent circular imports and to keep the
14+
> codebase clean and maintainable.
15+
16+
### `types`
17+
18+
Contains python types and dataclasses that are used in the following submodules. These
19+
are used to represent the data in a more pythonic way, and are used to define the
20+
pydantic models.
21+
22+
### `base`
23+
24+
Contains the base models defined in the Discord docs. These are the models you will
25+
often find with a heading like "... Template", and hyperlinks linking to it referring to
26+
it as an "object".
27+
28+
For example, the
29+
[User Template](https://discord.com/developers/docs/resources/user#user-object) is
30+
defined in `base/user.py`.
31+
32+
### `api`
33+
34+
Contains the models that are used to represent the data received and set trough discord
35+
API requests. They represent payloads that are sent and received from the Discord API.
36+
37+
When representing a route, it is preferred to create a single python file for each base
38+
route. If the file may become too large, it is preferred to split it into multiple
39+
files, one for each sub-route. In that case, a submodule with the name of the base route
40+
should be created to hold the sub-routes.
41+
42+
For example, the
43+
[Modify Guild Template](https://discord.com/developers/docs/resources/guild-template#modify-guild-template)
44+
is defined in `api/guild_template.py`.
45+
46+
### `gateway`
47+
48+
Contains the models that are used to represent the data received and sent trough the
49+
Discord Gateway. They represent payloads that are sent and received from the Discord
50+
Gateway.
51+
52+
For example, the [Ready Event](https://discord.com/developers/docs/topics/gateway#hello)
53+
is defined in `gateway/ready.py`.
54+
55+
## Naming
56+
57+
The naming of the models is based on the Discord API documentation. The models are named
58+
after the object they represent in the Discord API documentation. It is generally
59+
preferred to create a new model for each object in the Discord API documentation, even
60+
if the file may only contain a single class, so that the structure keeps a 1:1 mapping
61+
with the Discord API documentation.
62+
63+
## Exporting strategies
64+
65+
The models are exported in the following way:
66+
67+
- The models are exported in the `__init__.py` of their respective submodules.
68+
- Models from the `base` submodule are re-exported in the `__init__.py` of the `modules`
69+
module.
70+
- The other submodules are re-exported in the `__init__.py` of the `models` module as a
71+
single import.
72+
- The `models` module is re-exported in the `discord` module.

discord/models/__init__.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
from discord.models.base.role import Role
2+
13
from . import gateway, types
2-
from .emoji import Emoji
3-
from .guild import Guild, UnavailableGuild
4-
from .role import Role
5-
from .sticker import Sticker
4+
from .base import (
5+
AvatarDecorationData,
6+
Ban,
7+
Emoji,
8+
Guild,
9+
Sticker,
10+
UnavailableGuild,
11+
User,
12+
)
613
from .types.utils import MISSING
7-
from .user import AvatarDecorationData, User
814

9-
__all__ = [
15+
__all__ = (
1016
"Emoji",
1117
"Guild",
1218
"UnavailableGuild",
@@ -17,4 +23,5 @@
1723
"MISSING",
1824
"AvatarDecorationData",
1925
"gateway",
20-
]
26+
"Ban",
27+
)

discord/models/base/__init__.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from .ban import Ban
2+
from .emoji import Emoji
3+
from .guild import Guild, UnavailableGuild
4+
from .role import Role
5+
from .sticker import Sticker
6+
from .user import AvatarDecorationData, User
7+
8+
__all__ = (
9+
"Emoji",
10+
"Guild",
11+
"UnavailableGuild",
12+
"Role",
13+
"Sticker",
14+
"User",
15+
"Ban",
16+
"AvatarDecorationData",
17+
)

discord/models/base/ban.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pydantic import BaseModel
2+
3+
from .user import User
4+
5+
6+
class Ban(BaseModel):
7+
reason: str
8+
user: User

discord/models/emoji.py renamed to discord/models/base/emoji.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from pydantic import BaseModel
44

5-
from .types import MISSING, EmojiID, MissingSentinel, RoleID
5+
from ..types import MISSING, EmojiID, MissingSentinel, RoleID
66
from .user import User
77

88

File renamed without changes.

discord/models/role.py renamed to discord/models/base/role.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
from typing_extensions import Annotated
1313

14-
from discord.models.types import (
14+
from ..types import (
1515
MISSING,
1616
Color,
1717
MissingSentinel,

discord/models/sticker.py renamed to discord/models/base/sticker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from pydantic import BaseModel
66

7-
from .types import MISSING, GuildID, MissingSentinel, Snowflake, StickerID
7+
from ..types import MISSING, GuildID, MissingSentinel, Snowflake, StickerID
88
from .user import User
99

1010

discord/models/user.py renamed to discord/models/base/user.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
from pydantic import BaseModel
66

7-
from .types import MISSING, Color, Locale, MissingSentinel, Snowflake, UserID
8-
from .types.flags import UserFlags
7+
from ..types import MISSING, Color, Locale, MissingSentinel, Snowflake, UserID
8+
from ..types.flags import UserFlags
99

1010

1111
class PremiumType(IntEnum):

discord/models/gateway/ready.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from __future__ import annotations
22

3-
from pydantic import BaseModel, field_validator
3+
from pydantic import BaseModel
44

5-
from ..guild import Guild, UnavailableGuild
5+
from ..base import Guild, UnavailableGuild, User
66
from ..types.utils import MISSING, MissingSentinel
7-
from ..user import User
87
from .base import GatewayEvent
98

109

0 commit comments

Comments
 (0)