moai-adk 0.15.1__py3-none-any.whl → 0.25.4__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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +1 -2
- moai_adk/__main__.py +85 -2
- moai_adk/cli/__init__.py +0 -1
- moai_adk/cli/commands/__init__.py +0 -1
- moai_adk/cli/commands/analyze.py +127 -0
- moai_adk/cli/commands/backup.py +5 -3
- moai_adk/cli/commands/doctor.py +35 -11
- moai_adk/cli/commands/improve_user_experience.py +348 -0
- moai_adk/cli/commands/init.py +150 -23
- moai_adk/cli/commands/language.py +269 -0
- moai_adk/cli/commands/migrate.py +158 -0
- moai_adk/cli/commands/status.py +13 -12
- moai_adk/cli/commands/update.py +364 -60
- moai_adk/cli/commands/validate_links.py +118 -0
- moai_adk/cli/main.py +3 -2
- moai_adk/cli/prompts/init_prompts.py +79 -82
- moai_adk/core/__init__.py +0 -1
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +439 -0
- moai_adk/core/claude_integration.py +421 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/config/__init__.py +6 -0
- moai_adk/core/config/auto_spec_config.py +346 -0
- moai_adk/core/config/migration.py +133 -12
- moai_adk/core/context_manager.py +279 -0
- moai_adk/core/diagnostics/slash_commands.py +0 -1
- moai_adk/core/error_recovery_system.py +1289 -0
- moai_adk/core/git/__init__.py +0 -1
- moai_adk/core/git/branch.py +0 -1
- moai_adk/core/git/branch_manager.py +4 -4
- moai_adk/core/git/checkpoint.py +1 -5
- moai_adk/core/git/commit.py +0 -1
- moai_adk/core/git/event_detector.py +3 -5
- moai_adk/core/git/manager.py +0 -1
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +925 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +169 -0
- moai_adk/core/integration/integration_tester.py +225 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +28 -18
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_validator.py +556 -0
- moai_adk/core/mcp/setup.py +113 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/backup_manager.py +208 -0
- moai_adk/core/migration/file_migrator.py +218 -0
- moai_adk/core/migration/version_detector.py +143 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +318 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/project/__init__.py +0 -1
- moai_adk/core/project/backup_utils.py +2 -7
- moai_adk/core/project/checker.py +3 -3
- moai_adk/core/project/detector.py +20 -40
- moai_adk/core/project/initializer.py +42 -17
- moai_adk/core/project/phase_executor.py +415 -58
- moai_adk/core/project/validator.py +6 -25
- moai_adk/core/quality/__init__.py +1 -1
- moai_adk/core/quality/trust_checker.py +64 -110
- moai_adk/core/quality/validators/__init__.py +1 -1
- moai_adk/core/quality/validators/base_validator.py +1 -1
- moai_adk/core/rollback_manager.py +993 -0
- moai_adk/core/session_manager.py +667 -0
- moai_adk/core/spec/confidence_scoring.py +749 -0
- moai_adk/core/spec/ears_template_engine.py +1182 -0
- moai_adk/core/spec/quality_validator.py +721 -0
- moai_adk/core/spec_status_manager.py +488 -0
- moai_adk/core/template/__init__.py +0 -1
- moai_adk/core/template/backup.py +41 -1
- moai_adk/core/template/config.py +11 -12
- moai_adk/core/template/languages.py +0 -1
- moai_adk/core/template/merger.py +79 -22
- moai_adk/core/template/processor.py +614 -40
- moai_adk/core/template_engine.py +36 -27
- moai_adk/foundation/git/commit_templates.py +565 -0
- moai_adk/foundation/trust/trust_principles.py +725 -0
- moai_adk/foundation/trust/validation_checklist.py +1678 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +107 -0
- moai_adk/statusline/config.py +364 -0
- moai_adk/statusline/enhanced_output_style_detector.py +364 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +228 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +327 -0
- moai_adk/statusline/update_checker.py +135 -0
- moai_adk/statusline/version_reader.py +647 -0
- moai_adk/templates/.git-hooks/pre-commit +66 -0
- moai_adk/templates/.git-hooks/pre-push +116 -4
- moai_adk/templates/.github/workflows/moai-gitflow.yml +1 -7
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +0 -1
- moai_adk/templates/.gitignore +44 -0
- moai_adk/templates/.mcp.json +22 -0
- moai_adk/templates/CLAUDE.md +450 -1071
- moai_adk/utils/__init__.py +0 -1
- moai_adk/utils/banner.py +0 -1
- moai_adk/utils/common.py +308 -0
- moai_adk/utils/link_validator.py +249 -0
- moai_adk/utils/logger.py +4 -9
- moai_adk/utils/safe_file_reader.py +210 -0
- moai_adk/utils/user_experience.py +531 -0
- moai_adk-0.25.4.dist-info/METADATA +2279 -0
- moai_adk-0.25.4.dist-info/RECORD +112 -0
- moai_adk/core/tags/__init__.py +0 -86
- moai_adk/core/tags/ci_validator.py +0 -463
- moai_adk/core/tags/cli.py +0 -283
- moai_adk/core/tags/generator.py +0 -109
- moai_adk/core/tags/inserter.py +0 -99
- moai_adk/core/tags/mapper.py +0 -126
- moai_adk/core/tags/parser.py +0 -76
- moai_adk/core/tags/pre_commit_validator.py +0 -393
- moai_adk/core/tags/reporter.py +0 -956
- moai_adk/core/tags/tags.py +0 -149
- moai_adk/core/tags/validator.py +0 -897
- moai_adk/templates/.claude/agents/alfred/backend-expert.md +0 -319
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +0 -316
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +0 -208
- moai_adk/templates/.claude/agents/alfred/devops-expert.md +0 -464
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +0 -214
- moai_adk/templates/.claude/agents/alfred/frontend-expert.md +0 -357
- moai_adk/templates/.claude/agents/alfred/git-manager.md +0 -406
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +0 -423
- moai_adk/templates/.claude/agents/alfred/project-manager.md +0 -312
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +0 -343
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +0 -865
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +0 -426
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +0 -361
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +0 -428
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +0 -375
- moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +0 -571
- moai_adk/templates/.claude/commands/alfred/0-project.md +0 -1854
- moai_adk/templates/.claude/commands/alfred/1-plan.md +0 -880
- moai_adk/templates/.claude/commands/alfred/2-run.md +0 -793
- moai_adk/templates/.claude/commands/alfred/3-sync.md +0 -1084
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +0 -149
- moai_adk/templates/.claude/hooks/alfred/core/project.py +0 -748
- moai_adk/templates/.claude/hooks/alfred/core/timeout.py +0 -136
- moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +0 -108
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +0 -198
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +0 -29
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +0 -100
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/shared/core/__init__.py +0 -170
- moai_adk/templates/.claude/hooks/alfred/shared/core/checkpoint.py +0 -271
- moai_adk/templates/.claude/hooks/alfred/shared/core/context.py +0 -67
- moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +0 -749
- moai_adk/templates/.claude/hooks/alfred/shared/core/tags.py +0 -230
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +0 -198
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +0 -21
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +0 -154
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/session.py +0 -174
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/tool.py +0 -87
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/user.py +0 -61
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +0 -112
- moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +0 -1
- moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +0 -161
- moai_adk/templates/.claude/settings.json +0 -144
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +0 -70
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +0 -62
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/reference.md +0 -242
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +0 -56
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/reference.md +0 -444
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +0 -62
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +0 -405
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +0 -51
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +0 -355
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +0 -239
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +0 -323
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +0 -286
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +0 -126
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/SKILL.md +0 -74
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/reference.md +0 -269
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/SKILL.md +0 -237
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/examples.md +0 -615
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/reference.md +0 -653
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +0 -150
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/SKILL.md +0 -198
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/examples.md +0 -431
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/reference.md +0 -141
- moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +0 -89
- moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +0 -122
- moai_adk/templates/.claude/skills/moai-alfred-practices/reference.md +0 -369
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +0 -508
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +0 -481
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +0 -100
- moai_adk/templates/.claude/skills/moai-alfred-reporting/SKILL.md +0 -273
- moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +0 -77
- moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +0 -265
- moai_adk/templates/.claude/skills/moai-alfred-rules/reference.md +0 -539
- moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +0 -84
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +0 -137
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +0 -219
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples/validate-spec.sh +0 -161
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +0 -541
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +0 -622
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/SKILL.md +0 -115
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/reference.md +0 -348
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +0 -211
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +0 -288
- moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +0 -269
- moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +0 -32
- moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +0 -298
- moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +0 -26
- moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +0 -21
- moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +0 -252
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +0 -24
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +0 -199
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +0 -39
- moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +0 -316
- moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +0 -18
- moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +0 -263
- moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +0 -30
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/reference.md +0 -218
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/CHECKLIST.md +0 -482
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/EXAMPLES.md +0 -278
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/INTERACTIVE-DISCOVERY.md +0 -524
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/METADATA.md +0 -477
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PARALLEL-ANALYSIS-REPORT.md +0 -429
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PYTHON-VERSION-MATRIX.md +0 -391
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-FACTORY-WORKFLOW.md +0 -431
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-UPDATE-ADVISOR.md +0 -577
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL.md +0 -271
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STEP-BY-STEP-GUIDE.md +0 -466
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STRUCTURE.md +0 -583
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/WEB-RESEARCH.md +0 -526
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/reference.md +0 -465
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/generate-structure.sh +0 -328
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/validate-skill.sh +0 -312
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/SKILL_TEMPLATE.md +0 -245
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/examples-template.md +0 -285
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/reference-template.md +0 -278
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/scripts-template.sh +0 -303
- moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +0 -291
- moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +0 -15
- moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +0 -802
- moai_adk/templates/.claude/skills/moai-design-systems/examples.md +0 -1238
- moai_adk/templates/.claude/skills/moai-design-systems/reference.md +0 -673
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +0 -290
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +0 -1633
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +0 -660
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +0 -128
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-security/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-security/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +0 -303
- moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +0 -1064
- moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +0 -1047
- moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +0 -116
- moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +0 -1099
- moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-c/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-c/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +0 -127
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +0 -126
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +0 -125
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +0 -32
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +0 -126
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +0 -433
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +0 -624
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +0 -316
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +0 -127
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +0 -125
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +0 -133
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +0 -34
- moai_adk/templates/.claude/skills/moai-project-documentation.md +0 -622
- moai_adk/templates/.github/workflows/c-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/cpp-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/csharp-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/dart-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/go-tag-validation.yml +0 -130
- moai_adk/templates/.github/workflows/java-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/javascript-tag-validation.yml +0 -135
- moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/php-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/python-tag-validation.yml +0 -118
- moai_adk/templates/.github/workflows/release.yml +0 -118
- moai_adk/templates/.github/workflows/ruby-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/rust-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/shell-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/swift-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/tag-report.yml +0 -269
- moai_adk/templates/.github/workflows/tag-validation.yml +0 -186
- moai_adk/templates/.github/workflows/typescript-tag-validation.yml +0 -154
- moai_adk/templates/.moai/config.json +0 -115
- moai_adk/templates/workflows/go-tag-validation.yml +0 -30
- moai_adk/templates/workflows/javascript-tag-validation.yml +0 -41
- moai_adk/templates/workflows/python-tag-validation.yml +0 -42
- moai_adk/templates/workflows/typescript-tag-validation.yml +0 -31
- moai_adk-0.15.1.dist-info/METADATA +0 -3094
- moai_adk-0.15.1.dist-info/RECORD +0 -365
- {moai_adk-0.15.1.dist-info → moai_adk-0.25.4.dist-info}/WHEEL +0 -0
- {moai_adk-0.15.1.dist-info → moai_adk-0.25.4.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.15.1.dist-info → moai_adk-0.25.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,624 +0,0 @@
|
|
|
1
|
-
# Python 3.13 Code Examples
|
|
2
|
-
|
|
3
|
-
Production-ready examples for modern Python development with pytest 8.4.2, ruff 0.13.1, mypy 1.8.0, FastAPI 0.115.0, and Python 3.13.1 features.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Example 1: pytest 8.4.2 with Fixtures and Async Tests
|
|
8
|
-
|
|
9
|
-
### Test File: `tests/test_user_service.py`
|
|
10
|
-
|
|
11
|
-
```python
|
|
12
|
-
"""
|
|
13
|
-
Test suite for UserService with pytest fixtures and async support.
|
|
14
|
-
Demonstrates pytest 8.4.2 best practices for Python 3.13.
|
|
15
|
-
"""
|
|
16
|
-
import pytest
|
|
17
|
-
from unittest.mock import AsyncMock
|
|
18
|
-
from src.services.user_service import UserService
|
|
19
|
-
from src.models.user import User
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@pytest.fixture
|
|
23
|
-
def user_service():
|
|
24
|
-
"""Fixture providing a UserService instance with mocked dependencies."""
|
|
25
|
-
return UserService(db_client=AsyncMock())
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@pytest.fixture
|
|
29
|
-
def sample_user():
|
|
30
|
-
"""Fixture providing a sample User instance for tests."""
|
|
31
|
-
return User(id=1, name="Alice", email="alice@example.com")
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test_user_creation(user_service, sample_user):
|
|
35
|
-
"""Verify user creation with valid data."""
|
|
36
|
-
result = user_service.validate_user(sample_user)
|
|
37
|
-
assert result is True
|
|
38
|
-
assert sample_user.id > 0
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.mark.asyncio
|
|
42
|
-
async def test_fetch_user_async(user_service):
|
|
43
|
-
"""Test async user fetching with mocked database."""
|
|
44
|
-
user_service.db_client.fetch_user.return_value = User(
|
|
45
|
-
id=1, name="Bob", email="bob@example.com"
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
user = await user_service.fetch_user(user_id=1)
|
|
49
|
-
|
|
50
|
-
assert user is not None
|
|
51
|
-
assert user.name == "Bob"
|
|
52
|
-
user_service.db_client.fetch_user.assert_called_once_with(1)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@pytest.mark.parametrize("user_id,expected_name", [
|
|
56
|
-
(1, "Alice"),
|
|
57
|
-
(2, "Bob"),
|
|
58
|
-
(3, "Charlie"),
|
|
59
|
-
])
|
|
60
|
-
@pytest.mark.asyncio
|
|
61
|
-
async def test_fetch_multiple_users(user_service, user_id, expected_name):
|
|
62
|
-
"""Parametrized test for fetching multiple users."""
|
|
63
|
-
user_service.db_client.fetch_user.return_value = User(
|
|
64
|
-
id=user_id, name=expected_name, email=f"{expected_name.lower()}@example.com"
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
user = await user_service.fetch_user(user_id=user_id)
|
|
68
|
-
|
|
69
|
-
assert user.name == expected_name
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Key Features**:
|
|
73
|
-
- ✅ Fixtures for dependency injection
|
|
74
|
-
- ✅ `@pytest.mark.asyncio` for async tests
|
|
75
|
-
- ✅ `@pytest.mark.parametrize` for data-driven tests
|
|
76
|
-
- ✅ AsyncMock for mocking async operations
|
|
77
|
-
- ✅ One assertion per test (clarity)
|
|
78
|
-
|
|
79
|
-
**Run Commands**:
|
|
80
|
-
```bash
|
|
81
|
-
pytest tests/test_user_service.py -v
|
|
82
|
-
pytest tests/test_user_service.py --cov=src.services --cov-report=term
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Example 2: ruff 0.13.1 Linting and Formatting Workflow
|
|
88
|
-
|
|
89
|
-
### Project Configuration: `pyproject.toml`
|
|
90
|
-
|
|
91
|
-
```toml
|
|
92
|
-
[tool.ruff]
|
|
93
|
-
line-length = 100
|
|
94
|
-
target-version = "py313"
|
|
95
|
-
exclude = [".venv", "build", "dist", "__pycache__"]
|
|
96
|
-
|
|
97
|
-
[tool.ruff.lint]
|
|
98
|
-
select = [
|
|
99
|
-
"E", # pycodestyle errors
|
|
100
|
-
"F", # pyflakes
|
|
101
|
-
"W", # pycodestyle warnings
|
|
102
|
-
"I", # isort (import sorting)
|
|
103
|
-
"N", # pep8-naming
|
|
104
|
-
"UP", # pyupgrade (use Python 3.13 features)
|
|
105
|
-
"B", # flake8-bugbear
|
|
106
|
-
"C4", # flake8-comprehensions
|
|
107
|
-
]
|
|
108
|
-
ignore = ["E501"] # Line length handled by formatter
|
|
109
|
-
|
|
110
|
-
[tool.ruff.lint.per-file-ignores]
|
|
111
|
-
"tests/**/*.py" = ["F401", "F811"] # Allow unused imports in tests
|
|
112
|
-
|
|
113
|
-
[tool.ruff.format]
|
|
114
|
-
quote-style = "double"
|
|
115
|
-
indent-style = "space"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Example Source File: `src/utils/formatter.py`
|
|
119
|
-
|
|
120
|
-
```python
|
|
121
|
-
"""String formatting utilities using Python 3.13 features."""
|
|
122
|
-
from typing import override
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
class Formatter:
|
|
126
|
-
"""Base formatter class."""
|
|
127
|
-
|
|
128
|
-
def format(self, text: str) -> str:
|
|
129
|
-
"""Format text with default behavior."""
|
|
130
|
-
return text.strip()
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
class UppercaseFormatter(Formatter):
|
|
134
|
-
"""Formatter that converts text to uppercase."""
|
|
135
|
-
|
|
136
|
-
@override # Python 3.13 PEP 698
|
|
137
|
-
def format(self, text: str) -> str:
|
|
138
|
-
"""Format text to uppercase."""
|
|
139
|
-
return text.strip().upper()
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def format_user_info(name: str, age: int, city: str) -> str:
|
|
143
|
-
"""Format user information with nested f-strings (Python 3.13 PEP 701)."""
|
|
144
|
-
# Python 3.13 allows nested f-strings and arbitrary expressions
|
|
145
|
-
return f"User: {name}, Details: {f'Age: {age}, City: {city.upper()}'}"
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**Workflow Commands**:
|
|
149
|
-
```bash
|
|
150
|
-
# Lint and auto-fix issues
|
|
151
|
-
ruff check . --fix
|
|
152
|
-
|
|
153
|
-
# Format code (replaces black)
|
|
154
|
-
ruff format .
|
|
155
|
-
|
|
156
|
-
# Check specific rules
|
|
157
|
-
ruff check --select I . # Import sorting only
|
|
158
|
-
ruff check --select UP . # Python 3.13 upgrade suggestions
|
|
159
|
-
|
|
160
|
-
# Show what would be fixed (dry-run)
|
|
161
|
-
ruff check --show-fixes .
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## Example 3: mypy 1.8.0 Type Checking with Pydantic 2.7.0
|
|
167
|
-
|
|
168
|
-
### Source File: `src/models/product.py`
|
|
169
|
-
|
|
170
|
-
```python
|
|
171
|
-
"""Product models with static (mypy) and runtime (Pydantic) validation."""
|
|
172
|
-
from typing import override
|
|
173
|
-
from pydantic import BaseModel, Field, field_validator
|
|
174
|
-
from decimal import Decimal
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
class Product(BaseModel):
|
|
178
|
-
"""Product model with runtime validation via Pydantic 2.7.0."""
|
|
179
|
-
|
|
180
|
-
id: int = Field(gt=0, description="Product ID must be positive")
|
|
181
|
-
name: str = Field(min_length=1, max_length=100)
|
|
182
|
-
price: Decimal = Field(gt=0, decimal_places=2)
|
|
183
|
-
stock: int = Field(ge=0, description="Stock cannot be negative")
|
|
184
|
-
|
|
185
|
-
@field_validator("name")
|
|
186
|
-
@classmethod
|
|
187
|
-
def name_must_not_contain_special_chars(cls, v: str) -> str:
|
|
188
|
-
"""Validate that name contains only alphanumeric characters."""
|
|
189
|
-
if not v.replace(" ", "").isalnum():
|
|
190
|
-
raise ValueError("Product name must be alphanumeric")
|
|
191
|
-
return v
|
|
192
|
-
|
|
193
|
-
def apply_discount(self, percentage: float) -> Decimal:
|
|
194
|
-
"""Apply discount percentage to product price."""
|
|
195
|
-
if not 0 <= percentage <= 100:
|
|
196
|
-
raise ValueError("Discount must be between 0 and 100")
|
|
197
|
-
discount_amount = self.price * Decimal(percentage / 100)
|
|
198
|
-
return self.price - discount_amount
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
class GenericContainer[T]: # Python 3.13 PEP 695 type parameters
|
|
202
|
-
"""Generic container using Python 3.13 type parameter syntax."""
|
|
203
|
-
|
|
204
|
-
def __init__(self, items: list[T]) -> None:
|
|
205
|
-
self.items = items
|
|
206
|
-
|
|
207
|
-
def first(self) -> T | None:
|
|
208
|
-
"""Return first item or None if empty."""
|
|
209
|
-
return self.items[0] if self.items else None
|
|
210
|
-
|
|
211
|
-
def add(self, item: T) -> None:
|
|
212
|
-
"""Add item to container."""
|
|
213
|
-
self.items.append(item)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
# Usage example
|
|
217
|
-
def process_products(products: GenericContainer[Product]) -> list[str]:
|
|
218
|
-
"""Process products and return their names."""
|
|
219
|
-
return [p.name for p in products.items if p.stock > 0]
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### mypy Configuration: `pyproject.toml`
|
|
223
|
-
|
|
224
|
-
```toml
|
|
225
|
-
[tool.mypy]
|
|
226
|
-
python_version = "3.13"
|
|
227
|
-
strict = true
|
|
228
|
-
warn_return_any = true
|
|
229
|
-
warn_unused_configs = true
|
|
230
|
-
disallow_untyped_defs = true
|
|
231
|
-
disallow_any_generics = true
|
|
232
|
-
check_untyped_defs = true
|
|
233
|
-
no_implicit_optional = true
|
|
234
|
-
warn_redundant_casts = true
|
|
235
|
-
warn_unused_ignores = true
|
|
236
|
-
|
|
237
|
-
[[tool.mypy.overrides]]
|
|
238
|
-
module = "tests.*"
|
|
239
|
-
disallow_untyped_defs = false
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Run Commands**:
|
|
243
|
-
```bash
|
|
244
|
-
mypy . # Type check all files
|
|
245
|
-
mypy --strict src/ # Strict mode for production code
|
|
246
|
-
mypy --show-column-numbers . # Show precise error locations
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
---
|
|
250
|
-
|
|
251
|
-
## Example 4: FastAPI 0.115.0 REST API with Async Handlers
|
|
252
|
-
|
|
253
|
-
### API Server: `src/api/main.py`
|
|
254
|
-
|
|
255
|
-
```python
|
|
256
|
-
"""FastAPI 0.115.0 application with async handlers and dependency injection."""
|
|
257
|
-
from fastapi import FastAPI, HTTPException, Depends
|
|
258
|
-
from fastapi.responses import JSONResponse
|
|
259
|
-
from pydantic import BaseModel, Field
|
|
260
|
-
from typing import Annotated
|
|
261
|
-
import asyncio
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
app = FastAPI(title="Product API", version="1.0.0")
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
class ProductCreate(BaseModel):
|
|
268
|
-
"""Product creation request schema."""
|
|
269
|
-
name: str = Field(min_length=1, max_length=100)
|
|
270
|
-
price: float = Field(gt=0)
|
|
271
|
-
stock: int = Field(ge=0)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
class ProductResponse(BaseModel):
|
|
275
|
-
"""Product response schema."""
|
|
276
|
-
id: int
|
|
277
|
-
name: str
|
|
278
|
-
price: float
|
|
279
|
-
stock: int
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
# Dependency injection
|
|
283
|
-
async def get_db_session():
|
|
284
|
-
"""Simulated database session (replace with actual DB)."""
|
|
285
|
-
# In production: use SQLAlchemy async session
|
|
286
|
-
yield {"connection": "active"}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
@app.get("/")
|
|
290
|
-
async def root():
|
|
291
|
-
"""Health check endpoint."""
|
|
292
|
-
return {"status": "ok", "version": "1.0.0"}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
@app.post("/products", response_model=ProductResponse, status_code=201)
|
|
296
|
-
async def create_product(
|
|
297
|
-
product: ProductCreate,
|
|
298
|
-
db: Annotated[dict, Depends(get_db_session)]
|
|
299
|
-
):
|
|
300
|
-
"""Create a new product (async handler)."""
|
|
301
|
-
# Simulate async database operation
|
|
302
|
-
await asyncio.sleep(0.1)
|
|
303
|
-
|
|
304
|
-
# In production: insert into database
|
|
305
|
-
product_data = {
|
|
306
|
-
"id": 1,
|
|
307
|
-
"name": product.name,
|
|
308
|
-
"price": product.price,
|
|
309
|
-
"stock": product.stock,
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return ProductResponse(**product_data)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
@app.get("/products/{product_id}", response_model=ProductResponse)
|
|
316
|
-
async def get_product(
|
|
317
|
-
product_id: int,
|
|
318
|
-
db: Annotated[dict, Depends(get_db_session)]
|
|
319
|
-
):
|
|
320
|
-
"""Retrieve product by ID (async handler)."""
|
|
321
|
-
# Simulate async database lookup
|
|
322
|
-
await asyncio.sleep(0.1)
|
|
323
|
-
|
|
324
|
-
# In production: query from database
|
|
325
|
-
if product_id == 999:
|
|
326
|
-
raise HTTPException(status_code=404, detail="Product not found")
|
|
327
|
-
|
|
328
|
-
return ProductResponse(id=product_id, name="Sample Product", price=29.99, stock=100)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
@app.exception_handler(ValueError)
|
|
332
|
-
async def value_error_handler(request, exc):
|
|
333
|
-
"""Global exception handler for ValueError."""
|
|
334
|
-
return JSONResponse(
|
|
335
|
-
status_code=400,
|
|
336
|
-
content={"error": "Validation failed", "detail": str(exc)},
|
|
337
|
-
)
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
### Test File: `tests/test_api.py`
|
|
341
|
-
|
|
342
|
-
```python
|
|
343
|
-
"""Tests for FastAPI endpoints using pytest-asyncio."""
|
|
344
|
-
import pytest
|
|
345
|
-
from httpx import AsyncClient, ASGITransport
|
|
346
|
-
from src.api.main import app
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
@pytest.mark.asyncio
|
|
350
|
-
async def test_root_endpoint():
|
|
351
|
-
"""Test health check endpoint."""
|
|
352
|
-
async with AsyncClient(
|
|
353
|
-
transport=ASGITransport(app=app),
|
|
354
|
-
base_url="http://test"
|
|
355
|
-
) as client:
|
|
356
|
-
response = await client.get("/")
|
|
357
|
-
assert response.status_code == 200
|
|
358
|
-
assert response.json() == {"status": "ok", "version": "1.0.0"}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
@pytest.mark.asyncio
|
|
362
|
-
async def test_create_product():
|
|
363
|
-
"""Test product creation endpoint."""
|
|
364
|
-
async with AsyncClient(
|
|
365
|
-
transport=ASGITransport(app=app),
|
|
366
|
-
base_url="http://test"
|
|
367
|
-
) as client:
|
|
368
|
-
response = await client.post("/products", json={
|
|
369
|
-
"name": "Test Product",
|
|
370
|
-
"price": 19.99,
|
|
371
|
-
"stock": 50,
|
|
372
|
-
})
|
|
373
|
-
assert response.status_code == 201
|
|
374
|
-
data = response.json()
|
|
375
|
-
assert data["name"] == "Test Product"
|
|
376
|
-
assert data["price"] == 19.99
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
@pytest.mark.asyncio
|
|
380
|
-
async def test_get_product_not_found():
|
|
381
|
-
"""Test product retrieval with non-existent ID."""
|
|
382
|
-
async with AsyncClient(
|
|
383
|
-
transport=ASGITransport(app=app),
|
|
384
|
-
base_url="http://test"
|
|
385
|
-
) as client:
|
|
386
|
-
response = await client.get("/products/999")
|
|
387
|
-
assert response.status_code == 404
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Run Commands**:
|
|
391
|
-
```bash
|
|
392
|
-
# Start development server
|
|
393
|
-
uvicorn src.api.main:app --reload
|
|
394
|
-
|
|
395
|
-
# Run tests
|
|
396
|
-
pytest tests/test_api.py -v --cov=src.api
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
---
|
|
400
|
-
|
|
401
|
-
## Example 5: asyncio.TaskGroup Concurrent Pattern (Python 3.13)
|
|
402
|
-
|
|
403
|
-
### Concurrent Operations: `src/services/data_fetcher.py`
|
|
404
|
-
|
|
405
|
-
```python
|
|
406
|
-
"""Data fetching service using Python 3.13 asyncio.TaskGroup."""
|
|
407
|
-
import asyncio
|
|
408
|
-
from typing import Any
|
|
409
|
-
import httpx
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
class DataFetcher:
|
|
413
|
-
"""Fetch data from multiple sources concurrently using TaskGroup."""
|
|
414
|
-
|
|
415
|
-
def __init__(self, base_url: str):
|
|
416
|
-
self.base_url = base_url
|
|
417
|
-
|
|
418
|
-
async def fetch_user(self, user_id: int) -> dict[str, Any]:
|
|
419
|
-
"""Fetch user data from API."""
|
|
420
|
-
await asyncio.sleep(0.1) # Simulate network delay
|
|
421
|
-
return {"id": user_id, "name": f"User{user_id}"}
|
|
422
|
-
|
|
423
|
-
async def fetch_posts(self, user_id: int) -> list[dict[str, Any]]:
|
|
424
|
-
"""Fetch user posts from API."""
|
|
425
|
-
await asyncio.sleep(0.15) # Simulate network delay
|
|
426
|
-
return [
|
|
427
|
-
{"id": 1, "user_id": user_id, "title": "Post 1"},
|
|
428
|
-
{"id": 2, "user_id": user_id, "title": "Post 2"},
|
|
429
|
-
]
|
|
430
|
-
|
|
431
|
-
async def fetch_comments(self, user_id: int) -> list[dict[str, Any]]:
|
|
432
|
-
"""Fetch user comments from API."""
|
|
433
|
-
await asyncio.sleep(0.12) # Simulate network delay
|
|
434
|
-
return [
|
|
435
|
-
{"id": 1, "user_id": user_id, "text": "Comment 1"},
|
|
436
|
-
]
|
|
437
|
-
|
|
438
|
-
async def fetch_user_profile(self, user_id: int) -> dict[str, Any]:
|
|
439
|
-
"""
|
|
440
|
-
Fetch complete user profile concurrently using TaskGroup.
|
|
441
|
-
|
|
442
|
-
TaskGroup advantages over asyncio.gather:
|
|
443
|
-
- Automatic exception propagation
|
|
444
|
-
- Structured concurrency (cancellation safety)
|
|
445
|
-
- Cleaner error handling
|
|
446
|
-
"""
|
|
447
|
-
async with asyncio.TaskGroup() as tg:
|
|
448
|
-
user_task = tg.create_task(self.fetch_user(user_id))
|
|
449
|
-
posts_task = tg.create_task(self.fetch_posts(user_id))
|
|
450
|
-
comments_task = tg.create_task(self.fetch_comments(user_id))
|
|
451
|
-
# All tasks run concurrently here
|
|
452
|
-
# If any task fails, TaskGroup cancels others and raises
|
|
453
|
-
|
|
454
|
-
# After TaskGroup exits, all tasks are complete
|
|
455
|
-
return {
|
|
456
|
-
"user": user_task.result(),
|
|
457
|
-
"posts": posts_task.result(),
|
|
458
|
-
"comments": comments_task.result(),
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
async def fetch_multiple_users(self, user_ids: list[int]) -> list[dict[str, Any]]:
|
|
462
|
-
"""Fetch multiple user profiles concurrently."""
|
|
463
|
-
async with asyncio.TaskGroup() as tg:
|
|
464
|
-
tasks = [
|
|
465
|
-
tg.create_task(self.fetch_user_profile(user_id))
|
|
466
|
-
for user_id in user_ids
|
|
467
|
-
]
|
|
468
|
-
|
|
469
|
-
return [task.result() for task in tasks]
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
# Context Variables for request tracking
|
|
473
|
-
from contextvars import ContextVar
|
|
474
|
-
|
|
475
|
-
request_id_var: ContextVar[str | None] = ContextVar("request_id", default=None)
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
async def process_request(request_id: str) -> dict[str, Any]:
|
|
479
|
-
"""Process request with context variable tracking."""
|
|
480
|
-
# Set context variable (inherited by all spawned tasks)
|
|
481
|
-
token = request_id_var.set(request_id)
|
|
482
|
-
|
|
483
|
-
try:
|
|
484
|
-
fetcher = DataFetcher(base_url="https://api.example.com")
|
|
485
|
-
result = await fetcher.fetch_user_profile(user_id=1)
|
|
486
|
-
|
|
487
|
-
# Log with request ID (available in all async contexts)
|
|
488
|
-
current_request_id = request_id_var.get()
|
|
489
|
-
print(f"Request {current_request_id} completed")
|
|
490
|
-
|
|
491
|
-
return result
|
|
492
|
-
finally:
|
|
493
|
-
request_id_var.reset(token)
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
# Main execution
|
|
497
|
-
async def main():
|
|
498
|
-
"""Example usage of DataFetcher with TaskGroup."""
|
|
499
|
-
fetcher = DataFetcher(base_url="https://api.example.com")
|
|
500
|
-
|
|
501
|
-
# Fetch single user profile
|
|
502
|
-
profile = await fetcher.fetch_user_profile(user_id=1)
|
|
503
|
-
print(f"Profile: {profile}")
|
|
504
|
-
|
|
505
|
-
# Fetch multiple users concurrently
|
|
506
|
-
profiles = await fetcher.fetch_multiple_users([1, 2, 3])
|
|
507
|
-
print(f"Fetched {len(profiles)} profiles")
|
|
508
|
-
|
|
509
|
-
# Process request with context tracking
|
|
510
|
-
result = await process_request(request_id="req-12345")
|
|
511
|
-
print(f"Result: {result}")
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
if __name__ == "__main__":
|
|
515
|
-
asyncio.run(main())
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
### Test File: `tests/test_data_fetcher.py`
|
|
519
|
-
|
|
520
|
-
```python
|
|
521
|
-
"""Tests for DataFetcher using pytest-asyncio."""
|
|
522
|
-
import pytest
|
|
523
|
-
from src.services.data_fetcher import DataFetcher
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
@pytest.mark.asyncio
|
|
527
|
-
async def test_fetch_user_profile():
|
|
528
|
-
"""Test concurrent user profile fetching."""
|
|
529
|
-
fetcher = DataFetcher(base_url="https://api.example.com")
|
|
530
|
-
profile = await fetcher.fetch_user_profile(user_id=1)
|
|
531
|
-
|
|
532
|
-
assert "user" in profile
|
|
533
|
-
assert "posts" in profile
|
|
534
|
-
assert "comments" in profile
|
|
535
|
-
assert profile["user"]["id"] == 1
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
@pytest.mark.asyncio
|
|
539
|
-
async def test_fetch_multiple_users():
|
|
540
|
-
"""Test fetching multiple user profiles concurrently."""
|
|
541
|
-
fetcher = DataFetcher(base_url="https://api.example.com")
|
|
542
|
-
profiles = await fetcher.fetch_multiple_users([1, 2, 3])
|
|
543
|
-
|
|
544
|
-
assert len(profiles) == 3
|
|
545
|
-
assert all("user" in p for p in profiles)
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
@pytest.mark.asyncio
|
|
549
|
-
async def test_taskgroup_error_propagation():
|
|
550
|
-
"""Test that TaskGroup properly propagates exceptions."""
|
|
551
|
-
fetcher = DataFetcher(base_url="https://api.example.com")
|
|
552
|
-
|
|
553
|
-
# Override method to raise error
|
|
554
|
-
async def failing_fetch(user_id: int):
|
|
555
|
-
raise ValueError("Simulated error")
|
|
556
|
-
|
|
557
|
-
fetcher.fetch_user = failing_fetch
|
|
558
|
-
|
|
559
|
-
with pytest.raises(ValueError, match="Simulated error"):
|
|
560
|
-
await fetcher.fetch_user_profile(user_id=1)
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
**Run Commands**:
|
|
564
|
-
```bash
|
|
565
|
-
# Run the example
|
|
566
|
-
python -m src.services.data_fetcher
|
|
567
|
-
|
|
568
|
-
# Run tests
|
|
569
|
-
pytest tests/test_data_fetcher.py -v --cov=src.services
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
---
|
|
573
|
-
|
|
574
|
-
## Quick Reference
|
|
575
|
-
|
|
576
|
-
### Setup New Project (uv 0.9.3)
|
|
577
|
-
|
|
578
|
-
```bash
|
|
579
|
-
# Create project with Python 3.13
|
|
580
|
-
uv venv --python 3.13
|
|
581
|
-
source .venv/bin/activate
|
|
582
|
-
|
|
583
|
-
# Install dependencies
|
|
584
|
-
uv add pytest pytest-asyncio ruff mypy fastapi uvicorn httpx pydantic
|
|
585
|
-
|
|
586
|
-
# Add development dependencies
|
|
587
|
-
uv add --dev pytest-cov pytest-mock
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
### Quality Gate Commands
|
|
591
|
-
|
|
592
|
-
```bash
|
|
593
|
-
# Run all tests with coverage
|
|
594
|
-
pytest --cov=src --cov-report=term-missing --cov-report=html
|
|
595
|
-
|
|
596
|
-
# Lint and format
|
|
597
|
-
ruff check . --fix
|
|
598
|
-
ruff format .
|
|
599
|
-
|
|
600
|
-
# Type check
|
|
601
|
-
mypy --strict src/
|
|
602
|
-
|
|
603
|
-
# Full quality gate (run before commit)
|
|
604
|
-
pytest --cov=src --cov-report=term && ruff check . && mypy .
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
### Production Dependencies Matrix
|
|
608
|
-
|
|
609
|
-
| Package | Version | Purpose |
|
|
610
|
-
|---------|---------|---------|
|
|
611
|
-
| pytest | 8.4.2 | Testing framework |
|
|
612
|
-
| pytest-asyncio | latest | Async test support |
|
|
613
|
-
| pytest-cov | latest | Coverage reporting |
|
|
614
|
-
| ruff | 0.13.1 | Linting & formatting |
|
|
615
|
-
| mypy | 1.8.0 | Static type checking |
|
|
616
|
-
| uv | 0.9.3 | Package management |
|
|
617
|
-
| FastAPI | 0.115.0 | Web framework |
|
|
618
|
-
| Pydantic | 2.7.0 | Data validation |
|
|
619
|
-
| httpx | latest | Async HTTP client |
|
|
620
|
-
| uvicorn | latest | ASGI server |
|
|
621
|
-
|
|
622
|
-
---
|
|
623
|
-
|
|
624
|
-
All examples are tested against Python 3.13.1 and follow MoAI-ADK TRUST 5 principles.
|