Add this skill
npx mdskills install sickn33/azure-cosmos-pyComprehensive SDK guide with clear examples, best practices, and strong partition key emphasis
1---2name: azure-cosmos-py3description: |4 Azure Cosmos DB SDK for Python (NoSQL API). Use for document CRUD, queries, containers, and globally distributed data.5 Triggers: "cosmos db", "CosmosClient", "container", "document", "NoSQL", "partition key".6package: azure-cosmos7---89# Azure Cosmos DB SDK for Python1011Client library for Azure Cosmos DB NoSQL API — globally distributed, multi-model database.1213## Installation1415```bash16pip install azure-cosmos azure-identity17```1819## Environment Variables2021```bash22COSMOS_ENDPOINT=https://<account>.documents.azure.com:443/23COSMOS_DATABASE=mydb24COSMOS_CONTAINER=mycontainer25```2627## Authentication2829```python30from azure.identity import DefaultAzureCredential31from azure.cosmos import CosmosClient3233credential = DefaultAzureCredential()34endpoint = "https://<account>.documents.azure.com:443/"3536client = CosmosClient(url=endpoint, credential=credential)37```3839## Client Hierarchy4041| Client | Purpose | Get From |42|--------|---------|----------|43| `CosmosClient` | Account-level operations | Direct instantiation |44| `DatabaseProxy` | Database operations | `client.get_database_client()` |45| `ContainerProxy` | Container/item operations | `database.get_container_client()` |4647## Core Workflow4849### Setup Database and Container5051```python52# Get or create database53database = client.create_database_if_not_exists(id="mydb")5455# Get or create container with partition key56container = database.create_container_if_not_exists(57 id="mycontainer",58 partition_key=PartitionKey(path="/category")59)6061# Get existing62database = client.get_database_client("mydb")63container = database.get_container_client("mycontainer")64```6566### Create Item6768```python69item = {70 "id": "item-001", # Required: unique within partition71 "category": "electronics", # Partition key value72 "name": "Laptop",73 "price": 999.99,74 "tags": ["computer", "portable"]75}7677created = container.create_item(body=item)78print(f"Created: {created['id']}")79```8081### Read Item8283```python84# Read requires id AND partition key85item = container.read_item(86 item="item-001",87 partition_key="electronics"88)89print(f"Name: {item['name']}")90```9192### Update Item (Replace)9394```python95item = container.read_item(item="item-001", partition_key="electronics")96item["price"] = 899.9997item["on_sale"] = True9899updated = container.replace_item(item=item["id"], body=item)100```101102### Upsert Item103104```python105# Create if not exists, replace if exists106item = {107 "id": "item-002",108 "category": "electronics",109 "name": "Tablet",110 "price": 499.99111}112113result = container.upsert_item(body=item)114```115116### Delete Item117118```python119container.delete_item(120 item="item-001",121 partition_key="electronics"122)123```124125## Queries126127### Basic Query128129```python130# Query within a partition (efficient)131query = "SELECT * FROM c WHERE c.price < @max_price"132items = container.query_items(133 query=query,134 parameters=[{"name": "@max_price", "value": 500}],135 partition_key="electronics"136)137138for item in items:139 print(f"{item['name']}: ${item['price']}")140```141142### Cross-Partition Query143144```python145# Cross-partition (more expensive, use sparingly)146query = "SELECT * FROM c WHERE c.price < @max_price"147items = container.query_items(148 query=query,149 parameters=[{"name": "@max_price", "value": 500}],150 enable_cross_partition_query=True151)152153for item in items:154 print(item)155```156157### Query with Projection158159```python160query = "SELECT c.id, c.name, c.price FROM c WHERE c.category = @category"161items = container.query_items(162 query=query,163 parameters=[{"name": "@category", "value": "electronics"}],164 partition_key="electronics"165)166```167168### Read All Items169170```python171# Read all in a partition172items = container.read_all_items() # Cross-partition173# Or with partition key174items = container.query_items(175 query="SELECT * FROM c",176 partition_key="electronics"177)178```179180## Partition Keys181182**Critical**: Always include partition key for efficient operations.183184```python185from azure.cosmos import PartitionKey186187# Single partition key188container = database.create_container_if_not_exists(189 id="orders",190 partition_key=PartitionKey(path="/customer_id")191)192193# Hierarchical partition key (preview)194container = database.create_container_if_not_exists(195 id="events",196 partition_key=PartitionKey(path=["/tenant_id", "/user_id"])197)198```199200## Throughput201202```python203# Create container with provisioned throughput204container = database.create_container_if_not_exists(205 id="mycontainer",206 partition_key=PartitionKey(path="/pk"),207 offer_throughput=400 # RU/s208)209210# Read current throughput211offer = container.read_offer()212print(f"Throughput: {offer.offer_throughput} RU/s")213214# Update throughput215container.replace_throughput(throughput=1000)216```217218## Async Client219220```python221from azure.cosmos.aio import CosmosClient222from azure.identity.aio import DefaultAzureCredential223224async def cosmos_operations():225 credential = DefaultAzureCredential()226227 async with CosmosClient(endpoint, credential=credential) as client:228 database = client.get_database_client("mydb")229 container = database.get_container_client("mycontainer")230231 # Create232 await container.create_item(body={"id": "1", "pk": "test"})233234 # Read235 item = await container.read_item(item="1", partition_key="test")236237 # Query238 async for item in container.query_items(239 query="SELECT * FROM c",240 partition_key="test"241 ):242 print(item)243244import asyncio245asyncio.run(cosmos_operations())246```247248## Error Handling249250```python251from azure.cosmos.exceptions import CosmosHttpResponseError252253try:254 item = container.read_item(item="nonexistent", partition_key="pk")255except CosmosHttpResponseError as e:256 if e.status_code == 404:257 print("Item not found")258 elif e.status_code == 429:259 print(f"Rate limited. Retry after: {e.headers.get('x-ms-retry-after-ms')}ms")260 else:261 raise262```263264## Best Practices2652661. **Always specify partition key** for point reads and queries2672. **Use parameterized queries** to prevent injection and improve caching2683. **Avoid cross-partition queries** when possible2694. **Use `upsert_item`** for idempotent writes2705. **Use async client** for high-throughput scenarios2716. **Design partition key** for even data distribution2727. **Use `read_item`** instead of query for single document retrieval273274## Reference Files275276| File | Contents |277|------|----------|278| [references/partitioning.md](references/partitioning.md) | Partition key strategies, hierarchical keys, hot partition detection and mitigation |279| [references/query-patterns.md](references/query-patterns.md) | Query optimization, aggregations, pagination, transactions, change feed |280| [scripts/setup_cosmos_container.py](scripts/setup_cosmos_container.py) | CLI tool for creating containers with partitioning, throughput, and indexing |281
Full transparency — inspect the skill content before installing.