pax_global_header 0000666 0000000 0000000 00000000064 14547324250 0014520 g ustar 00root root 0000000 0000000 52 comment=b862a16b9d2d621e32ed26d84e75f18d21bc74e6
python-kanboard-1.1.5/ 0000775 0000000 0000000 00000000000 14547324250 0014624 5 ustar 00root root 0000000 0000000 python-kanboard-1.1.5/LICENSE 0000664 0000000 0000000 00000002066 14547324250 0015635 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) Frederic Guillot
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
python-kanboard-1.1.5/MANIFEST.in 0000664 0000000 0000000 00000000043 14547324250 0016357 0 ustar 00root root 0000000 0000000 include README.rst
include LICENSE
python-kanboard-1.1.5/PKG-INFO 0000664 0000000 0000000 00000012204 14547324250 0015720 0 ustar 00root root 0000000 0000000 Metadata-Version: 2.1
Name: kanboard
Version: 1.1.5
Summary: Client library for Kanboard
Home-page: https://github.com/kanboard/python-api-client
Author: Frederic Guillot
Author-email: fred@kanboard.net
License: MIT
Keywords: kanboard api client
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
License-File: LICENSE
==============================
Python API Client for Kanboard
==============================
Client library for Kanboard API.
- Author: Frédéric Guillot
- License: MIT
Installation
============
.. code-block:: bash
python3 -m pip install kanboard
This library is compatible with Python >= 3.5.
Note: **Support for Python 2.7 has been dropped since version 1.1.0.**
On Fedora (36 and later), you can install the package using DNF:
.. code-block:: bash
dnf install python3-kanboard
Examples
========
Methods and arguments are the same as the JSON-RPC procedures described in the
`official documentation `_.
Python methods are dynamically mapped to the API procedures: **You must use named arguments**.
By default, calls are made synchronously, meaning that they will block the program until completed.
Creating a new team project
---------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
Authenticate as user
--------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Create a new task
-----------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
task_id = kb.create_task(project_id=project_id, title='My task title')
Use a personalized user agent
-----------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client(url='http://localhost/jsonrpc.php',
username='admin',
password='secret',
user_agent='My Kanboard client')
SSL connection and self-signed certificates
===========================================
Example with a valid certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client('https://example.org/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Example with a custom certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem')
kb.get_my_projects()
Example with a custom certificate and hostname mismatch:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem',
ignore_hostname_verification=True)
kb.get_my_projects()
Ignore invalid/expired certificates and hostname mismatches, which will make your application vulnerable to man-in-the-middle (MitM) attacks:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
insecure=True)
kb.get_my_projects()
Asynchronous I/O
================
The client also exposes async/await style method calls. Similarly to the synchronous calls (see above),
the method names are mapped to the API methods.
To invoke an asynchronous call, the method name must be appended with ``_async``. For example, a synchronous call
to ``create_project`` can be made asynchronous by calling ``create_project_async`` instead.
.. code-block:: python
import asyncio
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(kb.create_project_async(name='My project'))
.. code-block:: python
import asyncio
import kanboard
async def call_within_function():
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
return await kb.create_project_async(name='My project')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(call_within_function())
See the `official API documentation `_ for the complete list of
methods and arguments.
python-kanboard-1.1.5/README.rst 0000664 0000000 0000000 00000010537 14547324250 0016321 0 ustar 00root root 0000000 0000000 ==============================
Python API Client for Kanboard
==============================
Client library for Kanboard API.
- Author: Frédéric Guillot
- License: MIT
Installation
============
.. code-block:: bash
python3 -m pip install kanboard
This library is compatible with Python >= 3.5.
Note: **Support for Python 2.7 has been dropped since version 1.1.0.**
On Fedora (36 and later), you can install the package using DNF:
.. code-block:: bash
dnf install python3-kanboard
Examples
========
Methods and arguments are the same as the JSON-RPC procedures described in the
`official documentation `_.
Python methods are dynamically mapped to the API procedures: **You must use named arguments**.
By default, calls are made synchronously, meaning that they will block the program until completed.
Creating a new team project
---------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
Authenticate as user
--------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Create a new task
-----------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
task_id = kb.create_task(project_id=project_id, title='My task title')
Use a personalized user agent
-----------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client(url='http://localhost/jsonrpc.php',
username='admin',
password='secret',
user_agent='My Kanboard client')
SSL connection and self-signed certificates
===========================================
Example with a valid certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client('https://example.org/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Example with a custom certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem')
kb.get_my_projects()
Example with a custom certificate and hostname mismatch:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem',
ignore_hostname_verification=True)
kb.get_my_projects()
Ignore invalid/expired certificates and hostname mismatches, which will make your application vulnerable to man-in-the-middle (MitM) attacks:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
insecure=True)
kb.get_my_projects()
Asynchronous I/O
================
The client also exposes async/await style method calls. Similarly to the synchronous calls (see above),
the method names are mapped to the API methods.
To invoke an asynchronous call, the method name must be appended with ``_async``. For example, a synchronous call
to ``create_project`` can be made asynchronous by calling ``create_project_async`` instead.
.. code-block:: python
import asyncio
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(kb.create_project_async(name='My project'))
.. code-block:: python
import asyncio
import kanboard
async def call_within_function():
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
return await kb.create_project_async(name='My project')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(call_within_function())
See the `official API documentation `_ for the complete list of
methods and arguments.
python-kanboard-1.1.5/kanboard.egg-info/ 0000775 0000000 0000000 00000000000 14547324250 0020077 5 ustar 00root root 0000000 0000000 python-kanboard-1.1.5/kanboard.egg-info/PKG-INFO 0000664 0000000 0000000 00000012204 14547324250 0021173 0 ustar 00root root 0000000 0000000 Metadata-Version: 2.1
Name: kanboard
Version: 1.1.5
Summary: Client library for Kanboard
Home-page: https://github.com/kanboard/python-api-client
Author: Frederic Guillot
Author-email: fred@kanboard.net
License: MIT
Keywords: kanboard api client
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
License-File: LICENSE
==============================
Python API Client for Kanboard
==============================
Client library for Kanboard API.
- Author: Frédéric Guillot
- License: MIT
Installation
============
.. code-block:: bash
python3 -m pip install kanboard
This library is compatible with Python >= 3.5.
Note: **Support for Python 2.7 has been dropped since version 1.1.0.**
On Fedora (36 and later), you can install the package using DNF:
.. code-block:: bash
dnf install python3-kanboard
Examples
========
Methods and arguments are the same as the JSON-RPC procedures described in the
`official documentation `_.
Python methods are dynamically mapped to the API procedures: **You must use named arguments**.
By default, calls are made synchronously, meaning that they will block the program until completed.
Creating a new team project
---------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
Authenticate as user
--------------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Create a new task
-----------------
.. code-block:: python
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
project_id = kb.create_project(name='My project')
task_id = kb.create_task(project_id=project_id, title='My task title')
Use a personalized user agent
-----------------------------
.. code-block:: python
import kanboard
kb = kanboard.Client(url='http://localhost/jsonrpc.php',
username='admin',
password='secret',
user_agent='My Kanboard client')
SSL connection and self-signed certificates
===========================================
Example with a valid certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client('https://example.org/jsonrpc.php', 'admin', 'secret')
kb.get_my_projects()
Example with a custom certificate:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem')
kb.get_my_projects()
Example with a custom certificate and hostname mismatch:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
cafile='/path/to/my/cert.pem',
ignore_hostname_verification=True)
kb.get_my_projects()
Ignore invalid/expired certificates and hostname mismatches, which will make your application vulnerable to man-in-the-middle (MitM) attacks:
.. code-block:: python
import kanboard
kb = kanboard.Client(url='https://example.org/jsonrpc.php',
username='admin',
password='secret',
insecure=True)
kb.get_my_projects()
Asynchronous I/O
================
The client also exposes async/await style method calls. Similarly to the synchronous calls (see above),
the method names are mapped to the API methods.
To invoke an asynchronous call, the method name must be appended with ``_async``. For example, a synchronous call
to ``create_project`` can be made asynchronous by calling ``create_project_async`` instead.
.. code-block:: python
import asyncio
import kanboard
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(kb.create_project_async(name='My project'))
.. code-block:: python
import asyncio
import kanboard
async def call_within_function():
kb = kanboard.Client('http://localhost/jsonrpc.php', 'jsonrpc', 'your_api_token')
return await kb.create_project_async(name='My project')
loop = asyncio.get_event_loop()
project_id = loop.run_until_complete(call_within_function())
See the `official API documentation `_ for the complete list of
methods and arguments.
python-kanboard-1.1.5/kanboard.egg-info/SOURCES.txt 0000664 0000000 0000000 00000000263 14547324250 0021764 0 ustar 00root root 0000000 0000000 LICENSE
MANIFEST.in
README.rst
kanboard.py
setup.py
kanboard.egg-info/PKG-INFO
kanboard.egg-info/SOURCES.txt
kanboard.egg-info/dependency_links.txt
kanboard.egg-info/top_level.txt python-kanboard-1.1.5/kanboard.egg-info/dependency_links.txt 0000664 0000000 0000000 00000000001 14547324250 0024145 0 ustar 00root root 0000000 0000000
python-kanboard-1.1.5/kanboard.egg-info/top_level.txt 0000664 0000000 0000000 00000000011 14547324250 0022621 0 ustar 00root root 0000000 0000000 kanboard
python-kanboard-1.1.5/kanboard.py 0000664 0000000 0000000 00000014215 14547324250 0016762 0 ustar 00root root 0000000 0000000 # The MIT License (MIT)
#
# Copyright (c) Frederic Guillot
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import json
import base64
import functools
import asyncio
import ssl
from typing import Dict, Optional
from urllib import request as http
DEFAULT_AUTH_HEADER = 'Authorization'
ASYNC_FUNCNAME_MARKER = "_async"
class ClientError(Exception):
pass
class Client:
"""
Kanboard API client
Example:
from kanboard import Client
kb = Client(url="http://localhost/jsonrpc.php",
username="jsonrpc",
password="your_api_token")
project_id = kb.create_project(name="My project")
"""
def __init__(self,
url: str,
username: str,
password: str,
auth_header: str = DEFAULT_AUTH_HEADER,
cafile: Optional[str] = None,
insecure: bool = False,
ignore_hostname_verification: bool = False,
user_agent: str = 'Kanboard Python API Client',
loop: Optional[asyncio.AbstractEventLoop] = None):
"""
Constructor
Args:
url: API url endpoint
username: API username or real username
password: API token or user password
auth_header: API HTTP header
cafile: Path to a custom CA certificate
insecure: Ignore SSL certificate errors and ignore hostname mismatches
ignore_hostname_verification: Ignore SSL certificate hostname verification
user_agent: Use a personalized user agent
loop: An asyncio event loop. Default: asyncio.get_event_loop()
"""
self._url = url
self._username = username
self._password = password
self._auth_header = auth_header
self._cafile = cafile
self._insecure = insecure
self._user_agent = user_agent
self._ignore_hostname_verification = ignore_hostname_verification
if not loop:
try:
self._event_loop = asyncio.get_event_loop()
except RuntimeError:
self._event_loop = asyncio.new_event_loop()
def __getattr__(self, name: str):
if self.is_async_method_name(name):
async def function(*args, **kwargs):
return await self._event_loop.run_in_executor(
None,
functools.partial(
self.execute,
method=self._to_camel_case(self.get_funcname_from_async_name(name)), **kwargs))
return function
else:
def function(*args, **kwargs):
return self.execute(method=self._to_camel_case(name), **kwargs)
return function
@staticmethod
def is_async_method_name(funcname: str) -> bool:
return funcname.endswith(ASYNC_FUNCNAME_MARKER)
@staticmethod
def get_funcname_from_async_name(funcname: str) -> str:
return funcname[:len(funcname) - len(ASYNC_FUNCNAME_MARKER)]
@staticmethod
def _to_camel_case(snake_str: str) -> str:
components = snake_str.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
@staticmethod
def _parse_response(response: bytes):
try:
body = json.loads(response.decode(errors='ignore'))
if 'error' in body:
message = body.get('error').get('message')
raise ClientError(message)
return body.get('result')
except ValueError:
return None
def _do_request(self, headers: Dict[str, str], body: Dict):
try:
request = http.Request(self._url,
headers=headers,
data=json.dumps(body).encode())
ssl_context = ssl.create_default_context(cafile=self._cafile)
if self._insecure:
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
if self._ignore_hostname_verification:
ssl_context.check_hostname = False
response = http.urlopen(request, context=ssl_context).read()
except Exception as e:
raise ClientError(str(e))
return self._parse_response(response)
def execute(self, method: str, **kwargs):
"""
Call remote API procedure
Args:
method: Procedure name
kwargs: Procedure named arguments
Returns:
Procedure result
Raises:
urllib.error.HTTPError: Any HTTP error (Python 3)
"""
payload = {
'id': 1,
'jsonrpc': '2.0',
'method': method,
'params': kwargs
}
credentials = base64.b64encode('{}:{}'.format(self._username, self._password).encode())
auth_header_prefix = 'Basic ' if self._auth_header == DEFAULT_AUTH_HEADER else ''
headers = {
self._auth_header: auth_header_prefix + credentials.decode(),
'Content-Type': 'application/json',
'User-Agent': self._user_agent,
}
return self._do_request(headers, payload)
python-kanboard-1.1.5/setup.cfg 0000664 0000000 0000000 00000000046 14547324250 0016445 0 ustar 00root root 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
python-kanboard-1.1.5/setup.py 0000664 0000000 0000000 00000004136 14547324250 0016342 0 ustar 00root root 0000000 0000000 # The MIT License (MIT)
#
# Copyright (c) Frederic Guillot
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from setuptools import setup
def readme():
with open('README.rst') as f:
return f.read()
setup(
name='kanboard',
version='1.1.5',
description='Client library for Kanboard',
long_description=readme(),
keywords='kanboard api client',
url='https://github.com/kanboard/python-api-client',
author='Frederic Guillot',
author_email='fred@kanboard.net',
license='MIT',
py_modules=['kanboard'],
test_suite='test_kanboard',
classifiers=[
'Intended Audience :: Developers',
'Intended Audience :: Information Technology',
'Natural Language :: English',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
]
)
python-kanboard-1.1.5/test_kanboard.py 0000664 0000000 0000000 00000010327 14547324250 0020021 0 ustar 00root root 0000000 0000000 # The MIT License (MIT)
#
# Copyright (c) Frederic Guillot
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import unittest
from unittest import mock
import types
import warnings
import kanboard
class TestClient(unittest.TestCase):
def setUp(self):
self.url = 'some api url'
self.client = kanboard.Client(self.url, 'username', 'password')
self.request, self.urlopen = self._create_mocks()
def ignore_warnings(test_func):
def do_test(self, *args, **kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
test_func(self, *args, **kwargs)
return do_test
def test_api_call(self):
body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
self.urlopen.return_value.read.return_value = body
self.assertEqual(True, self.client.remote_procedure())
self.request.assert_called_once_with(self.url,
data=mock.ANY,
headers=mock.ANY)
def test_custom_auth_header(self):
self.client._auth_header = 'X-Auth-Header'
body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
self.urlopen.return_value.read.return_value = body
self.assertEqual(True, self.client.remote_procedure())
self.request.assert_called_once_with(self.url,
data=mock.ANY,
headers=mock.ANY)
_, kwargs = self.request.call_args
assert kwargs['headers']['X-Auth-Header'] == 'dXNlcm5hbWU6cGFzc3dvcmQ='
def test_http_error(self):
self.urlopen.side_effect = Exception()
with self.assertRaises(kanboard.ClientError):
self.client.remote_procedure()
def test_application_error(self):
body = b'{"jsonrpc": "2.0", "error": {"code": -32603, "message": "Internal error"}, "id": 123}'
self.urlopen.return_value.read.return_value = body
with self.assertRaises(kanboard.ClientError, msg='Internal error'):
self.client.remote_procedure()
def test_async_method_call_recognised(self):
method_name = "some_method_async"
result = self.client.is_async_method_name(method_name)
self.assertTrue(result)
def test_standard_method_call_recognised(self):
method_name = "some_method"
result = self.client.is_async_method_name(method_name)
self.assertFalse(result)
def test_method_name_extracted_from_async_name(self):
expected_method_name = "some_method"
async_method_name = expected_method_name + "_async"
result = self.client.get_funcname_from_async_name(async_method_name)
self.assertEqual(expected_method_name, result)
# suppress a RuntimeWarning because coro is not awaited
# this is done on purpose
@ignore_warnings
def test_async_call_generates_coro(self):
method = self.client.my_method_async()
self.assertIsInstance(method, types.CoroutineType)
@staticmethod
def _create_mocks():
request_patcher = mock.patch('urllib.request.Request')
urlopen_patcher = mock.patch('urllib.request.urlopen')
return request_patcher.start(), urlopen_patcher.start()