[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6QQDBFJF5DFB5YS4V2DS367":3,"skill-same:01M6QQDBFJF5DFB5YS4V2DS367":46},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":13,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":30,"updatedAt":31,"install":32,"resources":45},"01M6QQDBFJF5DFB5YS4V2DS367","python-conventions",null,"lfr-ai\u002Fcopier-fullstack-template","lfr-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F233346551?v=4","01M6QPWTJWTSJV1TQTTY8ZPBYJ","Laurits Fromberg","01M6QPWTQ47BZGA4TH17H14N80",0,"MIT","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.claude\u002Fskills\u002Fpython-conventions\u002FSKILL.md",[],[18,19,20],"python","conventions","python conventions","2026-11-10 10:12:30",false,"# Python Conventions Skill\n\n## Type Hints\n\n### Do\n\n```python\n# Builtin generics\nitems: list[str]\nmapping: dict[str, int]\npair: tuple[str, int]\nnullable: str | None\n\n# Plain constants (no Final annotation)\nMAX_RETRIES = 3\n\n# @final for sealed classes\u002Fmethods\nfrom typing import final\n\n@final\nclass ImmutableConfig: ...\n```\n\n### Do NOT\n\n```python\n# Never import generic aliases from typing\nfrom typing import List, Dict, Tuple, Optional, Union\n\n# Never use Any\nfrom typing import Any\nvalue: Any  # Use object instead\n```\n\n## Dataclasses\n\nAlways `frozen=True, slots=True`:\n\n```python\nfrom dataclasses import dataclass\n\n@dataclass(frozen=True, slots=True)\nclass Config:\n    host: str\n    port: int\n    timeout: float = 30.0\n```\n\n## Enums\n\nAlways `@unique`, use `StrEnum` or `IntEnum`:\n\n```python\nfrom enum import StrEnum, unique\n\n@unique\nclass Status(StrEnum):\n    PENDING = \"pending\"\n    APPROVED = \"approved\"\n    REJECTED = \"rejected\"\n```\n\n## Logging\n\nUse `structlog` for structured JSON logging with context binding:\n\n```python\nimport structlog\n\nlogger = structlog.get_logger(__name__)\n\n# Bind context for all subsequent log calls\nlogger = logger.bind(claim_id=claim_id, user_id=user_id)\n\nlogger.info(\"processing_claim\")\nlogger.error(\"validation_failed\", reason=\"missing_diagnosis\")\nlogger.exception(\"unexpected_error\", resource_id=resource_id)\n```\n\nStructured logging outputs JSON:\n\n```json\n{\"event\": \"processing_claim\", \"claim_id\": 123, \"user_id\": \"abc\", \"timestamp\": \"2025-02-01T10:30:00Z\"}\n```\n\n## Async SQLAlchemy\n\nUse async session and query patterns:\n\n```python\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy import select\n\nasync def get_claim(session: AsyncSession, claim_id: int) -> Claim | None:\n    \"\"\"Retrieve claim by ID.\"\"\"\n    stmt = select(Claim).where(Claim.id == claim_id)\n    result = await session.execute(stmt)\n    return result.scalar_one_or_none()\n\nasync def create_claim(session: AsyncSession, claim_data: dict) -> Claim:\n    \"\"\"Create new claim.\"\"\"\n    claim = Claim(**claim_data)\n    session.add(claim)\n    await session.commit()\n    await session.refresh(claim)\n    return claim\n```\n\n## Exception Handling\n\nSpecific catches with chaining:\n\n```python\ntry:\n    result = process(data)\nexcept ValidationError as e:\n    logger.error(\"Validation failed for %s\", data_id, exc_info=True)\n    raise ProcessingError(\"Invalid data\") from e\nexcept DatabaseError as e:\n    raise StorageError(\"Database operation failed\") from e\n```\n\n## Function Signatures\n\nKeyword-only args with `*` for 3+ params:\n\n```python\ndef process_claim(\n    claim_id: int,\n    *,\n    validate: bool = True,\n    strict_mode: bool = False,\n    timeout: float = 30.0,\n) -> ClaimResult:\n    \"\"\"Process insurance claim with configurable validation.\"\"\"\n```\n\n## Docstrings (Google Convention)\n\n```python\ndef validate_cpr(cpr: str) -> bool:\n    \"\"\"Validate CPR number format and checksum.\n\n    Args:\n        cpr: Danish CPR number string.\n\n    Returns:\n        True if CPR is valid.\n\n    Raises:\n        ValueError: If CPR format is invalid.\n    \"\"\"\n```\n\nRules:\n- NEVER start sentences with articles (\"a\", \"an\", \"the\")\n- Complete sentences with periods\n- Short, concise — avoid redundancy\n\n## Pydantic Models\n\n```python\nfrom typing import Annotated\nfrom pydantic import BaseModel, ConfigDict, Field\n\nclass ClaimModel(BaseModel):\n    model_config = ConfigDict(\n        str_strip_whitespace=True,\n        validate_assignment=True,\n    )\n\n    diagnosis: Annotated[\n        str | None,\n        Field(\n            default=None,\n            min_length=1,\n            max_length=500,\n            description=\"Primary medical diagnosis\",\n            examples=[\"Type 2 diabetes\"],\n        ),\n    ]\n```\n\n## Naming Conventions\n\n| Entity | Convention | Example |\n|--------|-----------|---------|\n| Files | snake_case | `my_module.py` |\n| Classes | PascalCase | `ClaimProcessor` |\n| Functions | snake_case | `process_claim` |\n| Variables | snake_case | `claim_count` |\n| Constants | UPPER_SNAKE_CASE | `MAX_RETRIES` |\n| Private | `_` prefix | `_internal_state` |\n\nRule: Never use `Final[...]` for internal constants or variables.\n\n## Caching\n\n```python\nfrom functools import lru_cache, cached_property\n\n@lru_cache(maxsize=128)\ndef expensive_computation(key: int) -> str: ...\n\nclass Config:\n    @cached_property\n    def db_url(self) -> str: ...\n```\n\n## Retry Policies\n\n```python\nfrom tenacity import retry, stop_after_attempt, wait_exponential\n\n@retry(\n    stop=stop_after_attempt(3),\n    wait=wait_exponential(multiplier=1.5, min=2, max=15),\n    reraise=True,\n)\ndef call_api() -> dict[str, object]: ...\n```\n\n## Package Management\n\nUse `uv` for dependency management:\n\n```bash\nuv add httpx            # Add production dependency\nuv add --group dev pytest  # Add dev dependency\nuv sync                 # Install all dependencies\nuv run pytest           # Run command in virtual environment\n```\n---\nname: python-conventions\ndescription: >\n  Enforces project Python coding standards including type hints, structured logging,\n  keyword-only args, and forbidden patterns. Use when writing or refactoring Python code.\n---\n\n# Skill: Python Conventions\n\n## Purpose\n\nApply project Python standards consistently for readability, safety, and\nmaintainability.\n\n## Use This Skill When\n\n- Writing or refactoring Python code\n- Adding public APIs, services, DTOs, mappers\n- Fixing lint\u002Ftype\u002Fdocumentation issues\n\n## Rules\n\n- Use Python {{ python_version }}+ features and full type hints\n- 'from __future__ import annotations' ONLY in files with TYPE_CHECKING blocks or forward references\n- Use keyword-only args ('*') for multi-parameter constructors\u002Ffunctions\n- Use structured logging, not 'print()'\n- Avoid 'Any'; prefer precise types or 'object'\n- Keep line length \u003C= 88\n- Google-style docstrings on all public symbols; args\u002Freturns MUST include typehints\n- StrEnum + @unique + auto() for string enums\n- @final on all concrete leaf classes\n- raise ... from e to preserve exception context; catch specific exceptions only\n- No emojis in code, comments, logs, or documentation\n\n## Quick Checklist\n\n- [ ] Types complete and precise\n- [ ] Docstrings present for public symbols\n- [ ] Logging structured and safe\n- [ ] No forbidden patterns (raw SQL, mutable defaults, unsafe eval)\n",{},"main","f726ce2f2bb4e3bcc2f56c066598f4acd910c5ee","template\u002F.claude\u002Fskills\u002Fpython-conventions","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template","https:\u002F\u002Fgithub.com\u002Flfr-ai","Optimizing for elegance","2026-07-20 12:19:48",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add lfr-ai\u002Fcopier-fullstack-template --skill python-conventions",{"tool":38,"command":39},"bunx","bunx skills add lfr-ai\u002Fcopier-fullstack-template --skill python-conventions",{"tool":41,"command":42},"pnpm","pnpm dlx skills add lfr-ai\u002Fcopier-fullstack-template --skill python-conventions","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.claude\u002Fskills\u002Fpython-conventions\u002FSKILL.md",true,[],[47,80,91,97,114,120],{"skillNo":48,"name":49,"nameZh":6,"description":50,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":63,"publishedAt":21},"01M6QQGVYW8BZ3W165A5YMJ1PF","ui-ux-frontend","Frontend UX, accessibility, responsive layout, and Storybook interaction quality standards.","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fui-ux-frontend\u002FSKILL.md",[53,58],{"categoryNo":54,"categoryName":55,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":59,"categoryName":60,"taxonomyType":61,"taxonomyTypeDesc":62},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],"ui ux","ui ux frontend","ui","ux","frontend","storybook","frontend ux","interaction","layout","responsive","mdx","tsx","standards","quality","accessibility","css",{"skillNo":81,"name":82,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":88,"publishedAt":21},"01M6QQGS7N3ENQZR2Y5JBRYDHD","testing-conventions","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Ftesting-conventions\u002FSKILL.md",[85],{"categoryNo":86,"categoryName":87,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000008","测试与质量",[19,89,90],"testing conventions","testing",{"skillNo":92,"name":93,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":21},"01M6QQGQKA9Q6A147WXMS7QPGX","tdd","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Ftdd\u002FSKILL.md",[],[93],{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":104,"publishedAt":21},"01M6QQG5AZPRWSR6SSCCDDPAM3","shadcn-ui","shadcn\u002Fui component conventions and composition patterns","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fshadcn-ui\u002FSKILL.md",[103],{"categoryNo":59,"categoryName":60,"taxonomyType":61,"taxonomyTypeDesc":62},[105,66,106,107,75,108,109,110,111,19,112,113],"shadcn ui","shadcn","component","Composition","src","composition patterns","presentation","patterns","ui component",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":21},"01M6QQG3WMMB8X8C4T8PR7WBV4","sdd","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fsdd\u002FSKILL.md",[],[116],{"skillNo":121,"name":122,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":21},"01M6QQG241NAC5PQFXFD01NR16","quality-gate","https:\u002F\u002Fgithub.com\u002Flfr-ai\u002Fcopier-fullstack-template\u002Fblob\u002Fmain\u002Ftemplate\u002F.github\u002Fskills\u002Fquality-gate\u002FSKILL.md",[],[126,77,127],"quality gate","gate"]