@sylix/coworker 2.0.11 → 2.0.14

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.
Files changed (169) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +22 -4
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  5. package/dist/core/CoWorkerAgent.js +6 -3
  6. package/dist/core/CoWorkerAgent.js.map +1 -1
  7. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  8. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  9. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  10. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  11. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  12. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  13. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  14. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  15. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  16. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  17. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  18. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  19. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  20. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  21. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  22. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  23. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  24. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  25. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  26. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  27. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  28. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  29. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  30. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  31. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  32. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  33. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  34. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  35. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  36. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  37. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  38. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  39. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  40. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  41. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  42. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  43. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  44. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  45. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  46. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  47. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  48. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  49. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  50. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  51. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  52. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  53. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  54. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  55. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  56. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  57. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  58. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  59. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  60. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  61. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  62. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  63. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  64. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  65. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  66. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  67. package/dist/skills/defaults/database/postgresql.md +202 -0
  68. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  69. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  70. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  71. package/dist/skills/defaults/devops/cicd.md +314 -0
  72. package/dist/skills/defaults/devops/cloud.md +263 -0
  73. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  74. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  75. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  76. package/dist/skills/defaults/devops/docker.md +281 -0
  77. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  78. package/dist/skills/defaults/devops/github-actions.md +311 -0
  79. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  80. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  81. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  82. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  83. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  84. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  85. package/dist/skills/defaults/devops/observability.md +243 -0
  86. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  87. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  88. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  89. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  90. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  91. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  92. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  93. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  94. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  95. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  96. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  97. package/dist/skills/defaults/frontend/javascript.md +311 -0
  98. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  99. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  100. package/dist/skills/defaults/frontend/react.md +345 -0
  101. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  102. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  103. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  104. package/dist/skills/defaults/frontend/typescript.md +334 -0
  105. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  106. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  107. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  108. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  109. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  110. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  111. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  112. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  113. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  114. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  115. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  116. package/dist/skills/defaults/kubernetes/security.md +337 -0
  117. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  118. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  119. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  120. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  121. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  122. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  123. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  124. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  125. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  126. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  127. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  128. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  129. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  130. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  131. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  132. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  133. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  134. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  135. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  136. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  137. package/dist/skills/defaults/security/auditor.md +168 -0
  138. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  139. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  140. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  141. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  142. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  143. package/dist/skills/defaults/security/security.md +313 -0
  144. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  145. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  146. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  147. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  148. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  149. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  150. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  151. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  152. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  153. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  154. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  155. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  156. package/dist/skills/defaults/testing/testing.md +332 -0
  157. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  158. package/dist/skills/defaults/workflows/track-management.md +592 -0
  159. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  160. package/dist/skills/index.d.ts +11 -0
  161. package/dist/skills/index.d.ts.map +1 -0
  162. package/dist/skills/index.js +129 -0
  163. package/dist/skills/index.js.map +1 -0
  164. package/dist/utils/character.js +4 -4
  165. package/dist/utils/character.js.map +1 -1
  166. package/dist/utils/inputbar.d.ts.map +1 -1
  167. package/dist/utils/inputbar.js +7 -0
  168. package/dist/utils/inputbar.js.map +1 -1
  169. package/package.json +1 -1
@@ -0,0 +1,252 @@
1
+ ---
2
+ name: python-project-structure
3
+ description: Python project organization, module architecture, and public API design. Use when setting up new projects, organizing modules, defining public interfaces with __all__, or planning directory layouts.
4
+ ---
5
+
6
+ # Python Project Structure & Module Architecture
7
+
8
+ Design well-organized Python projects with clear module boundaries, explicit public interfaces, and maintainable directory structures. Good organization makes code discoverable and changes predictable.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Starting a new Python project from scratch
13
+ - Reorganizing an existing codebase for clarity
14
+ - Defining module public APIs with `__all__`
15
+ - Deciding between flat and nested directory structures
16
+ - Determining test file placement strategies
17
+ - Creating reusable library packages
18
+
19
+ ## Core Concepts
20
+
21
+ ### 1. Module Cohesion
22
+
23
+ Group related code that changes together. A module should have a single, clear purpose.
24
+
25
+ ### 2. Explicit Interfaces
26
+
27
+ Define what's public with `__all__`. Everything not listed is an internal implementation detail.
28
+
29
+ ### 3. Flat Hierarchies
30
+
31
+ Prefer shallow directory structures. Add depth only for genuine sub-domains.
32
+
33
+ ### 4. Consistent Conventions
34
+
35
+ Apply naming and organization patterns uniformly across the project.
36
+
37
+ ## Quick Start
38
+
39
+ ```
40
+ myproject/
41
+ ├── src/
42
+ │ └── myproject/
43
+ │ ├── __init__.py
44
+ │ ├── services/
45
+ │ ├── models/
46
+ │ └── api/
47
+ ├── tests/
48
+ ├── pyproject.toml
49
+ └── README.md
50
+ ```
51
+
52
+ ## Fundamental Patterns
53
+
54
+ ### Pattern 1: One Concept Per File
55
+
56
+ Each file should focus on a single concept or closely related set of functions. Consider splitting when a file:
57
+
58
+ - Handles multiple unrelated responsibilities
59
+ - Grows beyond 300-500 lines (varies by complexity)
60
+ - Contains classes that change for different reasons
61
+
62
+ ```python
63
+ # Good: Focused files
64
+ # user_service.py - User business logic
65
+ # user_repository.py - User data access
66
+ # user_models.py - User data structures
67
+
68
+ # Avoid: Kitchen sink files
69
+ # user.py - Contains service, repository, models, utilities...
70
+ ```
71
+
72
+ ### Pattern 2: Explicit Public APIs with `__all__`
73
+
74
+ Define the public interface for every module. Unlisted members are internal implementation details.
75
+
76
+ ```python
77
+ # mypackage/services/__init__.py
78
+ from .user_service import UserService
79
+ from .order_service import OrderService
80
+ from .exceptions import ServiceError, ValidationError
81
+
82
+ __all__ = [
83
+ "UserService",
84
+ "OrderService",
85
+ "ServiceError",
86
+ "ValidationError",
87
+ ]
88
+
89
+ # Internal helpers remain private by omission
90
+ # from .internal_helpers import _validate_input # Not exported
91
+ ```
92
+
93
+ ### Pattern 3: Flat Directory Structure
94
+
95
+ Prefer minimal nesting. Deep hierarchies make imports verbose and navigation difficult.
96
+
97
+ ```
98
+ # Preferred: Flat structure
99
+ project/
100
+ ├── api/
101
+ │ ├── routes.py
102
+ │ └── middleware.py
103
+ ├── services/
104
+ │ ├── user_service.py
105
+ │ └── order_service.py
106
+ ├── models/
107
+ │ ├── user.py
108
+ │ └── order.py
109
+ └── utils/
110
+ └── validation.py
111
+
112
+ # Avoid: Deep nesting
113
+ project/core/internal/services/impl/user/
114
+ ```
115
+
116
+ Add sub-packages only when there's a genuine sub-domain requiring isolation.
117
+
118
+ ### Pattern 4: Test File Organization
119
+
120
+ Choose one approach and apply it consistently throughout the project.
121
+
122
+ **Option A: Colocated Tests**
123
+
124
+ ```
125
+ src/
126
+ ├── user_service.py
127
+ ├── test_user_service.py
128
+ ├── order_service.py
129
+ └── test_order_service.py
130
+ ```
131
+
132
+ Benefits: Tests live next to the code they verify. Easy to see coverage gaps.
133
+
134
+ **Option B: Parallel Test Directory**
135
+
136
+ ```
137
+ src/
138
+ ├── services/
139
+ │ ├── user_service.py
140
+ │ └── order_service.py
141
+ tests/
142
+ ├── services/
143
+ │ ├── test_user_service.py
144
+ │ └── test_order_service.py
145
+ ```
146
+
147
+ Benefits: Clean separation between production and test code. Standard for larger projects.
148
+
149
+ ## Advanced Patterns
150
+
151
+ ### Pattern 5: Package Initialization
152
+
153
+ Use `__init__.py` to provide a clean public interface for package consumers.
154
+
155
+ ```python
156
+ # mypackage/__init__.py
157
+ """MyPackage - A library for doing useful things."""
158
+
159
+ from .core import MainClass, HelperClass
160
+ from .exceptions import PackageError, ConfigError
161
+ from .config import Settings
162
+
163
+ __all__ = [
164
+ "MainClass",
165
+ "HelperClass",
166
+ "PackageError",
167
+ "ConfigError",
168
+ "Settings",
169
+ ]
170
+
171
+ __version__ = "1.0.0"
172
+ ```
173
+
174
+ Consumers can then import directly from the package:
175
+
176
+ ```python
177
+ from mypackage import MainClass, Settings
178
+ ```
179
+
180
+ ### Pattern 6: Layered Architecture
181
+
182
+ Organize code by architectural layer for clear separation of concerns.
183
+
184
+ ```
185
+ myapp/
186
+ ├── api/ # HTTP handlers, request/response
187
+ │ ├── routes/
188
+ │ └── middleware/
189
+ ├── services/ # Business logic
190
+ ├── repositories/ # Data access
191
+ ├── models/ # Domain entities
192
+ ├── schemas/ # API schemas (Pydantic)
193
+ └── config/ # Configuration
194
+ ```
195
+
196
+ Each layer should only depend on layers below it, never above.
197
+
198
+ ### Pattern 7: Domain-Driven Structure
199
+
200
+ For complex applications, organize by business domain rather than technical layer.
201
+
202
+ ```
203
+ ecommerce/
204
+ ├── users/
205
+ │ ├── models.py
206
+ │ ├── services.py
207
+ │ ├── repository.py
208
+ │ └── api.py
209
+ ├── orders/
210
+ │ ├── models.py
211
+ │ ├── services.py
212
+ │ ├── repository.py
213
+ │ └── api.py
214
+ └── shared/
215
+ ├── database.py
216
+ └── exceptions.py
217
+ ```
218
+
219
+ ## File and Module Naming
220
+
221
+ ### Conventions
222
+
223
+ - Use `snake_case` for all file and module names: `user_repository.py`
224
+ - Avoid abbreviations that obscure meaning: `user_repository.py` not `usr_repo.py`
225
+ - Match class names to file names: `UserService` in `user_service.py`
226
+
227
+ ### Import Style
228
+
229
+ Use absolute imports for clarity and reliability:
230
+
231
+ ```python
232
+ # Preferred: Absolute imports
233
+ from myproject.services import UserService
234
+ from myproject.models import User
235
+
236
+ # Avoid: Relative imports
237
+ from ..services import UserService
238
+ from . import models
239
+ ```
240
+
241
+ Relative imports can break when modules are moved or reorganized.
242
+
243
+ ## Best Practices Summary
244
+
245
+ 1. **Keep files focused** - One concept per file, consider splitting at 300-500 lines (varies by complexity)
246
+ 2. **Define `__all__` explicitly** - Make public interfaces clear
247
+ 3. **Prefer flat structures** - Add depth only for genuine sub-domains
248
+ 4. **Use absolute imports** - More reliable and clearer
249
+ 5. **Be consistent** - Apply patterns uniformly across the project
250
+ 6. **Match names to content** - File names should describe their purpose
251
+ 7. **Separate concerns** - Keep layers distinct and dependencies flowing one direction
252
+ 8. **Document your structure** - Include a README explaining the organization
@@ -0,0 +1,376 @@
1
+ ---
2
+ name: python-resilience
3
+ description: Python resilience patterns including automatic retries, exponential backoff, timeouts, and fault-tolerant decorators. Use when adding retry logic, implementing timeouts, building fault-tolerant services, or handling transient failures.
4
+ ---
5
+
6
+ # Python Resilience Patterns
7
+
8
+ Build fault-tolerant Python applications that gracefully handle transient failures, network issues, and service outages. Resilience patterns keep systems running when dependencies are unreliable.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Adding retry logic to external service calls
13
+ - Implementing timeouts for network operations
14
+ - Building fault-tolerant microservices
15
+ - Handling rate limiting and backpressure
16
+ - Creating infrastructure decorators
17
+ - Designing circuit breakers
18
+
19
+ ## Core Concepts
20
+
21
+ ### 1. Transient vs Permanent Failures
22
+
23
+ Retry transient errors (network timeouts, temporary service issues). Don't retry permanent errors (invalid credentials, bad requests).
24
+
25
+ ### 2. Exponential Backoff
26
+
27
+ Increase wait time between retries to avoid overwhelming recovering services.
28
+
29
+ ### 3. Jitter
30
+
31
+ Add randomness to backoff to prevent thundering herd when many clients retry simultaneously.
32
+
33
+ ### 4. Bounded Retries
34
+
35
+ Cap both attempt count and total duration to prevent infinite retry loops.
36
+
37
+ ## Quick Start
38
+
39
+ ```python
40
+ from tenacity import retry, stop_after_attempt, wait_exponential_jitter
41
+
42
+ @retry(
43
+ stop=stop_after_attempt(3),
44
+ wait=wait_exponential_jitter(initial=1, max=10),
45
+ )
46
+ def call_external_service(request: dict) -> dict:
47
+ return httpx.post("https://api.example.com", json=request).json()
48
+ ```
49
+
50
+ ## Fundamental Patterns
51
+
52
+ ### Pattern 1: Basic Retry with Tenacity
53
+
54
+ Use the `tenacity` library for production-grade retry logic. For simpler cases, consider built-in retry functionality or a lightweight custom implementation.
55
+
56
+ ```python
57
+ from tenacity import (
58
+ retry,
59
+ stop_after_attempt,
60
+ stop_after_delay,
61
+ wait_exponential_jitter,
62
+ retry_if_exception_type,
63
+ )
64
+
65
+ TRANSIENT_ERRORS = (ConnectionError, TimeoutError, OSError)
66
+
67
+ @retry(
68
+ retry=retry_if_exception_type(TRANSIENT_ERRORS),
69
+ stop=stop_after_attempt(5) | stop_after_delay(60),
70
+ wait=wait_exponential_jitter(initial=1, max=30),
71
+ )
72
+ def fetch_data(url: str) -> dict:
73
+ """Fetch data with automatic retry on transient failures."""
74
+ response = httpx.get(url, timeout=30)
75
+ response.raise_for_status()
76
+ return response.json()
77
+ ```
78
+
79
+ ### Pattern 2: Retry Only Appropriate Errors
80
+
81
+ Whitelist specific transient exceptions. Never retry:
82
+
83
+ - `ValueError`, `TypeError` - These are bugs, not transient issues
84
+ - `AuthenticationError` - Invalid credentials won't become valid
85
+ - HTTP 4xx errors (except 429) - Client errors are permanent
86
+
87
+ ```python
88
+ from tenacity import retry, retry_if_exception_type
89
+ import httpx
90
+
91
+ # Define what's retryable
92
+ RETRYABLE_EXCEPTIONS = (
93
+ ConnectionError,
94
+ TimeoutError,
95
+ httpx.ConnectTimeout,
96
+ httpx.ReadTimeout,
97
+ )
98
+
99
+ @retry(
100
+ retry=retry_if_exception_type(RETRYABLE_EXCEPTIONS),
101
+ stop=stop_after_attempt(3),
102
+ wait=wait_exponential_jitter(initial=1, max=10),
103
+ )
104
+ def resilient_api_call(endpoint: str) -> dict:
105
+ """Make API call with retry on network issues."""
106
+ return httpx.get(endpoint, timeout=10).json()
107
+ ```
108
+
109
+ ### Pattern 3: HTTP Status Code Retries
110
+
111
+ Retry specific HTTP status codes that indicate transient issues.
112
+
113
+ ```python
114
+ from tenacity import retry, retry_if_result, stop_after_attempt
115
+ import httpx
116
+
117
+ RETRY_STATUS_CODES = {429, 502, 503, 504}
118
+
119
+ def should_retry_response(response: httpx.Response) -> bool:
120
+ """Check if response indicates a retryable error."""
121
+ return response.status_code in RETRY_STATUS_CODES
122
+
123
+ @retry(
124
+ retry=retry_if_result(should_retry_response),
125
+ stop=stop_after_attempt(3),
126
+ wait=wait_exponential_jitter(initial=1, max=10),
127
+ )
128
+ def http_request(method: str, url: str, **kwargs) -> httpx.Response:
129
+ """Make HTTP request with retry on transient status codes."""
130
+ return httpx.request(method, url, timeout=30, **kwargs)
131
+ ```
132
+
133
+ ### Pattern 4: Combined Exception and Status Retry
134
+
135
+ Handle both network exceptions and HTTP status codes.
136
+
137
+ ```python
138
+ from tenacity import (
139
+ retry,
140
+ retry_if_exception_type,
141
+ retry_if_result,
142
+ stop_after_attempt,
143
+ wait_exponential_jitter,
144
+ before_sleep_log,
145
+ )
146
+ import logging
147
+ import httpx
148
+
149
+ logger = logging.getLogger(__name__)
150
+
151
+ TRANSIENT_EXCEPTIONS = (
152
+ ConnectionError,
153
+ TimeoutError,
154
+ httpx.ConnectError,
155
+ httpx.ReadTimeout,
156
+ )
157
+ RETRY_STATUS_CODES = {429, 500, 502, 503, 504}
158
+
159
+ def is_retryable_response(response: httpx.Response) -> bool:
160
+ return response.status_code in RETRY_STATUS_CODES
161
+
162
+ @retry(
163
+ retry=(
164
+ retry_if_exception_type(TRANSIENT_EXCEPTIONS) |
165
+ retry_if_result(is_retryable_response)
166
+ ),
167
+ stop=stop_after_attempt(5),
168
+ wait=wait_exponential_jitter(initial=1, max=30),
169
+ before_sleep=before_sleep_log(logger, logging.WARNING),
170
+ )
171
+ def robust_http_call(
172
+ method: str,
173
+ url: str,
174
+ **kwargs,
175
+ ) -> httpx.Response:
176
+ """HTTP call with comprehensive retry handling."""
177
+ return httpx.request(method, url, timeout=30, **kwargs)
178
+ ```
179
+
180
+ ## Advanced Patterns
181
+
182
+ ### Pattern 5: Logging Retry Attempts
183
+
184
+ Track retry behavior for debugging and alerting.
185
+
186
+ ```python
187
+ from tenacity import retry, stop_after_attempt, wait_exponential
188
+ import structlog
189
+
190
+ logger = structlog.get_logger()
191
+
192
+ def log_retry_attempt(retry_state):
193
+ """Log detailed retry information."""
194
+ exception = retry_state.outcome.exception()
195
+ logger.warning(
196
+ "Retrying operation",
197
+ attempt=retry_state.attempt_number,
198
+ exception_type=type(exception).__name__,
199
+ exception_message=str(exception),
200
+ next_wait_seconds=retry_state.next_action.sleep if retry_state.next_action else None,
201
+ )
202
+
203
+ @retry(
204
+ stop=stop_after_attempt(3),
205
+ wait=wait_exponential(multiplier=1, max=10),
206
+ before_sleep=log_retry_attempt,
207
+ )
208
+ def call_with_logging(request: dict) -> dict:
209
+ """External call with retry logging."""
210
+ ...
211
+ ```
212
+
213
+ ### Pattern 6: Timeout Decorator
214
+
215
+ Create reusable timeout decorators for consistent timeout handling.
216
+
217
+ ```python
218
+ import asyncio
219
+ from functools import wraps
220
+ from typing import TypeVar, Callable
221
+
222
+ T = TypeVar("T")
223
+
224
+ def with_timeout(seconds: float):
225
+ """Decorator to add timeout to async functions."""
226
+ def decorator(func: Callable[..., T]) -> Callable[..., T]:
227
+ @wraps(func)
228
+ async def wrapper(*args, **kwargs) -> T:
229
+ return await asyncio.wait_for(
230
+ func(*args, **kwargs),
231
+ timeout=seconds,
232
+ )
233
+ return wrapper
234
+ return decorator
235
+
236
+ @with_timeout(30)
237
+ async def fetch_with_timeout(url: str) -> dict:
238
+ """Fetch URL with 30 second timeout."""
239
+ async with httpx.AsyncClient() as client:
240
+ response = await client.get(url)
241
+ return response.json()
242
+ ```
243
+
244
+ ### Pattern 7: Cross-Cutting Concerns via Decorators
245
+
246
+ Stack decorators to separate infrastructure from business logic.
247
+
248
+ ```python
249
+ from functools import wraps
250
+ from typing import TypeVar, Callable
251
+ import structlog
252
+
253
+ logger = structlog.get_logger()
254
+ T = TypeVar("T")
255
+
256
+ def traced(name: str | None = None):
257
+ """Add tracing to function calls."""
258
+ def decorator(func: Callable[..., T]) -> Callable[..., T]:
259
+ span_name = name or func.__name__
260
+
261
+ @wraps(func)
262
+ async def wrapper(*args, **kwargs) -> T:
263
+ logger.info("Operation started", operation=span_name)
264
+ try:
265
+ result = await func(*args, **kwargs)
266
+ logger.info("Operation completed", operation=span_name)
267
+ return result
268
+ except Exception as e:
269
+ logger.error("Operation failed", operation=span_name, error=str(e))
270
+ raise
271
+ return wrapper
272
+ return decorator
273
+
274
+ # Stack multiple concerns
275
+ @traced("fetch_user_data")
276
+ @with_timeout(30)
277
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential_jitter())
278
+ async def fetch_user_data(user_id: str) -> dict:
279
+ """Fetch user with tracing, timeout, and retry."""
280
+ ...
281
+ ```
282
+
283
+ ### Pattern 8: Dependency Injection for Testability
284
+
285
+ Pass infrastructure components through constructors for easy testing.
286
+
287
+ ```python
288
+ from dataclasses import dataclass
289
+ from typing import Protocol
290
+
291
+ class Logger(Protocol):
292
+ def info(self, msg: str, **kwargs) -> None: ...
293
+ def error(self, msg: str, **kwargs) -> None: ...
294
+
295
+ class MetricsClient(Protocol):
296
+ def increment(self, metric: str, tags: dict | None = None) -> None: ...
297
+ def timing(self, metric: str, value: float) -> None: ...
298
+
299
+ @dataclass
300
+ class UserService:
301
+ """Service with injected infrastructure."""
302
+
303
+ repository: UserRepository
304
+ logger: Logger
305
+ metrics: MetricsClient
306
+
307
+ async def get_user(self, user_id: str) -> User:
308
+ self.logger.info("Fetching user", user_id=user_id)
309
+ start = time.perf_counter()
310
+
311
+ try:
312
+ user = await self.repository.get(user_id)
313
+ self.metrics.increment("user.fetch.success")
314
+ return user
315
+ except Exception as e:
316
+ self.metrics.increment("user.fetch.error")
317
+ self.logger.error("Failed to fetch user", user_id=user_id, error=str(e))
318
+ raise
319
+ finally:
320
+ elapsed = time.perf_counter() - start
321
+ self.metrics.timing("user.fetch.duration", elapsed)
322
+
323
+ # Easy to test with fakes
324
+ service = UserService(
325
+ repository=FakeRepository(),
326
+ logger=FakeLogger(),
327
+ metrics=FakeMetrics(),
328
+ )
329
+ ```
330
+
331
+ ### Pattern 9: Fail-Safe Defaults
332
+
333
+ Degrade gracefully when non-critical operations fail.
334
+
335
+ ```python
336
+ from typing import TypeVar
337
+ from collections.abc import Callable
338
+
339
+ T = TypeVar("T")
340
+
341
+ def fail_safe(default: T, log_failure: bool = True):
342
+ """Return default value on failure instead of raising."""
343
+ def decorator(func: Callable[..., T]) -> Callable[..., T]:
344
+ @wraps(func)
345
+ async def wrapper(*args, **kwargs) -> T:
346
+ try:
347
+ return await func(*args, **kwargs)
348
+ except Exception as e:
349
+ if log_failure:
350
+ logger.warning(
351
+ "Operation failed, using default",
352
+ function=func.__name__,
353
+ error=str(e),
354
+ )
355
+ return default
356
+ return wrapper
357
+ return decorator
358
+
359
+ @fail_safe(default=[])
360
+ async def get_recommendations(user_id: str) -> list[str]:
361
+ """Get recommendations, return empty list on failure."""
362
+ ...
363
+ ```
364
+
365
+ ## Best Practices Summary
366
+
367
+ 1. **Retry only transient errors** - Don't retry bugs or authentication failures
368
+ 2. **Use exponential backoff** - Give services time to recover
369
+ 3. **Add jitter** - Prevent thundering herd from synchronized retries
370
+ 4. **Cap total duration** - `stop_after_attempt(5) | stop_after_delay(60)`
371
+ 5. **Log every retry** - Silent retries hide systemic problems
372
+ 6. **Use decorators** - Keep retry logic separate from business logic
373
+ 7. **Inject dependencies** - Make infrastructure testable
374
+ 8. **Set timeouts everywhere** - Every network call needs a timeout
375
+ 9. **Fail gracefully** - Return cached/default values for non-critical paths
376
+ 10. **Monitor retry rates** - High retry rates indicate underlying issues