AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The azure-cosmos-py skill provides the Python client library for Azure Cosmos DB NoSQL API. It enables developers to perform CRUD operations, manage databases and containers, execute queries, and handle throughput settings. The skill emphasizes using DefaultAzureCredential for authentication and context managers for resource lifecycle management, while providing guidance on partition key design and query optimization patterns.
What it does
- Provides client classes for account, database, and container operations.
- Supports document CRUD operations including create, read, replace, upsert, and delete.
- Enables SQL-like querying of data with support for parameters and projections.
- Facilitates management of container throughput and partition key configuration.
- Offers both synchronous and asynchronous client implementations.
- Includes patterns for pagination and handling hierarchical partition keys.
When to use it
- When developing Python applications that need to interact with Azure Cosmos DB.
- When implementing data access layers for NoSQL document storage.
- When designing partition strategies for data distribution.
- When optimizing query performance through parameterized queries and efficient partition key usage.
Advantages
- Provides a unified interface for both sync and async operations.
- Integrates with Azure identity services for credential management.
- Includes built-in support for handling common database exceptions.
- Offers clear patterns for managing resource lifecycles using context managers.
Usage examples
- “How do I create a new item in an Azure Cosmos DB container using Python?”
- The agent provides a code snippet using container.create_item() with a dictionary representing the item, ensuring the partition key is included.
- “How can I query items in Cosmos DB while avoiding cross-partition overhead?”
- The agent demonstrates how to use container.query_items() by specifying the partition_key parameter to target a single partition.
- “What is the best way to handle authentication in my Cosmos DB Python code?”
- The agent explains the use of DefaultAzureCredential and provides a code example showing how to pass it to the CosmosClient.
- “How do I implement pagination for a large query result set?”
- The agent provides a function using continuation tokens with query_items() to iterate through results page by page.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/microsoft/azure-cosmos-py/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-cosmos-py.zip -d .agents/skills
Documentation by Microsoft
Azure Cosmos DB SDK for Python
Client library for Azure Cosmos DB NoSQL API — globally distributed, multi-model database.
Installation
pip install azure-cosmos azure-identityEnvironment Variables
COSMOS_ENDPOINT=https://<account>.documents.azure.com:443/ # Required for all auth methods
COSMOS_DATABASE=mydb # Required for all auth methods
COSMOS_CONTAINER=mycontainer # Required for all auth methods
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionAuthentication & Lifecycle
🔑 Two rules apply to every code sample below:
Prefer
DefaultAzureCredential. It works locally (Azure CLI / VS Code / Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account/API keys — they bypass Entra audit and rotation.
Local dev:
DefaultAzureCredentialworks as-is.Production: set
AZURE_TOKEN_CREDENTIALS=prod(orAZURE_TOKEN_CREDENTIALS=<specific_credential>) to constrain the credential chain to production-safe credentials.Wrap every client in a context manager so HTTP transports, sockets, and token caches are released deterministically:
Sync:
with <Client>(...) as client:Async:
async with <Client>(...) as client:andasync with DefaultAzureCredential() as credential:(fromazure.identity.aio)Snippets may abbreviate this setup, but production code should always follow both rules.
import os
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.cosmos import CosmosClient
# Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
credential = DefaultAzureCredential(require_envvar=True)
# Or use a specific credential directly in production:
# See https://learn.microsoft.com/python/api/overview/azure/identity-readme?view=azure-python#credential-classes
# credential = ManagedIdentityCredential()
endpoint = "https://<account>.documents.azure.com:443/"
with CosmosClient(url=endpoint, credential=credential) as client:
# Use client here (see following sections for operations)
...Client Hierarchy
| Client | Purpose | Get From |
|---|---|---|
CosmosClient | Account-level operations | Direct instantiation |
DatabaseProxy | Database operations | client.get_database_client() |
ContainerProxy | Container/item operations | database.get_container_client() |
Core Workflow
Setup Database and Container
# Get or create database
database = client.create_database_if_not_exists(id="mydb")
# Get or create container with partition key
container = database.create_container_if_not_exists(
id="mycontainer",
partition_key=PartitionKey(path="/category")
)
# Get existing
database = client.get_database_client("mydb")
container = database.get_container_client("mycontainer")Create Item
item = {
"id": "item-001", # Required: unique within partition
"category": "electronics", # Partition key value
"name": "Laptop",
"price": 999.99,
"tags": ["computer", "portable"]
}
created = container.create_item(body=item)
print(f"Created: {created['id']}")Read Item
# Read requires id AND partition key
item = container.read_item(
item="item-001",
partition_key="electronics"
)
print(f"Name: {item['name']}")Update Item (Replace)
item = container.read_item(item="item-001", partition_key="electronics")
item["price"] = 899.99
item["on_sale"] = True
updated = container.replace_item(item=item["id"], body=item)Upsert Item
# Create if not exists, replace if exists
item = {
"id": "item-002",
"category": "electronics",
"name": "Tablet",
"price": 499.99
}
result = container.upsert_item(body=item)Delete Item
container.delete_item(
item="item-001",
partition_key="electronics"
)Queries
Basic Query
# Query within a partition (efficient)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
query=query,
parameters=[{"name": "@max_price", "value": 500}],
partition_key="electronics"
)
for item in items:
print(f"{item['name']}: ${item['price']}")Cross-Partition Query
# Cross-partition (more expensive, use sparingly)
query = "SELECT * FROM c WHERE c.price < @max_price"
items = container.query_items(
query=query,
parameters=[{"name": "@max_price", "value": 500}],
enable_cross_partition_query=True
)
for item in items:
print(item)Query with Projection
query = "SELECT c.id, c.name, c.price FROM c WHERE c.category = @category"
items = container.query_items(
query=query,
parameters=[{"name": "@category", "value": "electronics"}],
partition_key="electronics"
)Read All Items
# Read all in a partition
items = container.read_all_items() # Cross-partition
# Or with partition key
items = container.query_items(
query="SELECT * FROM c",
partition_key="electronics"
)Partition Keys
Critical: Always include partition key for efficient operations.
from azure.cosmos import PartitionKey
# Single partition key
container = database.create_container_if_not_exists(
id="orders",
partition_key=PartitionKey(path="/customer_id")
)
# Hierarchical partition key (preview)
container = database.create_container_if_not_exists(
id="events",
partition_key=PartitionKey(path=["/tenant_id", "/user_id"])
)Throughput
# Create container with provisioned throughput
container = database.create_container_if_not_exists(
id="mycontainer",
partition_key=PartitionKey(path="/pk"),
offer_throughput=400 # RU/s
)
# Read current throughput
offer = container.read_offer()
print(f"Throughput: {offer.offer_throughput} RU/s")
# Update throughput
container.replace_throughput(throughput=1000)Async Client
from azure.cosmos.aio import CosmosClient
from azure.identity.aio import DefaultAzureCredential
async def cosmos_operations():
async with DefaultAzureCredential() as credential:
async with CosmosClient(endpoint, credential=credential) as client:
database = client.get_database_client("mydb")
container = database.get_container_client("mycontainer")
# Create
await container.create_item(body={"id": "1", "pk": "test"})
# Read
item = await container.read_item(item="1", partition_key="test")
# Query
async for item in container.query_items(
query="SELECT * FROM c",
partition_key="test"
):
print(item)
import asyncio
asyncio.run(cosmos_operations())Error Handling
from azure.cosmos.exceptions import CosmosHttpResponseError
try:
item = container.read_item(item="nonexistent", partition_key="pk")
except CosmosHttpResponseError as e:
if e.status_code == 404:
print("Item not found")
elif e.status_code == 429:
print(f"Rate limited. Retry after: {e.headers.get('x-ms-retry-after-ms')}ms")
else:
raiseBest Practices
Pick sync OR async and stay consistent. Do not mix
azure.cosmossync clients withazure.cosmos.aioasync clients in the same call path. Choose one mode per module.Always use context managers for clients and async credentials. Wrap every client in
with CosmosClient(...) as client:(sync) orasync with CosmosClient(...) as client:(async). For asyncDefaultAzureCredentialfromazure.identity.aio, also useasync with credential:so tokens and transports are cleaned up.Use
DefaultAzureCredentialfor portable auth across local dev and Azure (avoid connection strings / API keys when possible).Always specify partition key for point reads and queries
Use parameterized queries to prevent injection and improve caching
Avoid cross-partition queries when possible
Use
upsert_itemfor idempotent writesUse async client for high-throughput scenarios
Design partition key for even data distribution
Use
read_iteminstead of query for single document retrieval
Reference Files
| File | Contents |
|---|---|
| references/partitioning.md | Partition key strategies, hierarchical keys, hot partition detection and mitigation |
| references/query-patterns.md | Query optimization, aggregations, pagination, transactions, change feed |
| scripts/setup_cosmos_container.py | CLI tool for creating containers with partitioning, throughput, and indexing |
Files
- ATTRIBUTION.mdAdded by AutoGineer956 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md9.1 KiB
- references/partitioning.md10.3 KiB
- references/query-patterns.md10.6 KiB
references/partitioning.md
Partition Key Strategies
Comprehensive guide to partition key design and optimization for Azure Cosmos DB.
Partition Key Fundamentals
What is a Partition Key?
A partition key determines how data is distributed across physical partitions:
Logical partition: All items with the same partition key value
Physical partition: Storage unit that holds one or more logical partitions
Maximum logical partition size: 20 GB
from azure.cosmos import PartitionKey
# Define partition key at container creation
container = database.create_container_if_not_exists(
id="orders",
partition_key=PartitionKey(path="/customer_id")
)Choosing a Partition Key
Good Partition Key Characteristics
| Characteristic | Why It Matters |
|---|---|
| High cardinality | Many unique values = even distribution |
| Even distribution | Prevents hot partitions |
| Frequently used in queries | Enables efficient single-partition queries |
| Immutable | Partition key cannot be changed after item creation |
Common Partition Key Patterns
# E-commerce orders - partition by customer
container = database.create_container_if_not_exists(
id="orders",
partition_key=PartitionKey(path="/customer_id")
)
# Query: "Get all orders for customer X" - efficient single partition
# IoT telemetry - partition by device
container = database.create_container_if_not_exists(
id="telemetry",
partition_key=PartitionKey(path="/device_id")
)
# Query: "Get recent readings for device X" - efficient
# Multi-tenant SaaS - partition by tenant
container = database.create_container_if_not_exists(
id="data",
partition_key=PartitionKey(path="/tenant_id")
)
# Query: "Get all data for tenant X" - efficient, isolatedAnti-Patterns to Avoid
# BAD: Low cardinality partition key
# Only 2 values = all data in 2 partitions
partition_key=PartitionKey(path="/status") # "active" or "inactive"
# BAD: Timestamp as partition key (unless with synthetic key)
# Creates write-only partitions, recent partition is always hot
partition_key=PartitionKey(path="/created_date")
# BAD: Monotonically increasing ID
# All recent writes go to the same partition
partition_key=PartitionKey(path="/auto_increment_id")Hierarchical Partition Keys
For workloads needing multi-level distribution:
from azure.cosmos import PartitionKey
# Two-level hierarchy: tenant → user
container = database.create_container_if_not_exists(
id="user_events",
partition_key=PartitionKey(path=["/tenant_id", "/user_id"])
)
# Three-level hierarchy: tenant → department → user
container = database.create_container_if_not_exists(
id="enterprise_data",
partition_key=PartitionKey(path=["/tenant_id", "/department", "/user_id"])
)Querying with Hierarchical Keys
# Full key path - most efficient
items = container.query_items(
query="SELECT * FROM c WHERE c.status = 'active'",
partition_key=["tenant-123", "user-456"] # List for hierarchical
)
# Partial key path - queries within tenant
items = container.query_items(
query="SELECT * FROM c WHERE c.department = 'engineering'",
partition_key=["tenant-123"] # Queries all users in tenant
)Hierarchical Key Benefits
| Scenario | Single Key | Hierarchical Key |
|---|---|---|
| Multi-tenant with user isolation | Cross-partition for tenant-wide queries | Single partition for tenant, sub-partitions for users |
| Geographic + temporal data | Choose one dimension | Partition by region, then by date |
| Hot partition mitigation | Limited options | Add synthetic suffix as sub-key |
Synthetic Partition Keys
When natural keys have poor distribution:
import hashlib
def create_item_with_synthetic_key(container, item: dict, num_buckets: int = 10):
"""Add synthetic partition key for better distribution."""
# Generate bucket from item ID
bucket = int(hashlib.md5(item["id"].encode()).hexdigest(), 16) % num_buckets
# Combine natural key with bucket
item["pk"] = f"{item['category']}_{bucket}"
return container.create_item(body=item)
# Example: Distribute "electronics" category across 10 partitions
item = {
"id": "item-001",
"category": "electronics",
"name": "Laptop"
}
create_item_with_synthetic_key(container, item)
# Results in pk: "electronics_7" (depending on hash)Time-Based Synthetic Keys
from datetime import datetime
def create_event_with_time_bucket(container, event: dict):
"""Partition by device with hourly buckets."""
timestamp = event.get("timestamp", datetime.utcnow())
hour_bucket = timestamp.strftime("%Y%m%d%H")
event["pk"] = f"{event['device_id']}_{hour_bucket}"
return container.create_item(body=event)
# Distributes writes across time-based partitions
event = {
"id": "event-001",
"device_id": "device-123",
"timestamp": datetime.utcnow(),
"value": 42.5
}
create_event_with_time_bucket(container, event)
# Results in pk: "device-123_2025012812"Hot Partition Detection
Monitoring Partition Metrics
from azure.cosmos import CosmosClient
def check_partition_metrics(container):
"""Check container throughput and partition distribution."""
# Get container properties
properties = container.read()
print(f"Container ID: {properties['id']}")
# Get current throughput
try:
offer = container.read_offer()
print(f"Provisioned throughput: {offer.offer_throughput} RU/s")
except Exception:
print("Using serverless or database-level throughput")
# Query to check partition key distribution
query = """
SELECT COUNT(1) as count, c.pk
FROM c
GROUP BY c.pk
"""
partition_counts = list(container.query_items(
query=query,
enable_cross_partition_query=True
))
if partition_counts:
total = sum(p['count'] for p in partition_counts)
print(f"\nPartition distribution ({len(partition_counts)} partitions):")
for p in sorted(partition_counts, key=lambda x: x['count'], reverse=True)[:10]:
pct = (p['count'] / total) * 100
print(f" {p['pk']}: {p['count']} items ({pct:.1f}%)")
if pct > 20:
print(f" ⚠️ Hot partition detected!")Identifying Hot Partitions via Azure Portal
Key metrics to monitor:
Normalized RU Consumption: >70% indicates potential hot partition
Partition Key Range Statistics: Uneven distribution warnings
Throttled Requests (429s): May indicate hot partition
Mitigation Strategies
# Strategy 1: Add randomized suffix
def add_random_suffix(pk: str, num_suffixes: int = 5) -> str:
"""Distribute writes across multiple logical partitions."""
import random
suffix = random.randint(0, num_suffixes - 1)
return f"{pk}_{suffix}"
# Strategy 2: Time-based bucketing
def add_time_bucket(pk: str, bucket_minutes: int = 60) -> str:
"""Create time-based sub-partitions."""
from datetime import datetime
bucket = datetime.utcnow().hour
return f"{pk}_{bucket}"
# Strategy 3: Hash-based distribution
def add_hash_bucket(pk: str, item_id: str, num_buckets: int = 10) -> str:
"""Deterministic distribution based on item ID."""
import hashlib
bucket = int(hashlib.sha256(item_id.encode()).hexdigest(), 16) % num_buckets
return f"{pk}_{bucket}"Partition Key Design Patterns by Use Case
E-commerce
# Orders container: partition by customer for order history queries
orders_container = database.create_container_if_not_exists(
id="orders",
partition_key=PartitionKey(path="/customer_id")
)
# Products container: partition by category for browsing
products_container = database.create_container_if_not_exists(
id="products",
partition_key=PartitionKey(path="/category")
)
# Cart container: partition by session for cart operations
cart_container = database.create_container_if_not_exists(
id="carts",
partition_key=PartitionKey(path="/session_id")
)Multi-tenant SaaS
# Hierarchical: tenant → resource type for isolation + efficient queries
container = database.create_container_if_not_exists(
id="tenant_data",
partition_key=PartitionKey(path=["/tenant_id", "/resource_type"])
)
# Document structure
document = {
"id": "doc-001",
"tenant_id": "tenant-abc",
"resource_type": "project",
"name": "My Project",
"data": {...}
}IoT / Time Series
# Hierarchical: device → time bucket for efficient range queries
container = database.create_container_if_not_exists(
id="telemetry",
partition_key=PartitionKey(path=["/device_id", "/day"])
)
# Document structure
telemetry = {
"id": "reading-001",
"device_id": "sensor-123",
"day": "2025-01-28", # Daily bucket
"timestamp": "2025-01-28T12:30:00Z",
"temperature": 22.5,
"humidity": 45.2
}Social / Activity Feeds
# Partition by user for personal feed queries
container = database.create_container_if_not_exists(
id="activity_feed",
partition_key=PartitionKey(path="/user_id")
)
# With write amplification for follower feeds
# Store activity in both author and follower partitions
async def post_activity(container, author_id: str, follower_ids: list[str], activity: dict):
"""Fan-out activity to author and all followers."""
tasks = []
# Author's partition
author_activity = {**activity, "user_id": author_id, "id": f"{activity['id']}_author"}
tasks.append(container.create_item(body=author_activity))
# Each follower's partition
for follower_id in follower_ids:
follower_activity = {**activity, "user_id": follower_id, "id": f"{activity['id']}_{follower_id}"}
tasks.append(container.create_item(body=follower_activity))
await asyncio.gather(*tasks)Best Practices Summary
| Practice | Recommendation |
|---|---|
| Cardinality | Aim for thousands+ unique values |
| Distribution | Monitor and rebalance if >20% in single partition |
| Query alignment | Partition key should match most frequent query filter |
| Size monitoring | Keep logical partitions under 15GB (20GB limit) |
| Throughput | Consider hierarchical keys for mixed workloads |
| Immutability | Plan partition key carefully - cannot change later |
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-python/skills/azure-cosmos-py · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-cosmos-py.zip