diff --git a/sdk/cosmos/azure-cosmos/HISTORY.md b/sdk/cosmos/azure-cosmos/HISTORY.md index 09087e4b5421..bbf84b9678aa 100644 --- a/sdk/cosmos/azure-cosmos/HISTORY.md +++ b/sdk/cosmos/azure-cosmos/HISTORY.md @@ -1,5 +1,11 @@ # Release History +## 4.0.0b6 + +- Fixed bug in synchronized_request for media APIs. +- Removed MediaReadMode and MediaRequestTimeout from ConnectionPolicy as media requests are not supported. + + ## 4.0.0b5 - azure.cosmos.errors module deprecated and replaced by azure.cosmos.exceptions diff --git a/sdk/cosmos/azure-cosmos/README.md b/sdk/cosmos/azure-cosmos/README.md index 5344752a2bae..81ee4336440d 100644 --- a/sdk/cosmos/azure-cosmos/README.md +++ b/sdk/cosmos/azure-cosmos/README.md @@ -305,15 +305,15 @@ 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]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.ContainerProxy.delete_item -[ref_container_query_items]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.ContainerProxy.query_items -[ref_container_upsert_item]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.ContainerProxy.upsert_item -[ref_container]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.ContainerProxy -[ref_cosmos_sdk]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html -[ref_cosmosclient_create_database]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.CosmosClient.create_database -[ref_cosmosclient]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.CosmosClient -[ref_database]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.DatabaseProxy -[ref_httpfailure]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b5/azure.cosmos.html#azure.cosmos.exceptions.CosmosHttpResponseError +[ref_container_delete_item]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.ContainerProxy.delete_item +[ref_container_query_items]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.ContainerProxy.query_items +[ref_container_upsert_item]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.ContainerProxy.upsert_item +[ref_container]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.ContainerProxy +[ref_cosmos_sdk]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html +[ref_cosmosclient_create_database]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.CosmosClient.create_database +[ref_cosmosclient]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.CosmosClient +[ref_database]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.DatabaseProxy +[ref_httpfailure]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-cosmos/4.0.0b6/azure.cosmos.html#azure.cosmos.exceptions.CosmosHttpResponseError [sample_database_mgmt]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/database_management.py [sample_document_mgmt]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/document_management.py [sample_examples_misc]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/cosmos/azure-cosmos/samples/examples.py diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_base.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_base.py index 5b866e541158..fcf61707c42f 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_base.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_base.py @@ -336,33 +336,6 @@ def GetResourceIdOrFullNameFromLink(resource_link): return None -def GetAttachmentIdFromMediaId(media_id): - """Gets attachment id from media id. - - :param str media_id: - - :return: - The attachment id from the media id. - :rtype: str - """ - altchars = "+-" - if not six.PY2: - altchars = altchars.encode("utf-8") - # altchars for '+' and '/'. We keep '+' but replace '/' with '-' - buffer = base64.b64decode(str(media_id), altchars) - resoure_id_length = 20 - attachment_id = "" - if len(buffer) > resoure_id_length: - # We are cutting off the storage index. - attachment_id = base64.b64encode(buffer[0:resoure_id_length], altchars) - if not six.PY2: - attachment_id = attachment_id.decode("utf-8") - else: - attachment_id = media_id - - return attachment_id - - def GenerateGuidId(): """Gets a random GUID. diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py index e7bcc94dc978..4484f7fabc4c 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py @@ -1708,301 +1708,6 @@ def DeleteItem(self, document_link, options=None, **kwargs): document_id = base.GetResourceIdOrFullNameFromLink(document_link) return self.DeleteResource(path, "docs", document_id, None, options, **kwargs) - def CreateAttachment(self, document_link, attachment, options=None, **kwargs): - """Creates an attachment in a document. - - :param str document_link: - The link to the document. - :param dict attachment: - The Azure Cosmos attachment to create. - :param dict options: - The request options for the request. - - :return: - The created Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - document_id, path = self._GetItemIdWithPathForAttachment(attachment, document_link) - return self.Create(attachment, path, "attachments", document_id, None, options, **kwargs) - - def UpsertAttachment(self, document_link, attachment, options=None, **kwargs): - """Upserts an attachment in a document. - - :param str document_link: - The link to the document. - :param dict attachment: - The Azure Cosmos attachment to upsert. - :param dict options: - The request options for the request. - - :return: - The upserted Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - document_id, path = self._GetItemIdWithPathForAttachment(attachment, document_link) - return self.Upsert(attachment, path, "attachments", document_id, None, options, **kwargs) - - def _GetItemIdWithPathForAttachment(self, attachment, document_link): # pylint: disable=no-self-use - CosmosClientConnection.__ValidateResource(attachment) - path = base.GetPathFromLink(document_link, "attachments") - document_id = base.GetResourceIdOrFullNameFromLink(document_link) - return document_id, path - - def CreateAttachmentAndUploadMedia(self, document_link, readable_stream, options=None, **kwargs): - """Creates an attachment and upload media. - - :param str document_link: - The link to the document. - :param (file-like stream object) readable_stream: - :param dict options: - The request options for the request. - - :return: - The created Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - document_id, initial_headers, path = self._GetItemIdWithPathForAttachmentMedia(document_link, options) - return self.Create(readable_stream, path, "attachments", document_id, initial_headers, options, **kwargs) - - def UpsertAttachmentAndUploadMedia(self, document_link, readable_stream, options=None, **kwargs): - """Upserts an attachment and upload media. - - :param str document_link: - The link to the document. - :param (file-like stream object) readable_stream: - :param dict options: - The request options for the request. - - :return: - The upserted Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - document_id, initial_headers, path = self._GetItemIdWithPathForAttachmentMedia(document_link, options) - return self.Upsert(readable_stream, path, "attachments", document_id, initial_headers, options, **kwargs) - - def _GetItemIdWithPathForAttachmentMedia(self, document_link, options): - initial_headers = dict(self.default_headers) - - # Add required headers slug and content-type. - if options.get("slug"): - initial_headers[http_constants.HttpHeaders.Slug] = options["slug"] - - if options.get("contentType"): - initial_headers[http_constants.HttpHeaders.ContentType] = options["contentType"] - else: - initial_headers[http_constants.HttpHeaders.ContentType] = runtime_constants.MediaTypes.OctetStream - - path = base.GetPathFromLink(document_link, "attachments") - document_id = base.GetResourceIdOrFullNameFromLink(document_link) - return document_id, initial_headers, path - - def ReadAttachment(self, attachment_link, options=None, **kwargs): - """Reads an attachment. - - :param str attachment_link: - The link to the attachment. - :param dict options: - The request options for the request. - - :return: - The read Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - path = base.GetPathFromLink(attachment_link) - attachment_id = base.GetResourceIdOrFullNameFromLink(attachment_link) - return self.Read(path, "attachments", attachment_id, None, options, **kwargs) - - def ReadAttachments(self, document_link, options=None, **kwargs): - """Reads all attachments in a document. - - :param str document_link: - The link to the document. - :param dict options: - The request options for the request. - - :return: - Query Iterable of Attachments. - :rtype: - query_iterable.QueryIterable - - """ - if options is None: - options = {} - - return self.QueryAttachments(document_link, None, options, **kwargs) - - def QueryAttachments(self, document_link, query, options=None, **kwargs): - """Queries attachments in a document. - - :param str document_link: - The link to the document. - :param (str or dict) query: - :param dict options: - The request options for the request. - - :return: - Query Iterable of Attachments. - :rtype: - query_iterable.QueryIterable - - """ - if options is None: - options = {} - - path = base.GetPathFromLink(document_link, "attachments") - document_id = base.GetResourceIdOrFullNameFromLink(document_link) - - def fetch_fn(options): - return ( - self.__QueryFeed( - path, "attachments", document_id, lambda r: r["Attachments"], - lambda _, b: b, query, options, **kwargs - ), - self.last_response_headers, - ) - - return ItemPaged( - self, query, options, fetch_function=fetch_fn, page_iterator_class=query_iterable.QueryIterable - ) - - def ReadMedia(self, media_link, **kwargs): - """Reads a media. - - When self.connection_policy.MediaReadMode == - documents.MediaReadMode.Streamed, returns a file-like stream object; - otherwise, returns a str. - - :param str media_link: - The link to the media. - - :return: - The read Media. - :rtype: - str or file-like stream object - - """ - default_headers = self.default_headers - - path = base.GetPathFromLink(media_link) - media_id = base.GetResourceIdOrFullNameFromLink(media_link) - attachment_id = base.GetAttachmentIdFromMediaId(media_id) - headers = base.GetHeaders(self, default_headers, "get", path, attachment_id, "media", {}) - - # ReadMedia will always use WriteEndpoint since it's not replicated in readable Geo regions - request_params = _request_object.RequestObject("media", documents._OperationType.Read) - result, self.last_response_headers = self.__Get(path, request_params, headers, **kwargs) - return result - - def UpdateMedia(self, media_link, readable_stream, options=None, **kwargs): - """Updates a media and returns it. - - :param str media_link: - The link to the media. - :param (file-like stream object) readable_stream: - :param dict options: - The request options for the request. - - :return: - The updated Media. - :rtype: - str or file-like stream object - - """ - if options is None: - options = {} - - initial_headers = dict(self.default_headers) - - # Add required headers slug and content-type in case the body is a stream - if options.get("slug"): - initial_headers[http_constants.HttpHeaders.Slug] = options["slug"] - - if options.get("contentType"): - initial_headers[http_constants.HttpHeaders.ContentType] = options["contentType"] - else: - initial_headers[http_constants.HttpHeaders.ContentType] = runtime_constants.MediaTypes.OctetStream - - path = base.GetPathFromLink(media_link) - media_id = base.GetResourceIdOrFullNameFromLink(media_link) - attachment_id = base.GetAttachmentIdFromMediaId(media_id) - headers = base.GetHeaders(self, initial_headers, "put", path, attachment_id, "media", options) - - # UpdateMedia will use WriteEndpoint since it uses PUT operation - request_params = _request_object.RequestObject("media", documents._OperationType.Update) - result, self.last_response_headers = self.__Put(path, request_params, readable_stream, headers, **kwargs) - - self._UpdateSessionIfRequired(headers, result, self.last_response_headers) - return result - - def ReplaceAttachment(self, attachment_link, attachment, options=None, **kwargs): - """Replaces an attachment and returns it. - - :param str attachment_link: - The link to the attachment. - :param dict attachment: - :param dict options: - The request options for the request. - - :return: - The replaced Attachment - :rtype: - dict - - """ - if options is None: - options = {} - - CosmosClientConnection.__ValidateResource(attachment) - path = base.GetPathFromLink(attachment_link) - attachment_id = base.GetResourceIdOrFullNameFromLink(attachment_link) - return self.Replace(attachment, path, "attachments", attachment_id, None, options, **kwargs) - - def DeleteAttachment(self, attachment_link, options=None, **kwargs): - """Deletes an attachment. - - :param str attachment_link: - The link to the attachment. - :param dict options: - The request options for the request. - - :return: - The deleted Attachment. - :rtype: - dict - - """ - if options is None: - options = {} - - path = base.GetPathFromLink(attachment_link) - attachment_id = base.GetResourceIdOrFullNameFromLink(attachment_link) - return self.DeleteResource(path, "attachments", attachment_id, None, options, **kwargs) - def ReplaceTrigger(self, trigger_link, trigger, options=None, **kwargs): """Replaces a trigger and returns it. diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_synchronized_request.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_synchronized_request.py index 00716020cc97..7bac90774806 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_synchronized_request.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_synchronized_request.py @@ -29,7 +29,6 @@ import six from azure.core.exceptions import DecodeError # type: ignore -from . import documents from . import exceptions from . import http_constants from . import _retry_utility @@ -90,10 +89,7 @@ def _Request(global_endpoint_manager, request_params, connection_policy, pipelin """ # pylint: disable=protected-access - is_media = request.url.find("media") > -1 - is_media_stream = is_media and connection_policy.MediaReadMode == documents.MediaReadMode.Streamed - - connection_timeout = connection_policy.MediaRequestTimeout if is_media else connection_policy.RequestTimeout + connection_timeout = connection_policy.RequestTimeout connection_timeout = kwargs.pop("connection_timeout", connection_timeout / 1000.0) # Every request tries to perform a refresh @@ -129,18 +125,18 @@ def _Request(global_endpoint_manager, request_params, connection_policy, pipelin if connection_policy.SSLConfiguration or "connection_cert" in kwargs: ca_certs = connection_policy.SSLConfiguration.SSLCaCerts cert_files = (connection_policy.SSLConfiguration.SSLCertFile, connection_policy.SSLConfiguration.SSLKeyFile) - response = pipeline_client._pipeline.run( + response = _PipelineRunFunction( + pipeline_client, request, - stream=is_media_stream, connection_timeout=connection_timeout, connection_verify=kwargs.pop("connection_verify", ca_certs), connection_cert=kwargs.pop("connection_cert", cert_files), **kwargs ) else: - response = pipeline_client._pipeline.run( + response = _PipelineRunFunction( + pipeline_client, request, - stream=is_media_stream, connection_timeout=connection_timeout, # If SSL is disabled, verify = false connection_verify=kwargs.pop("connection_verify", is_ssl_enabled), @@ -150,11 +146,6 @@ def _Request(global_endpoint_manager, request_params, connection_policy, pipelin response = response.http_response headers = dict(response.headers) - # In case of media stream response, return the response to the user and the user - # will need to handle reading the response. - if is_media_stream: - return (response.stream_download(pipeline_client._pipeline), headers) - data = response.body() if data and not six.PY2: # python 3 compatible: convert data from byte to unicode string @@ -170,20 +161,22 @@ def _Request(global_endpoint_manager, request_params, connection_policy, pipelin raise exceptions.CosmosHttpResponseError(message=data, response=response) result = None - if is_media: - result = data - else: - if data: - try: - result = json.loads(data) - except Exception as e: - raise DecodeError( - message="Failed to decode JSON data: {}".format(e), - response=response, - error=e) + if data: + try: + result = json.loads(data) + except Exception as e: + raise DecodeError( + message="Failed to decode JSON data: {}".format(e), + response=response, + error=e) - return (result, headers) + return result, headers + + +def _PipelineRunFunction(pipeline_client, request, **kwargs): + # pylint: disable=protected-access + return pipeline_client._pipeline.run(request, **kwargs) def SynchronizedRequest( client, diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_version.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_version.py index a989c2271afe..95f4cc3e8f15 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_version.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_version.py @@ -19,4 +19,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -VERSION = "4.0.0b5" +VERSION = "4.0.0b6" diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py index d1b61957ad8c..44e843c05853 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py @@ -143,7 +143,6 @@ def __GetAuthorizationTokenUsingResourceTokens(resource_tokens, path, resource_i "users", "permissions", "attachments", - "media", "conflicts", "offers", ] diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py b/sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py index aeca4e68de5f..804a219f8b97 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py @@ -77,9 +77,7 @@ def _build_connection_policy(kwargs): policy.RequestTimeout = kwargs.pop('request_timeout', None) or \ kwargs.pop('connection_timeout', None) or \ policy.RequestTimeout - policy.MediaRequestTimeout = kwargs.pop('media_request_timeout', None) or policy.MediaRequestTimeout policy.ConnectionMode = kwargs.pop('connection_mode', None) or policy.ConnectionMode - policy.MediaReadMode = kwargs.pop('media_read_mode', None) or policy.MediaReadMode policy.ProxyConfiguration = kwargs.pop('proxy_config', None) or policy.ProxyConfiguration policy.EnableEndpointDiscovery = kwargs.pop('enable_endpoint_discovery', None) or policy.EnableEndpointDiscovery policy.PreferredLocations = kwargs.pop('preferred_locations', None) or policy.PreferredLocations @@ -131,9 +129,7 @@ class CosmosClient(object): :param str consistency_level: Consistency level to use for the session. The default value is "Session". :keyword int timeout: An absolute timeout in seconds, for the combined HTTP request and response processing. :keyword int request_timeout: The HTTP request timeout in seconds. - :keyword int media_request_timeout: The media request timeout in seconds. :keyword str connection_mode: The connection mode for the client - currently only supports 'Gateway'. - :keyword str media_read_mode: The mode for use with downloading attachment content - default value is `Buffered`. :keyword proxy_config: Connection proxy configuration. :paramtype proxy_config: ~azure.cosmos.ProxyConfiguration :keyword ssl_config: Connection SSL configuration. diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/documents.py b/sdk/cosmos/azure-cosmos/azure/cosmos/documents.py index 0f5f4d1e22b6..bd7f2271a1fe 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/documents.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/documents.py @@ -227,27 +227,6 @@ class ConnectionMode(object): Gateway = 0 -class MediaReadMode(object): - """Represents the mode for use with downloading attachment content - (aka media). - - :ivar str Buffered: - Content is buffered at the client and not directly - streamed from the content store. - - Use Buffered to reduce the time taken to read and write media files. - :ivar str Streamed: - Content is directly streamed from the content store - without any buffering at the client. - - Use Streamed to reduce the client memory overhead of reading and - writing media files. - """ - - Buffered = "Buffered" - Streamed = "Streamed" - - class PermissionMode(object): """Enumeration specifying applicability of permission. @@ -338,14 +317,9 @@ class ConnectionPolicy(object): # pylint: disable=too-many-instance-attributes :ivar int RequestTimeout: Gets or sets the request timeout (time to wait for response from network peer). - :ivar int MediaRequestTimeout: - Gets or sets Time to wait for response - from network peer for attachment content (aka media) operations. :ivar documents.ConnectionMode ConnectionMode: Gets or sets the connection mode used in the client. Currently only Gateway is supported. - :ivar MediaReadMode.Buffered MediaReadMode: - Gets or sets the attachment content (aka media) download mode. :ivar documents.SSLConfiguration SSLConfiguration: Gets or sets the SSL configuration. :ivar documents.ProxyConfiguration ProxyConfiguration: @@ -379,15 +353,10 @@ class ConnectionPolicy(object): # pylint: disable=too-many-instance-attributes """ __defaultRequestTimeout = 60000 # milliseconds - # defaultMediaRequestTimeout is based upon the blob client timeout and the - # retry policy. - __defaultMediaRequestTimeout = 300000 # milliseconds def __init__(self): self.RequestTimeout = self.__defaultRequestTimeout - self.MediaRequestTimeout = self.__defaultMediaRequestTimeout self.ConnectionMode = ConnectionMode.Gateway - self.MediaReadMode = MediaReadMode.Buffered self.SSLConfiguration = None self.ProxyConfiguration = None self.EnableEndpointDiscovery = True diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/http_constants.py b/sdk/cosmos/azure-cosmos/azure/cosmos/http_constants.py index 040d6d0c9ab8..c08917fa601d 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/http_constants.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/http_constants.py @@ -406,7 +406,6 @@ class ResourceType(object): Offer = "offers" Topology = "topology" DatabaseAccount = "databaseaccount" - Media = "media" @staticmethod def IsCollectionChild(resourceType): diff --git a/sdk/cosmos/azure-cosmos/test/media_tests.py b/sdk/cosmos/azure-cosmos/test/media_tests.py new file mode 100644 index 000000000000..49e306fcce49 --- /dev/null +++ b/sdk/cosmos/azure-cosmos/test/media_tests.py @@ -0,0 +1,62 @@ +import azure.cosmos.cosmos_client as cosmos_client +import azure.cosmos._synchronized_request as synchronized_request +import unittest +import test_config + + +class FakePipelineResponse: + def __init__( + self, + http_response, + ): + self.http_response = http_response + + +class FakeHttpResponse: + def __init__( + self, + content, + headers, + status_code + ): + self.content = content + self.headers = headers + self.status_code = status_code + + def body(self): + return self.content + + +class MediaTests(unittest.TestCase): + database_account_string = b'''{"_self": "", + "id": "fake-media", + "_rid": "fake-media.documents.azure.com", + "media": "//media/", + "addresses": "//addresses/", + "_dbs": "//dbs/", + "writableLocations": [ + {"name": "UK South", "databaseAccountEndpoint": "https://fake-media-uksouth.documents.azure.com:443/"}], + "readableLocations": [ + {"name": "UK South", "databaseAccountEndpoint": "https://fake-media-uksouth.documents.azure.com:443/"}, + {"name": "UK West", "databaseAccountEndpoint": "https://fake-media-ukwest.documents.azure.com:443/"}], + "enableMultipleWriteLocations": false, + "userReplicationPolicy": {"asyncReplication": false, "minReplicaSetSize": 3, "maxReplicasetSize": 4}, + "userConsistencyPolicy": {"defaultConsistencyLevel": "Session"}, + "systemReplicationPolicy": {"minReplicaSetSize": 3, "maxReplicasetSize": 4}, + "readPolicy": {"primaryReadCoefficient": 1, "secondaryReadCoefficient": 1}}''' + + response = FakePipelineResponse(FakeHttpResponse(database_account_string, {}, 200)) + + def test_account_name_with_media(self): + host = "https://fake-media.documents.azure.com:443/" + master_key = test_config._test_config.masterKey + try: + original_execute_function = synchronized_request._PipelineRunFunction + synchronized_request._PipelineRunFunction = self._MockRunFunction + cosmos_client.CosmosClient(host, master_key) + finally: + synchronized_request._PipelineRunFunction = original_execute_function + + def _MockRunFunction(self, pipeline_client, request, **kwargs): + return self.response +