@mytechtoday/augment-extensions 0.7.0 → 1.2.1

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 (483) hide show
  1. package/AGENTS.md +265 -232
  2. package/README.md +956 -771
  3. package/augment-extensions/coding-standards/bash/README.md +196 -196
  4. package/augment-extensions/coding-standards/bash/module.json +163 -163
  5. package/augment-extensions/coding-standards/bash/rules/naming-conventions.md +336 -336
  6. package/augment-extensions/coding-standards/bash/rules/universal-standards.md +289 -289
  7. package/augment-extensions/coding-standards/css/README.md +40 -40
  8. package/augment-extensions/coding-standards/css/examples/css-examples.css +550 -550
  9. package/augment-extensions/coding-standards/css/module.json +44 -44
  10. package/augment-extensions/coding-standards/css/rules/css-modern-features.md +448 -448
  11. package/augment-extensions/coding-standards/css/rules/css-standards.md +492 -492
  12. package/augment-extensions/coding-standards/html/README.md +40 -40
  13. package/augment-extensions/coding-standards/html/examples/html-examples.html +267 -267
  14. package/augment-extensions/coding-standards/html/examples/responsive-layout.html +505 -505
  15. package/augment-extensions/coding-standards/html/module.json +44 -44
  16. package/augment-extensions/coding-standards/html/rules/html-standards.md +349 -349
  17. package/augment-extensions/coding-standards/html-css-js/README.md +194 -194
  18. package/augment-extensions/coding-standards/html-css-js/examples/async-examples.js +487 -487
  19. package/augment-extensions/coding-standards/html-css-js/examples/css-examples.css +550 -550
  20. package/augment-extensions/coding-standards/html-css-js/examples/dom-examples.js +667 -667
  21. package/augment-extensions/coding-standards/html-css-js/examples/html-examples.html +267 -267
  22. package/augment-extensions/coding-standards/html-css-js/examples/javascript-examples.js +612 -612
  23. package/augment-extensions/coding-standards/html-css-js/examples/responsive-layout.html +505 -505
  24. package/augment-extensions/coding-standards/html-css-js/module.json +48 -48
  25. package/augment-extensions/coding-standards/html-css-js/rules/async-patterns.md +515 -515
  26. package/augment-extensions/coding-standards/html-css-js/rules/css-modern-features.md +448 -448
  27. package/augment-extensions/coding-standards/html-css-js/rules/css-standards.md +492 -492
  28. package/augment-extensions/coding-standards/html-css-js/rules/dom-manipulation.md +439 -439
  29. package/augment-extensions/coding-standards/html-css-js/rules/html-standards.md +349 -349
  30. package/augment-extensions/coding-standards/html-css-js/rules/javascript-standards.md +486 -486
  31. package/augment-extensions/coding-standards/html-css-js/rules/performance.md +463 -463
  32. package/augment-extensions/coding-standards/html-css-js/rules/tooling.md +543 -543
  33. package/augment-extensions/coding-standards/js/README.md +46 -46
  34. package/augment-extensions/coding-standards/js/examples/async-examples.js +487 -487
  35. package/augment-extensions/coding-standards/js/examples/dom-examples.js +667 -667
  36. package/augment-extensions/coding-standards/js/examples/javascript-examples.js +612 -612
  37. package/augment-extensions/coding-standards/js/module.json +49 -49
  38. package/augment-extensions/coding-standards/js/rules/async-patterns.md +515 -515
  39. package/augment-extensions/coding-standards/js/rules/dom-manipulation.md +439 -439
  40. package/augment-extensions/coding-standards/js/rules/javascript-standards.md +486 -486
  41. package/augment-extensions/coding-standards/js/rules/performance.md +463 -463
  42. package/augment-extensions/coding-standards/js/rules/tooling.md +543 -543
  43. package/augment-extensions/coding-standards/php/README.md +248 -248
  44. package/augment-extensions/coding-standards/php/examples/api-endpoint-example.php +204 -204
  45. package/augment-extensions/coding-standards/php/examples/cli-command-example.php +206 -206
  46. package/augment-extensions/coding-standards/php/examples/legacy-refactoring-example.php +234 -234
  47. package/augment-extensions/coding-standards/php/examples/web-application-example.php +211 -211
  48. package/augment-extensions/coding-standards/php/examples/woocommerce-extension-example.php +215 -215
  49. package/augment-extensions/coding-standards/php/examples/wordpress-plugin-example.php +189 -189
  50. package/augment-extensions/coding-standards/php/module.json +166 -166
  51. package/augment-extensions/coding-standards/php/rules/api-development.md +480 -480
  52. package/augment-extensions/coding-standards/php/rules/category-configuration.md +332 -332
  53. package/augment-extensions/coding-standards/php/rules/cli-tools.md +472 -472
  54. package/augment-extensions/coding-standards/php/rules/cms-integration.md +561 -561
  55. package/augment-extensions/coding-standards/php/rules/code-quality.md +402 -402
  56. package/augment-extensions/coding-standards/php/rules/documentation.md +425 -425
  57. package/augment-extensions/coding-standards/php/rules/ecommerce.md +627 -627
  58. package/augment-extensions/coding-standards/php/rules/error-handling.md +336 -336
  59. package/augment-extensions/coding-standards/php/rules/legacy-migration.md +677 -677
  60. package/augment-extensions/coding-standards/php/rules/naming-conventions.md +279 -279
  61. package/augment-extensions/coding-standards/php/rules/performance.md +392 -392
  62. package/augment-extensions/coding-standards/php/rules/psr-standards.md +186 -186
  63. package/augment-extensions/coding-standards/php/rules/security.md +358 -358
  64. package/augment-extensions/coding-standards/php/rules/testing.md +403 -403
  65. package/augment-extensions/coding-standards/php/rules/type-declarations.md +331 -331
  66. package/augment-extensions/coding-standards/php/rules/web-applications.md +426 -426
  67. package/augment-extensions/coding-standards/powershell/README.md +154 -154
  68. package/augment-extensions/coding-standards/powershell/examples/admin-example.ps1 +272 -272
  69. package/augment-extensions/coding-standards/powershell/examples/automation-example.ps1 +173 -173
  70. package/augment-extensions/coding-standards/powershell/examples/cloud-example.ps1 +243 -243
  71. package/augment-extensions/coding-standards/powershell/examples/cross-platform-example.ps1 +297 -297
  72. package/augment-extensions/coding-standards/powershell/examples/dsc-example.ps1 +224 -224
  73. package/augment-extensions/coding-standards/powershell/examples/legacy-migration-example.ps1 +340 -340
  74. package/augment-extensions/coding-standards/powershell/examples/module-example.psm1 +255 -255
  75. package/augment-extensions/coding-standards/powershell/module.json +165 -165
  76. package/augment-extensions/coding-standards/powershell/rules/administrative-tools.md +439 -439
  77. package/augment-extensions/coding-standards/powershell/rules/automation-scripts.md +240 -240
  78. package/augment-extensions/coding-standards/powershell/rules/cloud-orchestration.md +384 -384
  79. package/augment-extensions/coding-standards/powershell/rules/configuration-schema.md +383 -383
  80. package/augment-extensions/coding-standards/powershell/rules/cross-platform-scripts.md +482 -482
  81. package/augment-extensions/coding-standards/powershell/rules/dsc-configurations.md +296 -296
  82. package/augment-extensions/coding-standards/powershell/rules/error-handling.md +314 -314
  83. package/augment-extensions/coding-standards/powershell/rules/legacy-migrations.md +466 -466
  84. package/augment-extensions/coding-standards/powershell/rules/modules-functions.md +244 -244
  85. package/augment-extensions/coding-standards/powershell/rules/naming-conventions.md +266 -266
  86. package/augment-extensions/coding-standards/powershell/rules/performance-optimization.md +209 -209
  87. package/augment-extensions/coding-standards/powershell/rules/security-practices.md +314 -314
  88. package/augment-extensions/coding-standards/powershell/rules/testing-guidelines.md +268 -268
  89. package/augment-extensions/coding-standards/powershell/rules/universal-standards.md +197 -197
  90. package/augment-extensions/coding-standards/python/README.md +48 -48
  91. package/augment-extensions/coding-standards/python/examples/best-practices.py +373 -373
  92. package/augment-extensions/coding-standards/python/module.json +30 -30
  93. package/augment-extensions/coding-standards/python/rules/async-patterns.md +884 -884
  94. package/augment-extensions/coding-standards/python/rules/best-practices.md +232 -232
  95. package/augment-extensions/coding-standards/python/rules/code-organization.md +220 -220
  96. package/augment-extensions/coding-standards/python/rules/documentation.md +831 -831
  97. package/augment-extensions/coding-standards/python/rules/error-handling.md +1008 -1008
  98. package/augment-extensions/coding-standards/python/rules/naming-conventions.md +172 -172
  99. package/augment-extensions/coding-standards/python/rules/testing.md +409 -409
  100. package/augment-extensions/coding-standards/python/rules/tooling.md +446 -446
  101. package/augment-extensions/coding-standards/python/rules/type-hints.md +253 -253
  102. package/augment-extensions/coding-standards/react/README.md +45 -45
  103. package/augment-extensions/coding-standards/react/module.json +27 -27
  104. package/augment-extensions/coding-standards/react/rules/component-patterns.md +214 -214
  105. package/augment-extensions/coding-standards/react/rules/hooks-best-practices.md +235 -235
  106. package/augment-extensions/coding-standards/react/rules/performance.md +300 -300
  107. package/augment-extensions/coding-standards/react/rules/state-management.md +265 -265
  108. package/augment-extensions/coding-standards/react/rules/typescript-react.md +271 -271
  109. package/augment-extensions/coding-standards/typescript/README.md +45 -45
  110. package/augment-extensions/coding-standards/typescript/module.json +27 -27
  111. package/augment-extensions/coding-standards/typescript/rules/naming-conventions.md +225 -225
  112. package/augment-extensions/collections/html-css-js/README.md +82 -82
  113. package/augment-extensions/collections/html-css-js/collection.json +41 -41
  114. package/augment-extensions/domain-rules/api-design/README.md +41 -41
  115. package/augment-extensions/domain-rules/api-design/module.json +27 -27
  116. package/augment-extensions/domain-rules/api-design/rules/authentication.md +263 -263
  117. package/augment-extensions/domain-rules/api-design/rules/documentation.md +395 -395
  118. package/augment-extensions/domain-rules/api-design/rules/error-handling.md +290 -290
  119. package/augment-extensions/domain-rules/api-design/rules/graphql-api.md +313 -313
  120. package/augment-extensions/domain-rules/api-design/rules/rest-api.md +214 -214
  121. package/augment-extensions/domain-rules/api-design/rules/versioning.md +268 -268
  122. package/augment-extensions/domain-rules/database/README.md +161 -161
  123. package/augment-extensions/domain-rules/database/examples/flat-database-example.md +793 -793
  124. package/augment-extensions/domain-rules/database/examples/hybrid-database-example.md +1132 -1132
  125. package/augment-extensions/domain-rules/database/examples/nosql-document-example.md +868 -868
  126. package/augment-extensions/domain-rules/database/examples/nosql-graph-example.md +805 -805
  127. package/augment-extensions/domain-rules/database/examples/relational-schema-example.md +621 -621
  128. package/augment-extensions/domain-rules/database/examples/vector-database-example.md +965 -965
  129. package/augment-extensions/domain-rules/database/module.json +28 -28
  130. package/augment-extensions/domain-rules/database/rules/flat-databases.md +624 -624
  131. package/augment-extensions/domain-rules/database/rules/nosql-databases.md +588 -588
  132. package/augment-extensions/domain-rules/database/rules/nosql-document-stores.md +856 -856
  133. package/augment-extensions/domain-rules/database/rules/nosql-graph-databases.md +778 -778
  134. package/augment-extensions/domain-rules/database/rules/nosql-key-value-stores.md +963 -963
  135. package/augment-extensions/domain-rules/database/rules/performance-optimization.md +1076 -1076
  136. package/augment-extensions/domain-rules/database/rules/relational-databases.md +697 -697
  137. package/augment-extensions/domain-rules/database/rules/relational-indexing.md +671 -671
  138. package/augment-extensions/domain-rules/database/rules/relational-query-optimization.md +607 -607
  139. package/augment-extensions/domain-rules/database/rules/relational-schema-design.md +907 -907
  140. package/augment-extensions/domain-rules/database/rules/relational-transactions.md +783 -783
  141. package/augment-extensions/domain-rules/database/rules/security-standards.md +980 -980
  142. package/augment-extensions/domain-rules/database/rules/universal-best-practices.md +485 -485
  143. package/augment-extensions/domain-rules/database/rules/vector-databases.md +521 -521
  144. package/augment-extensions/domain-rules/database/rules/vector-embeddings.md +858 -858
  145. package/augment-extensions/domain-rules/database/rules/vector-indexing.md +934 -934
  146. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/README.md +23 -23
  147. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/module.json +26 -26
  148. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/README.md +23 -23
  149. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/module.json +26 -26
  150. package/augment-extensions/domain-rules/design/color/themes/dracula/README.md +23 -23
  151. package/augment-extensions/domain-rules/design/color/themes/dracula/module.json +26 -26
  152. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/README.md +23 -23
  153. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/module.json +26 -26
  154. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/README.md +23 -23
  155. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/module.json +26 -26
  156. package/augment-extensions/domain-rules/design/color/themes/high-contrast/README.md +27 -27
  157. package/augment-extensions/domain-rules/design/color/themes/high-contrast/module.json +26 -26
  158. package/augment-extensions/domain-rules/design/color/themes/monokai/README.md +23 -23
  159. package/augment-extensions/domain-rules/design/color/themes/monokai/module.json +26 -26
  160. package/augment-extensions/domain-rules/design/color/themes/nord/README.md +23 -23
  161. package/augment-extensions/domain-rules/design/color/themes/nord/module.json +26 -26
  162. package/augment-extensions/domain-rules/design/color/themes/one-dark/README.md +23 -23
  163. package/augment-extensions/domain-rules/design/color/themes/one-dark/module.json +26 -26
  164. package/augment-extensions/domain-rules/design/color/themes/one-light/README.md +23 -23
  165. package/augment-extensions/domain-rules/design/color/themes/one-light/module.json +26 -26
  166. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/README.md +23 -23
  167. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/module.json +26 -26
  168. package/augment-extensions/domain-rules/design/color/themes/solarized-light/README.md +23 -23
  169. package/augment-extensions/domain-rules/design/color/themes/solarized-light/module.json +26 -26
  170. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/README.md +23 -23
  171. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/module.json +26 -26
  172. package/augment-extensions/domain-rules/mcp/README.md +150 -150
  173. package/augment-extensions/domain-rules/mcp/examples/compressed-example.md +522 -522
  174. package/augment-extensions/domain-rules/mcp/examples/graph-augmented-example.md +520 -520
  175. package/augment-extensions/domain-rules/mcp/examples/hybrid-example.md +570 -570
  176. package/augment-extensions/domain-rules/mcp/examples/state-based-example.md +427 -427
  177. package/augment-extensions/domain-rules/mcp/examples/token-based-example.md +435 -435
  178. package/augment-extensions/domain-rules/mcp/examples/vector-based-example.md +502 -502
  179. package/augment-extensions/domain-rules/mcp/module.json +49 -49
  180. package/augment-extensions/domain-rules/mcp/rules/compressed-mcp.md +595 -595
  181. package/augment-extensions/domain-rules/mcp/rules/configuration.md +345 -345
  182. package/augment-extensions/domain-rules/mcp/rules/graph-augmented-mcp.md +687 -687
  183. package/augment-extensions/domain-rules/mcp/rules/hybrid-mcp.md +636 -636
  184. package/augment-extensions/domain-rules/mcp/rules/state-based-mcp.md +484 -484
  185. package/augment-extensions/domain-rules/mcp/rules/testing-validation.md +360 -360
  186. package/augment-extensions/domain-rules/mcp/rules/token-based-mcp.md +393 -393
  187. package/augment-extensions/domain-rules/mcp/rules/universal-rules.md +194 -194
  188. package/augment-extensions/domain-rules/mcp/rules/vector-based-mcp.md +625 -625
  189. package/augment-extensions/domain-rules/security/README.md +41 -41
  190. package/augment-extensions/domain-rules/security/module.json +28 -28
  191. package/augment-extensions/domain-rules/security/rules/authentication-security.md +361 -361
  192. package/augment-extensions/domain-rules/security/rules/encryption.md +208 -208
  193. package/augment-extensions/domain-rules/security/rules/input-validation.md +294 -294
  194. package/augment-extensions/domain-rules/security/rules/owasp-top-10.md +339 -339
  195. package/augment-extensions/domain-rules/security/rules/secure-coding.md +293 -293
  196. package/augment-extensions/domain-rules/security/rules/web-security.md +268 -268
  197. package/augment-extensions/domain-rules/seo-sales-marketing/ANNOUNCEMENT.md +143 -0
  198. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/README.md +140 -136
  199. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/SCHEMA-VALIDATION-REPORT.md +216 -216
  200. package/augment-extensions/domain-rules/seo-sales-marketing/TEST-VALIDATION.md +129 -0
  201. package/augment-extensions/domain-rules/seo-sales-marketing/USAGE-GUIDES.md +254 -0
  202. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/brand-kit-example.yaml +292 -292
  203. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/campaign-brief-example.yaml +389 -389
  204. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/content-calendar-example.yaml +643 -643
  205. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/email-newsletter-example.md +376 -376
  206. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/landing-page-example.md +934 -934
  207. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/ppc-ad-copy-example.md +301 -301
  208. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/seo-blog-post-example.md +347 -347
  209. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/examples/social-media-campaign-example.md +606 -606
  210. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/module.json +50 -50
  211. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/affiliate-influencer-marketing.md +593 -593
  212. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/asset-management.md +418 -418
  213. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/brand-consistency.md +210 -210
  214. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/content-marketing.md +337 -337
  215. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/conversion-optimization.md +455 -455
  216. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/direct-sales.md +499 -499
  217. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/email-marketing.md +439 -439
  218. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/legal-compliance.md +227 -227
  219. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/ppc-advertising.md +569 -569
  220. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/seo-optimization.md +470 -470
  221. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/social-media-marketing.md +414 -414
  222. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/rules/universal-marketing.md +177 -177
  223. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/schemas/asset-inventory.schema.json +247 -247
  224. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/schemas/brand-kit.schema.json +326 -326
  225. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/schemas/campaign-brief.schema.json +342 -342
  226. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/schemas/color-palette.schema.json +223 -223
  227. package/augment-extensions/domain-rules/{marketing-standards/seo-sales-marketing → seo-sales-marketing}/schemas/content-template.schema.json +383 -383
  228. package/augment-extensions/domain-rules/wordpress/README.md +163 -163
  229. package/augment-extensions/domain-rules/wordpress/module.json +32 -32
  230. package/augment-extensions/domain-rules/wordpress/rules/coding-standards.md +617 -617
  231. package/augment-extensions/domain-rules/wordpress/rules/directory-structure.md +270 -270
  232. package/augment-extensions/domain-rules/wordpress/rules/file-patterns.md +423 -423
  233. package/augment-extensions/domain-rules/wordpress/rules/gutenberg-blocks.md +493 -493
  234. package/augment-extensions/domain-rules/wordpress/rules/performance.md +568 -568
  235. package/augment-extensions/domain-rules/wordpress/rules/plugin-development.md +510 -510
  236. package/augment-extensions/domain-rules/wordpress/rules/project-detection.md +251 -251
  237. package/augment-extensions/domain-rules/wordpress/rules/rest-api.md +501 -501
  238. package/augment-extensions/domain-rules/wordpress/rules/security.md +564 -564
  239. package/augment-extensions/domain-rules/wordpress/rules/theme-development.md +388 -388
  240. package/augment-extensions/domain-rules/wordpress/rules/woocommerce.md +441 -441
  241. package/augment-extensions/domain-rules/wordpress-plugin/README.md +139 -139
  242. package/augment-extensions/domain-rules/wordpress-plugin/examples/ajax-plugin.md +1599 -1599
  243. package/augment-extensions/domain-rules/wordpress-plugin/examples/custom-post-type-plugin.md +1727 -1727
  244. package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block-plugin.md +428 -428
  245. package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block.md +422 -422
  246. package/augment-extensions/domain-rules/wordpress-plugin/examples/mvc-plugin.md +1623 -1623
  247. package/augment-extensions/domain-rules/wordpress-plugin/examples/object-oriented-plugin.md +1343 -1343
  248. package/augment-extensions/domain-rules/wordpress-plugin/examples/rest-endpoint.md +734 -734
  249. package/augment-extensions/domain-rules/wordpress-plugin/examples/settings-page-plugin.md +1350 -1350
  250. package/augment-extensions/domain-rules/wordpress-plugin/examples/simple-procedural-plugin.md +503 -503
  251. package/augment-extensions/domain-rules/wordpress-plugin/examples/singleton-plugin.md +971 -971
  252. package/augment-extensions/domain-rules/wordpress-plugin/module.json +53 -53
  253. package/augment-extensions/domain-rules/wordpress-plugin/rules/activation-hooks.md +770 -770
  254. package/augment-extensions/domain-rules/wordpress-plugin/rules/admin-interface.md +874 -874
  255. package/augment-extensions/domain-rules/wordpress-plugin/rules/ajax-handlers.md +629 -629
  256. package/augment-extensions/domain-rules/wordpress-plugin/rules/asset-management.md +559 -559
  257. package/augment-extensions/domain-rules/wordpress-plugin/rules/context-providers.md +709 -709
  258. package/augment-extensions/domain-rules/wordpress-plugin/rules/cron-jobs.md +736 -736
  259. package/augment-extensions/domain-rules/wordpress-plugin/rules/database-management.md +1057 -1057
  260. package/augment-extensions/domain-rules/wordpress-plugin/rules/documentation-standards.md +463 -463
  261. package/augment-extensions/domain-rules/wordpress-plugin/rules/frontend-functionality.md +478 -478
  262. package/augment-extensions/domain-rules/wordpress-plugin/rules/gutenberg-blocks.md +818 -818
  263. package/augment-extensions/domain-rules/wordpress-plugin/rules/internationalization.md +416 -416
  264. package/augment-extensions/domain-rules/wordpress-plugin/rules/migration.md +667 -667
  265. package/augment-extensions/domain-rules/wordpress-plugin/rules/performance-optimization.md +878 -878
  266. package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-architecture.md +693 -693
  267. package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-structure.md +352 -352
  268. package/augment-extensions/domain-rules/wordpress-plugin/rules/rest-api.md +818 -818
  269. package/augment-extensions/domain-rules/wordpress-plugin/rules/scaffolding-workflow.md +624 -624
  270. package/augment-extensions/domain-rules/wordpress-plugin/rules/security-best-practices.md +866 -866
  271. package/augment-extensions/domain-rules/wordpress-plugin/rules/testing-patterns.md +1165 -1165
  272. package/augment-extensions/domain-rules/wordpress-plugin/rules/testing.md +414 -414
  273. package/augment-extensions/domain-rules/wordpress-plugin/rules/vscode-integration.md +751 -751
  274. package/augment-extensions/domain-rules/wordpress-plugin/rules/woocommerce-integration.md +949 -949
  275. package/augment-extensions/domain-rules/wordpress-plugin/rules/wordpress-org-submission.md +458 -458
  276. package/augment-extensions/examples/design-patterns/README.md +37 -37
  277. package/augment-extensions/examples/design-patterns/examples/behavioral-patterns.md +370 -370
  278. package/augment-extensions/examples/design-patterns/examples/creational-patterns.md +250 -250
  279. package/augment-extensions/examples/design-patterns/examples/structural-patterns.md +264 -264
  280. package/augment-extensions/examples/design-patterns/module.json +27 -27
  281. package/augment-extensions/examples/gutenberg-block-plugin/README.md +101 -101
  282. package/augment-extensions/examples/gutenberg-block-plugin/examples/testimonial-block.md +428 -428
  283. package/augment-extensions/examples/gutenberg-block-plugin/module.json +40 -40
  284. package/augment-extensions/examples/rest-api-plugin/README.md +98 -98
  285. package/augment-extensions/examples/rest-api-plugin/examples/task-manager-api.md +1299 -1299
  286. package/augment-extensions/examples/rest-api-plugin/module.json +40 -40
  287. package/augment-extensions/examples/woocommerce-extension/README.md +98 -98
  288. package/augment-extensions/examples/woocommerce-extension/examples/product-customizer.md +763 -763
  289. package/augment-extensions/examples/woocommerce-extension/module.json +40 -40
  290. package/augment-extensions/workflows/beads/README.md +135 -135
  291. package/augment-extensions/workflows/beads/examples/complete-workflow-example.md +278 -278
  292. package/augment-extensions/workflows/beads/module.json +55 -55
  293. package/augment-extensions/workflows/beads/rules/best-practices.md +398 -398
  294. package/augment-extensions/workflows/beads/rules/file-format.md +327 -327
  295. package/augment-extensions/workflows/beads/rules/manual-setup.md +315 -315
  296. package/augment-extensions/workflows/beads/rules/workflow.md +326 -326
  297. package/augment-extensions/workflows/beads-integration/IMPLEMENTATION-STATUS.md +145 -145
  298. package/augment-extensions/workflows/beads-integration/README.md +143 -143
  299. package/augment-extensions/workflows/beads-integration/config/defaults.json +32 -32
  300. package/augment-extensions/workflows/beads-integration/config/schema.json +140 -140
  301. package/augment-extensions/workflows/beads-integration/examples/basic-task-generation.md +293 -293
  302. package/augment-extensions/workflows/beads-integration/module.json +75 -75
  303. package/augment-extensions/workflows/beads-integration/rules/core-rules.md +219 -219
  304. package/augment-extensions/workflows/beads-integration/rules/effectiveness-standards.md +256 -256
  305. package/augment-extensions/workflows/beads-integration/rules/task-generation.md +607 -607
  306. package/augment-extensions/workflows/database/README.md +195 -195
  307. package/augment-extensions/workflows/database/ai-prompt-testing.md +295 -295
  308. package/augment-extensions/workflows/database/examples/migration-example.md +498 -498
  309. package/augment-extensions/workflows/database/examples/optimization-example.md +496 -496
  310. package/augment-extensions/workflows/database/examples/schema-design-example.md +444 -444
  311. package/augment-extensions/workflows/database/module.json +42 -42
  312. package/augment-extensions/workflows/database/rules/data-migration.md +249 -249
  313. package/augment-extensions/workflows/database/rules/documentation-standards.md +339 -339
  314. package/augment-extensions/workflows/database/rules/migration-workflow.md +352 -352
  315. package/augment-extensions/workflows/database/rules/optimization-workflow.md +435 -435
  316. package/augment-extensions/workflows/database/rules/schema-design-workflow.md +535 -535
  317. package/augment-extensions/workflows/database/rules/testing-patterns.md +305 -305
  318. package/augment-extensions/workflows/database/rules/workflow.md +458 -458
  319. package/augment-extensions/workflows/wordpress-plugin/README.md +232 -232
  320. package/augment-extensions/workflows/wordpress-plugin/ai-prompts.md +839 -839
  321. package/augment-extensions/workflows/wordpress-plugin/bead-decomposition-patterns.md +854 -854
  322. package/augment-extensions/workflows/wordpress-plugin/examples/complete-plugin-example.md +540 -540
  323. package/augment-extensions/workflows/wordpress-plugin/examples/custom-post-type-example.md +1083 -1083
  324. package/augment-extensions/workflows/wordpress-plugin/examples/feature-addition-workflow.md +669 -669
  325. package/augment-extensions/workflows/wordpress-plugin/examples/plugin-creation-workflow.md +597 -597
  326. package/augment-extensions/workflows/wordpress-plugin/examples/secure-form-handler-example.md +925 -925
  327. package/augment-extensions/workflows/wordpress-plugin/examples/security-audit-workflow.md +752 -752
  328. package/augment-extensions/workflows/wordpress-plugin/examples/wordpress-org-submission-workflow.md +773 -773
  329. package/augment-extensions/workflows/wordpress-plugin/module.json +49 -49
  330. package/augment-extensions/workflows/wordpress-plugin/rules/best-practices.md +942 -942
  331. package/augment-extensions/workflows/wordpress-plugin/rules/development-workflow.md +702 -702
  332. package/augment-extensions/workflows/wordpress-plugin/rules/submission-workflow.md +728 -728
  333. package/augment-extensions/workflows/wordpress-plugin/rules/testing-workflow.md +775 -775
  334. package/augment-extensions/writing-standards/screenplay/README.md +339 -300
  335. package/augment-extensions/writing-standards/screenplay/_templates/README.md +121 -121
  336. package/augment-extensions/writing-standards/screenplay/_templates/genre-template.md +153 -153
  337. package/augment-extensions/writing-standards/screenplay/_templates/style-template.md +243 -243
  338. package/augment-extensions/writing-standards/screenplay/_templates/theme-template.md +213 -213
  339. package/augment-extensions/writing-standards/screenplay/examples/aaa-hollywood-scene.fountain +164 -164
  340. package/augment-extensions/writing-standards/screenplay/examples/beat-sheet-example.yaml +95 -95
  341. package/augment-extensions/writing-standards/screenplay/examples/character-profile-example.yaml +116 -116
  342. package/augment-extensions/writing-standards/screenplay/examples/commercial-30sec.fountain +151 -151
  343. package/augment-extensions/writing-standards/screenplay/examples/independent-monologue.fountain +67 -67
  344. package/augment-extensions/writing-standards/screenplay/examples/news-segment.fountain +142 -142
  345. package/augment-extensions/writing-standards/screenplay/examples/plot-outline-example.yaml +184 -184
  346. package/augment-extensions/writing-standards/screenplay/examples/tv-episode-teaser.fountain +204 -204
  347. package/augment-extensions/writing-standards/screenplay/genres/README.md +181 -181
  348. package/augment-extensions/writing-standards/screenplay/genres/examples/.gitkeep +2 -2
  349. package/augment-extensions/writing-standards/screenplay/genres/module.json +70 -70
  350. package/augment-extensions/writing-standards/screenplay/genres/rules/.gitkeep +2 -2
  351. package/augment-extensions/writing-standards/screenplay/genres/rules/action.md +399 -399
  352. package/augment-extensions/writing-standards/screenplay/genres/rules/adventure.md +407 -407
  353. package/augment-extensions/writing-standards/screenplay/genres/rules/animation.md +293 -293
  354. package/augment-extensions/writing-standards/screenplay/genres/rules/biographical.md +293 -293
  355. package/augment-extensions/writing-standards/screenplay/genres/rules/comedy.md +401 -401
  356. package/augment-extensions/writing-standards/screenplay/genres/rules/documentary.md +293 -293
  357. package/augment-extensions/writing-standards/screenplay/genres/rules/drama.md +409 -409
  358. package/augment-extensions/writing-standards/screenplay/genres/rules/fantasy.md +293 -293
  359. package/augment-extensions/writing-standards/screenplay/genres/rules/historical.md +293 -293
  360. package/augment-extensions/writing-standards/screenplay/genres/rules/horror.md +268 -268
  361. package/augment-extensions/writing-standards/screenplay/genres/rules/musical.md +294 -294
  362. package/augment-extensions/writing-standards/screenplay/genres/rules/mystery.md +293 -293
  363. package/augment-extensions/writing-standards/screenplay/genres/rules/noir.md +294 -294
  364. package/augment-extensions/writing-standards/screenplay/genres/rules/romance.md +293 -293
  365. package/augment-extensions/writing-standards/screenplay/genres/rules/sci-fi.md +289 -289
  366. package/augment-extensions/writing-standards/screenplay/genres/rules/superhero.md +293 -293
  367. package/augment-extensions/writing-standards/screenplay/genres/rules/thriller.md +294 -294
  368. package/augment-extensions/writing-standards/screenplay/genres/rules/western.md +293 -293
  369. package/augment-extensions/writing-standards/screenplay/module.json +124 -124
  370. package/augment-extensions/writing-standards/screenplay/rules/aaa-hollywood-films.md +339 -339
  371. package/augment-extensions/writing-standards/screenplay/rules/ai-integration-testing.md +329 -329
  372. package/augment-extensions/writing-standards/screenplay/rules/character-development.md +169 -169
  373. package/augment-extensions/writing-standards/screenplay/rules/commercials.md +437 -437
  374. package/augment-extensions/writing-standards/screenplay/rules/dialogue-writing.md +263 -263
  375. package/augment-extensions/writing-standards/screenplay/rules/diversity-inclusion.md +261 -261
  376. package/augment-extensions/writing-standards/screenplay/rules/examples-guide.md +315 -315
  377. package/augment-extensions/writing-standards/screenplay/rules/file-organization.md +213 -0
  378. package/augment-extensions/writing-standards/screenplay/rules/formatting-validation.md +413 -413
  379. package/augment-extensions/writing-standards/screenplay/rules/fountain-format.md +372 -372
  380. package/augment-extensions/writing-standards/screenplay/rules/independent-films.md +374 -374
  381. package/augment-extensions/writing-standards/screenplay/rules/live-tv-productions.md +443 -443
  382. package/augment-extensions/writing-standards/screenplay/rules/narrative-structures.md +207 -207
  383. package/augment-extensions/writing-standards/screenplay/rules/news-broadcasts.md +444 -444
  384. package/augment-extensions/writing-standards/screenplay/rules/pacing-timing.md +331 -331
  385. package/augment-extensions/writing-standards/screenplay/rules/quality-review-checklist.md +334 -334
  386. package/augment-extensions/writing-standards/screenplay/rules/quick-reference.md +299 -299
  387. package/augment-extensions/writing-standards/screenplay/rules/screen-continuity.md +263 -263
  388. package/augment-extensions/writing-standards/screenplay/rules/streaming-content.md +412 -412
  389. package/augment-extensions/writing-standards/screenplay/rules/trope-management.md +370 -370
  390. package/augment-extensions/writing-standards/screenplay/rules/tv-series.md +374 -374
  391. package/augment-extensions/writing-standards/screenplay/rules/universal-formatting.md +339 -339
  392. package/augment-extensions/writing-standards/screenplay/rules/vscode-integration.md +277 -277
  393. package/augment-extensions/writing-standards/screenplay/rules/web-content.md +393 -393
  394. package/augment-extensions/writing-standards/screenplay/schemas/beat-sheet.json +332 -332
  395. package/augment-extensions/writing-standards/screenplay/schemas/character-profile.json +247 -247
  396. package/augment-extensions/writing-standards/screenplay/schemas/feature-selection.json +200 -200
  397. package/augment-extensions/writing-standards/screenplay/schemas/plot-outline.json +233 -233
  398. package/augment-extensions/writing-standards/screenplay/schemas/screenplay-config.json +245 -245
  399. package/augment-extensions/writing-standards/screenplay/schemas/trope-inventory.json +221 -221
  400. package/augment-extensions/writing-standards/screenplay/styles/README.md +159 -159
  401. package/augment-extensions/writing-standards/screenplay/styles/examples/.gitkeep +2 -2
  402. package/augment-extensions/writing-standards/screenplay/styles/examples/style-applications.md +1449 -1449
  403. package/augment-extensions/writing-standards/screenplay/styles/module.json +64 -64
  404. package/augment-extensions/writing-standards/screenplay/styles/rules/.gitkeep +2 -2
  405. package/augment-extensions/writing-standards/screenplay/styles/rules/dialogue-centric.md +520 -520
  406. package/augment-extensions/writing-standards/screenplay/styles/rules/ensemble.md +499 -499
  407. package/augment-extensions/writing-standards/screenplay/styles/rules/epic.md +497 -497
  408. package/augment-extensions/writing-standards/screenplay/styles/rules/experimental.md +492 -492
  409. package/augment-extensions/writing-standards/screenplay/styles/rules/flashback.md +509 -509
  410. package/augment-extensions/writing-standards/screenplay/styles/rules/linear.md +490 -490
  411. package/augment-extensions/writing-standards/screenplay/styles/rules/minimalist.md +499 -499
  412. package/augment-extensions/writing-standards/screenplay/styles/rules/non-linear.md +501 -501
  413. package/augment-extensions/writing-standards/screenplay/styles/rules/poetic.md +499 -499
  414. package/augment-extensions/writing-standards/screenplay/styles/rules/realistic.md +498 -498
  415. package/augment-extensions/writing-standards/screenplay/styles/rules/satirical.md +499 -499
  416. package/augment-extensions/writing-standards/screenplay/styles/rules/surreal.md +508 -508
  417. package/augment-extensions/writing-standards/screenplay/styles/rules/voice-over.md +500 -500
  418. package/augment-extensions/writing-standards/screenplay/themes/README.md +158 -158
  419. package/augment-extensions/writing-standards/screenplay/themes/examples/.gitkeep +2 -2
  420. package/augment-extensions/writing-standards/screenplay/themes/examples/common-mistakes-and-fixes.md +643 -643
  421. package/augment-extensions/writing-standards/screenplay/themes/examples/complete-scene-example.md +311 -311
  422. package/augment-extensions/writing-standards/screenplay/themes/examples/individual-theme-examples.md +562 -562
  423. package/augment-extensions/writing-standards/screenplay/themes/examples/multi-theme-weaving.md +538 -538
  424. package/augment-extensions/writing-standards/screenplay/themes/examples/theme-application-guide.md +432 -432
  425. package/augment-extensions/writing-standards/screenplay/themes/examples/theme-integration-across-acts.md +637 -637
  426. package/augment-extensions/writing-standards/screenplay/themes/module.json +66 -66
  427. package/augment-extensions/writing-standards/screenplay/themes/rules/.gitkeep +2 -2
  428. package/augment-extensions/writing-standards/screenplay/themes/rules/ambition.md +458 -458
  429. package/augment-extensions/writing-standards/screenplay/themes/rules/betrayal.md +490 -490
  430. package/augment-extensions/writing-standards/screenplay/themes/rules/environment.md +458 -458
  431. package/augment-extensions/writing-standards/screenplay/themes/rules/fate.md +459 -459
  432. package/augment-extensions/writing-standards/screenplay/themes/rules/friendship.md +491 -491
  433. package/augment-extensions/writing-standards/screenplay/themes/rules/growth.md +491 -491
  434. package/augment-extensions/writing-standards/screenplay/themes/rules/identity.md +490 -490
  435. package/augment-extensions/writing-standards/screenplay/themes/rules/isolation.md +464 -464
  436. package/augment-extensions/writing-standards/screenplay/themes/rules/justice.md +461 -461
  437. package/augment-extensions/writing-standards/screenplay/themes/rules/love.md +489 -489
  438. package/augment-extensions/writing-standards/screenplay/themes/rules/power.md +494 -494
  439. package/augment-extensions/writing-standards/screenplay/themes/rules/redemption.md +483 -483
  440. package/augment-extensions/writing-standards/screenplay/themes/rules/revenge.md +489 -489
  441. package/augment-extensions/writing-standards/screenplay/themes/rules/survival.md +496 -496
  442. package/augment-extensions/writing-standards/screenplay/themes/rules/technology.md +463 -463
  443. package/augment-extensions/writing-standards/screenplay/utils/__tests__/file-organization.test.ts +169 -0
  444. package/augment-extensions/writing-standards/screenplay/utils/file-organization.ts +165 -0
  445. package/cli/MODULES.md +302 -302
  446. package/cli/dist/cli.js +109 -22
  447. package/cli/dist/cli.js.map +1 -1
  448. package/cli/dist/commands/gui.d.ts.map +1 -1
  449. package/cli/dist/commands/gui.js +54 -6
  450. package/cli/dist/commands/gui.js.map +1 -1
  451. package/cli/dist/commands/init.d.ts.map +1 -1
  452. package/cli/dist/commands/init.js +76 -23
  453. package/cli/dist/commands/init.js.map +1 -1
  454. package/cli/dist/commands/self-remove.d.ts.map +1 -1
  455. package/cli/dist/commands/self-remove.js +48 -74
  456. package/cli/dist/commands/self-remove.js.map +1 -1
  457. package/cli/dist/commands/show.d.ts +11 -0
  458. package/cli/dist/commands/show.d.ts.map +1 -1
  459. package/cli/dist/commands/show.js +120 -0
  460. package/cli/dist/commands/show.js.map +1 -1
  461. package/cli/dist/commands/showCompleted.d.ts +21 -0
  462. package/cli/dist/commands/showCompleted.d.ts.map +1 -0
  463. package/cli/dist/commands/showCompleted.js +225 -0
  464. package/cli/dist/commands/showCompleted.js.map +1 -0
  465. package/cli/dist/commands/skill.js +88 -88
  466. package/cli/dist/commands/update.d.ts +2 -0
  467. package/cli/dist/commands/update.d.ts.map +1 -1
  468. package/cli/dist/commands/update.js +67 -1
  469. package/cli/dist/commands/update.js.map +1 -1
  470. package/cli/dist/utils/beadsCompletedChecker.d.ts +72 -0
  471. package/cli/dist/utils/beadsCompletedChecker.d.ts.map +1 -0
  472. package/cli/dist/utils/beadsCompletedChecker.js +198 -0
  473. package/cli/dist/utils/beadsCompletedChecker.js.map +1 -0
  474. package/cli/dist/utils/catalog-sync.js +13 -13
  475. package/cli/dist/utils/extractCommandHelp.d.ts +51 -0
  476. package/cli/dist/utils/extractCommandHelp.d.ts.map +1 -0
  477. package/cli/dist/utils/extractCommandHelp.js +250 -0
  478. package/cli/dist/utils/extractCommandHelp.js.map +1 -0
  479. package/cli/dist/utils/install-rules.js +55 -55
  480. package/cli/dist/utils/mcp-integration.js +44 -44
  481. package/cli/dist/utils/rule-install-hooks.js +8 -8
  482. package/modules.md +667 -630
  483. package/package.json +85 -85
@@ -1,884 +1,884 @@
1
- # Python Async Patterns
2
-
3
- Comprehensive guide to asynchronous programming in Python using async/await, asyncio, and related patterns.
4
-
5
- ## Async/Await Basics
6
-
7
- ### Defining Async Functions
8
-
9
- ```python
10
- import asyncio
11
- from typing import List
12
-
13
- # Async function definition
14
- async def fetch_data(url: str) -> dict:
15
- """Fetch data from URL asynchronously.
16
-
17
- Args:
18
- url: URL to fetch from
19
-
20
- Returns:
21
- Fetched data as dictionary
22
- """
23
- # Simulate async I/O operation
24
- await asyncio.sleep(1)
25
- return {"url": url, "data": "..."}
26
-
27
- # Calling async functions
28
- async def main():
29
- # Must use 'await' to call async functions
30
- result = await fetch_data("https://api.example.com")
31
- print(result)
32
-
33
- # Running async code
34
- if __name__ == "__main__":
35
- # Python 3.7+
36
- asyncio.run(main())
37
-
38
- # Python 3.6 (older style)
39
- # loop = asyncio.get_event_loop()
40
- # loop.run_until_complete(main())
41
- ```
42
-
43
- ### Async vs Sync
44
-
45
- ```python
46
- # Synchronous - Blocks execution
47
- def sync_fetch(url: str) -> dict:
48
- time.sleep(1) # Blocks the entire thread
49
- return {"url": url}
50
-
51
- # Asynchronous - Allows other tasks to run
52
- async def async_fetch(url: str) -> dict:
53
- await asyncio.sleep(1) # Yields control to event loop
54
- return {"url": url}
55
-
56
- # Synchronous execution - Takes 3 seconds
57
- def sync_main():
58
- results = []
59
- for url in ["url1", "url2", "url3"]:
60
- results.append(sync_fetch(url)) # Each takes 1 second
61
- return results
62
-
63
- # Asynchronous execution - Takes 1 second total
64
- async def async_main():
65
- tasks = [async_fetch(url) for url in ["url1", "url2", "url3"]]
66
- results = await asyncio.gather(*tasks) # All run concurrently
67
- return results
68
- ```
69
-
70
- ## Running Async Tasks
71
-
72
- ### asyncio.gather() - Run Multiple Tasks
73
-
74
- ```python
75
- # Run multiple tasks concurrently
76
- async def fetch_all_data():
77
- # Create multiple tasks
78
- task1 = fetch_data("https://api1.example.com")
79
- task2 = fetch_data("https://api2.example.com")
80
- task3 = fetch_data("https://api3.example.com")
81
-
82
- # Wait for all tasks to complete
83
- results = await asyncio.gather(task1, task2, task3)
84
- return results
85
-
86
- # With list comprehension
87
- async def fetch_multiple_urls(urls: List[str]):
88
- tasks = [fetch_data(url) for url in urls]
89
- results = await asyncio.gather(*tasks)
90
- return results
91
-
92
- # Handle exceptions in gather
93
- async def fetch_with_error_handling():
94
- tasks = [fetch_data(url) for url in urls]
95
-
96
- # return_exceptions=True: Return exceptions instead of raising
97
- results = await asyncio.gather(*tasks, return_exceptions=True)
98
-
99
- # Process results and exceptions
100
- for i, result in enumerate(results):
101
- if isinstance(result, Exception):
102
- logger.error(f"Task {i} failed: {result}")
103
- else:
104
- process_result(result)
105
- ```
106
-
107
- ### asyncio.create_task() - Create Background Tasks
108
-
109
- ```python
110
- # Create tasks that run in background
111
- async def background_task(name: str):
112
- while True:
113
- print(f"{name} running")
114
- await asyncio.sleep(1)
115
-
116
- async def main():
117
- # Create background tasks
118
- task1 = asyncio.create_task(background_task("Task 1"))
119
- task2 = asyncio.create_task(background_task("Task 2"))
120
-
121
- # Do other work
122
- await asyncio.sleep(5)
123
-
124
- # Cancel background tasks
125
- task1.cancel()
126
- task2.cancel()
127
-
128
- # Wait for cancellation to complete
129
- await asyncio.gather(task1, task2, return_exceptions=True)
130
- ```
131
-
132
- ### asyncio.wait() - Advanced Task Management
133
-
134
- ```python
135
- # Wait for tasks with more control
136
- async def wait_for_tasks():
137
- tasks = [fetch_data(url) for url in urls]
138
-
139
- # Wait for all tasks
140
- done, pending = await asyncio.wait(tasks)
141
-
142
- # Wait for first task to complete
143
- done, pending = await asyncio.wait(
144
- tasks,
145
- return_when=asyncio.FIRST_COMPLETED
146
- )
147
-
148
- # Wait with timeout
149
- done, pending = await asyncio.wait(
150
- tasks,
151
- timeout=5.0
152
- )
153
-
154
- # Cancel pending tasks
155
- for task in pending:
156
- task.cancel()
157
- ```
158
-
159
- ## Async Context Managers
160
-
161
- Async context managers use `async with` for asynchronous resource management.
162
-
163
- ### Defining Async Context Managers
164
-
165
- ```python
166
- from typing import AsyncGenerator
167
-
168
- # Class-based async context manager
169
- class AsyncDatabaseConnection:
170
- """Async context manager for database connections."""
171
-
172
- def __init__(self, db_url: str):
173
- self.db_url = db_url
174
- self.conn = None
175
-
176
- async def __aenter__(self):
177
- """Establish connection when entering context."""
178
- self.conn = await async_connect(self.db_url)
179
- logger.info(f"Connected to {self.db_url}")
180
- return self.conn
181
-
182
- async def __aexit__(self, exc_type, exc_val, exc_tb):
183
- """Close connection when exiting context."""
184
- if self.conn is not None:
185
- await self.conn.close()
186
- logger.info(f"Closed connection to {self.db_url}")
187
- return False
188
-
189
- # Usage
190
- async def fetch_users():
191
- async with AsyncDatabaseConnection("postgresql://...") as conn:
192
- return await conn.fetch("SELECT * FROM users")
193
-
194
- # Generator-based async context manager
195
- from contextlib import asynccontextmanager
196
-
197
- @asynccontextmanager
198
- async def async_database_connection(
199
- db_url: str
200
- ) -> AsyncGenerator[AsyncConnection, None]:
201
- """Async context manager for database connections.
202
-
203
- Args:
204
- db_url: Database connection URL
205
-
206
- Yields:
207
- Active database connection
208
- """
209
- conn = await async_connect(db_url)
210
- try:
211
- logger.info(f"Connected to {db_url}")
212
- yield conn
213
- except Exception as e:
214
- logger.error(f"Database error: {e}")
215
- raise
216
- finally:
217
- await conn.close()
218
- logger.info(f"Closed connection to {db_url}")
219
-
220
- # Usage
221
- async def fetch_data():
222
- async with async_database_connection("postgresql://...") as conn:
223
- return await conn.fetch("SELECT * FROM users")
224
- ```
225
-
226
- ### Common Async Context Manager Patterns
227
-
228
- ```python
229
- # Async file operations (Python 3.9+ with aiofiles)
230
- import aiofiles
231
-
232
- async def read_file_async(file_path: str) -> str:
233
- async with aiofiles.open(file_path, mode='r') as f:
234
- contents = await f.read()
235
- return contents
236
-
237
- async def write_file_async(file_path: str, data: str) -> None:
238
- async with aiofiles.open(file_path, mode='w') as f:
239
- await f.write(data)
240
-
241
- # Async HTTP client (with aiohttp)
242
- import aiohttp
243
-
244
- async def fetch_url(url: str) -> dict:
245
- async with aiohttp.ClientSession() as session:
246
- async with session.get(url) as response:
247
- return await response.json()
248
-
249
- # Async lock
250
- async def critical_section():
251
- lock = asyncio.Lock()
252
-
253
- async with lock:
254
- # Only one coroutine can execute this at a time
255
- await modify_shared_resource()
256
-
257
- # Async semaphore - Limit concurrent operations
258
- async def rate_limited_fetch(urls: List[str], max_concurrent: int = 5):
259
- semaphore = asyncio.Semaphore(max_concurrent)
260
-
261
- async def fetch_with_semaphore(url: str):
262
- async with semaphore:
263
- # Only max_concurrent tasks run simultaneously
264
- return await fetch_data(url)
265
-
266
- tasks = [fetch_with_semaphore(url) for url in urls]
267
- return await asyncio.gather(*tasks)
268
- ```
269
-
270
- ### Async Context Manager with Timeout
271
-
272
- ```python
273
- @asynccontextmanager
274
- async def async_timeout(seconds: float) -> AsyncGenerator[None, None]:
275
- """Context manager with timeout.
276
-
277
- Args:
278
- seconds: Timeout in seconds
279
-
280
- Raises:
281
- asyncio.TimeoutError: If operation exceeds timeout
282
- """
283
- try:
284
- async with asyncio.timeout(seconds): # Python 3.11+
285
- yield
286
- except asyncio.TimeoutError:
287
- logger.error(f"Operation timed out after {seconds} seconds")
288
- raise
289
-
290
- # For Python < 3.11, use asyncio.wait_for
291
- async def with_timeout_legacy(coro, seconds: float):
292
- try:
293
- return await asyncio.wait_for(coro, timeout=seconds)
294
- except asyncio.TimeoutError:
295
- logger.error(f"Operation timed out after {seconds} seconds")
296
- raise
297
-
298
- # Usage
299
- async def fetch_with_timeout():
300
- async with async_timeout(5.0):
301
- return await fetch_data("https://api.example.com")
302
- ```
303
-
304
- ## Task Cancellation
305
-
306
- ### Basic Cancellation
307
-
308
- ```python
309
- # Cancel a task
310
- async def long_running_task():
311
- try:
312
- while True:
313
- await asyncio.sleep(1)
314
- print("Working...")
315
- except asyncio.CancelledError:
316
- print("Task was cancelled")
317
- # Cleanup code here
318
- raise # Re-raise to complete cancellation
319
-
320
- async def main():
321
- # Create task
322
- task = asyncio.create_task(long_running_task())
323
-
324
- # Let it run for a bit
325
- await asyncio.sleep(3)
326
-
327
- # Cancel the task
328
- task.cancel()
329
-
330
- # Wait for cancellation to complete
331
- try:
332
- await task
333
- except asyncio.CancelledError:
334
- print("Task cancelled successfully")
335
- ```
336
-
337
- ### Graceful Cancellation
338
-
339
- ```python
340
- async def graceful_task():
341
- """Task that handles cancellation gracefully."""
342
- try:
343
- while True:
344
- await asyncio.sleep(1)
345
- await process_item()
346
- except asyncio.CancelledError:
347
- logger.info("Cancellation requested, cleaning up...")
348
- await cleanup_resources()
349
- logger.info("Cleanup complete")
350
- raise # Re-raise to complete cancellation
351
-
352
- async def main():
353
- task = asyncio.create_task(graceful_task())
354
- await asyncio.sleep(5)
355
- task.cancel()
356
-
357
- try:
358
- await task
359
- except asyncio.CancelledError:
360
- logger.info("Task cancelled gracefully")
361
- ```
362
-
363
- ### Cancellation with Timeout
364
-
365
- ```python
366
- # Cancel task if it takes too long
367
- async def task_with_timeout(timeout: float):
368
- task = asyncio.create_task(long_running_operation())
369
-
370
- try:
371
- # Python 3.11+
372
- async with asyncio.timeout(timeout):
373
- result = await task
374
- except asyncio.TimeoutError:
375
- logger.warning(f"Task timed out after {timeout} seconds")
376
- task.cancel()
377
- try:
378
- await task
379
- except asyncio.CancelledError:
380
- pass
381
- raise
382
-
383
- return result
384
-
385
- # Python < 3.11
386
- async def task_with_timeout_legacy(timeout: float):
387
- task = asyncio.create_task(long_running_operation())
388
-
389
- try:
390
- result = await asyncio.wait_for(task, timeout=timeout)
391
- except asyncio.TimeoutError:
392
- logger.warning(f"Task timed out after {timeout} seconds")
393
- task.cancel()
394
- try:
395
- await task
396
- except asyncio.CancelledError:
397
- pass
398
- raise
399
-
400
- return result
401
- ```
402
-
403
- ### Shield from Cancellation
404
-
405
- ```python
406
- # Protect critical operations from cancellation
407
- async def critical_operation():
408
- """Operation that should not be cancelled."""
409
- await save_to_database()
410
- await send_confirmation_email()
411
-
412
- async def main():
413
- task = asyncio.create_task(critical_operation())
414
-
415
- # Shield the task from cancellation
416
- try:
417
- result = await asyncio.shield(task)
418
- except asyncio.CancelledError:
419
- # Even if this coroutine is cancelled, task continues
420
- logger.info("Main cancelled, but task continues")
421
- # Wait for task to complete
422
- result = await task
423
-
424
- return result
425
- ```
426
-
427
- ### Cancelling Multiple Tasks
428
-
429
- ```python
430
- async def cancel_all_tasks(tasks: List[asyncio.Task]) -> None:
431
- """Cancel all tasks and wait for them to finish.
432
-
433
- Args:
434
- tasks: List of tasks to cancel
435
- """
436
- # Cancel all tasks
437
- for task in tasks:
438
- task.cancel()
439
-
440
- # Wait for all cancellations to complete
441
- await asyncio.gather(*tasks, return_exceptions=True)
442
-
443
- # Log results
444
- for i, task in enumerate(tasks):
445
- if task.cancelled():
446
- logger.info(f"Task {i} cancelled")
447
- elif task.exception():
448
- logger.error(f"Task {i} failed: {task.exception()}")
449
-
450
- # Usage
451
- async def main():
452
- tasks = [
453
- asyncio.create_task(worker(i))
454
- for i in range(10)
455
- ]
456
-
457
- # Let them run
458
- await asyncio.sleep(5)
459
-
460
- # Cancel all
461
- await cancel_all_tasks(tasks)
462
- ```
463
-
464
- ## Advanced Patterns
465
-
466
- ### Async Generators
467
-
468
- ```python
469
- from typing import AsyncIterator
470
-
471
- async def async_range(count: int) -> AsyncIterator[int]:
472
- """Async generator that yields numbers.
473
-
474
- Args:
475
- count: Number of items to generate
476
-
477
- Yields:
478
- Numbers from 0 to count-1
479
- """
480
- for i in range(count):
481
- await asyncio.sleep(0.1) # Simulate async work
482
- yield i
483
-
484
- # Usage
485
- async def consume_async_generator():
486
- async for value in async_range(10):
487
- print(value)
488
-
489
- # Async generator with cleanup
490
- async def fetch_items_stream(url: str) -> AsyncIterator[dict]:
491
- """Stream items from API.
492
-
493
- Args:
494
- url: API endpoint URL
495
-
496
- Yields:
497
- Items from API
498
- """
499
- async with aiohttp.ClientSession() as session:
500
- async with session.get(url) as response:
501
- async for line in response.content:
502
- yield json.loads(line)
503
- ```
504
-
505
- ### Async Comprehensions
506
-
507
- ```python
508
- # Async list comprehension
509
- async def fetch_all_users(user_ids: List[int]) -> List[User]:
510
- return [
511
- user
512
- async for user_id in async_user_ids()
513
- if await is_active(user_id)
514
- for user in [await fetch_user(user_id)]
515
- ]
516
-
517
- # Async dict comprehension
518
- async def fetch_user_map(user_ids: List[int]) -> dict[int, User]:
519
- return {
520
- user_id: user
521
- async for user_id in async_user_ids()
522
- for user in [await fetch_user(user_id)]
523
- }
524
-
525
- # Async set comprehension
526
- async def fetch_active_user_ids() -> set[int]:
527
- return {
528
- user_id
529
- async for user_id in async_user_ids()
530
- if await is_active(user_id)
531
- }
532
- ```
533
-
534
- ### Task Groups (Python 3.11+)
535
-
536
- ```python
537
- # Task groups provide structured concurrency
538
- async def fetch_all_data():
539
- async with asyncio.TaskGroup() as tg:
540
- task1 = tg.create_task(fetch_data("url1"))
541
- task2 = tg.create_task(fetch_data("url2"))
542
- task3 = tg.create_task(fetch_data("url3"))
543
-
544
- # All tasks complete here (or exception is raised)
545
- return [task1.result(), task2.result(), task3.result()]
546
-
547
- # Task groups with exception handling
548
- async def fetch_with_error_handling():
549
- try:
550
- async with asyncio.TaskGroup() as tg:
551
- for url in urls:
552
- tg.create_task(fetch_data(url))
553
- except* HTTPError as eg:
554
- # Handle all HTTP errors
555
- for exc in eg.exceptions:
556
- logger.error(f"HTTP error: {exc}")
557
- except* TimeoutError as eg:
558
- # Handle all timeout errors
559
- for exc in eg.exceptions:
560
- logger.error(f"Timeout: {exc}")
561
- ```
562
-
563
-
564
-
565
- ### Async Queue
566
-
567
- ```python
568
- from asyncio import Queue
569
-
570
- # Producer-consumer pattern
571
- async def producer(queue: Queue, n: int):
572
- """Produce items and put them in queue."""
573
- for i in range(n):
574
- await asyncio.sleep(0.1)
575
- await queue.put(i)
576
- logger.info(f"Produced: {i}")
577
-
578
- # Signal completion
579
- await queue.put(None)
580
-
581
- async def consumer(queue: Queue, name: str):
582
- """Consume items from queue."""
583
- while True:
584
- item = await queue.get()
585
-
586
- if item is None:
587
- # Completion signal
588
- queue.task_done()
589
- break
590
-
591
- logger.info(f"{name} consumed: {item}")
592
- await process_item(item)
593
- queue.task_done()
594
-
595
- async def main():
596
- queue = Queue(maxsize=10)
597
-
598
- # Create producer and consumers
599
- producer_task = asyncio.create_task(producer(queue, 20))
600
- consumer_tasks = [
601
- asyncio.create_task(consumer(queue, f"Consumer-{i}"))
602
- for i in range(3)
603
- ]
604
-
605
- # Wait for producer to finish
606
- await producer_task
607
-
608
- # Wait for queue to be empty
609
- await queue.join()
610
-
611
- # Cancel consumers
612
- for task in consumer_tasks:
613
- task.cancel()
614
-
615
- await asyncio.gather(*consumer_tasks, return_exceptions=True)
616
- ```
617
-
618
- ### Async Iterators
619
-
620
- ```python
621
- class AsyncIterator:
622
- """Custom async iterator."""
623
-
624
- def __init__(self, count: int):
625
- self.count = count
626
- self.current = 0
627
-
628
- def __aiter__(self):
629
- return self
630
-
631
- async def __anext__(self):
632
- if self.current >= self.count:
633
- raise StopAsyncIteration
634
-
635
- await asyncio.sleep(0.1)
636
- value = self.current
637
- self.current += 1
638
- return value
639
-
640
- # Usage
641
- async def use_async_iterator():
642
- async for value in AsyncIterator(10):
643
- print(value)
644
- ```
645
-
646
- ## Best Practices
647
-
648
- ### DO
649
-
650
- ✅ **Use async/await for I/O-bound operations** - Network, file I/O, database queries
651
-
652
- ✅ **Use asyncio.gather() for concurrent tasks** - Run multiple tasks simultaneously
653
-
654
- ✅ **Use async context managers** - For async resource management
655
-
656
- ✅ **Handle CancelledError properly** - Clean up resources before re-raising
657
-
658
- ✅ **Use asyncio.create_task()** - For background tasks
659
-
660
- ✅ **Use semaphores for rate limiting** - Control concurrent operations
661
-
662
- ✅ **Use task groups (Python 3.11+)** - For structured concurrency
663
-
664
- ✅ **Shield critical operations** - Use asyncio.shield() for operations that must complete
665
-
666
- ✅ **Use async generators** - For streaming data
667
-
668
- ✅ **Set timeouts** - Prevent tasks from running indefinitely
669
-
670
- ### DON'T
671
-
672
- ❌ **Don't use async for CPU-bound operations** - Use multiprocessing instead
673
-
674
- ```python
675
- # Bad - Async doesn't help with CPU-bound work
676
- async def cpu_intensive():
677
- result = 0
678
- for i in range(10_000_000):
679
- result += i
680
- return result
681
-
682
- # Good - Use ProcessPoolExecutor for CPU-bound work
683
- from concurrent.futures import ProcessPoolExecutor
684
-
685
- async def cpu_intensive_async():
686
- loop = asyncio.get_event_loop()
687
- with ProcessPoolExecutor() as pool:
688
- result = await loop.run_in_executor(pool, cpu_intensive_sync)
689
- return result
690
- ```
691
-
692
- ❌ **Don't mix blocking and async code** - Use run_in_executor for blocking calls
693
-
694
- ```python
695
- # Bad - Blocking call in async function
696
- async def bad_async():
697
- result = requests.get("https://api.example.com") # Blocks!
698
- return result.json()
699
-
700
- # Good - Use async HTTP client
701
- async def good_async():
702
- async with aiohttp.ClientSession() as session:
703
- async with session.get("https://api.example.com") as response:
704
- return await response.json()
705
-
706
- # Good - Use run_in_executor for blocking calls
707
- async def blocking_in_executor():
708
- loop = asyncio.get_event_loop()
709
- result = await loop.run_in_executor(
710
- None, # Use default executor
711
- requests.get,
712
- "https://api.example.com"
713
- )
714
- return result.json()
715
- ```
716
-
717
- ❌ **Don't forget to await** - Forgetting await returns a coroutine object
718
-
719
- ```python
720
- # Bad - Forgot to await
721
- async def bad():
722
- result = fetch_data() # Returns coroutine, doesn't execute!
723
- return result
724
-
725
- # Good - Properly awaited
726
- async def good():
727
- result = await fetch_data()
728
- return result
729
- ```
730
-
731
- ❌ **Don't swallow CancelledError** - Always re-raise after cleanup
732
-
733
- ```python
734
- # Bad - Swallows cancellation
735
- async def bad_cancellation():
736
- try:
737
- await long_operation()
738
- except asyncio.CancelledError:
739
- logger.info("Cancelled")
740
- # Forgot to re-raise!
741
-
742
- # Good - Re-raises after cleanup
743
- async def good_cancellation():
744
- try:
745
- await long_operation()
746
- except asyncio.CancelledError:
747
- logger.info("Cancelled, cleaning up")
748
- await cleanup()
749
- raise # Re-raise to complete cancellation
750
- ```
751
-
752
- ❌ **Don't create tasks without tracking them** - Can lead to resource leaks
753
-
754
- ```python
755
- # Bad - Fire and forget
756
- async def bad():
757
- asyncio.create_task(background_work()) # Task not tracked!
758
-
759
- # Good - Track tasks
760
- async def good():
761
- task = asyncio.create_task(background_work())
762
- # Store task reference or await it later
763
- tasks.append(task)
764
- ```
765
-
766
- ## Common Patterns
767
-
768
- ### Retry with Exponential Backoff
769
-
770
- ```python
771
- async def retry_with_backoff(
772
- coro_func,
773
- max_attempts: int = 3,
774
- base_delay: float = 1.0,
775
- max_delay: float = 60.0,
776
- ):
777
- """Retry async function with exponential backoff.
778
-
779
- Args:
780
- coro_func: Async function to retry
781
- max_attempts: Maximum number of attempts
782
- base_delay: Initial delay in seconds
783
- max_delay: Maximum delay in seconds
784
-
785
- Returns:
786
- Result of successful call
787
-
788
- Raises:
789
- Last exception if all attempts fail
790
- """
791
- for attempt in range(max_attempts):
792
- try:
793
- return await coro_func()
794
- except Exception as e:
795
- if attempt == max_attempts - 1:
796
- raise
797
-
798
- delay = min(base_delay * (2 ** attempt), max_delay)
799
- logger.warning(
800
- f"Attempt {attempt + 1} failed: {e}. "
801
- f"Retrying in {delay}s..."
802
- )
803
- await asyncio.sleep(delay)
804
- ```
805
-
806
- ### Batch Processing
807
-
808
- ```python
809
- async def process_in_batches(
810
- items: List[Any],
811
- batch_size: int,
812
- process_func,
813
- ):
814
- """Process items in batches.
815
-
816
- Args:
817
- items: Items to process
818
- batch_size: Number of items per batch
819
- process_func: Async function to process each item
820
-
821
- Returns:
822
- List of results
823
- """
824
- results = []
825
-
826
- for i in range(0, len(items), batch_size):
827
- batch = items[i:i + batch_size]
828
- batch_results = await asyncio.gather(
829
- *[process_func(item) for item in batch]
830
- )
831
- results.extend(batch_results)
832
-
833
- # Optional: Add delay between batches
834
- if i + batch_size < len(items):
835
- await asyncio.sleep(0.1)
836
-
837
- return results
838
- ```
839
-
840
- ### Timeout for Multiple Operations
841
-
842
- ```python
843
- async def fetch_with_individual_timeouts(
844
- urls: List[str],
845
- timeout: float = 5.0,
846
- ):
847
- """Fetch URLs with individual timeouts.
848
-
849
- Args:
850
- urls: List of URLs to fetch
851
- timeout: Timeout for each request
852
-
853
- Returns:
854
- List of results (or None for timeouts)
855
- """
856
- async def fetch_with_timeout(url: str):
857
- try:
858
- async with asyncio.timeout(timeout):
859
- return await fetch_data(url)
860
- except asyncio.TimeoutError:
861
- logger.warning(f"Timeout fetching {url}")
862
- return None
863
-
864
- return await asyncio.gather(
865
- *[fetch_with_timeout(url) for url in urls]
866
- )
867
- ```
868
-
869
- ## Summary
870
-
871
- **Key Takeaways:**
872
-
873
- 1. **Use async/await for I/O-bound operations** - Not CPU-bound
874
- 2. **Use asyncio.gather()** - For running multiple tasks concurrently
875
- 3. **Use async context managers** - For async resource management
876
- 4. **Handle cancellation properly** - Clean up and re-raise CancelledError
877
- 5. **Use semaphores** - For rate limiting and controlling concurrency
878
- 6. **Set timeouts** - Prevent indefinite waiting
879
- 7. **Don't mix blocking and async code** - Use run_in_executor for blocking calls
880
- 8. **Track all tasks** - Prevent resource leaks
881
- 9. **Use task groups (Python 3.11+)** - For structured concurrency
882
- 10. **Shield critical operations** - Use asyncio.shield() when needed
883
-
884
-
1
+ # Python Async Patterns
2
+
3
+ Comprehensive guide to asynchronous programming in Python using async/await, asyncio, and related patterns.
4
+
5
+ ## Async/Await Basics
6
+
7
+ ### Defining Async Functions
8
+
9
+ ```python
10
+ import asyncio
11
+ from typing import List
12
+
13
+ # Async function definition
14
+ async def fetch_data(url: str) -> dict:
15
+ """Fetch data from URL asynchronously.
16
+
17
+ Args:
18
+ url: URL to fetch from
19
+
20
+ Returns:
21
+ Fetched data as dictionary
22
+ """
23
+ # Simulate async I/O operation
24
+ await asyncio.sleep(1)
25
+ return {"url": url, "data": "..."}
26
+
27
+ # Calling async functions
28
+ async def main():
29
+ # Must use 'await' to call async functions
30
+ result = await fetch_data("https://api.example.com")
31
+ print(result)
32
+
33
+ # Running async code
34
+ if __name__ == "__main__":
35
+ # Python 3.7+
36
+ asyncio.run(main())
37
+
38
+ # Python 3.6 (older style)
39
+ # loop = asyncio.get_event_loop()
40
+ # loop.run_until_complete(main())
41
+ ```
42
+
43
+ ### Async vs Sync
44
+
45
+ ```python
46
+ # Synchronous - Blocks execution
47
+ def sync_fetch(url: str) -> dict:
48
+ time.sleep(1) # Blocks the entire thread
49
+ return {"url": url}
50
+
51
+ # Asynchronous - Allows other tasks to run
52
+ async def async_fetch(url: str) -> dict:
53
+ await asyncio.sleep(1) # Yields control to event loop
54
+ return {"url": url}
55
+
56
+ # Synchronous execution - Takes 3 seconds
57
+ def sync_main():
58
+ results = []
59
+ for url in ["url1", "url2", "url3"]:
60
+ results.append(sync_fetch(url)) # Each takes 1 second
61
+ return results
62
+
63
+ # Asynchronous execution - Takes 1 second total
64
+ async def async_main():
65
+ tasks = [async_fetch(url) for url in ["url1", "url2", "url3"]]
66
+ results = await asyncio.gather(*tasks) # All run concurrently
67
+ return results
68
+ ```
69
+
70
+ ## Running Async Tasks
71
+
72
+ ### asyncio.gather() - Run Multiple Tasks
73
+
74
+ ```python
75
+ # Run multiple tasks concurrently
76
+ async def fetch_all_data():
77
+ # Create multiple tasks
78
+ task1 = fetch_data("https://api1.example.com")
79
+ task2 = fetch_data("https://api2.example.com")
80
+ task3 = fetch_data("https://api3.example.com")
81
+
82
+ # Wait for all tasks to complete
83
+ results = await asyncio.gather(task1, task2, task3)
84
+ return results
85
+
86
+ # With list comprehension
87
+ async def fetch_multiple_urls(urls: List[str]):
88
+ tasks = [fetch_data(url) for url in urls]
89
+ results = await asyncio.gather(*tasks)
90
+ return results
91
+
92
+ # Handle exceptions in gather
93
+ async def fetch_with_error_handling():
94
+ tasks = [fetch_data(url) for url in urls]
95
+
96
+ # return_exceptions=True: Return exceptions instead of raising
97
+ results = await asyncio.gather(*tasks, return_exceptions=True)
98
+
99
+ # Process results and exceptions
100
+ for i, result in enumerate(results):
101
+ if isinstance(result, Exception):
102
+ logger.error(f"Task {i} failed: {result}")
103
+ else:
104
+ process_result(result)
105
+ ```
106
+
107
+ ### asyncio.create_task() - Create Background Tasks
108
+
109
+ ```python
110
+ # Create tasks that run in background
111
+ async def background_task(name: str):
112
+ while True:
113
+ print(f"{name} running")
114
+ await asyncio.sleep(1)
115
+
116
+ async def main():
117
+ # Create background tasks
118
+ task1 = asyncio.create_task(background_task("Task 1"))
119
+ task2 = asyncio.create_task(background_task("Task 2"))
120
+
121
+ # Do other work
122
+ await asyncio.sleep(5)
123
+
124
+ # Cancel background tasks
125
+ task1.cancel()
126
+ task2.cancel()
127
+
128
+ # Wait for cancellation to complete
129
+ await asyncio.gather(task1, task2, return_exceptions=True)
130
+ ```
131
+
132
+ ### asyncio.wait() - Advanced Task Management
133
+
134
+ ```python
135
+ # Wait for tasks with more control
136
+ async def wait_for_tasks():
137
+ tasks = [fetch_data(url) for url in urls]
138
+
139
+ # Wait for all tasks
140
+ done, pending = await asyncio.wait(tasks)
141
+
142
+ # Wait for first task to complete
143
+ done, pending = await asyncio.wait(
144
+ tasks,
145
+ return_when=asyncio.FIRST_COMPLETED
146
+ )
147
+
148
+ # Wait with timeout
149
+ done, pending = await asyncio.wait(
150
+ tasks,
151
+ timeout=5.0
152
+ )
153
+
154
+ # Cancel pending tasks
155
+ for task in pending:
156
+ task.cancel()
157
+ ```
158
+
159
+ ## Async Context Managers
160
+
161
+ Async context managers use `async with` for asynchronous resource management.
162
+
163
+ ### Defining Async Context Managers
164
+
165
+ ```python
166
+ from typing import AsyncGenerator
167
+
168
+ # Class-based async context manager
169
+ class AsyncDatabaseConnection:
170
+ """Async context manager for database connections."""
171
+
172
+ def __init__(self, db_url: str):
173
+ self.db_url = db_url
174
+ self.conn = None
175
+
176
+ async def __aenter__(self):
177
+ """Establish connection when entering context."""
178
+ self.conn = await async_connect(self.db_url)
179
+ logger.info(f"Connected to {self.db_url}")
180
+ return self.conn
181
+
182
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
183
+ """Close connection when exiting context."""
184
+ if self.conn is not None:
185
+ await self.conn.close()
186
+ logger.info(f"Closed connection to {self.db_url}")
187
+ return False
188
+
189
+ # Usage
190
+ async def fetch_users():
191
+ async with AsyncDatabaseConnection("postgresql://...") as conn:
192
+ return await conn.fetch("SELECT * FROM users")
193
+
194
+ # Generator-based async context manager
195
+ from contextlib import asynccontextmanager
196
+
197
+ @asynccontextmanager
198
+ async def async_database_connection(
199
+ db_url: str
200
+ ) -> AsyncGenerator[AsyncConnection, None]:
201
+ """Async context manager for database connections.
202
+
203
+ Args:
204
+ db_url: Database connection URL
205
+
206
+ Yields:
207
+ Active database connection
208
+ """
209
+ conn = await async_connect(db_url)
210
+ try:
211
+ logger.info(f"Connected to {db_url}")
212
+ yield conn
213
+ except Exception as e:
214
+ logger.error(f"Database error: {e}")
215
+ raise
216
+ finally:
217
+ await conn.close()
218
+ logger.info(f"Closed connection to {db_url}")
219
+
220
+ # Usage
221
+ async def fetch_data():
222
+ async with async_database_connection("postgresql://...") as conn:
223
+ return await conn.fetch("SELECT * FROM users")
224
+ ```
225
+
226
+ ### Common Async Context Manager Patterns
227
+
228
+ ```python
229
+ # Async file operations (Python 3.9+ with aiofiles)
230
+ import aiofiles
231
+
232
+ async def read_file_async(file_path: str) -> str:
233
+ async with aiofiles.open(file_path, mode='r') as f:
234
+ contents = await f.read()
235
+ return contents
236
+
237
+ async def write_file_async(file_path: str, data: str) -> None:
238
+ async with aiofiles.open(file_path, mode='w') as f:
239
+ await f.write(data)
240
+
241
+ # Async HTTP client (with aiohttp)
242
+ import aiohttp
243
+
244
+ async def fetch_url(url: str) -> dict:
245
+ async with aiohttp.ClientSession() as session:
246
+ async with session.get(url) as response:
247
+ return await response.json()
248
+
249
+ # Async lock
250
+ async def critical_section():
251
+ lock = asyncio.Lock()
252
+
253
+ async with lock:
254
+ # Only one coroutine can execute this at a time
255
+ await modify_shared_resource()
256
+
257
+ # Async semaphore - Limit concurrent operations
258
+ async def rate_limited_fetch(urls: List[str], max_concurrent: int = 5):
259
+ semaphore = asyncio.Semaphore(max_concurrent)
260
+
261
+ async def fetch_with_semaphore(url: str):
262
+ async with semaphore:
263
+ # Only max_concurrent tasks run simultaneously
264
+ return await fetch_data(url)
265
+
266
+ tasks = [fetch_with_semaphore(url) for url in urls]
267
+ return await asyncio.gather(*tasks)
268
+ ```
269
+
270
+ ### Async Context Manager with Timeout
271
+
272
+ ```python
273
+ @asynccontextmanager
274
+ async def async_timeout(seconds: float) -> AsyncGenerator[None, None]:
275
+ """Context manager with timeout.
276
+
277
+ Args:
278
+ seconds: Timeout in seconds
279
+
280
+ Raises:
281
+ asyncio.TimeoutError: If operation exceeds timeout
282
+ """
283
+ try:
284
+ async with asyncio.timeout(seconds): # Python 3.11+
285
+ yield
286
+ except asyncio.TimeoutError:
287
+ logger.error(f"Operation timed out after {seconds} seconds")
288
+ raise
289
+
290
+ # For Python < 3.11, use asyncio.wait_for
291
+ async def with_timeout_legacy(coro, seconds: float):
292
+ try:
293
+ return await asyncio.wait_for(coro, timeout=seconds)
294
+ except asyncio.TimeoutError:
295
+ logger.error(f"Operation timed out after {seconds} seconds")
296
+ raise
297
+
298
+ # Usage
299
+ async def fetch_with_timeout():
300
+ async with async_timeout(5.0):
301
+ return await fetch_data("https://api.example.com")
302
+ ```
303
+
304
+ ## Task Cancellation
305
+
306
+ ### Basic Cancellation
307
+
308
+ ```python
309
+ # Cancel a task
310
+ async def long_running_task():
311
+ try:
312
+ while True:
313
+ await asyncio.sleep(1)
314
+ print("Working...")
315
+ except asyncio.CancelledError:
316
+ print("Task was cancelled")
317
+ # Cleanup code here
318
+ raise # Re-raise to complete cancellation
319
+
320
+ async def main():
321
+ # Create task
322
+ task = asyncio.create_task(long_running_task())
323
+
324
+ # Let it run for a bit
325
+ await asyncio.sleep(3)
326
+
327
+ # Cancel the task
328
+ task.cancel()
329
+
330
+ # Wait for cancellation to complete
331
+ try:
332
+ await task
333
+ except asyncio.CancelledError:
334
+ print("Task cancelled successfully")
335
+ ```
336
+
337
+ ### Graceful Cancellation
338
+
339
+ ```python
340
+ async def graceful_task():
341
+ """Task that handles cancellation gracefully."""
342
+ try:
343
+ while True:
344
+ await asyncio.sleep(1)
345
+ await process_item()
346
+ except asyncio.CancelledError:
347
+ logger.info("Cancellation requested, cleaning up...")
348
+ await cleanup_resources()
349
+ logger.info("Cleanup complete")
350
+ raise # Re-raise to complete cancellation
351
+
352
+ async def main():
353
+ task = asyncio.create_task(graceful_task())
354
+ await asyncio.sleep(5)
355
+ task.cancel()
356
+
357
+ try:
358
+ await task
359
+ except asyncio.CancelledError:
360
+ logger.info("Task cancelled gracefully")
361
+ ```
362
+
363
+ ### Cancellation with Timeout
364
+
365
+ ```python
366
+ # Cancel task if it takes too long
367
+ async def task_with_timeout(timeout: float):
368
+ task = asyncio.create_task(long_running_operation())
369
+
370
+ try:
371
+ # Python 3.11+
372
+ async with asyncio.timeout(timeout):
373
+ result = await task
374
+ except asyncio.TimeoutError:
375
+ logger.warning(f"Task timed out after {timeout} seconds")
376
+ task.cancel()
377
+ try:
378
+ await task
379
+ except asyncio.CancelledError:
380
+ pass
381
+ raise
382
+
383
+ return result
384
+
385
+ # Python < 3.11
386
+ async def task_with_timeout_legacy(timeout: float):
387
+ task = asyncio.create_task(long_running_operation())
388
+
389
+ try:
390
+ result = await asyncio.wait_for(task, timeout=timeout)
391
+ except asyncio.TimeoutError:
392
+ logger.warning(f"Task timed out after {timeout} seconds")
393
+ task.cancel()
394
+ try:
395
+ await task
396
+ except asyncio.CancelledError:
397
+ pass
398
+ raise
399
+
400
+ return result
401
+ ```
402
+
403
+ ### Shield from Cancellation
404
+
405
+ ```python
406
+ # Protect critical operations from cancellation
407
+ async def critical_operation():
408
+ """Operation that should not be cancelled."""
409
+ await save_to_database()
410
+ await send_confirmation_email()
411
+
412
+ async def main():
413
+ task = asyncio.create_task(critical_operation())
414
+
415
+ # Shield the task from cancellation
416
+ try:
417
+ result = await asyncio.shield(task)
418
+ except asyncio.CancelledError:
419
+ # Even if this coroutine is cancelled, task continues
420
+ logger.info("Main cancelled, but task continues")
421
+ # Wait for task to complete
422
+ result = await task
423
+
424
+ return result
425
+ ```
426
+
427
+ ### Cancelling Multiple Tasks
428
+
429
+ ```python
430
+ async def cancel_all_tasks(tasks: List[asyncio.Task]) -> None:
431
+ """Cancel all tasks and wait for them to finish.
432
+
433
+ Args:
434
+ tasks: List of tasks to cancel
435
+ """
436
+ # Cancel all tasks
437
+ for task in tasks:
438
+ task.cancel()
439
+
440
+ # Wait for all cancellations to complete
441
+ await asyncio.gather(*tasks, return_exceptions=True)
442
+
443
+ # Log results
444
+ for i, task in enumerate(tasks):
445
+ if task.cancelled():
446
+ logger.info(f"Task {i} cancelled")
447
+ elif task.exception():
448
+ logger.error(f"Task {i} failed: {task.exception()}")
449
+
450
+ # Usage
451
+ async def main():
452
+ tasks = [
453
+ asyncio.create_task(worker(i))
454
+ for i in range(10)
455
+ ]
456
+
457
+ # Let them run
458
+ await asyncio.sleep(5)
459
+
460
+ # Cancel all
461
+ await cancel_all_tasks(tasks)
462
+ ```
463
+
464
+ ## Advanced Patterns
465
+
466
+ ### Async Generators
467
+
468
+ ```python
469
+ from typing import AsyncIterator
470
+
471
+ async def async_range(count: int) -> AsyncIterator[int]:
472
+ """Async generator that yields numbers.
473
+
474
+ Args:
475
+ count: Number of items to generate
476
+
477
+ Yields:
478
+ Numbers from 0 to count-1
479
+ """
480
+ for i in range(count):
481
+ await asyncio.sleep(0.1) # Simulate async work
482
+ yield i
483
+
484
+ # Usage
485
+ async def consume_async_generator():
486
+ async for value in async_range(10):
487
+ print(value)
488
+
489
+ # Async generator with cleanup
490
+ async def fetch_items_stream(url: str) -> AsyncIterator[dict]:
491
+ """Stream items from API.
492
+
493
+ Args:
494
+ url: API endpoint URL
495
+
496
+ Yields:
497
+ Items from API
498
+ """
499
+ async with aiohttp.ClientSession() as session:
500
+ async with session.get(url) as response:
501
+ async for line in response.content:
502
+ yield json.loads(line)
503
+ ```
504
+
505
+ ### Async Comprehensions
506
+
507
+ ```python
508
+ # Async list comprehension
509
+ async def fetch_all_users(user_ids: List[int]) -> List[User]:
510
+ return [
511
+ user
512
+ async for user_id in async_user_ids()
513
+ if await is_active(user_id)
514
+ for user in [await fetch_user(user_id)]
515
+ ]
516
+
517
+ # Async dict comprehension
518
+ async def fetch_user_map(user_ids: List[int]) -> dict[int, User]:
519
+ return {
520
+ user_id: user
521
+ async for user_id in async_user_ids()
522
+ for user in [await fetch_user(user_id)]
523
+ }
524
+
525
+ # Async set comprehension
526
+ async def fetch_active_user_ids() -> set[int]:
527
+ return {
528
+ user_id
529
+ async for user_id in async_user_ids()
530
+ if await is_active(user_id)
531
+ }
532
+ ```
533
+
534
+ ### Task Groups (Python 3.11+)
535
+
536
+ ```python
537
+ # Task groups provide structured concurrency
538
+ async def fetch_all_data():
539
+ async with asyncio.TaskGroup() as tg:
540
+ task1 = tg.create_task(fetch_data("url1"))
541
+ task2 = tg.create_task(fetch_data("url2"))
542
+ task3 = tg.create_task(fetch_data("url3"))
543
+
544
+ # All tasks complete here (or exception is raised)
545
+ return [task1.result(), task2.result(), task3.result()]
546
+
547
+ # Task groups with exception handling
548
+ async def fetch_with_error_handling():
549
+ try:
550
+ async with asyncio.TaskGroup() as tg:
551
+ for url in urls:
552
+ tg.create_task(fetch_data(url))
553
+ except* HTTPError as eg:
554
+ # Handle all HTTP errors
555
+ for exc in eg.exceptions:
556
+ logger.error(f"HTTP error: {exc}")
557
+ except* TimeoutError as eg:
558
+ # Handle all timeout errors
559
+ for exc in eg.exceptions:
560
+ logger.error(f"Timeout: {exc}")
561
+ ```
562
+
563
+
564
+
565
+ ### Async Queue
566
+
567
+ ```python
568
+ from asyncio import Queue
569
+
570
+ # Producer-consumer pattern
571
+ async def producer(queue: Queue, n: int):
572
+ """Produce items and put them in queue."""
573
+ for i in range(n):
574
+ await asyncio.sleep(0.1)
575
+ await queue.put(i)
576
+ logger.info(f"Produced: {i}")
577
+
578
+ # Signal completion
579
+ await queue.put(None)
580
+
581
+ async def consumer(queue: Queue, name: str):
582
+ """Consume items from queue."""
583
+ while True:
584
+ item = await queue.get()
585
+
586
+ if item is None:
587
+ # Completion signal
588
+ queue.task_done()
589
+ break
590
+
591
+ logger.info(f"{name} consumed: {item}")
592
+ await process_item(item)
593
+ queue.task_done()
594
+
595
+ async def main():
596
+ queue = Queue(maxsize=10)
597
+
598
+ # Create producer and consumers
599
+ producer_task = asyncio.create_task(producer(queue, 20))
600
+ consumer_tasks = [
601
+ asyncio.create_task(consumer(queue, f"Consumer-{i}"))
602
+ for i in range(3)
603
+ ]
604
+
605
+ # Wait for producer to finish
606
+ await producer_task
607
+
608
+ # Wait for queue to be empty
609
+ await queue.join()
610
+
611
+ # Cancel consumers
612
+ for task in consumer_tasks:
613
+ task.cancel()
614
+
615
+ await asyncio.gather(*consumer_tasks, return_exceptions=True)
616
+ ```
617
+
618
+ ### Async Iterators
619
+
620
+ ```python
621
+ class AsyncIterator:
622
+ """Custom async iterator."""
623
+
624
+ def __init__(self, count: int):
625
+ self.count = count
626
+ self.current = 0
627
+
628
+ def __aiter__(self):
629
+ return self
630
+
631
+ async def __anext__(self):
632
+ if self.current >= self.count:
633
+ raise StopAsyncIteration
634
+
635
+ await asyncio.sleep(0.1)
636
+ value = self.current
637
+ self.current += 1
638
+ return value
639
+
640
+ # Usage
641
+ async def use_async_iterator():
642
+ async for value in AsyncIterator(10):
643
+ print(value)
644
+ ```
645
+
646
+ ## Best Practices
647
+
648
+ ### DO
649
+
650
+ ✅ **Use async/await for I/O-bound operations** - Network, file I/O, database queries
651
+
652
+ ✅ **Use asyncio.gather() for concurrent tasks** - Run multiple tasks simultaneously
653
+
654
+ ✅ **Use async context managers** - For async resource management
655
+
656
+ ✅ **Handle CancelledError properly** - Clean up resources before re-raising
657
+
658
+ ✅ **Use asyncio.create_task()** - For background tasks
659
+
660
+ ✅ **Use semaphores for rate limiting** - Control concurrent operations
661
+
662
+ ✅ **Use task groups (Python 3.11+)** - For structured concurrency
663
+
664
+ ✅ **Shield critical operations** - Use asyncio.shield() for operations that must complete
665
+
666
+ ✅ **Use async generators** - For streaming data
667
+
668
+ ✅ **Set timeouts** - Prevent tasks from running indefinitely
669
+
670
+ ### DON'T
671
+
672
+ ❌ **Don't use async for CPU-bound operations** - Use multiprocessing instead
673
+
674
+ ```python
675
+ # Bad - Async doesn't help with CPU-bound work
676
+ async def cpu_intensive():
677
+ result = 0
678
+ for i in range(10_000_000):
679
+ result += i
680
+ return result
681
+
682
+ # Good - Use ProcessPoolExecutor for CPU-bound work
683
+ from concurrent.futures import ProcessPoolExecutor
684
+
685
+ async def cpu_intensive_async():
686
+ loop = asyncio.get_event_loop()
687
+ with ProcessPoolExecutor() as pool:
688
+ result = await loop.run_in_executor(pool, cpu_intensive_sync)
689
+ return result
690
+ ```
691
+
692
+ ❌ **Don't mix blocking and async code** - Use run_in_executor for blocking calls
693
+
694
+ ```python
695
+ # Bad - Blocking call in async function
696
+ async def bad_async():
697
+ result = requests.get("https://api.example.com") # Blocks!
698
+ return result.json()
699
+
700
+ # Good - Use async HTTP client
701
+ async def good_async():
702
+ async with aiohttp.ClientSession() as session:
703
+ async with session.get("https://api.example.com") as response:
704
+ return await response.json()
705
+
706
+ # Good - Use run_in_executor for blocking calls
707
+ async def blocking_in_executor():
708
+ loop = asyncio.get_event_loop()
709
+ result = await loop.run_in_executor(
710
+ None, # Use default executor
711
+ requests.get,
712
+ "https://api.example.com"
713
+ )
714
+ return result.json()
715
+ ```
716
+
717
+ ❌ **Don't forget to await** - Forgetting await returns a coroutine object
718
+
719
+ ```python
720
+ # Bad - Forgot to await
721
+ async def bad():
722
+ result = fetch_data() # Returns coroutine, doesn't execute!
723
+ return result
724
+
725
+ # Good - Properly awaited
726
+ async def good():
727
+ result = await fetch_data()
728
+ return result
729
+ ```
730
+
731
+ ❌ **Don't swallow CancelledError** - Always re-raise after cleanup
732
+
733
+ ```python
734
+ # Bad - Swallows cancellation
735
+ async def bad_cancellation():
736
+ try:
737
+ await long_operation()
738
+ except asyncio.CancelledError:
739
+ logger.info("Cancelled")
740
+ # Forgot to re-raise!
741
+
742
+ # Good - Re-raises after cleanup
743
+ async def good_cancellation():
744
+ try:
745
+ await long_operation()
746
+ except asyncio.CancelledError:
747
+ logger.info("Cancelled, cleaning up")
748
+ await cleanup()
749
+ raise # Re-raise to complete cancellation
750
+ ```
751
+
752
+ ❌ **Don't create tasks without tracking them** - Can lead to resource leaks
753
+
754
+ ```python
755
+ # Bad - Fire and forget
756
+ async def bad():
757
+ asyncio.create_task(background_work()) # Task not tracked!
758
+
759
+ # Good - Track tasks
760
+ async def good():
761
+ task = asyncio.create_task(background_work())
762
+ # Store task reference or await it later
763
+ tasks.append(task)
764
+ ```
765
+
766
+ ## Common Patterns
767
+
768
+ ### Retry with Exponential Backoff
769
+
770
+ ```python
771
+ async def retry_with_backoff(
772
+ coro_func,
773
+ max_attempts: int = 3,
774
+ base_delay: float = 1.0,
775
+ max_delay: float = 60.0,
776
+ ):
777
+ """Retry async function with exponential backoff.
778
+
779
+ Args:
780
+ coro_func: Async function to retry
781
+ max_attempts: Maximum number of attempts
782
+ base_delay: Initial delay in seconds
783
+ max_delay: Maximum delay in seconds
784
+
785
+ Returns:
786
+ Result of successful call
787
+
788
+ Raises:
789
+ Last exception if all attempts fail
790
+ """
791
+ for attempt in range(max_attempts):
792
+ try:
793
+ return await coro_func()
794
+ except Exception as e:
795
+ if attempt == max_attempts - 1:
796
+ raise
797
+
798
+ delay = min(base_delay * (2 ** attempt), max_delay)
799
+ logger.warning(
800
+ f"Attempt {attempt + 1} failed: {e}. "
801
+ f"Retrying in {delay}s..."
802
+ )
803
+ await asyncio.sleep(delay)
804
+ ```
805
+
806
+ ### Batch Processing
807
+
808
+ ```python
809
+ async def process_in_batches(
810
+ items: List[Any],
811
+ batch_size: int,
812
+ process_func,
813
+ ):
814
+ """Process items in batches.
815
+
816
+ Args:
817
+ items: Items to process
818
+ batch_size: Number of items per batch
819
+ process_func: Async function to process each item
820
+
821
+ Returns:
822
+ List of results
823
+ """
824
+ results = []
825
+
826
+ for i in range(0, len(items), batch_size):
827
+ batch = items[i:i + batch_size]
828
+ batch_results = await asyncio.gather(
829
+ *[process_func(item) for item in batch]
830
+ )
831
+ results.extend(batch_results)
832
+
833
+ # Optional: Add delay between batches
834
+ if i + batch_size < len(items):
835
+ await asyncio.sleep(0.1)
836
+
837
+ return results
838
+ ```
839
+
840
+ ### Timeout for Multiple Operations
841
+
842
+ ```python
843
+ async def fetch_with_individual_timeouts(
844
+ urls: List[str],
845
+ timeout: float = 5.0,
846
+ ):
847
+ """Fetch URLs with individual timeouts.
848
+
849
+ Args:
850
+ urls: List of URLs to fetch
851
+ timeout: Timeout for each request
852
+
853
+ Returns:
854
+ List of results (or None for timeouts)
855
+ """
856
+ async def fetch_with_timeout(url: str):
857
+ try:
858
+ async with asyncio.timeout(timeout):
859
+ return await fetch_data(url)
860
+ except asyncio.TimeoutError:
861
+ logger.warning(f"Timeout fetching {url}")
862
+ return None
863
+
864
+ return await asyncio.gather(
865
+ *[fetch_with_timeout(url) for url in urls]
866
+ )
867
+ ```
868
+
869
+ ## Summary
870
+
871
+ **Key Takeaways:**
872
+
873
+ 1. **Use async/await for I/O-bound operations** - Not CPU-bound
874
+ 2. **Use asyncio.gather()** - For running multiple tasks concurrently
875
+ 3. **Use async context managers** - For async resource management
876
+ 4. **Handle cancellation properly** - Clean up and re-raise CancelledError
877
+ 5. **Use semaphores** - For rate limiting and controlling concurrency
878
+ 6. **Set timeouts** - Prevent indefinite waiting
879
+ 7. **Don't mix blocking and async code** - Use run_in_executor for blocking calls
880
+ 8. **Track all tasks** - Prevent resource leaks
881
+ 9. **Use task groups (Python 3.11+)** - For structured concurrency
882
+ 10. **Shield critical operations** - Use asyncio.shield() when needed
883
+
884
+