dubidoc 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dubidoc/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ """Top-level package for Dubidoc API wrapper."""
2
+
3
+ __author__ = 'Dmytro Litvinov'
4
+ __email__ = 'me@dmytrolitvinov.com'
5
+ __version__ = '0.1.0'
6
+
7
+ from .client import DubidocAPIClient
@@ -0,0 +1,7 @@
1
+ from .access_token import *
2
+ from .authentication import *
3
+ from .device import *
4
+ from .document import *
5
+ from .document_link import *
6
+ from .download import *
7
+ from .participant import *
@@ -0,0 +1,33 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+ __all__ = ('AccessTokenAPI',)
4
+
5
+
6
+ class AccessTokenAPI:
7
+ PATH = 'access-tokens'
8
+
9
+ def __init__(self, client):
10
+ self.client = client
11
+
12
+ def get_tokens(self):
13
+ """
14
+ Отримати список всіх згенерованих Вами API-ключів (токенів)
15
+ """
16
+ path = self.PATH
17
+ return self.client.make_request(HttpMethod.GET, path)
18
+
19
+ def generate_token(self, title):
20
+ """
21
+ Генерування статичного API-ключа (токену) для доступу до API
22
+ :param title:
23
+ """
24
+ path = self.PATH
25
+ return self.client.make_request(HttpMethod.POST, path, body={'title': title})
26
+
27
+ def revoke_token(self, token_id):
28
+ """
29
+ Зробити обраний API-ключ (токен) недійсним
30
+ :param token_id:
31
+ """
32
+ path = f'{self.PATH}/{token_id}'
33
+ return self.client.make_request(HttpMethod.DELETE, path)
@@ -0,0 +1,38 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+
4
+ __all__ = ('AuthenticationAPI',)
5
+
6
+
7
+ class AuthenticationAPI:
8
+ def __init__(self, client):
9
+ self.client = client
10
+
11
+ def get_code(self, login):
12
+ """
13
+ Title: Отримати код авторизації
14
+ Description: Метод відправки тимчасового коду для авторизації через email
15
+ """
16
+ path = self.PATH
17
+ body = {'login': login}
18
+ return self.client.make_request(HttpMethod.POST, path, body)
19
+
20
+ def get_token(self, login, code):
21
+ """
22
+ Title: Отримати авторизаційний токен
23
+ Description: Метод для отримання токену користувача на основі email та тимчасового коду авторизації
24
+ """
25
+ path = 'auth/get-token'
26
+ body = {'login': login, 'code': code}
27
+ return self.client.make_request(HttpMethod.POST, path, body)
28
+
29
+ def refresh(self, refresh_token):
30
+ """
31
+ Title: Оновити авторизаційний токен
32
+ Description: Продовжити дію авторизаційного токену користувача на основі refresh токену
33
+ :param token_id:
34
+ :return:
35
+ """
36
+ path = 'token/refresh'
37
+ body = {'refresh_token': refresh_token}
38
+ return self.client.delete(HttpMethod.POST, path, body)
@@ -0,0 +1,25 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+ __all__ = ('DeviceAPI',)
4
+
5
+
6
+ class DeviceAPI:
7
+ def __init__(self, client):
8
+ self.client = client
9
+
10
+ def register(self, token):
11
+ """
12
+ Title: Зареєструвати пристрій для відправки сповіщень
13
+ Description: Зареєструвати device token який отриманий через Firebase Cloud Messaging для відправки нотифікацій користувачу
14
+ """
15
+ path = 'devices'
16
+ body = {'token': token}
17
+ return self.client.make_request(HttpMethod.POST, path, body)
18
+
19
+ def unregister(self, token):
20
+ """
21
+ Title: Відписати пристрій від отримання сповіщень
22
+ Description: Скасувати відправку сповіщень для device token
23
+ """
24
+ path = f'devices/{token}'
25
+ return self.client.make_request(HttpMethod.DELETE, path)
@@ -0,0 +1,54 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+
4
+ __all__ = ('DocumentAPI',)
5
+
6
+
7
+ class DocumentAPI:
8
+ PATH = 'documents'
9
+
10
+ def __init__(self, client):
11
+ self.client = client
12
+
13
+ def list(self):
14
+ return self.client.make_request(HttpMethod.GET, self.PATH)
15
+
16
+ def create(self, body, organization_id=None):
17
+ return self.client.make_request(HttpMethod.POST, self.PATH, body)
18
+
19
+ def get(self, document_id):
20
+ path = f'{self.PATH}/{document_id}'
21
+ return self.client.make_request(HttpMethod.GET, path)
22
+
23
+ def edit(self, document_id, title):
24
+ path = f'{self.PATH}/{document_id}'
25
+ body = {
26
+ 'title': title,
27
+ }
28
+ return self.client.make_request(HttpMethod.PUT, path, body)
29
+
30
+ def delete(self, document_id):
31
+ """
32
+ Title: Видалення документа
33
+ Description: Увага, видалити документ можливо лише за умови, що він не був підписаний або надісланий отримувачу
34
+ """
35
+ path = f'{self.PATH}/{document_id}'
36
+ return self.client.make_request(HttpMethod.DELETE, path)
37
+
38
+ def download(self):
39
+ raise NotImplementedError
40
+
41
+ def unarchive(self):
42
+ raise NotImplementedError
43
+
44
+ def participants(self):
45
+ raise NotImplementedError
46
+
47
+ def sign(self):
48
+ raise NotImplementedError
49
+
50
+ def signatures(self):
51
+ raise NotImplementedError
52
+
53
+ def archive(self):
54
+ raise NotImplementedError
@@ -0,0 +1,18 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+ __all__ = ('DocumentLinkAPI',)
4
+
5
+
6
+ class DocumentLinkAPI:
7
+ PATH = 'documents/{}/links'
8
+
9
+ def __init__(self, client):
10
+ self.client = client
11
+
12
+ def generate_public_link(self, document_id):
13
+ path = self.PATH.format(document_id)
14
+ return self.client.make_request(HttpMethod.POST, path)
15
+
16
+ def revoke_public_link(self, document_id):
17
+ path = self.PATH.format(document_id)
18
+ return self.client.make_request(HttpMethod.DELETE, path)
@@ -0,0 +1,23 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+
4
+ __all__ = ('DownloadAPI',)
5
+
6
+
7
+ class DownloadAPI:
8
+ PATH = 'downloads'
9
+
10
+ def __init__(self, client):
11
+ self.client = client
12
+
13
+ def bulk_uploads(self, body):
14
+ path = self.PATH
15
+ return self.client.make_request(HttpMethod.POST, path, body)
16
+
17
+ def download(self, download_id):
18
+ path = f'{self.PATH}/{download_id}/download'
19
+ return self.client.make_request(HttpMethod.GET, path)
20
+
21
+ def check_status(self, download_id):
22
+ path = f'{self.PATH}/{download_id}/status'
23
+ return self.client.make_request(HttpMethod.GET, path)
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1,24 @@
1
+ from dubidoc.enum import HttpMethod
2
+
3
+ __all__ = ('ParticipantAPI',)
4
+
5
+
6
+ class ParticipantAPI:
7
+ def __init__(self, client):
8
+ self.client = client
9
+
10
+ def add_participant(self, document_id, body):
11
+ path = 'documents/{}/participants'.format(document_id)
12
+ return self.client.make_request(HttpMethod.POST, path, body)
13
+
14
+ def remove_participant(self, participant_id):
15
+ """
16
+ It sounds like it should be DELETE 'documents/{}/participants/{}', but
17
+ each participant has own unique id, so it should be 'participants/{}'.
18
+ You can retrieve participant_id from the response of 'add_participant' method.
19
+ """
20
+ path = 'participants/{}'.format(participant_id)
21
+ return self.client.make_request(
22
+ HttpMethod.DELETE,
23
+ path,
24
+ )
@@ -0,0 +1 @@
1
+ # TODO
dubidoc/client.py ADDED
@@ -0,0 +1,82 @@
1
+ import logging
2
+ from urllib.parse import urljoin
3
+
4
+ import requests
5
+
6
+ from dubidoc import __version__
7
+ from dubidoc._modules import (
8
+ AccessTokenAPI,
9
+ AuthenticationAPI,
10
+ DeviceAPI,
11
+ DocumentAPI,
12
+ DocumentLinkAPI,
13
+ ParticipantAPI,
14
+ DownloadAPI,
15
+ )
16
+ from dubidoc.enum import HttpMethod
17
+
18
+
19
+ logger = logging.getLogger('dubidoc')
20
+
21
+
22
+ class DubidocAPIClient:
23
+ """
24
+ - https://my.dubidoc.com.ua/auth - production URL
25
+ - https://docs-stage.navkolo.one/auth - staging URL
26
+ """
27
+
28
+ API_VERSION = 'v1'
29
+ DEFAULT_HEADERS = {
30
+ 'accept': 'application/json',
31
+ 'content-type': 'application/json',
32
+ 'user-agent': f'python-dubidoc/{__version__} | (https://github.com/DmytroLitvinov/python-dubidoc)',
33
+ }
34
+
35
+ def __init__(self, api_token: str, environment: str = 'stage'):
36
+ self.api_token = api_token
37
+ if environment == 'stage':
38
+ self.base_url = 'https://docs-stage.navkolo.one'
39
+ else:
40
+ self.base_url = 'https://my.dubidoc.com.ua'
41
+ # FIXME: The prefix should be "api/v1" instead of "api/api/v1"
42
+ # Dubidoc will notify when it will be fixed
43
+ self.prefix = f'api/api/{self.API_VERSION}/'
44
+ self.endpoint = urljoin(self.base_url, self.prefix)
45
+
46
+ # Modules
47
+ self.document_api = DocumentAPI(self)
48
+ self.document_link_api = DocumentLinkAPI(self)
49
+ self.participant_api = ParticipantAPI(self)
50
+ self.download_api = DownloadAPI(self)
51
+
52
+ if environment == 'stage':
53
+ self.access_token_api = AccessTokenAPI(self)
54
+ self.authentication_api = AuthenticationAPI(self)
55
+ self.device_api = DeviceAPI(self)
56
+ # Not yet implemented anot probably not needed
57
+ # self.organization_user_api = OrganizationUserAPI(self)
58
+ # self.organization_api = OrganizationAPI(self)
59
+ # self.shortcode_api = ShortcodeAPI(self)
60
+
61
+ def _get_headers(self):
62
+ headers = self.DEFAULT_HEADERS.copy()
63
+ headers.update({'X-Access-Token': f'{self.api_token}'})
64
+ return headers
65
+
66
+ def make_request(self, method: HttpMethod, path: str, body: dict = {}):
67
+ """
68
+ Fetches the given path in the Dubidoc API.
69
+ :param method: HTTP method
70
+ :param path: Api path
71
+ :param body: body of request
72
+ :return: Serialized server response or error
73
+ """
74
+ url = urljoin(self.endpoint, path)
75
+ headers = self._get_headers()
76
+
77
+ logger.debug(f'Making {method.value} request to {url} with headers {headers} and body {body}')
78
+ # https://github.com/psf/requests/issues/3070
79
+ response = requests.request(method.value, url, headers=headers, json=body, timeout=10)
80
+ logger.debug(f'Received response with status code {response.status_code} and body {response.text}')
81
+
82
+ return response.json()
dubidoc/enum.py ADDED
@@ -0,0 +1,8 @@
1
+ from enum import Enum
2
+
3
+
4
+ class HttpMethod(Enum):
5
+ GET = 'GET'
6
+ POST = 'POST'
7
+ PUT = 'PUT'
8
+ DELETE = 'DELETE'
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Dmytro Litvinov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.1
2
+ Name: dubidoc
3
+ Version: 0.1.0
4
+ Summary: Python SDK for dubidoc.com.ua API
5
+ Maintainer-email: Dmytro Litvinov <me@dmytrolitvinov.com>
6
+ License: MIT License
7
+ Project-URL: Homepage, https://github.com/DmytroLitvinov/python-dubidoc
8
+ Project-URL: Issues, https://github.com/DmytroLitvinov/python-dubidoc/issues
9
+ Project-URL: Changelog, https://github.com/DmytroLitvinov/python-dubidoc/CHANGELOG.md
10
+ Keywords: dubidoc,Ukraine,🇺🇦,api,dubidoc.com.ua
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Web Environment
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Natural Language :: English
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Topic :: Internet :: WWW/HTTP
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests
29
+
30
+ # Dubidoc API client ✍
31
+
32
+ [![PyPI](https://img.shields.io/pypi/v/dubidoc?style=flat-square)](https://pypi.python.org/pypi/dubidoc/)
33
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dubidoc?style=flat-square)](https://pypi.python.org/pypi/dubidoc/)
34
+ [![PyPI - License](https://img.shields.io/pypi/l/dubidoc?style=flat-square)](https://pypi.python.org/pypi/dubidoc/)
35
+
36
+ ---
37
+ **Documentation**: [https://my.dubidoc.com.ua/api/api/v1/docs](https://my.dubidoc.com.ua/api/api/v1/docs)
38
+
39
+ **Source Code**: [https://github.com/DmytroLitvinov/python-dubidoc](https://github.com/DmytroLitvinov/python-dubidoc)
40
+
41
+ **PyPI**: [https://pypi.org/project/dubidoc/](https://pypi.org/project/dubidoc/)
42
+
43
+ ---
44
+
45
+ Python API wrapper around Dubidoc API. Feel free to contribute and make it better! 🚀
46
+
47
+ ## Installation
48
+
49
+ ```sh
50
+ pip install dubidoc
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ 1) Request your token at [Dubidoc team](https://t.me/dmytro_dubilet/814)
56
+
57
+ 2) Use that token to initialize client:
58
+
59
+ ```python
60
+ from dubidoc import DubidocAPIClient
61
+
62
+ api_token = 'xxxxxxxxxxxxxxx'
63
+
64
+ dubidoc = DubidocAPIClient(api_token)
65
+
66
+ documents = dubidoc.document_api.list()
67
+ print(documents)
68
+ ```
69
+
70
+ ## License
71
+
72
+ This project is licensed under the terms of the [MIT license](https://github.com/DmytroLitvinov/python-dubidoc/blob/master/LICENSE).
@@ -0,0 +1,19 @@
1
+ dubidoc/__init__.py,sha256=7Hi9v5lFaX9zZQUJVuiPqvyDV39PIzMoYlZ7ydcGtDg,177
2
+ dubidoc/client.py,sha256=eHhPnlQIpCsxL4tN8GSPQQjoppQjRqCOPQlYwQphTGs,2847
3
+ dubidoc/enum.py,sha256=RTIS0WplquZrFTqZGtzkc95i_9jqu2Xvl6j0SFXZ72I,120
4
+ dubidoc/_modules/__init__.py,sha256=NUeLh3Onke4cs4BGkowtqbaBByLVh_tEqtXNtacKI2w,184
5
+ dubidoc/_modules/access_token.py,sha256=nHyYWWg95SJkifvlgtr9I_h7jPTcdpcgxORukdjwwBU,1018
6
+ dubidoc/_modules/authentication.py,sha256=AtIyTjtwdgT1nHBQkgqfvQsJvZ-T0qqK0epKi-TwGVE,1465
7
+ dubidoc/_modules/device.py,sha256=ItrK-wzZVEAXPIWbTUkTsYl1JHZLSSAAAHFuKbgw2MU,976
8
+ dubidoc/_modules/document.py,sha256=ltE_UFsiy8WODjiGbOLkJCP-GBWpzrLJ846dmuir_hY,1511
9
+ dubidoc/_modules/document_link.py,sha256=jBb0oB5aFGMLMg-iB1SIcE7R77iMskwN1MZ2ShsN6E4,503
10
+ dubidoc/_modules/download.py,sha256=foTua0_sFpGrwObwgOr6HPen4ngFrJOhGdsCqPUCjnI,608
11
+ dubidoc/_modules/organization.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
12
+ dubidoc/_modules/organization_user.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
13
+ dubidoc/_modules/participant.py,sha256=AJ60D7cokQNQFFeUWCngWvx-NQl6VuG-YarREAW9HtE,811
14
+ dubidoc/_modules/storecode.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
15
+ dubidoc-0.1.0.dist-info/LICENSE,sha256=wYGgsJKkNcLDvJQfbrT5HabzSp3imJCmSpCOS8_pu9o,1072
16
+ dubidoc-0.1.0.dist-info/METADATA,sha256=FDyva0F76MOODgQGOUTNFn85-b9r1kJFlMSCKwkP2O0,2533
17
+ dubidoc-0.1.0.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
18
+ dubidoc-0.1.0.dist-info/top_level.txt,sha256=SQKT6uKBzQCmsVr8MCszUFz4WYCc5Oq7wvy5Y-ZReU0,8
19
+ dubidoc-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (70.3.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ dubidoc