Get started with Azure Cosmos DB for NoSQL using Python

APPLIES TO: NoSQL

This article shows you how to connect to Azure Cosmos DB for NoSQL using the Python SDK. Once connected, you can perform operations on databases, containers, and items.

Package (PyPi) | Samples | API reference | Library source code | Give Feedback

Prerequisites

Set up your project

Create an environment that you can run Python code in.

With a virtual environment, you can install Python packages in an isolated environment without affecting the rest of your system.

Install the Azure Cosmos DB for NoSQL Python SDK in the virtual environment.

pip install azure-cosmos

Create the Python application

In your environment, create a new app.py file and add the following code to it:

"""Sample showing how to connect with endpoint and key."""
# <imports>
import json
import os
import sys
import uuid

from azure.core.exceptions import AzureError
from azure.cosmos import CosmosClient, PartitionKey

# </imports>

DATABASE_ID = "cosmicworks"
CONTAINER_ID = "products"
# <client>
ENDPOINT = os.environ["COSMOS_ENDPOINT"]
KEY = os.environ["COSMOS_KEY"]

client = CosmosClient(url=ENDPOINT, credential=KEY)
# </client>


def main():
    """How to CosmosDB and NoSQL samples."""
    try:
        # Create database and partition key.
        database = client.create_database_if_not_exists(id=DATABASE_ID)

        # Create a container.
        partition_key_path = PartitionKey(path="/categoryId")
        container = database.create_container_if_not_exists(
            id=CONTAINER_ID,
            partition_key=partition_key_path,
            offer_throughput=400,
        )

        # Create a new item.
        new_guid = str(uuid.uuid4())
        new_item = {
            "id": new_guid,
            "categoryId": "61dba35b-4f02-45c5-b648-c6badc0cbd79",
            "categoryName": "gear-surf-surfboards",
            "name": "Yamba Surfboard",
            "quantity": 12,
            "sale": False,
        }
        container.create_item(new_item)

        # Query items.
        sql_stmt = "SELECT * FROM products p WHERE p.categoryId = @categoryId"
        category_id = "61dba35b-4f02-45c5-b648-c6badc0cbd79"
        params = [dict(name="@categoryId", value=category_id)]

        items = container.query_items(
            query=sql_stmt,
            parameters=params,
            enable_cross_partition_query=False,
        )

        for item in items:
            print(json.dumps(item, indent=True))

    except AzureError as err:
        sys.exit("Error:" + str(err))


if __name__ == "__main__":
    main()

The preceding code imports modules that you'll use in the rest of the article.

Connect to Azure Cosmos DB for NoSQL

To connect to the API for NoSQL of Azure Cosmos DB, create an instance of the CosmosClient class. This class is the starting point to perform all operations against databases. There are three ways to connect to an API for NoSQL account using the CosmosClient class:

Connect with an endpoint and key

The constructor for CosmosClient has two required parameters:

Parameter Example value Description
url COSMOS_ENDPOINT environment variable API for NoSQL endpoint to use for all requests.
credential COSMOS_KEY environment variable Account key or resource token to use when authenticating.

Retrieve your account endpoint and key

  1. Create a shell variable for resourceGroupName.

    # Variable for resource group name
    resourceGroupName="msdocs-cosmos-python-howto-rg"
    
  2. Use the az cosmosdb list command to retrieve the name of the first Azure Cosmos DB account in your resource group and store it in the accountName shell variable.

    # Retrieve most recently created account name
    accountName=$(
        az cosmosdb list \
            --resource-group $resourceGroupName \
            --query "[0].name" \
            --output tsv
    )
    
  3. Get the API for NoSQL endpoint URI for the account using the az cosmosdb show command.

    az cosmosdb show \
        --resource-group $resourceGroupName \
        --name $accountName \
        --query "documentEndpoint"
    
  4. Find the PRIMARY KEY from the list of keys for the account with the az-cosmosdb-keys-list command.

    az cosmosdb keys list \
        --resource-group $resourceGroupName \
        --name $accountName \
        --type "keys" \
        --query "primaryMasterKey"
    
  5. Record the URI and PRIMARY KEY values. You'll use these credentials later.

To use the URI and PRIMARY KEY values within your Python code, persist them to new environment variables on the local machine running the application.

$env:COSMOS_ENDPOINT = "<cosmos-account-URI>"
$env:COSMOS_KEY = "<cosmos-account-PRIMARY-KEY>"

Create CosmosClient with account endpoint and key

Create a new instance of the CosmosClient class with the COSMOS_ENDPOINT and COSMOS_KEY environment variables as parameters.

"""Sample showing how to connect with endpoint and key."""
# <imports>
import json
import os
import sys
import uuid

from azure.core.exceptions import AzureError
from azure.cosmos import CosmosClient, PartitionKey

# </imports>

DATABASE_ID = "cosmicworks"
CONTAINER_ID = "products"
# <client>
ENDPOINT = os.environ["COSMOS_ENDPOINT"]
KEY = os.environ["COSMOS_KEY"]

client = CosmosClient(url=ENDPOINT, credential=KEY)
# </client>


def main():
    """How to CosmosDB and NoSQL samples."""
    try:
        # Create database and partition key.
        database = client.create_database_if_not_exists(id=DATABASE_ID)

        # Create a container.
        partition_key_path = PartitionKey(path="/categoryId")
        container = database.create_container_if_not_exists(
            id=CONTAINER_ID,
            partition_key=partition_key_path,
            offer_throughput=400,
        )

        # Create a new item.
        new_guid = str(uuid.uuid4())
        new_item = {
            "id": new_guid,
            "categoryId": "61dba35b-4f02-45c5-b648-c6badc0cbd79",
            "categoryName": "gear-surf-surfboards",
            "name": "Yamba Surfboard",
            "quantity": 12,
            "sale": False,
        }
        container.create_item(new_item)

        # Query items.
        sql_stmt = "SELECT * FROM products p WHERE p.categoryId = @categoryId"
        category_id = "61dba35b-4f02-45c5-b648-c6badc0cbd79"
        params = [dict(name="@categoryId", value=category_id)]

        items = container.query_items(
            query=sql_stmt,
            parameters=params,
            enable_cross_partition_query=False,
        )

        for item in items:
            print(json.dumps(item, indent=True))

    except AzureError as err:
        sys.exit("Error:" + str(err))


if __name__ == "__main__":
    main()

Connect with a connection string

The CosmosClient class has a from_connection_string method that you can use to connect with one required parameter:

Parameter Example value Description
conn_str COSMOS_CONNECTION_STRING environment variable The connection string to the API for NoSQL account.
credential COSMOS_KEY environment variable An optional alternative account key or resource token to use instead of the one in the connection string.

Retrieve your account connection string

  1. Use the az cosmosdb list command to retrieve the name of the first Azure Cosmos DB account in your resource group and store it in the accountName shell variable.

    # Retrieve most recently created account name
    accountName=$(
        az cosmosdb list \
            --resource-group $resourceGroupName \
            --query "[0].name" \
            --output tsv
    )
    
  2. Find the PRIMARY CONNECTION STRING from the list of connection strings for the account with the az-cosmosdb-keys-list command.

    az cosmosdb keys list \
        --resource-group $resourceGroupName \
        --name $accountName \
        --type "connection-strings" \
        --query "connectionStrings[?description == \`Primary SQL Connection String\`] | [0].connectionString"
    

To use the PRIMARY CONNECTION STRING value within your Python code, persist it to a new environment variable on the local machine running the application.

$env:COSMOS_CONNECTION_STRING = "<cosmos-account-PRIMARY-CONNECTION-STRING>"

Create CosmosClient with connection string

Create a new instance of the CosmosClient class with the COSMOS_CONNECTION_STRING environment variable as the only parameter.

"""Sample showing how to connect with connection string."""
import json
import os
import sys
import uuid

from azure.core.exceptions import AzureError
from azure.cosmos import CosmosClient, PartitionKey

DATABASE_ID = "cosmicworks"
CONTAINER_ID = "products"
# <connection_string>
CONN_STR = os.environ["COSMOS_CONNECTION_STRING"]

client = CosmosClient.from_connection_string(conn_str=CONN_STR)
# </connection_string>


def main():
    """How to CosmosDB and NoSQL samples."""
    try:
        # Create database and partition key.
        database = client.create_database_if_not_exists(id=DATABASE_ID)

        # Create a container.
        partition_key_path = PartitionKey(path="/categoryId")
        container = database.create_container_if_not_exists(
            id=CONTAINER_ID,
            partition_key=partition_key_path,
            offer_throughput=400,
        )

        # Create a new item.
        new_guid = str(uuid.uuid4())
        new_item = {
            "id": new_guid,
            "categoryId": "61dba35b-4f02-45c5-b648-c6badc0cbd79",
            "categoryName": "gear-surf-surfboards",
            "name": "Yamba Surfboard",
            "quantity": 12,
            "sale": False,
        }
        container.create_item(new_item)

        # Query items.
        sql_stmt = "SELECT * FROM products p WHERE p.categoryId = @categoryId"
        category_id = "61dba35b-4f02-45c5-b648-c6badc0cbd79"
        params = [dict(name="@categoryId", value=category_id)]

        items = container.query_items(
            query=sql_stmt,
            parameters=params,
            enable_cross_partition_query=False,
        )

        for item in items:
            print(json.dumps(item, indent=True))

    except AzureError as err:
        sys.exit("Error:" + str(err))


if __name__ == "__main__":
    main()

To connect to your API for NoSQL account using the Microsoft identity platform and Microsoft Entra ID, use a security principal. The exact type of principal will depend on where you host your application code. The table below serves as a quick reference guide.

Where the application runs Security principal
Local machine (developing and testing) User identity or service principal
Azure Managed identity
Servers or clients outside of Azure Service principal

Import Azure.Identity

The azure-identity package contains core authentication functionality that is shared among all Azure SDK libraries.

Import the azure-identity package into your environment.

pip install azure-identity

Create CosmosClient with default credential implementation

If you're testing on a local machine, or your application will run on Azure services with direct support for managed identities, obtain an OAuth token by creating a DefaultAzureCredential instance.

In your app.py:

  • Get the endpoint to connect to as show in the section above for Connect with an endpoint and key and set that as the environment variable COSMOS_ENDPOINT.

  • Import the DefaultAzureCredential and create an instance of it.

  • Create a new instance of the CosmosClient class with the ENDPOINT and credential as parameters.

"""Sample showing how to connect with AAD."""
import json
import os
import sys
import uuid

from azure.core.exceptions import AzureError
from azure.cosmos import CosmosClient

# <credential>
from azure.identity import DefaultAzureCredential

ENDPOINT = os.environ["COSMOS_ENDPOINT"]

credential = DefaultAzureCredential()

client = CosmosClient(ENDPOINT, credential)
# </credential>

DATABASE_ID = "cosmicworks"
CONTAINER_ID = "products"


def main():
    """How to CosmosDB and NoSQL samples."""
    try:
        # Get database.
        database = client.get_database_client(DATABASE_ID)

        # Get container.
        container = database.get_container_client(CONTAINER_ID)
        print("Container info: " + str(container.read()))

        # Create a new item.
        new_guid = str(uuid.uuid4())
        new_item = {
            "id": new_guid,
            "categoryId": "61dba35b-4f02-45c5-b648-c6badc0cbd79",
            "categoryName": "gear-surf-surfboards",
            "name": "Yamba Surfboard",
            "quantity": 12,
            "sale": False,
        }
        container.create_item(new_item)

        # Query items.
        sql_stmt = "SELECT * FROM products p WHERE p.categoryId = @categoryId"
        category_id = "61dba35b-4f02-45c5-b648-c6badc0cbd79"
        params = [dict(name="@categoryId", value=category_id)]

        items = container.query_items(
            query=sql_stmt,
            parameters=params,
            enable_cross_partition_query=False,
        )

        for item in items:
            print(json.dumps(item, indent=True))

    except AzureError as err:
        sys.exit("Error:" + str(err))


if __name__ == "__main__":
    main()

Important

For details on how to add the correct role to enable DefaultAzureCredential to work, see Configure role-based access control with Microsoft Entra ID for your Azure Cosmos DB account. In particular, see the section on creating roles and assigning them to a principal ID.

Create CosmosClient with a custom credential implementation

If you plan to deploy the application out of Azure, you can obtain an OAuth token by using other classes in the Azure.Identity client library for Python. These other classes also derive from the TokenCredential class.

For this example, we create a ClientSecretCredential instance by using client and tenant identifiers, along with a client secret.

In your app.py:

  • Get the credential information from environment variables for a service principal. You can obtain the client ID, tenant ID, and client secret when you register an application in Microsoft Entra ID. For more information about registering Microsoft Entra applications, see Register an application with the Microsoft identity platform.

  • Import the ClientSecretCredential and create an instance with the TENANT_ID, CLIENT_ID, and CLIENT_SECRET environment variables as parameters.

  • Create a new instance of the CosmosClient class with the ENDPOINT and credential as parameters.

"""Sample showing how to connect with AAD service principal."""
import json
import os
import sys
import uuid

from azure.core.exceptions import AzureError
from azure.cosmos import CosmosClient

# <credential>
from azure.identity import ClientSecretCredential

ENDPOINT = os.environ["COSMOS_ENDPOINT"]
TENANT_ID = os.environ["TENANT_ID"]
CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"]

credential = ClientSecretCredential(
    tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=CLIENT_SECRET
)

client = CosmosClient(ENDPOINT, credential)
# </credential>

DATABASE_ID = "cosmicworks"
CONTAINER_ID = "products"


def main():
    """How to CosmosDB and NoSQL samples."""
    try:
        # Get database.
        database = client.get_database_client(DATABASE_ID)

        # Get container.
        container = database.get_container_client(CONTAINER_ID)
        print("Container info: " + str(container.read()))

        # Create a new item.
        new_guid = str(uuid.uuid4())
        new_item = {
            "id": new_guid,
            "categoryId": "61dba35b-4f02-45c5-b648-c6badc0cbd79",
            "categoryName": "gear-surf-surfboards",
            "name": "Yamba Surfboard",
            "quantity": 12,
            "sale": False,
        }
        container.create_item(new_item)

        # Query items.
        sql_stmt = "SELECT * FROM products p WHERE p.categoryId = @categoryId"
        category_id = "61dba35b-4f02-45c5-b648-c6badc0cbd79"
        params = [dict(name="@categoryId", value=category_id)]

        items = container.query_items(
            query=sql_stmt,
            parameters=params,
            enable_cross_partition_query=False,
        )

        for item in items:
            print(json.dumps(item, indent=True))

    except AzureError as err:
        sys.exit("Error:" + str(err))


if __name__ == "__main__":
    main()

Build your application

As you build your application, your code will primarily interact with four types of resources:

  • The API for NoSQL account, which is the unique top-level namespace for your Azure Cosmos DB data.

  • Databases, which organize the containers in your account.

  • Containers, which contain a set of individual items in your database.

  • Items, which represent a JSON document in your container.

The following diagram shows the relationship between these resources.

Diagram of the Azure Cosmos DB hierarchy including accounts, databases, containers, and items.

Hierarchical diagram showing an Azure Cosmos DB account at the top. The account has two child database nodes. One of the database nodes includes two child container nodes. The other database node includes a single child container node. That single container node has three child item nodes.

Each type of resource is represented by one or more associated Python classes. Here's a list of the most common classes for synchronous programming. (There are similar classes for asynchronous programming under the azure.cosmos.aio namespace.)

Class Description
CosmosClient This class provides a client-side logical representation for the Azure Cosmos DB service. The client object is used to configure and execute requests against the service.
DatabaseProxy An interface to a database that may, or may not, exist in the service yet. This class shouldn't be instantiated directly. Instead you should use the CosmosClient get_database_client method.
ContainerProxy An interface to interact with a specific Cosmos DB container. This class shouldn't be instantiated directly. Instead, use the DatabaseProxy get_container_client method to get an existing container, or the create_container method to create a new container.

The following guides show you how to use each of these classes to build your application.

Guide Description
Create a database Create databases
Create container Create containers
Item examples Point read a specific item

See also

Next steps

Now that you've connected to an API for NoSQL account, use the next guide to create and manage databases.