[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FD0ZS949SCA87G8FPDDZ55":3,"skill-same:01M6FD0ZS949SCA87G8FPDDZ55":50},{"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":23,"linkOnly":24,"markdownContent":25,"markdownBody":25,"frontMatter":26,"refName":27,"commitSha":28,"skillDirectory":29,"forksCount":30,"repositoryHtmlUrl":31,"repositoryHomepageUrl":32,"ownerHtmlUrl":33,"ownerBlogUrl":6,"ownerDescription":34,"updatedAt":35,"install":36,"resources":49},"01M6FD0ZS949SCA87G8FPDDZ55","azure-cosmos-db-py",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft\u002Fskills\u002Fazure-cosmos-db-py\u002FSKILL.md",[],[18,19,20,21,22],"azure","azure cosmos db py","azure cosmos db","db","cosmos","2026-11-10 10:12:30",false,"# Cosmos DB Service Implementation\n\nBuild production-grade Azure Cosmos DB NoSQL services following clean code, security best practices, and TDD principles.\n\n## Installation\n\n```bash\npip install azure-cosmos azure-identity\n```\n\n## Environment Variables\n\n```bash\nCOSMOS_ENDPOINT=https:\u002F\u002F\u003Caccount>.documents.azure.com:443\u002F\nCOSMOS_DATABASE_NAME=\u003Cdatabase-name>\nCOSMOS_CONTAINER_ID=\u003Ccontainer-id>\n# For emulator only (not production)\nCOSMOS_KEY=\u003Cemulator-key>\n```\n\n## Authentication\n\n**DefaultAzureCredential (preferred)**:\n```python\nfrom azure.cosmos import CosmosClient\nfrom azure.identity import DefaultAzureCredential\n\nclient = CosmosClient(\n    url=os.environ[\"COSMOS_ENDPOINT\"],\n    credential=DefaultAzureCredential()\n)\n```\n\n**Emulator (local development)**:\n```python\nfrom azure.cosmos import CosmosClient\n\nclient = CosmosClient(\n    url=\"https:\u002F\u002Flocalhost:8081\",\n    credential=os.environ[\"COSMOS_KEY\"],\n    connection_verify=False\n)\n```\n\n## Architecture Overview\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                         FastAPI Router                          │\n│  - Auth dependencies (get_current_user, get_current_user_required)\n│  - HTTP error responses (HTTPException)                         │\n└──────────────────────────────┬──────────────────────────────────┘\n                               │\n┌──────────────────────────────▼──────────────────────────────────┐\n│                        Service Layer                            │\n│  - Business logic and validation                                │\n│  - Document ↔ Model conversion                                  │\n│  - Graceful degradation when Cosmos unavailable                 │\n└──────────────────────────────┬──────────────────────────────────┘\n                               │\n┌──────────────────────────────▼──────────────────────────────────┐\n│                     Cosmos DB Client Module                     │\n│  - Singleton container initialization                           │\n│  - Dual auth: DefaultAzureCredential (Azure) \u002F Key (emulator)   │\n│  - Async wrapper via run_in_threadpool                          │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n## Quick Start\n\n### 1. Client Module Setup\n\nCreate a singleton Cosmos client with dual authentication:\n\n```python\n# db\u002Fcosmos.py\nfrom azure.cosmos import CosmosClient\nfrom azure.identity import DefaultAzureCredential\nfrom starlette.concurrency import run_in_threadpool\n\n_cosmos_container = None\n\ndef _is_emulator_endpoint(endpoint: str) -> bool:\n    return \"localhost\" in endpoint or \"127.0.0.1\" in endpoint\n\nasync def get_container():\n    global _cosmos_container\n    if _cosmos_container is None:\n        if _is_emulator_endpoint(settings.cosmos_endpoint):\n            client = CosmosClient(\n                url=settings.cosmos_endpoint,\n                credential=settings.cosmos_key,\n                connection_verify=False\n            )\n        else:\n            client = CosmosClient(\n                url=settings.cosmos_endpoint,\n                credential=DefaultAzureCredential()\n            )\n        db = client.get_database_client(settings.cosmos_database_name)\n        _cosmos_container = db.get_container_client(settings.cosmos_container_id)\n    return _cosmos_container\n```\n\n**Full implementation**: See [references\u002Fclient-setup.md](references\u002Fclient-setup.md)\n\n### 2. Pydantic Model Hierarchy\n\nUse five-tier model pattern for clean separation:\n\n```python\nclass ProjectBase(BaseModel):           # Shared fields\n    name: str = Field(..., min_length=1, max_length=200)\n\nclass ProjectCreate(ProjectBase):       # Creation request\n    workspace_id: str = Field(..., alias=\"workspaceId\")\n\nclass ProjectUpdate(BaseModel):         # Partial updates (all optional)\n    name: Optional[str] = Field(None, min_length=1)\n\nclass Project(ProjectBase):             # API response\n    id: str\n    created_at: datetime = Field(..., alias=\"createdAt\")\n\nclass ProjectInDB(Project):             # Internal with docType\n    doc_type: str = \"project\"\n```\n\n### 3. Service Layer Pattern\n\n```python\nclass ProjectService:\n    def _use_cosmos(self) -> bool:\n        return get_container() is not None\n    \n    async def get_by_id(self, project_id: str, workspace_id: str) -> Project | None:\n        if not self._use_cosmos():\n            return None\n        doc = await get_document(project_id, partition_key=workspace_id)\n        if doc is None:\n            return None\n        return self._doc_to_model(doc)\n```\n\n**Full patterns**: See [references\u002Fservice-layer.md](references\u002Fservice-layer.md)\n\n## Core Principles\n\n### Security Requirements\n\n1. **RBAC Authentication**: Use `DefaultAzureCredential` in Azure — never store keys in code\n2. **Emulator-Only Keys**: Hardcode the well-known emulator key only for local development\n3. **Parameterized Queries**: Always use `@parameter` syntax — never string concatenation\n4. **Partition Key Validation**: Validate partition key access matches user authorization\n\n### Clean Code Conventions\n\n1. **Single Responsibility**: Client module handles connection; services handle business logic\n2. **Graceful Degradation**: Services return `None`\u002F`[]` when Cosmos unavailable\n3. **Consistent Naming**: `_doc_to_model()`, `_model_to_doc()`, `_use_cosmos()`\n4. **Type Hints**: Full typing on all public methods\n5. **CamelCase Aliases**: Use `Field(alias=\"camelCase\")` for JSON serialization\n\n### TDD Requirements\n\nWrite tests BEFORE implementation using these patterns:\n\n```python\n@pytest.fixture\ndef mock_cosmos_container(mocker):\n    container = mocker.MagicMock()\n    mocker.patch(\"app.db.cosmos.get_container\", return_value=container)\n    return container\n\n@pytest.mark.asyncio\nasync def test_get_project_by_id_returns_project(mock_cosmos_container):\n    # Arrange\n    mock_cosmos_container.read_item.return_value = {\"id\": \"123\", \"name\": \"Test\"}\n    \n    # Act\n    result = await project_service.get_by_id(\"123\", \"workspace-1\")\n    \n    # Assert\n    assert result.id == \"123\"\n    assert result.name == \"Test\"\n```\n\n**Full testing guide**: See [references\u002Ftesting.md](references\u002Ftesting.md)\n\n## Reference Files\n\n| File | When to Read |\n|------|--------------|\n| [references\u002Fclient-setup.md](references\u002Fclient-setup.md) | Setting up Cosmos client with dual auth, SSL config, singleton pattern |\n| [references\u002Fservice-layer.md](references\u002Fservice-layer.md) | Implementing full service class with CRUD, conversions, graceful degradation |\n| [references\u002Ftesting.md](references\u002Ftesting.md) | Writing pytest tests, mocking Cosmos, integration test setup |\n| [references\u002Fpartitioning.md](references\u002Fpartitioning.md) | Choosing partition keys, cross-partition queries, move operations |\n| [references\u002Ferror-handling.md](references\u002Ferror-handling.md) | Handling CosmosResourceNotFoundError, logging, HTTP error mapping |\n\n## Template Files\n\n| File | Purpose |\n|------|---------|\n| [assets\u002Fcosmos_client_template.py](assets\u002Fcosmos_client_template.py) | Ready-to-use client module |\n| [assets\u002Fservice_template.py](assets\u002Fservice_template.py) | Service class skeleton |\n| [assets\u002Fconftest_template.py](assets\u002Fconftest_template.py) | pytest fixtures for Cosmos mocking |\n\n## Quality Attributes (NFRs)\n\n### Reliability\n- Graceful degradation when Cosmos unavailable\n- Retry logic with exponential backoff for transient failures\n- Connection pooling via singleton pattern\n\n### Security\n- Zero secrets in code (RBAC via DefaultAzureCredential)\n- Parameterized queries prevent injection\n- Partition key isolation enforces data boundaries\n\n### Maintainability\n- Five-tier model pattern enables schema evolution\n- Service layer decouples business logic from storage\n- Consistent patterns across all entity services\n\n### Testability\n- Dependency injection via `get_container()`\n- Easy mocking with module-level globals\n- Clear separation enables unit testing without Cosmos\n\n### Performance\n- Partition key queries avoid cross-partition scans\n- Async wrapping prevents blocking FastAPI event loop\n- Minimal document conversion overhead\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fmicrosoft\u002Fskills\u002Fazure-cosmos-db-py",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill azure-cosmos-db-py",{"tool":42,"command":43},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill azure-cosmos-db-py",{"tool":45,"command":46},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill azure-cosmos-db-py","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft\u002Fskills\u002Fazure-cosmos-db-py\u002FSKILL.md",true,[],[51,65,75,84,90,97],{"skillNo":52,"name":53,"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":54,"categories":55,"keywords":61,"publishedAt":23},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[56],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[62,63,64],"model","model hierarchy","model hierarchy skill",{"skillNo":66,"name":67,"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":68,"categories":69,"keywords":71,"publishedAt":23},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[70],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},[72,73,74],"MCP","zoom","zoom mcp",{"skillNo":76,"name":77,"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":78,"categories":79,"keywords":80,"publishedAt":23},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[81,82,83,73],"sdk","zoom apps sdk","apps",{"skillNo":85,"name":86,"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":87,"categories":88,"keywords":89,"publishedAt":23},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[86],{"skillNo":91,"name":92,"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":93,"categories":94,"keywords":96,"publishedAt":23},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[95],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},[92],{"skillNo":98,"name":99,"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":100,"categories":101,"keywords":102,"publishedAt":23},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[99]]