Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
10 changes: 8 additions & 2 deletions async_couch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -53,5 +55,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)
44 changes: 19 additions & 25 deletions async_couch/clients/database/endpoints.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -745,39 +744,35 @@ 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',
endpoint='/{db}/_find',
method=types.HttpMethod.POST,
statuses={
200: 'Request completed successfully',
Expand All @@ -786,9 +781,8 @@ 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=ExecuteViewResponse
response_model=resp.FindResponse
)

16 changes: 16 additions & 0 deletions async_couch/clients/database/responses.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
import typing

from async_couch.types import EmptyResponse

Expand Down Expand Up @@ -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.
8 changes: 4 additions & 4 deletions async_couch/clients/designs/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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"""


Expand All @@ -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
Expand Down
29 changes: 22 additions & 7 deletions async_couch/clients/documents/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__,
Expand Down Expand Up @@ -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
Expand All @@ -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`
Expand All @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions async_couch/clients/documents/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down