Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sdk/cosmos/azure-cosmos/HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release History

## 4.0.0b6

- Fixed bug in synchronized_request for media APIs.
Comment thread
srinathnarayanan marked this conversation as resolved.
Outdated

## 4.0.0b5

- azure.cosmos.errors module deprecated and replaced by azure.cosmos.exceptions
Expand Down
18 changes: 9 additions & 9 deletions sdk/cosmos/azure-cosmos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 0 additions & 27 deletions sdk/cosmos/azure-cosmos/azure/cosmos/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
295 changes: 0 additions & 295 deletions sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
Loading