Skip to content

Commit 72c0f3d

Browse files
committed
implement client.get_app_flavor('appname')
looks like: ``` [1]: from hypernode_api_python.client import HypernodeAPIPython In [2]: client = HypernodeAPIPython(token='yoursecrettoken') In [3]: response = client.get_app_flavor('yourhypernodeappname') In [4]: response.json() Out[4]: {'name': '2CPU/8GB/60GB (Falcon S 202202)', 'redis_size': '1024'} ```
1 parent 988d9e4 commit 72c0f3d

File tree

8 files changed

+126
-24
lines changed

8 files changed

+126
-24
lines changed

.gitignore

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
1-
venv/
1+
# python
2+
__pycache__
3+
*.pyc
4+
*.egg-info
5+
.eggs
6+
/dist
7+
/pip-selfcheck.json
8+
9+
# virtualenv
10+
/.venv
11+
/.virtualenv
12+
/include
13+
/lib
14+
/lib64
15+
/share
16+
/venv
17+
18+
# misc
19+
.idea

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,31 @@ pip install -r requirements/development.txt
1717
### Acquiring an API token
1818

1919
Each Hypernode has an API token associated with it, you can use that to talk to the API directly. You can find the token in `/etc/hypernode/hypernode_api_token`. For API tokens with special permissions please contact support@hypernode.com.
20+
21+
22+
### Installing the library in your project
23+
24+
First make sure your project has the library installed:
25+
```bash
26+
pip install -e git+https://github.com/byteinternet/hypernode-api-python.git@master#egg=hypernode_api_python
27+
```
28+
Of course you might want to put that in a `requirements.txt` file in your project instead of installing it manually.
29+
30+
Then to use the API client you can test out an example request in your Python repl:
31+
```bash
32+
[1]: from hypernode_api_python.client import HypernodeAPIPython
33+
34+
In [2]: client = HypernodeAPIPython(token='yoursecrettoken')
35+
36+
In [3]: response = client.get_app_flavor('yourhypernodeappname')
37+
38+
In [4]: response.json()
39+
Out[4]: {'name': '2CPU/8GB/60GB (Falcon S 202202)', 'redis_size': '1024'}
40+
41+
```
42+
43+
## Related projects
44+
45+
- The official [Hypernode API PHP Client](https://github.com/byteinternet/hypernode-api-php)
46+
- The official [Hypernode Deploy](https://github.com/byteinternet/hypernode-deploy-configuration) tool
47+
- The official [Hypernode Docker](https://github.com/byteinternet/hypernode-docker) image

hypernode_api_python/client.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
from requests import Session
22

3-
HYPERNODE_API_URL = 'https://api.hypernode.com'
3+
HYPERNODE_API_URL = "https://api.hypernode.com"
4+
5+
HYPERNODE_API_APP_FLAVOR_ENDPOINT = "/v2/app/{}/flavor/"
46

57

68
class HypernodeAPIPython:
79
def __init__(self, token, api_url=None):
810
self.session = Session()
911
self.token = token
1012
self.api_url = api_url if api_url else HYPERNODE_API_URL
11-
self.authorization_header = 'Token {}'.format(self.token)
13+
self.authorization_header = "Token {}".format(self.token)
1214

1315
def requests(self, method, path, *args, **kwargs):
14-
kwargs.setdefault('headers', {}).update({
15-
'Accept': 'application/json',
16-
'Authorization': self.authorization_header,
17-
'Accept-Language': 'en-US'
18-
})
19-
return session.request(method, HYPERNODE_API_URL.rstrip('/') + path, *args, **kwargs)
16+
kwargs.setdefault("headers", {}).update(
17+
{
18+
"Accept": "application/json",
19+
"Authorization": self.authorization_header,
20+
"Accept-Language": "en-US",
21+
}
22+
)
23+
return self.session.request(
24+
method, HYPERNODE_API_URL.rstrip("/") + path, *args, **kwargs
25+
)
2026

2127
def get_app_flavor(self, app_name):
22-
return self.requests('GET', HYPERNODE_API_APP_FLAVOR_ENDPOINT.format(app_name))
28+
return self.requests("GET", HYPERNODE_API_APP_FLAVOR_ENDPOINT.format(app_name))

pycodestyle.ini

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[pycodestyle]
2+
count = False
3+
max-line-length = 160
4+
statistics = True
5+
exclude = migrations,build,tasks,.git,.tox,__pycache__,help
6+
# @TODO: try to shorten the list of ignored errors
7+
ignore = E305,E501,E731,E741,W292,W391,W503,W504,W605

setup.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,21 @@
55

66
def readfile(filename):
77
path = join(dirname(abspath(__file__)), filename)
8-
with open(path, 'rt') as filehandle:
8+
with open(path, "rt") as filehandle:
99
return filehandle.read()
1010

1111

1212
setup(
13-
name='hypernode_api_python',
14-
version='0.0.1',
13+
name="hypernode_api_python",
14+
version="0.0.1",
1515
description='"Hypernode API Client for Python"',
16-
long_description=readfile('README.md'),
17-
long_description_content_type='text/markdown',
18-
author='Hypernode',
19-
author_email='support@hypernode.com',
20-
license='MIT',
21-
url='https://github.com/ByteInternet/hypernode_api_python',
22-
packages=['hypernode_api_python'],
23-
install_requires=['pip'],
24-
entry_points={
25-
'console_scripts': []
26-
}
16+
long_description=readfile("README.md"),
17+
long_description_content_type="text/markdown",
18+
author="Hypernode",
19+
author_email="support@hypernode.com",
20+
license="MIT",
21+
url="https://github.com/ByteInternet/hypernode_api_python",
22+
packages=["hypernode_api_python"],
23+
install_requires=["pip"],
24+
entry_points={"console_scripts": []},
2725
)

tests/client/__init__.py

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from unittest.mock import Mock
2+
3+
from tests.testcase import TestCase
4+
from hypernode_api_python.client import (
5+
HypernodeAPIPython,
6+
HYPERNODE_API_APP_FLAVOR_ENDPOINT,
7+
)
8+
9+
10+
class TestGetAppFlavor(TestCase):
11+
def setUp(self):
12+
self.client = HypernodeAPIPython(token="mytoken")
13+
self.mock_request = Mock()
14+
self.client.requests = self.mock_request
15+
16+
def test_app_flavor_endpoint_is_correct(self):
17+
self.assertEqual("/v2/app/{}/flavor/", HYPERNODE_API_APP_FLAVOR_ENDPOINT)
18+
19+
def test_calls_app_flavor_endpoint_propertly(self):
20+
self.client.get_app_flavor("my_app")
21+
22+
self.mock_request.assert_called_once_with("GET", "/v2/app/my_app/flavor/")
23+
24+
def test_returns_app_flavor_data(self):
25+
self.assertEqual(
26+
self.client.get_app_flavor("my_app"), self.mock_request.return_value
27+
)

tests/testcase.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import unittest
2+
from unittest.mock import Mock, mock_open, patch
3+
4+
5+
class TestCase(unittest.TestCase):
6+
def set_up_patch(self, patch_target, mock_target=None, **kwargs):
7+
patcher = patch(patch_target, mock_target or Mock(**kwargs))
8+
self.addCleanup(patcher.stop)
9+
return patcher.start()
10+
11+
def set_up_context_manager_patch(self, topatch, themock=None, **kwargs):
12+
patcher = self.set_up_patch(topatch, themock=themock, **kwargs)
13+
patcher.return_value.__exit__ = lambda a, b, c, d: None
14+
patcher.return_value.__enter__ = lambda x: None
15+
return patcher
16+
17+
def set_up_mock_open(self, read_value=""):
18+
return self.set_up_patch("builtins.open", mock_open(read_data=read_value))

0 commit comments

Comments
 (0)