Skip to content

Commit

Permalink
[Cosmos] Preview2 (#7140)
Browse files Browse the repository at this point in the history
* [Cosmos] Core pipeline integration (#6961)

* Updated dependencies

* Added core pipeline

* Ignore test config

* Fixed indexes test

* Refactored request creation

* Fixed index test

* Added trace decorators

* Bumped version

* Updated policies

* Renamed request_options -> request_params

* [Cosmos] Applying track 2 SDK guidelines (#7021)

* Updated dependencies

* Added core pipeline

* Ignore test config

* Fixed indexes test

* Refactored request creation

* Fixed index test

* Added trace decorators

* Bumped version

* Updated policies

* Renamed request_options -> request_params

* Renamed clients

* Updated with azure-core errors

* Fixed test warnings

* Updated config

* PR fixes

* Fixed init user import

* Fixed init clients

* Started revising constructors

* Test conn str constructor

* Update iterables with core paging

* Added context managers

* Reverted storage changes

* Updated constructor

* Mypy and Pylint

* Renamed all listing operations

* Some mypy fixes

* Cleaned up method signatures

* Fix pylint

* Propagate kwargs

* Fix pylint

* Some mypy fixes

* Updated readme and release notes

* Fix for passing in extra headers

* Reverted credentials

* Review feedback

* Fix pylint

* Fixed samples

* Updated docstrings

* Fixed whitespace and imports

* Some mypy fixes

* Mypy fixes

* Removed continuation token support

* Pylint fix

* Docs tweaks

* Updated continuation token

* Updated response header

* [Cosmos] Bumped dependency (#7147)

* Bumped dependency

* Update reqs

* Misc fixes for Cosmos SDK  (#7157)

* Made offer extend object instead of dict

* added support for urllib3 connection retry

* [Cosmos] docs updates (#7167)

* Bumped dependency

* Update reqs

* Fixed dependency, replaced changelog

* Updated readme and examples

* Updated docs URLs

* [Cosmos] Fix example formatting (#7171)

* Bumped dependency

* Update reqs

* Fixed dependency, replaced changelog

* Updated readme and examples

* Updated docs URLs

* Fixed f-strings

* Another f-string

* [Cosmos] Snippet references (#7174)

* Bumped dependency

* Update reqs

* Fixed dependency, replaced changelog

* Updated readme and examples

* Updated docs URLs

* Fixed f-strings

* Another f-string

* Snippet references
  • Loading branch information
annatisch authored Sep 10, 2019
1 parent 3037d37 commit a267b95
Show file tree
Hide file tree
Showing 71 changed files with 2,365 additions and 2,150 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,4 @@ sdk/storage/azure-storage-blob/tests/settings_real.py
sdk/storage/azure-storage-queue/tests/settings_real.py
sdk/storage/azure-storage-file/tests/settings_real.py
*.code-workspace
sdk/cosmos/azure-cosmos/test/test_config.py
42 changes: 42 additions & 0 deletions sdk/cosmos/azure-cosmos/HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@
# Change Log azure-cosmos

## Version 4.0.0b2:

Version 4.0.0b2 is the second iteration in our efforts to build a more Pythonic client library.

**Breaking changes**

- The client connection has been adapted to consume the HTTP pipeline defined in `azure.core.pipeline`.
- Interactive objects have now been renamed as proxies. This includes:
- `Database` -> `DatabaseProxy`
- `User` -> `UserProxy`
- `Container` -> `ContainerProxy`
- `Scripts` -> `ScriptsProxy`
- The constructor of `CosmosClient` has been updated:
- The `auth` parameter has been renamed to `credential` and will now take an authentication type directly. This means the master key value, a dictionary of resource tokens, or a list of permissions can be passed in. However the old dictionary format is still supported.
- The `connection_policy` parameter has been made a keyword only parameter, and while it is still supported, each of the individual attributes of the policy can now be passed in as explicit keyword arguments:
- `request_timeout`
- `media_request_timeout`
- `connection_mode`
- `media_read_mode`
- `proxy_config`
- `enable_endpoint_discovery`
- `preferred_locations`
- `multiple_write_locations`
- A new classmethod constructor has been added to `CosmosClient` to enable creation via a connection string retrieved from the Azure portal.
- Some `read_all` operations have been renamed to `list` operations:
- `CosmosClient.read_all_databases` -> `CosmosClient.list_databases`
- `Container.read_all_conflicts` -> `ContainerProxy.list_conflicts`
- `Database.read_all_containers` -> `DatabaseProxy.list_containers`
- `Database.read_all_users` -> `DatabaseProxy.list_users`
- `User.read_all_permissions` -> `UserProxy.list_permissions`
- All operations that take `request_options` or `feed_options` parameters, these have been moved to keyword only parameters. In addition, while these options dictionaries are still supported, each of the individual options within the dictionary are now supported as explicit keyword arguments.
- The error heirarchy is now inherited from `azure.core.AzureError` instead of `CosmosError` which has been removed.
- `HTTPFailure` has been renamed to `CosmosHttpResponseError`
- `JSONParseFailure` has been removed and replaced by `azure.core.DecodeError`
- Added additional errors for specific response codes:
- `CosmosResourceNotFoundError` for status 404
- `CosmosResourceExistsError` for status 409
- `CosmosAccessConditionFailedError` for status 412
- `CosmosClient` can now be run in a context manager to handle closing the client connection.
- Iterable responses (e.g. query responses and list responses) are now of type `azure.core.paging.ItemPaged`. The method `fetch_next_block` has been replaced by a secondary iterator, accessed by the `by_page` method.

## Version 4.0.0b1:

Version 4.0.0b1 is the first preview of our efforts to create a user-friendly and Pythonic client library for Azure Cosmos. For more information about this, and preview releases of other Azure SDK libraries, please visit https://aka.ms/azure-sdk-preview1-python.
Expand Down
2 changes: 1 addition & 1 deletion sdk/cosmos/azure-cosmos/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
include README.md
include changelog.md
include HISTORY.md
include LICENSE.txt
include azure/__init__.py
recursive-include doc *.bat
Expand Down
67 changes: 30 additions & 37 deletions sdk/cosmos/azure-cosmos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,23 @@ export ACCOUNT_KEY=$(az cosmosdb list-keys --resource-group $RES_GROUP --name $A
Once you've populated the `ACCOUNT_URI` and `ACCOUNT_KEY` environment variables, you can create the [CosmosClient][ref_cosmosclient].

```Python
from azure.cosmos import HTTPFailure, CosmosClient, Container, Database, PartitionKey
from azure.cosmos import CosmosClient, Container, Database, PartitionKey, errors

import os
url = os.environ['ACCOUNT_URI']
key = os.environ['ACCOUNT_KEY']
client = CosmosClient(url, auth = {
'masterKey': key
})
client = CosmosClient(url, credential=key)
```

## Usage

Once you've initialized a [CosmosClient][ref_cosmosclient], you can interact with the primary resource types in Cosmos DB:

* [Database][ref_database]: A Cosmos DB account can contain multiple databases. When you create a database, you specify the API you'd like to use when interacting with its documents: SQL, MongoDB, Gremlin, Cassandra, or Azure Table. Use the [Database][ref_database] object to manage its containers.
* [Database][ref_database]: A Cosmos DB account can contain multiple databases. When you create a database, you specify the API you'd like to use when interacting with its documents: SQL, MongoDB, Gremlin, Cassandra, or Azure Table. Use the [DatabaseProxy][ref_database] object to manage its containers.

* [Container][ref_container]: A container is a collection of JSON documents. You create (insert), read, update, and delete items in a container by using methods on the [Container][ref_container] object.
* [Container][ref_container]: A container is a collection of JSON documents. You create (insert), read, update, and delete items in a container by using methods on the [ContainerProxy][ref_container] object.

* [Item][ref_item]: An Item is the dictionary-like representation of a JSON document stored in a container. Each Item you add to a container must include an `id` key with a value that uniquely identifies the item within the container.
* Item: An Item is the dictionary-like representation of a JSON document stored in a container. Each Item you add to a container must include an `id` key with a value that uniquely identifies the item within the container.

For more information about these resources, see [Working with Azure Cosmos databases, containers and items][cosmos_resources].

Expand All @@ -106,9 +104,7 @@ After authenticating your [CosmosClient][ref_cosmosclient], you can work with an
database_name = 'testDatabase'
try:
database = client.create_database(database_name)
except HTTPFailure as e:
if e.status_code != 409:
raise
except errors.CosmosResourceExistsError:
database = client.get_database_client(database_name)
```

Expand All @@ -120,13 +116,13 @@ This example creates a container with default settings. If a container with the
container_name = 'products'
try:
container = database.create_container(id=container_name, partition_key=PartitionKey(path="/productName"))
except HTTPFailure as e:
if e.status_code != 409:
raise
except errors.CosmosResourceExistsError:
container = database.get_container_client(container_name)
except errors.CosmosHttpResponseError:
raise
```

The preceding snippet also handles the [HTTPFailure][ref_httpfailure] exception if the container creation failed. For more information on error handling and troubleshooting, see the [Troubleshooting](#troubleshooting) section.
The preceding snippet also handles the [CosmosHttpResponseError][ref_httpfailure] exception if the container creation failed. For more information on error handling and troubleshooting, see the [Troubleshooting](#troubleshooting) section.

### Get an existing container

Expand All @@ -139,7 +135,7 @@ container = database.get_container_client(container_name)

### Insert data

To insert items into a container, pass a dictionary containing your data to [Container.upsert_item][ref_container_upsert_item]. Each item you add to a container must include an `id` key with a value that uniquely identifies the item within the container.
To insert items into a container, pass a dictionary containing your data to [ContainerProxy.upsert_item][ref_container_upsert_item]. Each item you add to a container must include an `id` key with a value that uniquely identifies the item within the container.

This example inserts several items into the container, each with a unique `id`:

Expand All @@ -158,7 +154,7 @@ for i in range(1, 10):

### Delete data

To delete items from a container, use [Container.delete_item][ref_container_delete_item]. The SQL API in Cosmos DB does not support the SQL `DELETE` statement.
To delete items from a container, use [ContainerProxy.delete_item][ref_container_delete_item]. The SQL API in Cosmos DB does not support the SQL `DELETE` statement.

```Python
for item in container.query_items(query='SELECT * FROM products p WHERE p.productModel = "DISCONTINUED"',
Expand All @@ -168,7 +164,7 @@ for item in container.query_items(query='SELECT * FROM products p WHERE p.produc

### Query the database

A Cosmos DB SQL API database supports querying the items in a container with [Container.query_items][ref_container_query_items] using SQL-like syntax.
A Cosmos DB SQL API database supports querying the items in a container with [ContainerProxy.query_items][ref_container_query_items] using SQL-like syntax.

This example queries a container for items with a specific `id`:

Expand All @@ -186,7 +182,7 @@ for item in container.query_items(

> NOTE: Although you can specify any value for the container name in the `FROM` clause, we recommend you use the container name for consistency.
Perform parameterized queries by passing a dictionary containing the parameters and their values to [Container.query_items][ref_container_query_items]:
Perform parameterized queries by passing a dictionary containing the parameters and their values to [ContainerProxy.query_items][ref_container_query_items]:

```Python
discontinued_items = container.query_items(
Expand Down Expand Up @@ -243,13 +239,11 @@ For example, if you try to create a container using an ID (name) that's already
```Python
try:
database.create_container(id=container_name, partition_key=PartitionKey(path="/productName")
except HTTPFailure as e:
if e.status_code == 409:
print("""Error creating container.
except errors.CosmosResourceExistsError:
print("""Error creating container
HTTP status code 409: The ID (name) provided for the container is already in use.
The container name must be unique within the database.""")
else:
raise

```

## More sample code
Expand Down Expand Up @@ -277,20 +271,19 @@ For more extensive documentation on the Cosmos DB service, see the [Azure Cosmos
[cosmos_sql_queries]: https://docs.microsoft.com/azure/cosmos-db/how-to-sql-query
[cosmos_ttl]: https://docs.microsoft.com/azure/cosmos-db/time-to-live
[python]: https://www.python.org/downloads/
[ref_container_delete_item]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Container.delete_item
[ref_container_query_items]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Container.query_items
[ref_container_upsert_item]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Container.upsert_item
[ref_container]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Container
[ref_cosmos_sdk]: http://cosmosproto.westus.azurecontainer.io
[ref_cosmosclient_create_database]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.CosmosClient.create_database
[ref_cosmosclient]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.CosmosClient
[ref_database]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Database
[ref_httpfailure]: https://docs.microsoft.com/python/api/azure-cosmos/azure.cosmos.errors.httpfailure
[ref_item]: http://cosmosproto.westus.azurecontainer.io/#azure.cosmos.Item
[sample_database_mgmt]: https://github.com/binderjoe/cosmos-python-prototype/blob/master/examples/databasemanagementsample.py
[sample_document_mgmt]: https://github.com/binderjoe/cosmos-python-prototype/blob/master/examples/documentmanagementsample.py
[sample_examples_misc]: https://github.com/binderjoe/cosmos-python-prototype/blob/master/examples/examples.py
[source_code]: https://github.com/binderjoe/cosmos-python-prototype
[ref_container_delete_item]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.container.html#azure.cosmos.container.ContainerProxy.delete_item
[ref_container_query_items]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.container.html#azure.cosmos.container.ContainerProxy.query_items
[ref_container_upsert_item]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.container.html#azure.cosmos.container.ContainerProxy.upsert_item
[ref_container]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.container.html
[ref_cosmos_sdk]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.html
[ref_cosmosclient_create_database]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.cosmos_client.html#azure.cosmos.cosmos_client.CosmosClient.create_database
[ref_cosmosclient]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.cosmos_client.html
[ref_database]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.database.html
[ref_httpfailure]: https://azure.github.io/azure-sdk-for-python/ref/azure.cosmos.errors.html#azure.cosmos.errors.CosmosHttpResponseError
[sample_database_mgmt]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/DatabaseManagement
[sample_document_mgmt]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/DocumentManagement
[sample_examples_misc]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/examples.py
[source_code]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos
[venv]: https://docs.python.org/3/library/venv.html
[virtualenv]: https://virtualenv.pypa.io

Expand Down
2 changes: 1 addition & 1 deletion sdk/cosmos/azure-cosmos/azure/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
18 changes: 10 additions & 8 deletions sdk/cosmos/azure-cosmos/azure/cosmos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from .container import Container
from .container import ContainerProxy
from .cosmos_client import CosmosClient
from .database import Database
from .database import DatabaseProxy
from .user import UserProxy
from .scripts import ScriptsProxy
from .documents import (
ConsistencyLevel,
DataType,
Expand All @@ -35,17 +37,16 @@
)
from .partition_key import PartitionKey
from .permission import Permission
from .scripts import Scripts
from .user import User
from .version import VERSION

__all__ = (
"Container",
"CosmosClient",
"Database",
"DatabaseProxy",
"ContainerProxy",
"PartitionKey",
"Permission",
"Scripts",
"User",
"ScriptsProxy",
"UserProxy",
"ConsistencyLevel",
"DataType",
"IndexKind",
Expand All @@ -56,3 +57,4 @@
"TriggerOperation",
"TriggerType",
)
__version__ = VERSION
40 changes: 40 additions & 0 deletions sdk/cosmos/azure-cosmos/azure/cosmos/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import json
import uuid
import binascii
from typing import Dict, Any

import six
from six.moves.urllib.parse import quote as urllib_quote
Expand All @@ -39,6 +40,45 @@

# pylint: disable=protected-access

_COMMON_OPTIONS = {
'initial_headers': 'initialHeaders',
'pre_trigger_include': 'preTriggerInclude',
'post_trigger_include': 'postTriggerInclude',
'max_item_count': 'maxItemCount',
'access_condition': 'accessCondition',
'indexing_directive': 'indexingDirective',
'consistency_level': 'consistencyLevel',
'session_token': 'sessionToken',
'enable_scan_in_query': 'enableScanInQuery',
'resource_token_expiry_seconds': 'resourceTokenExpirySeconds',
'offer_type': 'offerType',
'offer_throughput': 'offerThroughput',
'partition_key': 'partitionKey',
'enable_cross_partition_query': 'enableCrossPartitionQuery',
'populate_query_metrics': 'populateQueryMetrics',
'enable_script_logging': 'enableScriptLogging',
'offer_enable_ru_per_minute_throughput': 'offerEnableRUPerMinuteThroughput',
'disable_ru_per_minute_usage': 'disableRUPerMinuteUsage',
'change_feed': 'changeFeed',
'continuation': 'continuation',
'is_start_from_beginning': 'isStartFromBeginning',
'populate_partition_key_range_statistics': 'populatePartitionKeyRangeStatistics',
'populate_quota_info': 'populateQuotaInfo'
}

def build_options(kwargs):
# type: (Dict[str, Any]) -> Dict[str, Any]
options = kwargs.pop('request_options', kwargs.pop('feed_options', {}))
for key, value in _COMMON_OPTIONS.items():
if key in kwargs:
options[value] = kwargs.pop(key)

if 'if_match' in kwargs:
options['accessCondition'] = {'type': 'IfMatch', 'condition': kwargs.pop('if_match')}
if 'if_none_match' in kwargs:
options['accessCondition'] = {'type': 'IfNoneMatch', 'condition': kwargs.pop('if_none_match')}
return options


def GetHeaders( # pylint: disable=too-many-statements,too-many-branches
cosmos_client_connection,
Expand Down
Loading

0 comments on commit a267b95

Please sign in to comment.