From 15dd5dfa2f9ef78b9d6b575ff6c2fca9c713fe57 Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Mon, 27 Dec 2021 15:14:24 +0300 Subject: [PATCH 1/7] Parsing e-tag. --- async_couch/clients/documents/responses.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/async_couch/clients/documents/responses.py b/async_couch/clients/documents/responses.py index 7f09d6d..1194076 100644 --- a/async_couch/clients/documents/responses.py +++ b/async_couch/clients/documents/responses.py @@ -10,6 +10,12 @@ class DocumentExistingResponse(EmptyResponse): e_tag: str # Document’s revision token + @classmethod + def load(cls, response): + e_tag = response.headers.get('ETag') + if e_tag: + return cls(e_tag=e_tag.replace('"', '')) + @dataclass class DocumentDetailedResponse(EmptyResponse): From c82151875d72d508bea9a37f96276d128694d88b Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Mon, 27 Dec 2021 19:00:22 +0300 Subject: [PATCH 2/7] Fixed find endpoint, added FindResponse. --- async_couch/clients/database/endpoints.py | 11 +++++------ async_couch/clients/database/responses.py | 16 ++++++++++++++++ async_couch/clients/designs/responses.py | 8 ++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/async_couch/clients/database/endpoints.py b/async_couch/clients/database/endpoints.py index 3cd6024..24e0fe3 100644 --- a/async_couch/clients/database/endpoints.py +++ b/async_couch/clients/database/endpoints.py @@ -1,7 +1,6 @@ -import typing - from async_couch import types from async_couch.clients.designs.responses import ExecuteViewResponse + from async_couch.http_clients.base_client import BaseEndpoint from . import responses as resp @@ -587,7 +586,7 @@ async def db_bulk_get(self, result['id'] = id return await self.http_client.make_request( - endpoint='/db/_bulk_get', + endpoint='/{db}/_bulk_get', method=types.HttpMethod.POST, statuses={ 200: 'Request completed successfully', @@ -648,7 +647,7 @@ async def db_bulk_docs(self, query['new_edits'] = new_edits return await self.http_client.make_request( - endpoint='/db/_bulk_docs', + endpoint='/{db}/_bulk_docs', method=types.HttpMethod.POST, statuses={ 201: 'Document(s) have been created or updated', @@ -777,7 +776,7 @@ async def db_find(self, json_data['selector'] = selector return await self.http_client.make_request( - endpoint='/db/_find', + endpoint='/{db}/_find', method=types.HttpMethod.POST, statuses={ 200: 'Request completed successfully', @@ -789,6 +788,6 @@ async def db_find(self, query=query, path={'db': db}, json_data=json_data, - response_model=ExecuteViewResponse + response_model=resp.FindResponse ) diff --git a/async_couch/clients/database/responses.py b/async_couch/clients/database/responses.py index c2d8ecf..44044ab 100644 --- a/async_couch/clients/database/responses.py +++ b/async_couch/clients/database/responses.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +import typing from async_couch.types import EmptyResponse @@ -53,3 +54,18 @@ class ServerResponse(EmptyResponse): # on this string for counting the number of updates props_partitioned: models.DatabaseProps + + +@dataclass +class FindResponse(EmptyResponse): + docs: typing.List[dict] + # Array of documents matching the search. In each matching document, the + # fields specified in the fields part of the request body are listed, along + # with their values. + + warning: str + # Execution warnings + + bookmark: str + # An opaque string used for paging. See the bookmark field in the request + # for usage details. diff --git a/async_couch/clients/designs/responses.py b/async_couch/clients/designs/responses.py index 7a9f5dd..1acc417 100644 --- a/async_couch/clients/designs/responses.py +++ b/async_couch/clients/designs/responses.py @@ -19,7 +19,7 @@ class SizeObj: @dataclass class DesignViewIndex: compact_running: bool - """Indicates whether a compaction routine is currently + """Indicates whether a compaction routine is currently running on the view""" sizes: SizeObj @@ -35,7 +35,7 @@ class DesignViewIndex: """MD5 signature of the views for the design document""" update_seq: int or str - """The update sequence of the corresponding database that has been + """The update sequence of the corresponding database that has been indexed""" updater_running: bool @@ -45,7 +45,7 @@ class DesignViewIndex: """Number of clients waiting on views from this design document""" waiting_commit: bool - """Indicates if there are outstanding commits to the underlying database + """Indicates if there are outstanding commits to the underlying database that need to processed""" @@ -71,7 +71,7 @@ class ExecuteViewResponse(EmptyResponse): """Offset where the document list started""" rows: typing.List[ExecuteViewRow] = None - """Array of view row objects. By default the information returned + """Array of view row objects. By default the information returned contains only the document ID and revision""" total_rows: int = None From 1f56c293ab0ffea0a9ff3691dbe6a5f7614aa649 Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Tue, 28 Dec 2021 13:21:47 +0300 Subject: [PATCH 3/7] Changed db url parsing to allow empty port. --- async_couch/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/async_couch/__init__.py b/async_couch/__init__.py index f385ac5..4217b51 100644 --- a/async_couch/__init__.py +++ b/async_couch/__init__.py @@ -53,5 +53,9 @@ def get_couch_client(https: bool = False, if https: schema += 's' - http_client = request_adapter.get_client(f'{schema}://{host}:{port}', **kwargs) + url = f'{schema}://{host}' + if port: + url += f':{port}' + + http_client = request_adapter.get_client(url, **kwargs) return CouchClient(http_client=http_client) From cf69fa35c317007421aa48b693d3dd0531275988 Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Fri, 28 Jan 2022 17:15:18 +0300 Subject: [PATCH 4/7] Fixed find endpoint --- async_couch/clients/database/endpoints.py | 33 ++++++++++------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/async_couch/clients/database/endpoints.py b/async_couch/clients/database/endpoints.py index 24e0fe3..4b16606 100644 --- a/async_couch/clients/database/endpoints.py +++ b/async_couch/clients/database/endpoints.py @@ -744,36 +744,32 @@ async def db_find(self, exc.CouchResponseError: If server error occurred """ + json_data = dict() - query = dict() - + if selector: + json_data['selector'] = selector if limit: - query['limit'] = limit + json_data['limit'] = limit if skip: - query['skip'] = skip + json_data['skip'] = skip if sort: - query['sort'] = sort + json_data['sort'] = sort if fields: - query['fields'] = fields + json_data['fields'] = fields if use_index: - query['use_index'] = use_index + json_data['use_index'] = use_index if r: - query['r'] = r + json_data['r'] = r if bookmark: - query['bookmark'] = bookmark + json_data['bookmark'] = bookmark if update: - query['update'] = update + json_data['update'] = update if stable: - query['stable'] = stable + json_data['stable'] = stable if stale: - query['stale'] = stale + json_data['stale'] = stale if execution_stats: - query['execution_stats'] = execution_stats - - json_data = dict() - - if selector: - json_data['selector'] = selector + json_data['execution_stats'] = execution_stats return await self.http_client.make_request( endpoint='/{db}/_find', @@ -785,7 +781,6 @@ async def db_find(self, 404: 'Requested database not found', 500: 'Query execution error' }, - query=query, path={'db': db}, json_data=json_data, response_model=resp.FindResponse From b79c4896282abacf574726b6b1b636455b7869e8 Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Fri, 25 Feb 2022 23:12:05 +0300 Subject: [PATCH 5/7] Added bytes range support --- async_couch/clients/documents/endpoints.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/async_couch/clients/documents/endpoints.py b/async_couch/clients/documents/endpoints.py index 648a02e..745542f 100644 --- a/async_couch/clients/documents/endpoints.py +++ b/async_couch/clients/documents/endpoints.py @@ -485,7 +485,8 @@ async def attachment_get(self, db: str, doc_id: str, attachment_id: str, - rev: str = None) -> types.UniversalResponse: + rev: str = None, + bytes_range: tuple = None) -> types.UniversalResponse: """ Returns the file attachment associated with the document. The raw data of the associated attachment is returned (just as if you were @@ -508,6 +509,10 @@ async def attachment_get(self, rev: str = None Actual document’s revision + bytes_range: tuple = None + Range of bytes to get from attachment, works only with 'application/octet-stream' + Content-Type of attachment + Returns ---------- `UniversalResponse` @@ -523,16 +528,26 @@ async def attachment_get(self, if rev: query['rev'] = rev + if bytes_range: + if len(bytes_range) == 2: + headers = {'Range': f'bytes={bytes_range[0]}-{bytes_range[1]}'} + else: + headers = {'Range': f'bytes={bytes_range[0]}-'} + else: + headers = None + return await self.http_client.make_request( endpoint=self.__doc_attachment_endpoint__, method=types.HttpMethod.GET, statuses={ 200: 'Attachment exists', + 206: 'Attachment partially read', 401: 'Read privilege required', 404: 'Specified database, document or attachment was not found' }, path={'db': db, 'doc_id': doc_id, 'att_id': attachment_id}, - query=query + query=query, + headers=headers, ) async def attachment_upload(self, From 21a36e1d133b4b5c7737d7fa56c782640d1af9b0 Mon Sep 17 00:00:00 2001 From: Kirill Ivkin Date: Fri, 4 Mar 2022 17:48:12 +0300 Subject: [PATCH 6/7] Added close method --- async_couch/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/async_couch/__init__.py b/async_couch/__init__.py index 4217b51..90657e4 100644 --- a/async_couch/__init__.py +++ b/async_couch/__init__.py @@ -17,7 +17,9 @@ class CouchClient(DocEndpoint, DesignDocEndpoint, DesignViewEndpoint, DatabaseEndpoint): - pass + + async def close(self): + await self.http_client.aclose() def get_couch_client(https: bool = False, From c46ce8da6f058024c95db67151a4498042280206 Mon Sep 17 00:00:00 2001 From: dzanadvornykh Date: Sat, 5 Mar 2022 09:31:04 +0300 Subject: [PATCH 7/7] bug with query prameters fixed --- async_couch/clients/documents/endpoints.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/async_couch/clients/documents/endpoints.py b/async_couch/clients/documents/endpoints.py index 745542f..b15a4a4 100644 --- a/async_couch/clients/documents/endpoints.py +++ b/async_couch/clients/documents/endpoints.py @@ -151,19 +151,19 @@ async def doc_get(self, query['local_seq'] = local_seq if meta: - query['local_seq'] = local_seq + query['meta'] = meta if open_revs: - query['open_revs'] = local_seq + query['open_revs'] = open_revs if rev: - query['rev'] = local_seq + query['rev'] = rev if revs: - query['revs'] = local_seq + query['revs'] = revs if revs_info: - query['revs_info'] = local_seq + query['revs_info'] = revs_info return await self.http_client.make_request( endpoint=self.__doc_endpoint__,