kryncord 0.1.0b1__tar.gz
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.
- kryncord-0.1.0b1/.gitignore +58 -0
- kryncord-0.1.0b1/CHANGELOG.md +36 -0
- kryncord-0.1.0b1/LICENSE +21 -0
- kryncord-0.1.0b1/PKG-INFO +209 -0
- kryncord-0.1.0b1/README.md +177 -0
- kryncord-0.1.0b1/docs/README.md +38 -0
- kryncord-0.1.0b1/docs/api/components-v1.md +507 -0
- kryncord-0.1.0b1/docs/api/components-v2-and-modals.md +679 -0
- kryncord-0.1.0b1/docs/decisions/0001-http-transport.md +41 -0
- kryncord-0.1.0b1/docs/decisions/0002-websocket-transport.md +38 -0
- kryncord-0.1.0b1/docs/decisions/0003-data-models.md +49 -0
- kryncord-0.1.0b1/docs/decisions/0004-build-order.md +54 -0
- kryncord-0.1.0b1/docs/decisions/0005-gateway-reconnect.md +72 -0
- kryncord-0.1.0b1/docs/decisions/0006-event-dispatch.md +121 -0
- kryncord-0.1.0b1/docs/decisions/0007-api-layer.md +175 -0
- kryncord-0.1.0b1/docs/decisions/0008-cache-and-state.md +362 -0
- kryncord-0.1.0b1/docs/decisions/0009-command-responder-surface.md +226 -0
- kryncord-0.1.0b1/docs/decisions/0010-client-options.md +137 -0
- kryncord-0.1.0b1/docs/decisions/0011-command-registry.md +117 -0
- kryncord-0.1.0b1/docs/decisions/0012-contextos.md +130 -0
- kryncord-0.1.0b1/docs/decisions/0013-router-syntax.md +144 -0
- kryncord-0.1.0b1/docs/decisions/0014-converters.md +126 -0
- kryncord-0.1.0b1/docs/decisions/0015-components.md +180 -0
- kryncord-0.1.0b1/docs/decisions/0016-interaction-state.md +179 -0
- kryncord-0.1.0b1/docs/decisions/0017-middleware-errors.md +162 -0
- kryncord-0.1.0b1/docs/decisions/0018-command-sync.md +150 -0
- kryncord-0.1.0b1/docs/decisions/0019-discovery-bootstrap.md +138 -0
- kryncord-0.1.0b1/docs/decisions/0020-events.md +162 -0
- kryncord-0.1.0b1/docs/decisions/0021-autocomplete.md +125 -0
- kryncord-0.1.0b1/docs/decisions/0022-context-menus-transport.md +119 -0
- kryncord-0.1.0b1/docs/decisions/0023-responder-parity.md +247 -0
- kryncord-0.1.0b1/docs/decisions/0024-components-block.md +204 -0
- kryncord-0.1.0b1/docs/decisions/0025-events-payloads-snapshot.md +268 -0
- kryncord-0.1.0b1/docs/decisions/0026-interaction-routing-commands.md +287 -0
- kryncord-0.1.0b1/docs/decisions/0027-discovery-bootstrap-impl.md +234 -0
- kryncord-0.1.0b1/docs/decisions/0028-command-scope-deferred.md +134 -0
- kryncord-0.1.0b1/docs/decisions/0029-on-not-found-arity.md +126 -0
- kryncord-0.1.0b1/docs/decisions/0030-per-command-error-handlers.md +139 -0
- kryncord-0.1.0b1/docs/decisions/README.md +61 -0
- kryncord-0.1.0b1/docs/guides/publication.md +137 -0
- kryncord-0.1.0b1/docs/internals/architecture.md +848 -0
- kryncord-0.1.0b1/docs/internals/initial-decisions.md +11 -0
- kryncord-0.1.0b1/docs/reference/ideiabase.md +2673 -0
- kryncord-0.1.0b1/examples/minimal_bot.py +43 -0
- kryncord-0.1.0b1/pyproject.toml +108 -0
- kryncord-0.1.0b1/src/kryncord/__init__.py +336 -0
- kryncord-0.1.0b1/src/kryncord/api/__init__.py +111 -0
- kryncord-0.1.0b1/src/kryncord/api/_parse.py +92 -0
- kryncord-0.1.0b1/src/kryncord/api/_resolve.py +65 -0
- kryncord-0.1.0b1/src/kryncord/api/applications.py +184 -0
- kryncord-0.1.0b1/src/kryncord/api/channels.py +336 -0
- kryncord-0.1.0b1/src/kryncord/api/guilds.py +52 -0
- kryncord-0.1.0b1/src/kryncord/api/interactions.py +316 -0
- kryncord-0.1.0b1/src/kryncord/api/members.py +235 -0
- kryncord-0.1.0b1/src/kryncord/api/messages.py +327 -0
- kryncord-0.1.0b1/src/kryncord/api/roles.py +116 -0
- kryncord-0.1.0b1/src/kryncord/api/users.py +47 -0
- kryncord-0.1.0b1/src/kryncord/api/webhooks.py +184 -0
- kryncord-0.1.0b1/src/kryncord/builders/__init__.py +33 -0
- kryncord-0.1.0b1/src/kryncord/builders/embed.py +437 -0
- kryncord-0.1.0b1/src/kryncord/builders/messages.py +137 -0
- kryncord-0.1.0b1/src/kryncord/cache/__init__.py +55 -0
- kryncord-0.1.0b1/src/kryncord/cache/keys.py +97 -0
- kryncord-0.1.0b1/src/kryncord/cache/memory.py +241 -0
- kryncord-0.1.0b1/src/kryncord/cache/policy.py +188 -0
- kryncord-0.1.0b1/src/kryncord/cache/protocol.py +114 -0
- kryncord-0.1.0b1/src/kryncord/cache/stats.py +122 -0
- kryncord-0.1.0b1/src/kryncord/client.py +662 -0
- kryncord-0.1.0b1/src/kryncord/commands/__init__.py +60 -0
- kryncord-0.1.0b1/src/kryncord/commands/autocomplete.py +229 -0
- kryncord-0.1.0b1/src/kryncord/commands/context.py +441 -0
- kryncord-0.1.0b1/src/kryncord/commands/decorators.py +296 -0
- kryncord-0.1.0b1/src/kryncord/commands/definition.py +104 -0
- kryncord-0.1.0b1/src/kryncord/commands/dispatch.py +434 -0
- kryncord-0.1.0b1/src/kryncord/commands/instance.py +437 -0
- kryncord-0.1.0b1/src/kryncord/commands/option.py +178 -0
- kryncord-0.1.0b1/src/kryncord/commands/registry.py +241 -0
- kryncord-0.1.0b1/src/kryncord/commands/sync.py +316 -0
- kryncord-0.1.0b1/src/kryncord/commands/validation.py +199 -0
- kryncord-0.1.0b1/src/kryncord/components/__init__.py +144 -0
- kryncord-0.1.0b1/src/kryncord/components/base.py +75 -0
- kryncord-0.1.0b1/src/kryncord/components/buttons.py +155 -0
- kryncord-0.1.0b1/src/kryncord/components/choices.py +116 -0
- kryncord-0.1.0b1/src/kryncord/components/colors.py +101 -0
- kryncord-0.1.0b1/src/kryncord/components/displays.py +400 -0
- kryncord-0.1.0b1/src/kryncord/components/inputs.py +206 -0
- kryncord-0.1.0b1/src/kryncord/components/modals.py +128 -0
- kryncord-0.1.0b1/src/kryncord/components/rows.py +213 -0
- kryncord-0.1.0b1/src/kryncord/components/selects.py +272 -0
- kryncord-0.1.0b1/src/kryncord/components/uploads.py +76 -0
- kryncord-0.1.0b1/src/kryncord/components/validation.py +199 -0
- kryncord-0.1.0b1/src/kryncord/config.py +277 -0
- kryncord-0.1.0b1/src/kryncord/discovery/__init__.py +24 -0
- kryncord-0.1.0b1/src/kryncord/discovery/bootstrap.py +188 -0
- kryncord-0.1.0b1/src/kryncord/discovery/loader.py +315 -0
- kryncord-0.1.0b1/src/kryncord/enums.py +374 -0
- kryncord-0.1.0b1/src/kryncord/errors.py +229 -0
- kryncord-0.1.0b1/src/kryncord/events/__init__.py +59 -0
- kryncord-0.1.0b1/src/kryncord/events/context.py +136 -0
- kryncord-0.1.0b1/src/kryncord/events/decorators.py +256 -0
- kryncord-0.1.0b1/src/kryncord/events/dispatcher.py +474 -0
- kryncord-0.1.0b1/src/kryncord/events/names.py +62 -0
- kryncord-0.1.0b1/src/kryncord/events/payloads.py +236 -0
- kryncord-0.1.0b1/src/kryncord/events/snapshot.py +114 -0
- kryncord-0.1.0b1/src/kryncord/gateway/__init__.py +70 -0
- kryncord-0.1.0b1/src/kryncord/gateway/client.py +750 -0
- kryncord-0.1.0b1/src/kryncord/gateway/compression.py +209 -0
- kryncord-0.1.0b1/src/kryncord/gateway/connection.py +243 -0
- kryncord-0.1.0b1/src/kryncord/gateway/heartbeat.py +243 -0
- kryncord-0.1.0b1/src/kryncord/gateway/identify.py +236 -0
- kryncord-0.1.0b1/src/kryncord/gateway/payloads.py +172 -0
- kryncord-0.1.0b1/src/kryncord/gateway/reconnect.py +250 -0
- kryncord-0.1.0b1/src/kryncord/gateway/session.py +120 -0
- kryncord-0.1.0b1/src/kryncord/http/__init__.py +76 -0
- kryncord-0.1.0b1/src/kryncord/http/authentication.py +76 -0
- kryncord-0.1.0b1/src/kryncord/http/buckets.py +181 -0
- kryncord-0.1.0b1/src/kryncord/http/client.py +213 -0
- kryncord-0.1.0b1/src/kryncord/http/multipart.py +191 -0
- kryncord-0.1.0b1/src/kryncord/http/rate_limits.py +272 -0
- kryncord-0.1.0b1/src/kryncord/http/request.py +97 -0
- kryncord-0.1.0b1/src/kryncord/http/response.py +104 -0
- kryncord-0.1.0b1/src/kryncord/http/retries.py +151 -0
- kryncord-0.1.0b1/src/kryncord/http/routes.py +138 -0
- kryncord-0.1.0b1/src/kryncord/intents.py +104 -0
- kryncord-0.1.0b1/src/kryncord/interactions/__init__.py +30 -0
- kryncord-0.1.0b1/src/kryncord/interactions/component.py +102 -0
- kryncord-0.1.0b1/src/kryncord/interactions/dispatch.py +148 -0
- kryncord-0.1.0b1/src/kryncord/interactions/response.py +354 -0
- kryncord-0.1.0b1/src/kryncord/internal/__init__.py +9 -0
- kryncord-0.1.0b1/src/kryncord/internal/compose.py +97 -0
- kryncord-0.1.0b1/src/kryncord/internal/tasks.py +67 -0
- kryncord-0.1.0b1/src/kryncord/internal/timing.py +47 -0
- kryncord-0.1.0b1/src/kryncord/lifecycle.py +138 -0
- kryncord-0.1.0b1/src/kryncord/logging.py +84 -0
- kryncord-0.1.0b1/src/kryncord/models/__init__.py +86 -0
- kryncord-0.1.0b1/src/kryncord/models/attachment.py +51 -0
- kryncord-0.1.0b1/src/kryncord/models/ban.py +42 -0
- kryncord-0.1.0b1/src/kryncord/models/base.py +191 -0
- kryncord-0.1.0b1/src/kryncord/models/channel.py +163 -0
- kryncord-0.1.0b1/src/kryncord/models/command.py +107 -0
- kryncord-0.1.0b1/src/kryncord/models/guild.py +126 -0
- kryncord-0.1.0b1/src/kryncord/models/interaction.py +232 -0
- kryncord-0.1.0b1/src/kryncord/models/member.py +81 -0
- kryncord-0.1.0b1/src/kryncord/models/message.py +177 -0
- kryncord-0.1.0b1/src/kryncord/models/partial.py +91 -0
- kryncord-0.1.0b1/src/kryncord/models/ready.py +93 -0
- kryncord-0.1.0b1/src/kryncord/models/role.py +109 -0
- kryncord-0.1.0b1/src/kryncord/models/typing.py +98 -0
- kryncord-0.1.0b1/src/kryncord/models/user.py +88 -0
- kryncord-0.1.0b1/src/kryncord/models/voice.py +111 -0
- kryncord-0.1.0b1/src/kryncord/models/webhook.py +84 -0
- kryncord-0.1.0b1/src/kryncord/permissions.py +190 -0
- kryncord-0.1.0b1/src/kryncord/py.typed +0 -0
- kryncord-0.1.0b1/src/kryncord/registry.py +40 -0
- kryncord-0.1.0b1/src/kryncord/responders/__init__.py +63 -0
- kryncord-0.1.0b1/src/kryncord/responders/context.py +324 -0
- kryncord-0.1.0b1/src/kryncord/responders/converters.py +479 -0
- kryncord-0.1.0b1/src/kryncord/responders/decorators.py +77 -0
- kryncord-0.1.0b1/src/kryncord/responders/dispatch.py +341 -0
- kryncord-0.1.0b1/src/kryncord/responders/ids.py +253 -0
- kryncord-0.1.0b1/src/kryncord/responders/params.py +61 -0
- kryncord-0.1.0b1/src/kryncord/responders/patterns.py +183 -0
- kryncord-0.1.0b1/src/kryncord/responders/registry.py +155 -0
- kryncord-0.1.0b1/src/kryncord/rest/__init__.py +10 -0
- kryncord-0.1.0b1/src/kryncord/rest/client.py +374 -0
- kryncord-0.1.0b1/src/kryncord/state/__init__.py +35 -0
- kryncord-0.1.0b1/src/kryncord/state/connection_state.py +441 -0
- kryncord-0.1.0b1/src/kryncord/state/event_updates.py +662 -0
- kryncord-0.1.0b1/src/kryncord/state/guild_state.py +134 -0
- kryncord-0.1.0b1/src/kryncord/version.py +8 -0
- kryncord-0.1.0b1/src/kryncord/voice/__init__.py +8 -0
- kryncord-0.1.0b1/tests/conftest.py +255 -0
- kryncord-0.1.0b1/tests/unit/builders/__init__.py +3 -0
- kryncord-0.1.0b1/tests/unit/builders/test_embed.py +225 -0
- kryncord-0.1.0b1/tests/unit/components/__init__.py +6 -0
- kryncord-0.1.0b1/tests/unit/components/test_button_rules.py +150 -0
- kryncord-0.1.0b1/tests/unit/components/test_displays.py +252 -0
- kryncord-0.1.0b1/tests/unit/components/test_flag.py +219 -0
- kryncord-0.1.0b1/tests/unit/components/test_modal.py +284 -0
- kryncord-0.1.0b1/tests/unit/components/test_rows.py +184 -0
- kryncord-0.1.0b1/tests/unit/components/test_selects.py +149 -0
- kryncord-0.1.0b1/tests/unit/pacote_circular/__init__.py +1 -0
- kryncord-0.1.0b1/tests/unit/pacote_circular/a.py +11 -0
- kryncord-0.1.0b1/tests/unit/pacote_circular/b.py +11 -0
- kryncord-0.1.0b1/tests/unit/pacote_quebrado/__init__.py +1 -0
- kryncord-0.1.0b1/tests/unit/pacote_quebrado/estoura.py +3 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/__init__.py +15 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/alpha_mod.py +5 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/beta_mod.py +5 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/handlers.py +18 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/sub/__init__.py +5 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/sub/profundo.py +5 -0
- kryncord-0.1.0b1/tests/unit/pacote_teste/util.py +5 -0
- kryncord-0.1.0b1/tests/unit/registro_ordem.py +15 -0
- kryncord-0.1.0b1/tests/unit/responders/__init__.py +12 -0
- kryncord-0.1.0b1/tests/unit/responders/test_context.py +472 -0
- kryncord-0.1.0b1/tests/unit/responders/test_converters.py +338 -0
- kryncord-0.1.0b1/tests/unit/responders/test_dispatch.py +429 -0
- kryncord-0.1.0b1/tests/unit/responders/test_ids.py +153 -0
- kryncord-0.1.0b1/tests/unit/responders/test_patterns.py +148 -0
- kryncord-0.1.0b1/tests/unit/responders/test_registry.py +170 -0
- kryncord-0.1.0b1/tests/unit/test_api.py +578 -0
- kryncord-0.1.0b1/tests/unit/test_api_resources.py +1108 -0
- kryncord-0.1.0b1/tests/unit/test_authentication.py +101 -0
- kryncord-0.1.0b1/tests/unit/test_autocomplete.py +210 -0
- kryncord-0.1.0b1/tests/unit/test_bootstrap.py +308 -0
- kryncord-0.1.0b1/tests/unit/test_buckets.py +224 -0
- kryncord-0.1.0b1/tests/unit/test_cache.py +554 -0
- kryncord-0.1.0b1/tests/unit/test_client.py +425 -0
- kryncord-0.1.0b1/tests/unit/test_command_context.py +455 -0
- kryncord-0.1.0b1/tests/unit/test_commands.py +505 -0
- kryncord-0.1.0b1/tests/unit/test_commands_routing.py +1071 -0
- kryncord-0.1.0b1/tests/unit/test_config.py +168 -0
- kryncord-0.1.0b1/tests/unit/test_dispatcher.py +418 -0
- kryncord-0.1.0b1/tests/unit/test_enums.py +140 -0
- kryncord-0.1.0b1/tests/unit/test_event_updates.py +655 -0
- kryncord-0.1.0b1/tests/unit/test_events.py +647 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_client.py +733 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_compression.py +255 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_connection.py +143 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_heartbeat.py +315 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_identify.py +299 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_payloads.py +204 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_reconnect.py +167 -0
- kryncord-0.1.0b1/tests/unit/test_gateway_session.py +149 -0
- kryncord-0.1.0b1/tests/unit/test_http_client.py +324 -0
- kryncord-0.1.0b1/tests/unit/test_intents.py +101 -0
- kryncord-0.1.0b1/tests/unit/test_interactions_state.py +398 -0
- kryncord-0.1.0b1/tests/unit/test_lifecycle.py +164 -0
- kryncord-0.1.0b1/tests/unit/test_loader.py +186 -0
- kryncord-0.1.0b1/tests/unit/test_logging.py +110 -0
- kryncord-0.1.0b1/tests/unit/test_models.py +1041 -0
- kryncord-0.1.0b1/tests/unit/test_multipart.py +221 -0
- kryncord-0.1.0b1/tests/unit/test_permissions.py +154 -0
- kryncord-0.1.0b1/tests/unit/test_public_api.py +97 -0
- kryncord-0.1.0b1/tests/unit/test_rate_limits.py +298 -0
- kryncord-0.1.0b1/tests/unit/test_rest_client.py +676 -0
- kryncord-0.1.0b1/tests/unit/test_retries.py +210 -0
- kryncord-0.1.0b1/tests/unit/test_routes.py +201 -0
- kryncord-0.1.0b1/tests/unit/test_state.py +491 -0
- kryncord-0.1.0b1/tests/unit/test_sync.py +433 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Ambientes virtuais
|
|
2
|
+
.venv/
|
|
3
|
+
venv/
|
|
4
|
+
env/
|
|
5
|
+
ENV/
|
|
6
|
+
|
|
7
|
+
# Bytecode e caches
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*$py.class
|
|
11
|
+
*.so
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.pytest_history/
|
|
16
|
+
|
|
17
|
+
# Build
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
*.egg
|
|
22
|
+
.eggs/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
|
|
25
|
+
# Editores
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/*
|
|
28
|
+
!.vscode/extensions.json
|
|
29
|
+
!.vscode/settings.json
|
|
30
|
+
*.swp
|
|
31
|
+
*.swo
|
|
32
|
+
*~
|
|
33
|
+
|
|
34
|
+
# Sistema
|
|
35
|
+
.DS_Store
|
|
36
|
+
Thumbs.db
|
|
37
|
+
|
|
38
|
+
# Segredos — nunca commitar
|
|
39
|
+
.env
|
|
40
|
+
.env.*
|
|
41
|
+
!.env.example
|
|
42
|
+
*.token
|
|
43
|
+
secrets.*
|
|
44
|
+
config.local.*
|
|
45
|
+
|
|
46
|
+
# Cobertura
|
|
47
|
+
.coverage
|
|
48
|
+
.coverage.*
|
|
49
|
+
htmlcov/
|
|
50
|
+
coverage.xml
|
|
51
|
+
|
|
52
|
+
# Fora do repositório — material local, não é parte da biblioteca
|
|
53
|
+
# (o gitignore não aceita comentário no fim da linha: o `#` viraria
|
|
54
|
+
# parte do padrão e nada seria ignorado)
|
|
55
|
+
base/
|
|
56
|
+
.freebuff/
|
|
57
|
+
ideias/
|
|
58
|
+
bot testes/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Formato em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/),
|
|
4
|
+
numeração em [SemVer](https://semver.org/lang/pt-BR/).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.1.0b1] — 2026-10-16
|
|
9
|
+
|
|
10
|
+
Primeira versão beta pública. O núcleo está de pé — REST e Gateway
|
|
11
|
+
próprios, sem dependência de `discord.py`.
|
|
12
|
+
|
|
13
|
+
### Adicionado
|
|
14
|
+
|
|
15
|
+
- `Client` e `Config` — ciclo de vida assíncrono, `async with` fecha a
|
|
16
|
+
conexão sozinho.
|
|
17
|
+
- Camada REST própria (`client.api`) com rate limit, retries e multipart.
|
|
18
|
+
- Camada Gateway: Identify, heartbeat, ACK, reconexão e retomada de
|
|
19
|
+
sessão.
|
|
20
|
+
- Payloads entregues **interpretados**: `Message`, `Guild`, `Ready` e
|
|
21
|
+
companhia em vez de `dict`.
|
|
22
|
+
- Roteamento de comandos, interações e responders.
|
|
23
|
+
- Cache opcional por política (`CachePolicy`) com estatísticas de hit
|
|
24
|
+
rate.
|
|
25
|
+
- Tipagem completa (`py.typed`) e `mypy --strict` no código inteiro.
|
|
26
|
+
|
|
27
|
+
### Conhecido
|
|
28
|
+
|
|
29
|
+
- O Discord não manda `guild_id` nos canais do `GUILD_CREATE` — a
|
|
30
|
+
biblioteca preenche a visão da guild por conta própria (verificado ao
|
|
31
|
+
vivo: 24/24 canais sem o campo).
|
|
32
|
+
- `MESSAGE_CONTENT` é privileged: precisa ser ligado no portal do
|
|
33
|
+
Discord antes de pedir o intent.
|
|
34
|
+
|
|
35
|
+
[Unreleased]: https://github.com/KrynCord/kryncord/compare/v0.1.0b1...HEAD
|
|
36
|
+
[0.1.0b1]: https://github.com/KrynCord/kryncord/releases/tag/v0.1.0b1
|
kryncord-0.1.0b1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gustavo Silva
|
|
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.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: kryncord
|
|
3
|
+
Version: 0.1.0b1
|
|
4
|
+
Summary: Async-first Discord API library for Python
|
|
5
|
+
Project-URL: Homepage, https://github.com/KrynCord/kryncord
|
|
6
|
+
Project-URL: Repository, https://github.com/KrynCord/kryncord
|
|
7
|
+
Project-URL: Documentation, https://github.com/KrynCord/kryncord#readme
|
|
8
|
+
Project-URL: Issues, https://github.com/KrynCord/kryncord/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/KrynCord/kryncord/blob/main/CHANGELOG.md
|
|
10
|
+
Author: kruldevb
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: api,async,bot,discord,gateway,rest
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Framework :: AsyncIO
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Communications :: Chat
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: httpx<1,>=0.28.1
|
|
25
|
+
Requires-Dist: websockets<18,>=17.2
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.13; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# KrynCord
|
|
34
|
+
|
|
35
|
+
Biblioteca assíncrona para criar bots Discord em Python, com implementação
|
|
36
|
+
própria das camadas REST e Gateway.
|
|
37
|
+
|
|
38
|
+
## Objetivos
|
|
39
|
+
|
|
40
|
+
- API async-first
|
|
41
|
+
- REST e Gateway independentes
|
|
42
|
+
- Roteamento de comandos e interações
|
|
43
|
+
- Cache opcional
|
|
44
|
+
- Tipagem e validação
|
|
45
|
+
- Testes e benchmarks
|
|
46
|
+
- Sem dependência de discord.py ou forks
|
|
47
|
+
|
|
48
|
+
## Instalação
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install kryncord
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Requer Python 3.11+.
|
|
55
|
+
|
|
56
|
+
## Uso
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import asyncio
|
|
60
|
+
import os
|
|
61
|
+
|
|
62
|
+
from kryncord import Client, Config, Intents, Message
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def main() -> None:
|
|
66
|
+
config = Config(token=os.environ["DISCORD_TOKEN"], intents=Intents.default())
|
|
67
|
+
|
|
68
|
+
async with Client(config) as client:
|
|
69
|
+
|
|
70
|
+
@client.on("message_create")
|
|
71
|
+
async def responde(message: Message) -> None:
|
|
72
|
+
if message.content == "!ping":
|
|
73
|
+
# `reply` aceita a própria mensagem — o canal sai de lá,
|
|
74
|
+
# e o `message_reference` é montado sozinho.
|
|
75
|
+
await client.api.messages.reply(message, "pong")
|
|
76
|
+
|
|
77
|
+
await client.start()
|
|
78
|
+
await asyncio.Event().wait() # fica no ar
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
asyncio.run(main())
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
O handler recebe o payload **já interpretado** — um `Message`, não um
|
|
85
|
+
`dict`. `message.content` é `None` quando o Discord não mandou texto, e
|
|
86
|
+
não `""`; `message.author` é `None` quando não veio autor. Campo ausente
|
|
87
|
+
nunca é preenchido com default, porque ausente e default são coisas
|
|
88
|
+
diferentes.
|
|
89
|
+
|
|
90
|
+
O nome do evento aceita as duas formas — `"message_create"` e
|
|
91
|
+
`"MESSAGE_CREATE"` chegam ao mesmo handler. E os métodos da API aceitam
|
|
92
|
+
ID ou objeto: `send(123, ...)`, `send("123", ...)`,
|
|
93
|
+
`send(channel, ...)` e `send(message, ...)` são o mesmo destino.
|
|
94
|
+
|
|
95
|
+
O `api/` é alcançado por `client.api`, e não por `message.reply()` — os
|
|
96
|
+
modelos são dados puros, sem referência a runtime. Ver
|
|
97
|
+
[0007](docs/decisions/0007-api-layer.md) para o porquê.
|
|
98
|
+
|
|
99
|
+
## Desenvolvimento
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
python -m pip install -e ".[dev]"
|
|
103
|
+
pytest
|
|
104
|
+
ruff check src tests
|
|
105
|
+
ruff format --check src tests
|
|
106
|
+
mypy src/kryncord
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Status
|
|
110
|
+
|
|
111
|
+
**Fase 3 — Core.** O bot recebe payload tipado e consegue responder.
|
|
112
|
+
`models/` traz `User`, `Message`, `Channel`, `Guild`, `Member`,
|
|
113
|
+
`Attachment`, `Role`, `Ban`, `Webhook`, `ApplicationCommand`,
|
|
114
|
+
`Interaction`, `Ready` e os `Partial*` para o que o Discord entrega
|
|
115
|
+
incompletos de propósito. `events/` converte o payload e decide a
|
|
116
|
+
política de execução — sequencial, exceção isolada, cancelamento
|
|
117
|
+
propaga.
|
|
118
|
+
|
|
119
|
+
`api/` é o vocabulário por recurso sobre a mecânica REST da Fase 1 —
|
|
120
|
+
**70 métodos em 9 módulos** (`messages`, `channels`, `members`,
|
|
121
|
+
`roles`, `webhooks`, `applications`, `interactions`, `guilds`,
|
|
122
|
+
`users`) — e o `Client` liga as duas.
|
|
123
|
+
|
|
124
|
+
`cache/` + `state/` dão ao bot memória local: `client.cache`, **ligada
|
|
125
|
+
por padrão**, guarda guilds, channels, roles e users — `members` e
|
|
126
|
+
`messages` são opt-in por serem os que crescem com o servidor. Remoção
|
|
127
|
+
híbrida (eventos invalidam o que o gateway anuncia; LRU com teto guarda
|
|
128
|
+
o que não tem evento de remoção) e o evento é aplicado **antes** dos
|
|
129
|
+
handlers rodarem, senão todo handler leria o estado do evento
|
|
130
|
+
anterior.
|
|
131
|
+
|
|
132
|
+
1516 testes passando. `ruff check`, `ruff format --check` e `mypy` limpos.
|
|
133
|
+
|
|
134
|
+
Fase 4 entrou em andamento pela metade dos registros de decisão —
|
|
135
|
+
`0010`–`0024` fecham a superfície inteira (construtor, registry,
|
|
136
|
+
contextos, rota, conversores, componentes, máquina de estados,
|
|
137
|
+
middleware, sync, bootstrap, eventos, autocomplete, context menus,
|
|
138
|
+
paridade com o discord.js e o bloco de componentes), e cada escolha
|
|
139
|
+
passou por um conselho de 22 perfis com veredito e divergência
|
|
140
|
+
registrados em `docs/decisions/`. Já em código: o `permissions.py` +
|
|
141
|
+
as três `Options` no `Config`, o `commands/` inteiro (option,
|
|
142
|
+
definition, validation, instance, registry, context, sync,
|
|
143
|
+
autocomplete), a máquina de estados de interação com a superfície do
|
|
144
|
+
discord.js (`update`, `defer_update`, `fetch_reply`, `launch_activity`,
|
|
145
|
+
`await_responder`), os 17 predicados `is_*()` no modelo, o `responders/`
|
|
146
|
+
inteiro (ids, patterns, router, converters, params, context, registry,
|
|
147
|
+
decorators, dispatch) e o `components/` inteiro (buttons, selects,
|
|
148
|
+
inputs, uploads, choices, rows, displays, modals, colors, validation)
|
|
149
|
+
com os embeds e a normalização que serializa no `api/`. Falta
|
|
150
|
+
`events/`, middleware como bloco próprio e o `bootstrap`.
|
|
151
|
+
|
|
152
|
+
| Fase | Conteúdo | Status |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| 0 | Pacote, erros, fundação, toolchain, CI | ✅ |
|
|
155
|
+
| 1 | REST: rotas, rate limits, buckets | ✅ |
|
|
156
|
+
| 2 | Gateway: connect, identify, heartbeat, resume | ✅ |
|
|
157
|
+
| 3 | Core: `Client`, `api/`, `models/`, dispatcher, `cache/`, `state/` | ✅ |
|
|
158
|
+
| 4 | Interações: commands, responders, components | 🔶 api/ |
|
|
159
|
+
| 5 | Benchmarks do cache | ⬜ |
|
|
160
|
+
|
|
161
|
+
## Estrutura
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
src/kryncord/ pacote público
|
|
165
|
+
client.py fachada e ciclo de vida
|
|
166
|
+
config.py Config, HTTPConfig, GatewayConfig (frozen)
|
|
167
|
+
intents.py bits de intent + validação privileged
|
|
168
|
+
enums.py opcodes, close codes, permissões
|
|
169
|
+
errors.py hierarquia de exceções
|
|
170
|
+
logging.py namespace kryncord + redact()
|
|
171
|
+
lifecycle.py tasks supervisionadas, encerramento limpo
|
|
172
|
+
<pacote>/ api, gateway, http, rest, interactions,
|
|
173
|
+
responders, commands, components, events,
|
|
174
|
+
models, builders, cache, state, discovery,
|
|
175
|
+
voice, internal
|
|
176
|
+
tests/unit/ testes sem rede
|
|
177
|
+
tests/integration/ testes com transportes simulados
|
|
178
|
+
docs/decisions/ registros de decisão de arquitetura
|
|
179
|
+
ideias/ design da API de alto nível (referência)
|
|
180
|
+
base/discord.js/ referência do discord.js (não é código do projeto)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Os pacotes de cada fase existem já com `__init__.py` documentando a
|
|
184
|
+
responsabilidade. Os arquivos de módulo entram quando tiverem testes e
|
|
185
|
+
uso claro — conforme o fim do `docs/internals/architecture.md`.
|
|
186
|
+
|
|
187
|
+
## Verificação
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python -m pip install -e ".[dev]"
|
|
191
|
+
python -m pytest
|
|
192
|
+
python -m ruff check src tests
|
|
193
|
+
python -m ruff format --check src tests
|
|
194
|
+
python -m mypy
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Decisões
|
|
198
|
+
|
|
199
|
+
- [0001 — Transporte HTTP: httpx](docs/decisions/0001-http-transport.md)
|
|
200
|
+
- [0002 — Transporte WebSocket: websockets](docs/decisions/0002-websocket-transport.md)
|
|
201
|
+
- [0003 — Modelos de dados: dataclasses](docs/decisions/0003-data-models.md)
|
|
202
|
+
- [0004 — Ordem de construção: REST → Gateway](docs/decisions/0004-build-order.md)
|
|
203
|
+
- [0005 — Reconexão do Gateway: classificação de close code](docs/decisions/0005-gateway-reconnect.md)
|
|
204
|
+
- [0006 — Eventos: payload tipado e política de dispatch](docs/decisions/0006-event-dispatch.md)
|
|
205
|
+
- [0007 — Camada `api/`: vocabulário sobre a mecânica REST](docs/decisions/0007-api-layer.md)
|
|
206
|
+
|
|
207
|
+
## Licença
|
|
208
|
+
|
|
209
|
+
MIT
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# KrynCord
|
|
2
|
+
|
|
3
|
+
Biblioteca assíncrona para criar bots Discord em Python, com implementação
|
|
4
|
+
própria das camadas REST e Gateway.
|
|
5
|
+
|
|
6
|
+
## Objetivos
|
|
7
|
+
|
|
8
|
+
- API async-first
|
|
9
|
+
- REST e Gateway independentes
|
|
10
|
+
- Roteamento de comandos e interações
|
|
11
|
+
- Cache opcional
|
|
12
|
+
- Tipagem e validação
|
|
13
|
+
- Testes e benchmarks
|
|
14
|
+
- Sem dependência de discord.py ou forks
|
|
15
|
+
|
|
16
|
+
## Instalação
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install kryncord
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Requer Python 3.11+.
|
|
23
|
+
|
|
24
|
+
## Uso
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import asyncio
|
|
28
|
+
import os
|
|
29
|
+
|
|
30
|
+
from kryncord import Client, Config, Intents, Message
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def main() -> None:
|
|
34
|
+
config = Config(token=os.environ["DISCORD_TOKEN"], intents=Intents.default())
|
|
35
|
+
|
|
36
|
+
async with Client(config) as client:
|
|
37
|
+
|
|
38
|
+
@client.on("message_create")
|
|
39
|
+
async def responde(message: Message) -> None:
|
|
40
|
+
if message.content == "!ping":
|
|
41
|
+
# `reply` aceita a própria mensagem — o canal sai de lá,
|
|
42
|
+
# e o `message_reference` é montado sozinho.
|
|
43
|
+
await client.api.messages.reply(message, "pong")
|
|
44
|
+
|
|
45
|
+
await client.start()
|
|
46
|
+
await asyncio.Event().wait() # fica no ar
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
asyncio.run(main())
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
O handler recebe o payload **já interpretado** — um `Message`, não um
|
|
53
|
+
`dict`. `message.content` é `None` quando o Discord não mandou texto, e
|
|
54
|
+
não `""`; `message.author` é `None` quando não veio autor. Campo ausente
|
|
55
|
+
nunca é preenchido com default, porque ausente e default são coisas
|
|
56
|
+
diferentes.
|
|
57
|
+
|
|
58
|
+
O nome do evento aceita as duas formas — `"message_create"` e
|
|
59
|
+
`"MESSAGE_CREATE"` chegam ao mesmo handler. E os métodos da API aceitam
|
|
60
|
+
ID ou objeto: `send(123, ...)`, `send("123", ...)`,
|
|
61
|
+
`send(channel, ...)` e `send(message, ...)` são o mesmo destino.
|
|
62
|
+
|
|
63
|
+
O `api/` é alcançado por `client.api`, e não por `message.reply()` — os
|
|
64
|
+
modelos são dados puros, sem referência a runtime. Ver
|
|
65
|
+
[0007](docs/decisions/0007-api-layer.md) para o porquê.
|
|
66
|
+
|
|
67
|
+
## Desenvolvimento
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python -m pip install -e ".[dev]"
|
|
71
|
+
pytest
|
|
72
|
+
ruff check src tests
|
|
73
|
+
ruff format --check src tests
|
|
74
|
+
mypy src/kryncord
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Status
|
|
78
|
+
|
|
79
|
+
**Fase 3 — Core.** O bot recebe payload tipado e consegue responder.
|
|
80
|
+
`models/` traz `User`, `Message`, `Channel`, `Guild`, `Member`,
|
|
81
|
+
`Attachment`, `Role`, `Ban`, `Webhook`, `ApplicationCommand`,
|
|
82
|
+
`Interaction`, `Ready` e os `Partial*` para o que o Discord entrega
|
|
83
|
+
incompletos de propósito. `events/` converte o payload e decide a
|
|
84
|
+
política de execução — sequencial, exceção isolada, cancelamento
|
|
85
|
+
propaga.
|
|
86
|
+
|
|
87
|
+
`api/` é o vocabulário por recurso sobre a mecânica REST da Fase 1 —
|
|
88
|
+
**70 métodos em 9 módulos** (`messages`, `channels`, `members`,
|
|
89
|
+
`roles`, `webhooks`, `applications`, `interactions`, `guilds`,
|
|
90
|
+
`users`) — e o `Client` liga as duas.
|
|
91
|
+
|
|
92
|
+
`cache/` + `state/` dão ao bot memória local: `client.cache`, **ligada
|
|
93
|
+
por padrão**, guarda guilds, channels, roles e users — `members` e
|
|
94
|
+
`messages` são opt-in por serem os que crescem com o servidor. Remoção
|
|
95
|
+
híbrida (eventos invalidam o que o gateway anuncia; LRU com teto guarda
|
|
96
|
+
o que não tem evento de remoção) e o evento é aplicado **antes** dos
|
|
97
|
+
handlers rodarem, senão todo handler leria o estado do evento
|
|
98
|
+
anterior.
|
|
99
|
+
|
|
100
|
+
1516 testes passando. `ruff check`, `ruff format --check` e `mypy` limpos.
|
|
101
|
+
|
|
102
|
+
Fase 4 entrou em andamento pela metade dos registros de decisão —
|
|
103
|
+
`0010`–`0024` fecham a superfície inteira (construtor, registry,
|
|
104
|
+
contextos, rota, conversores, componentes, máquina de estados,
|
|
105
|
+
middleware, sync, bootstrap, eventos, autocomplete, context menus,
|
|
106
|
+
paridade com o discord.js e o bloco de componentes), e cada escolha
|
|
107
|
+
passou por um conselho de 22 perfis com veredito e divergência
|
|
108
|
+
registrados em `docs/decisions/`. Já em código: o `permissions.py` +
|
|
109
|
+
as três `Options` no `Config`, o `commands/` inteiro (option,
|
|
110
|
+
definition, validation, instance, registry, context, sync,
|
|
111
|
+
autocomplete), a máquina de estados de interação com a superfície do
|
|
112
|
+
discord.js (`update`, `defer_update`, `fetch_reply`, `launch_activity`,
|
|
113
|
+
`await_responder`), os 17 predicados `is_*()` no modelo, o `responders/`
|
|
114
|
+
inteiro (ids, patterns, router, converters, params, context, registry,
|
|
115
|
+
decorators, dispatch) e o `components/` inteiro (buttons, selects,
|
|
116
|
+
inputs, uploads, choices, rows, displays, modals, colors, validation)
|
|
117
|
+
com os embeds e a normalização que serializa no `api/`. Falta
|
|
118
|
+
`events/`, middleware como bloco próprio e o `bootstrap`.
|
|
119
|
+
|
|
120
|
+
| Fase | Conteúdo | Status |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| 0 | Pacote, erros, fundação, toolchain, CI | ✅ |
|
|
123
|
+
| 1 | REST: rotas, rate limits, buckets | ✅ |
|
|
124
|
+
| 2 | Gateway: connect, identify, heartbeat, resume | ✅ |
|
|
125
|
+
| 3 | Core: `Client`, `api/`, `models/`, dispatcher, `cache/`, `state/` | ✅ |
|
|
126
|
+
| 4 | Interações: commands, responders, components | 🔶 api/ |
|
|
127
|
+
| 5 | Benchmarks do cache | ⬜ |
|
|
128
|
+
|
|
129
|
+
## Estrutura
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
src/kryncord/ pacote público
|
|
133
|
+
client.py fachada e ciclo de vida
|
|
134
|
+
config.py Config, HTTPConfig, GatewayConfig (frozen)
|
|
135
|
+
intents.py bits de intent + validação privileged
|
|
136
|
+
enums.py opcodes, close codes, permissões
|
|
137
|
+
errors.py hierarquia de exceções
|
|
138
|
+
logging.py namespace kryncord + redact()
|
|
139
|
+
lifecycle.py tasks supervisionadas, encerramento limpo
|
|
140
|
+
<pacote>/ api, gateway, http, rest, interactions,
|
|
141
|
+
responders, commands, components, events,
|
|
142
|
+
models, builders, cache, state, discovery,
|
|
143
|
+
voice, internal
|
|
144
|
+
tests/unit/ testes sem rede
|
|
145
|
+
tests/integration/ testes com transportes simulados
|
|
146
|
+
docs/decisions/ registros de decisão de arquitetura
|
|
147
|
+
ideias/ design da API de alto nível (referência)
|
|
148
|
+
base/discord.js/ referência do discord.js (não é código do projeto)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Os pacotes de cada fase existem já com `__init__.py` documentando a
|
|
152
|
+
responsabilidade. Os arquivos de módulo entram quando tiverem testes e
|
|
153
|
+
uso claro — conforme o fim do `docs/internals/architecture.md`.
|
|
154
|
+
|
|
155
|
+
## Verificação
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
python -m pip install -e ".[dev]"
|
|
159
|
+
python -m pytest
|
|
160
|
+
python -m ruff check src tests
|
|
161
|
+
python -m ruff format --check src tests
|
|
162
|
+
python -m mypy
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Decisões
|
|
166
|
+
|
|
167
|
+
- [0001 — Transporte HTTP: httpx](docs/decisions/0001-http-transport.md)
|
|
168
|
+
- [0002 — Transporte WebSocket: websockets](docs/decisions/0002-websocket-transport.md)
|
|
169
|
+
- [0003 — Modelos de dados: dataclasses](docs/decisions/0003-data-models.md)
|
|
170
|
+
- [0004 — Ordem de construção: REST → Gateway](docs/decisions/0004-build-order.md)
|
|
171
|
+
- [0005 — Reconexão do Gateway: classificação de close code](docs/decisions/0005-gateway-reconnect.md)
|
|
172
|
+
- [0006 — Eventos: payload tipado e política de dispatch](docs/decisions/0006-event-dispatch.md)
|
|
173
|
+
- [0007 — Camada `api/`: vocabulário sobre a mecânica REST](docs/decisions/0007-api-layer.md)
|
|
174
|
+
|
|
175
|
+
## Licença
|
|
176
|
+
|
|
177
|
+
MIT
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Documentação
|
|
2
|
+
|
|
3
|
+
O que cada pasta é, e quando você abre cada uma.
|
|
4
|
+
|
|
5
|
+
| Pasta | Abra quando… |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [`api/`](api/) | Quiser saber como a superfície pública se comporta — as regras de negócio, não o código. |
|
|
8
|
+
| [`decisions/`](decisions/) | Quiser saber **por que** o código é assim. ADRs numerados, um por escolha. |
|
|
9
|
+
| [`guides/`](guides/) | Quiser executar um procedimento passo a passo. |
|
|
10
|
+
| [`internals/`](internals/) | Quiser ver o desenho das camadas e o plano original. |
|
|
11
|
+
| [`reference/`](reference/) | Quiser o material externo que serviu de inspiração. |
|
|
12
|
+
|
|
13
|
+
## Ordem de leitura para quem chega agora
|
|
14
|
+
|
|
15
|
+
1. [`internals/initial-decisions.md`](internals/initial-decisions.md) — as
|
|
16
|
+
dez decisões que definem o projeto, em onze linhas.
|
|
17
|
+
2. [`internals/architecture.md`](internals/architecture.md) — o desenho
|
|
18
|
+
completo: camadas, módulos e limites.
|
|
19
|
+
3. [`decisions/`](decisions/) — na ordem dos números. Cada ADR explica o
|
|
20
|
+
que foi considerado, o que foi escolhido e o que foi descartado. Um
|
|
21
|
+
ADR **não é atualizado** quando a decisão muda: nasce um novo com
|
|
22
|
+
número maior, e o antigo fica como registro.
|
|
23
|
+
|
|
24
|
+
## Duas distinções que a documentação inteira repete
|
|
25
|
+
|
|
26
|
+
**Ausente ≠ default.** Campo que o Discord não mandou chega `None`, e
|
|
27
|
+
nunca é preenchido com um valor de convenção. `""` e `None` não são a
|
|
28
|
+
mesma coisa, e um canal sem `rate_limit_per_user` não é um canal com
|
|
29
|
+
`rate_limit_per_user = 0`.
|
|
30
|
+
|
|
31
|
+
**REST ≠ Gateway.** São camadas independentes: dá para usar `client.api`
|
|
32
|
+
sem abrir o socket, e o Gateway fica vivo mesmo se o REST falhar.
|
|
33
|
+
|
|
34
|
+
## Publicar
|
|
35
|
+
|
|
36
|
+
O passo a passo de publicação — incluindo TestPyPI, Trusted Publishing e
|
|
37
|
+
por que `pip install --pre` é obrigatório para beta — está em
|
|
38
|
+
[`guides/publication.md`](guides/publication.md).
|