Skip to content

♻️ 拆分api/model.py#80

Draft
shoucandanghehe wants to merge 71 commits intomasterfrom
refactor/split-api-models
Draft

♻️ 拆分api/model.py#80
shoucandanghehe wants to merge 71 commits intomasterfrom
refactor/split-api-models

Conversation

@shoucandanghehe
Copy link
Copy Markdown
Member

No description provided.

@shoucandanghehe shoucandanghehe force-pushed the refactor/split-api-models branch from 935ce0f to 1a6141a Compare February 28, 2026 07:09
@shoucandanghehe shoucandanghehe force-pushed the refactor/split-api-models branch from 4f778db to a5a4a93 Compare February 28, 2026 08:35
pre-commit-ci bot and others added 14 commits February 28, 2026 08:36
- Add test_models_facade_and_layers.py for export consistency and layer checks
- Create request/response/gateway.event package skeletons
- Move 15 entity domains from http/ to common/ (application, audit_log, etc.)
- Keep http/ modules as shims for backward compatibility
- Change all gateway imports from ..http.* to ..common.*
- Update layer guard test to forbid gateway->http imports
- Files modified:
  - gateway_event_fields.py, channel_events.py, gateway_payloads.py
  - integration_events.py, auto_moderation_events.py, invite_events.py
  - monetization_events.py, guild_events.py, gateway_events.py
- Add gateway/event/ directory with 8 domain files:
  auto_moderation, channels, guilds, integrations, invites,
  monetization, interactions, messages
- Convert old *_events.py files to shims
- Convert gateway_events.py to shim importing from event/
- Add request/messages.py, request/webhooks.py, request/user.py
- Add request/permissions.py, response/oauth2.py
- Remove request/response models from common/*
- Update facade imports in models/__init__.py
- Add request/channels.py with all *Params classes
- Add response/channels.py with *Response classes
- Keep http/channels.py as shim re-exporting from common/request/response
- Add request/guilds.py, request/guild_members.py
- Add request/guild_scheduled_events.py, request/guild_templates.py
- Add request/guild_welcome.py
- Add common/guild_templates.py for shared objects
- Convert http/guild*.py to shims
Tasks 9-11:
- Application/Gateway/AutoModeration: request/application, request/auto_moderation, response/gateway
- Emoji/Voice/Stickers/Soundboard/Polls: request/* and response/* for each domain
- Webhooks/Lobby/Invites: common/* for objects, request/* for params

All http/* modules converted to shims re-exporting from new locations
- Add common/interactions.py with all reusable interaction models
- Add request/interactions.py with request-specific interaction models
- Convert interactions/*.py to shims
- Update common/messages.py TYPE_CHECKING imports
- Update layer guard test to forbid common/gateway -> interactions/http
- Update AGENTS.md with new directory structure
- Document layer dependency constraints
- Add new model addition workflow
- Fix remaining lint issues in gateway/http modules
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Discord adapter’s API models by splitting the previous monolithic api/model.py into a layered api/models/ package and introducing a facade module for re-exports, then updates imports/tests/tooling to use the new structure.

Changes:

  • Introduces nonebot.adapters.discord.api.models as a facade that aggregates models from common/, request/, response/, http/, and gateway/, and rebuilds forward references.
  • Updates adapter/event/api code, stub generation, and tests to import from api.models (and related submodules) instead of the removed api.model/payload locations.
  • Adds tests to validate models.__all__ integrity and enforce model-layer dependency rules.

Reviewed changes

Copilot reviewed 116 out of 117 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/test_models_facade_and_layers.py New tests for facade __all__ consistency and AST-based layer dependency checks
tests/test_message_snapshot_missing_mention_roles.py Update imports to new api.models facade
tests/test_invite_target_users_upload.py Update imports to new api.models facade
tests/test_guild_create_compat_event.py Switch gateway frame imports to api.models (from old payload module)
tests/test_attachment_segment_url.py Update imports to new api.models facade
tests/test_api_nullability.py Update imports to new api.models facade
scripts/generate_client_pyi.py Teach stub generator to treat models as the model import source and emit from .models import ...
nonebot/adapters/discord/event.py Update model imports to new facade/submodules for gateway payload mixins
nonebot/adapters/discord/commands/params.py Update model import path for interaction option type
nonebot/adapters/discord/api/utils.py Update model imports to new api.models facade
nonebot/adapters/discord/api/models/response/stickers.py New response models split-out (stickers)
nonebot/adapters/discord/api/models/response/soundboard.py New response models split-out (soundboard)
nonebot/adapters/discord/api/models/response/oauth2.py New response models split-out (oauth2)
nonebot/adapters/discord/api/models/response/gateway.py New response models split-out (gateway URL responses)
nonebot/adapters/discord/api/models/response/emoji.py New response models split-out (emoji)
nonebot/adapters/discord/api/models/response/channels.py New response models split-out (channels)
nonebot/adapters/discord/api/models/response/init.py Response package exports
nonebot/adapters/discord/api/models/request/webhooks.py New request models split-out (webhooks)
nonebot/adapters/discord/api/models/request/voice.py New request models split-out (voice)
nonebot/adapters/discord/api/models/request/user.py New request models split-out (user)
nonebot/adapters/discord/api/models/request/stickers.py New request models split-out (stickers)
nonebot/adapters/discord/api/models/request/soundboard.py New request models split-out (soundboard)
nonebot/adapters/discord/api/models/request/polls.py New request models split-out (polls)
nonebot/adapters/discord/api/models/request/permissions.py New request models split-out (role permissions)
nonebot/adapters/discord/api/models/request/messages.py New request models split-out (message send/edit + multipart file types)
nonebot/adapters/discord/api/models/request/lobby.py New request models split-out (lobby)
nonebot/adapters/discord/api/models/request/interactions.py New request models split-out (interactions)
nonebot/adapters/discord/api/models/request/guilds.py New request models split-out (guilds)
nonebot/adapters/discord/api/models/request/guild_welcome.py New request models split-out (welcome screen)
nonebot/adapters/discord/api/models/request/guild_templates.py New request models split-out (guild templates)
nonebot/adapters/discord/api/models/request/guild_scheduled_events.py New request models split-out (scheduled events)
nonebot/adapters/discord/api/models/request/guild_members.py New request models split-out (guild members)
nonebot/adapters/discord/api/models/request/emoji.py New request models split-out (emoji)
nonebot/adapters/discord/api/models/request/channels.py New request models split-out (channels)
nonebot/adapters/discord/api/models/request/auto_moderation.py New request models split-out (auto moderation)
nonebot/adapters/discord/api/models/request/application.py New request models split-out (application)
nonebot/adapters/discord/api/models/request/init.py Request package exports
nonebot/adapters/discord/api/models/interactions/message_components.py New interactions re-export module (components)
nonebot/adapters/discord/api/models/interactions/interactions.py New interactions aggregation module (common + request)
nonebot/adapters/discord/api/models/interactions/application_commands.py New interactions aggregation module (application commands)
nonebot/adapters/discord/api/models/interactions/init.py Interactions package exports
nonebot/adapters/discord/api/models/http/webhooks.py New http “endpoint surface” exports (webhooks)
nonebot/adapters/discord/api/models/http/voice.py New http exports (voice)
nonebot/adapters/discord/api/models/http/stickers.py New http exports (stickers)
nonebot/adapters/discord/api/models/http/stage_instance.py New http exports (stage instance)
nonebot/adapters/discord/api/models/http/soundboard.py New http exports (soundboard)
nonebot/adapters/discord/api/models/http/polls.py New http exports (polls)
nonebot/adapters/discord/api/models/http/monetization.py New http exports (monetization)
nonebot/adapters/discord/api/models/http/lobby.py New http exports (lobby)
nonebot/adapters/discord/api/models/http/invites.py New http exports (invites)
nonebot/adapters/discord/api/models/http/integrations.py New http exports (integrations)
nonebot/adapters/discord/api/models/http/guilds.py New http exports (guilds)
nonebot/adapters/discord/api/models/http/guild_welcome.py New http exports (welcome screen)
nonebot/adapters/discord/api/models/http/guild_templates.py New http exports (guild templates)
nonebot/adapters/discord/api/models/http/guild_scheduled_events.py New http exports (scheduled events)
nonebot/adapters/discord/api/models/http/guild_members.py New http exports (guild members)
nonebot/adapters/discord/api/models/http/gateway.py New http exports (gateway response models)
nonebot/adapters/discord/api/models/http/emoji.py New http exports (emoji)
nonebot/adapters/discord/api/models/http/channels.py New http exports (channels)
nonebot/adapters/discord/api/models/http/auto_moderation.py New http exports (auto moderation)
nonebot/adapters/discord/api/models/http/audit_log.py New http exports (audit log)
nonebot/adapters/discord/api/models/http/application.py New http exports (application)
nonebot/adapters/discord/api/models/http/init.py HTTP package exports (aggregated)
nonebot/adapters/discord/api/models/gateway/monetization_events.py New gateway event re-export module (monetization)
nonebot/adapters/discord/api/models/gateway/invite_events.py New gateway event re-export module (invites)
nonebot/adapters/discord/api/models/gateway/integration_events.py New gateway event re-export module (integrations)
nonebot/adapters/discord/api/models/gateway/guild_events.py New gateway event re-export module (guilds)
nonebot/adapters/discord/api/models/gateway/gateway_payloads.py New gateway payload data models (identify/resume/etc.)
nonebot/adapters/discord/api/models/gateway/gateway_events.py Aggregate gateway event payload exports (__all__)
nonebot/adapters/discord/api/models/gateway/gateway_event_fields.py Shared gateway event field models (presence/activity/etc.)
nonebot/adapters/discord/api/models/gateway/frame.py Gateway frame models (opcodes/payload union) updated to new imports
nonebot/adapters/discord/api/models/gateway/event/monetization.py New gateway event models (monetization)
nonebot/adapters/discord/api/models/gateway/event/messages.py Gateway message event payload models split-out
nonebot/adapters/discord/api/models/gateway/event/invites.py New gateway event models (invites)
nonebot/adapters/discord/api/models/gateway/event/interactions.py Gateway interaction event payload models split-out
nonebot/adapters/discord/api/models/gateway/event/integrations.py New gateway event models (integrations)
nonebot/adapters/discord/api/models/gateway/event/guilds.py New gateway event models (guilds)
nonebot/adapters/discord/api/models/gateway/event/channels.py New gateway event models (channels)
nonebot/adapters/discord/api/models/gateway/event/auto_moderation.py New gateway event models (auto moderation)
nonebot/adapters/discord/api/models/gateway/event/init.py Gateway event package marker
nonebot/adapters/discord/api/models/gateway/channel_events.py New gateway event re-export module (channels)
nonebot/adapters/discord/api/models/gateway/auto_moderation_events.py New gateway event re-export module (auto moderation)
nonebot/adapters/discord/api/models/gateway/init.py Gateway package exports (aggregated)
nonebot/adapters/discord/api/models/common/webhooks.py New common models split-out (webhooks)
nonebot/adapters/discord/api/models/common/voice.py New common models split-out (voice)
nonebot/adapters/discord/api/models/common/user.py New common models split-out (user)
nonebot/adapters/discord/api/models/common/teams.py New common models split-out (teams)
nonebot/adapters/discord/api/models/common/stickers.py New common models split-out (stickers)
nonebot/adapters/discord/api/models/common/stage_instance.py New common models split-out (stage instance)
nonebot/adapters/discord/api/models/common/soundboard.py New common models split-out (soundboard)
nonebot/adapters/discord/api/models/common/snowflake.py New common type split-out (Snowflake)
nonebot/adapters/discord/api/models/common/polls.py New common models split-out (polls)
nonebot/adapters/discord/api/models/common/permissions.py New common models split-out (permissions/roles)
nonebot/adapters/discord/api/models/common/monetization.py New common models split-out (monetization)
nonebot/adapters/discord/api/models/common/messages.py New common models split-out (messages)
nonebot/adapters/discord/api/models/common/lobby.py New common models split-out (lobby)
nonebot/adapters/discord/api/models/common/invites.py New common models split-out (invites)
nonebot/adapters/discord/api/models/common/interactions.py New common models split-out (interactions + components)
nonebot/adapters/discord/api/models/common/integrations.py New common models split-out (integrations)
nonebot/adapters/discord/api/models/common/guilds.py New common models split-out (guilds)
nonebot/adapters/discord/api/models/common/guild_welcome.py New common models split-out (welcome screen)
nonebot/adapters/discord/api/models/common/guild_templates.py New common models split-out (guild templates)
nonebot/adapters/discord/api/models/common/guild_scheduled_events.py New common models split-out (scheduled events)
nonebot/adapters/discord/api/models/common/guild_members.py New common models split-out (guild members)
nonebot/adapters/discord/api/models/common/emoji.py New common models split-out (emoji)
nonebot/adapters/discord/api/models/common/embeds.py New common models split-out (embeds)
nonebot/adapters/discord/api/models/common/channels.py New common models split-out (channels/threads)
nonebot/adapters/discord/api/models/common/auto_moderation.py New common models split-out (auto moderation)
nonebot/adapters/discord/api/models/common/audit_log.py New common models split-out (audit log)
nonebot/adapters/discord/api/models/common/application.py New common models split-out (application)
nonebot/adapters/discord/api/models/common/init.py Common package exports (aggregated)
nonebot/adapters/discord/api/models/init.py Facade re-exports + forward-ref rebuild + __all__
nonebot/adapters/discord/api/handle.py Update handle to import model types from .models
nonebot/adapters/discord/api/client.pyi Regenerated stubs to import from .models
nonebot/adapters/discord/api/init.py Update public API re-exports to source from .models
nonebot/adapters/discord/adapter.py Update gateway frame/model imports to new api.models facade

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +58 to +62
msg = (
f"Illegal import in {py_file}: from {node.module} import ... "
"(common layer should not depend on request/response/gateway/interactions/http)",
)
raise AssertionError(msg)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msg is being created as a single-element tuple due to the trailing comma in the assignment. This makes the AssertionError message render as a tuple repr instead of a readable string; remove the trailing comma so msg is a plain str.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +15
if TYPE_CHECKING:
from ..common.embeds import Embed
from ..common.interactions import Component, DirectComponent
from ..common.messages import MessageReference
from ..http.polls import PollRequest

Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PollRequest is imported under TYPE_CHECKING from ..http.polls, which introduces an unnecessary cross-layer dependency (and can create type-checker import cycles since http modules themselves depend on request). Import PollRequest from the local request layer (.polls) instead.

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +40
def __init__(self, **data) -> None: # noqa: ANN003
super().__init__(**data)
warnings.warn(
"InviteStageInstance is deprecated by Discord",
DeprecationWarning,
stacklevel=2,
)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InviteDelete.__init__ currently emits a DeprecationWarning saying "InviteStageInstance is deprecated by Discord" for every InviteDelete payload. This warning appears unrelated to this model (it has no stage_instance field) and will create noisy warnings; remove it or move the deprecation warning to the model/field that is actually deprecated.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 3
from .client import ApiClient as ApiClient
from .model import (
from .models import (
SKU,
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor switches imports from nonebot.adapters.discord.api.model to nonebot.adapters.discord.api.models, but there is no longer an api/model.py module in the package. If api.model was part of the public import surface (and existing user code relies on it), this is a breaking change; consider adding a small api/model.py compatibility shim (optionally emitting a DeprecationWarning) that re-exports from .models.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +76
msg = (
f"Illegal import in {py_file}: from {node.module} import ... "
"(gateway layer should not depend on request/response/interactions/http)",
)
raise AssertionError(msg)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: the trailing comma makes msg a single-element tuple instead of a string, so the AssertionError message becomes a tuple repr. Drop the trailing comma so msg is str.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants