lswapi 0.4.2__tar.gz → 0.5.0__tar.gz
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.
- lswapi-0.5.0/.version +1 -0
- lswapi-0.5.0/PKG-INFO +114 -0
- lswapi-0.5.0/README.md +78 -0
- lswapi-0.5.0/lswapi.egg-info/PKG-INFO +114 -0
- lswapi-0.5.0/lswapi.egg-info/SOURCES.txt +22 -0
- {lswapi-0.4.2 → lswapi-0.5.0}/lswapi.egg-info/entry_points.txt +0 -1
- lswapi-0.5.0/lswapi.egg-info/requires.txt +17 -0
- lswapi-0.5.0/pyproject.toml +67 -0
- lswapi-0.5.0/setup.cfg +4 -0
- lswapi-0.5.0/src/lswapi/__init__.py +9 -0
- lswapi-0.5.0/src/lswapi/aio/__init__.py +27 -0
- lswapi-0.5.0/src/lswapi/aio/client.py +46 -0
- lswapi-0.5.0/src/lswapi/aio/middleware.py +20 -0
- lswapi-0.5.0/src/lswapi/aio/oauth.py +85 -0
- lswapi-0.4.2/lswapi/httpie/__init__.py → lswapi-0.5.0/src/lswapi/httpie.py +15 -11
- lswapi-0.5.0/src/lswapi/requests/__init__.py +21 -0
- lswapi-0.5.0/src/lswapi/requests/oauth.py +12 -0
- lswapi-0.5.0/src/lswapi/requests/session.py +49 -0
- lswapi-0.5.0/tests/test_aio.py +23 -0
- lswapi-0.5.0/tests/test_lswapi.py +7 -0
- lswapi-0.5.0/tests/test_requests.py +16 -0
- lswapi-0.4.2/MANIFEST.in +0 -6
- lswapi-0.4.2/PKG-INFO +0 -74
- lswapi-0.4.2/README.md +0 -51
- lswapi-0.4.2/lswapi/__init__.py +0 -76
- lswapi-0.4.2/lswapi.egg-info/PKG-INFO +0 -74
- lswapi-0.4.2/lswapi.egg-info/SOURCES.txt +0 -14
- lswapi-0.4.2/lswapi.egg-info/requires.txt +0 -1
- lswapi-0.4.2/requirements.txt +0 -1
- lswapi-0.4.2/setup.cfg +0 -24
- lswapi-0.4.2/setup.py +0 -50
- {lswapi-0.4.2 → lswapi-0.5.0}/LICENSE.txt +0 -0
- {lswapi-0.4.2 → lswapi-0.5.0}/lswapi.egg-info/dependency_links.txt +0 -0
- {lswapi-0.4.2 → lswapi-0.5.0}/lswapi.egg-info/top_level.txt +0 -0
lswapi-0.5.0/.version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.5.0
|
lswapi-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: lswapi
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: a python client library for easy leaseweb api access
|
|
5
|
+
Author-email: Nico Di Rocco <n.dirocco@global.leaseweb.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, http://developer.leaseweb.com
|
|
8
|
+
Project-URL: Issues, https://github.com/nrocco/lswapi
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
11
|
+
Classifier: Operating System :: Unix
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE.txt
|
|
23
|
+
Provides-Extra: develop
|
|
24
|
+
Requires-Dist: flake8; extra == "develop"
|
|
25
|
+
Requires-Dist: pytest; extra == "develop"
|
|
26
|
+
Requires-Dist: pytest-cov; extra == "develop"
|
|
27
|
+
Requires-Dist: requests-mock; extra == "develop"
|
|
28
|
+
Requires-Dist: twine; extra == "develop"
|
|
29
|
+
Provides-Extra: httpie
|
|
30
|
+
Requires-Dist: httpie; extra == "httpie"
|
|
31
|
+
Provides-Extra: requests
|
|
32
|
+
Requires-Dist: requests; extra == "requests"
|
|
33
|
+
Provides-Extra: aio
|
|
34
|
+
Requires-Dist: aiodns; extra == "aio"
|
|
35
|
+
Requires-Dist: aiohttp; extra == "aio"
|
|
36
|
+
|
|
37
|
+
# lswapi (beta)
|
|
38
|
+
|
|
39
|
+
[](https://github.com/nrocco/lswapi/actions)
|
|
40
|
+
|
|
41
|
+
Python module to talk to Leaseweb's API.
|
|
42
|
+
|
|
43
|
+
For more information refer to the documentation available at
|
|
44
|
+
[http://developer.leaseweb.com]
|
|
45
|
+
|
|
46
|
+
This module contains two api clients:
|
|
47
|
+
|
|
48
|
+
1. One is based on the `requests` module.
|
|
49
|
+
2. The second one is based on the `aiohttp` module for asyncio support.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Install the module using pip. This will not install `requests` or `aiohttp`.
|
|
55
|
+
|
|
56
|
+
pip install lswapi
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
You can install optional depencies, such as `aiohttp`:
|
|
60
|
+
|
|
61
|
+
pip install 'lswapi[aio]'
|
|
62
|
+
|
|
63
|
+
Or if you prefer to use `requests`:
|
|
64
|
+
|
|
65
|
+
pip install 'lswapi[requests]'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Using requests
|
|
72
|
+
|
|
73
|
+
The `lswapi.requests.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
74
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
75
|
+
to `get_leaseweb_api`
|
|
76
|
+
|
|
77
|
+
$ python
|
|
78
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
79
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
80
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
81
|
+
>>> servers = response.json()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
or get `LSW_API_KEY` from an environment variable:
|
|
85
|
+
|
|
86
|
+
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
87
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
88
|
+
>>> client = get_leaseweb_api()
|
|
89
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
90
|
+
>>> servers = response.json()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
### Using aiohttp
|
|
94
|
+
|
|
95
|
+
The `lswapi.aio.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
96
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
97
|
+
to `get_leaseweb_api` or via the environment variable `LSW_API_KEY`:
|
|
98
|
+
|
|
99
|
+
$ python -m asyncio
|
|
100
|
+
>>> from lswapi.aio import get_leaseweb_api
|
|
101
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
102
|
+
>>> response = await client.get("/bareMetals/v2/servers")
|
|
103
|
+
>>> servers = await response.json()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Contribute
|
|
107
|
+
----------
|
|
108
|
+
|
|
109
|
+
1. Fork it
|
|
110
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
111
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
112
|
+
4. Make sure that tests pass (`make test`)
|
|
113
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
114
|
+
6. Create new Pull Request
|
lswapi-0.5.0/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# lswapi (beta)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/nrocco/lswapi/actions)
|
|
4
|
+
|
|
5
|
+
Python module to talk to Leaseweb's API.
|
|
6
|
+
|
|
7
|
+
For more information refer to the documentation available at
|
|
8
|
+
[http://developer.leaseweb.com]
|
|
9
|
+
|
|
10
|
+
This module contains two api clients:
|
|
11
|
+
|
|
12
|
+
1. One is based on the `requests` module.
|
|
13
|
+
2. The second one is based on the `aiohttp` module for asyncio support.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install the module using pip. This will not install `requests` or `aiohttp`.
|
|
19
|
+
|
|
20
|
+
pip install lswapi
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
You can install optional depencies, such as `aiohttp`:
|
|
24
|
+
|
|
25
|
+
pip install 'lswapi[aio]'
|
|
26
|
+
|
|
27
|
+
Or if you prefer to use `requests`:
|
|
28
|
+
|
|
29
|
+
pip install 'lswapi[requests]'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Using requests
|
|
36
|
+
|
|
37
|
+
The `lswapi.requests.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
38
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
39
|
+
to `get_leaseweb_api`
|
|
40
|
+
|
|
41
|
+
$ python
|
|
42
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
43
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
44
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
45
|
+
>>> servers = response.json()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
or get `LSW_API_KEY` from an environment variable:
|
|
49
|
+
|
|
50
|
+
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
51
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
52
|
+
>>> client = get_leaseweb_api()
|
|
53
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
54
|
+
>>> servers = response.json()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Using aiohttp
|
|
58
|
+
|
|
59
|
+
The `lswapi.aio.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
60
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
61
|
+
to `get_leaseweb_api` or via the environment variable `LSW_API_KEY`:
|
|
62
|
+
|
|
63
|
+
$ python -m asyncio
|
|
64
|
+
>>> from lswapi.aio import get_leaseweb_api
|
|
65
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
66
|
+
>>> response = await client.get("/bareMetals/v2/servers")
|
|
67
|
+
>>> servers = await response.json()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Contribute
|
|
71
|
+
----------
|
|
72
|
+
|
|
73
|
+
1. Fork it
|
|
74
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
75
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
76
|
+
4. Make sure that tests pass (`make test`)
|
|
77
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
78
|
+
6. Create new Pull Request
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: lswapi
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: a python client library for easy leaseweb api access
|
|
5
|
+
Author-email: Nico Di Rocco <n.dirocco@global.leaseweb.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, http://developer.leaseweb.com
|
|
8
|
+
Project-URL: Issues, https://github.com/nrocco/lswapi
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
11
|
+
Classifier: Operating System :: Unix
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE.txt
|
|
23
|
+
Provides-Extra: develop
|
|
24
|
+
Requires-Dist: flake8; extra == "develop"
|
|
25
|
+
Requires-Dist: pytest; extra == "develop"
|
|
26
|
+
Requires-Dist: pytest-cov; extra == "develop"
|
|
27
|
+
Requires-Dist: requests-mock; extra == "develop"
|
|
28
|
+
Requires-Dist: twine; extra == "develop"
|
|
29
|
+
Provides-Extra: httpie
|
|
30
|
+
Requires-Dist: httpie; extra == "httpie"
|
|
31
|
+
Provides-Extra: requests
|
|
32
|
+
Requires-Dist: requests; extra == "requests"
|
|
33
|
+
Provides-Extra: aio
|
|
34
|
+
Requires-Dist: aiodns; extra == "aio"
|
|
35
|
+
Requires-Dist: aiohttp; extra == "aio"
|
|
36
|
+
|
|
37
|
+
# lswapi (beta)
|
|
38
|
+
|
|
39
|
+
[](https://github.com/nrocco/lswapi/actions)
|
|
40
|
+
|
|
41
|
+
Python module to talk to Leaseweb's API.
|
|
42
|
+
|
|
43
|
+
For more information refer to the documentation available at
|
|
44
|
+
[http://developer.leaseweb.com]
|
|
45
|
+
|
|
46
|
+
This module contains two api clients:
|
|
47
|
+
|
|
48
|
+
1. One is based on the `requests` module.
|
|
49
|
+
2. The second one is based on the `aiohttp` module for asyncio support.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Install the module using pip. This will not install `requests` or `aiohttp`.
|
|
55
|
+
|
|
56
|
+
pip install lswapi
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
You can install optional depencies, such as `aiohttp`:
|
|
60
|
+
|
|
61
|
+
pip install 'lswapi[aio]'
|
|
62
|
+
|
|
63
|
+
Or if you prefer to use `requests`:
|
|
64
|
+
|
|
65
|
+
pip install 'lswapi[requests]'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Using requests
|
|
72
|
+
|
|
73
|
+
The `lswapi.requests.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
74
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
75
|
+
to `get_leaseweb_api`
|
|
76
|
+
|
|
77
|
+
$ python
|
|
78
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
79
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
80
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
81
|
+
>>> servers = response.json()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
or get `LSW_API_KEY` from an environment variable:
|
|
85
|
+
|
|
86
|
+
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
87
|
+
>>> from lswapi.requests import get_leaseweb_api
|
|
88
|
+
>>> client = get_leaseweb_api()
|
|
89
|
+
>>> response = client.get("/bareMetals/v2/servers")
|
|
90
|
+
>>> servers = response.json()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
### Using aiohttp
|
|
94
|
+
|
|
95
|
+
The `lswapi.aio.get_leaseweb_api` function creates an instance of the Leaseweb Api
|
|
96
|
+
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
97
|
+
to `get_leaseweb_api` or via the environment variable `LSW_API_KEY`:
|
|
98
|
+
|
|
99
|
+
$ python -m asyncio
|
|
100
|
+
>>> from lswapi.aio import get_leaseweb_api
|
|
101
|
+
>>> client = get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
102
|
+
>>> response = await client.get("/bareMetals/v2/servers")
|
|
103
|
+
>>> servers = await response.json()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Contribute
|
|
107
|
+
----------
|
|
108
|
+
|
|
109
|
+
1. Fork it
|
|
110
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
111
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
112
|
+
4. Make sure that tests pass (`make test`)
|
|
113
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
114
|
+
6. Create new Pull Request
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.version
|
|
2
|
+
LICENSE.txt
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
lswapi.egg-info/PKG-INFO
|
|
6
|
+
lswapi.egg-info/SOURCES.txt
|
|
7
|
+
lswapi.egg-info/dependency_links.txt
|
|
8
|
+
lswapi.egg-info/entry_points.txt
|
|
9
|
+
lswapi.egg-info/requires.txt
|
|
10
|
+
lswapi.egg-info/top_level.txt
|
|
11
|
+
src/lswapi/__init__.py
|
|
12
|
+
src/lswapi/httpie.py
|
|
13
|
+
src/lswapi/aio/__init__.py
|
|
14
|
+
src/lswapi/aio/client.py
|
|
15
|
+
src/lswapi/aio/middleware.py
|
|
16
|
+
src/lswapi/aio/oauth.py
|
|
17
|
+
src/lswapi/requests/__init__.py
|
|
18
|
+
src/lswapi/requests/oauth.py
|
|
19
|
+
src/lswapi/requests/session.py
|
|
20
|
+
tests/test_aio.py
|
|
21
|
+
tests/test_lswapi.py
|
|
22
|
+
tests/test_requests.py
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "lswapi"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "a python client library for easy leaseweb api access"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name="Nico Di Rocco", email="n.dirocco@global.leaseweb.com" },
|
|
8
|
+
]
|
|
9
|
+
license = {text="Apache-2.0"}
|
|
10
|
+
requires-python = ">= 3.9"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 5 - Production/Stable",
|
|
13
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
14
|
+
"Operating System :: Unix",
|
|
15
|
+
"Programming Language :: Python",
|
|
16
|
+
"Programming Language :: Python :: 3.9",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
"Topic :: Utilities"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "http://developer.leaseweb.com"
|
|
27
|
+
Issues = "https://github.com/nrocco/lswapi"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
develop = [
|
|
31
|
+
"flake8",
|
|
32
|
+
"pytest",
|
|
33
|
+
"pytest-cov",
|
|
34
|
+
"requests-mock",
|
|
35
|
+
"twine",
|
|
36
|
+
]
|
|
37
|
+
httpie = [
|
|
38
|
+
"httpie",
|
|
39
|
+
]
|
|
40
|
+
requests = [
|
|
41
|
+
"requests",
|
|
42
|
+
]
|
|
43
|
+
aio = [
|
|
44
|
+
"aiodns",
|
|
45
|
+
"aiohttp",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.entry-points."httpie.plugins.auth.v1"]
|
|
49
|
+
httpie_lswapi = "lswapi.httpie:ApiAuthPlugin"
|
|
50
|
+
|
|
51
|
+
[build-system]
|
|
52
|
+
requires = [
|
|
53
|
+
"setuptools>=64",
|
|
54
|
+
]
|
|
55
|
+
build-backend = "setuptools.build_meta"
|
|
56
|
+
|
|
57
|
+
[tool.setuptools]
|
|
58
|
+
include-package-data = true
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.dynamic]
|
|
61
|
+
version = {file = ".version"}
|
|
62
|
+
|
|
63
|
+
[tool.pytest.ini_options]
|
|
64
|
+
testpaths = ["tests"]
|
|
65
|
+
|
|
66
|
+
[tool.distutils.egg_info]
|
|
67
|
+
egg_base = "."
|
lswapi-0.5.0/setup.cfg
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from lswapi import __api_base_url__
|
|
2
|
+
from lswapi import __auth_token_url__
|
|
3
|
+
from lswapi.aio.client import LeasewebHttpClient
|
|
4
|
+
from lswapi.aio.middleware import LoggingMiddleware
|
|
5
|
+
from lswapi.aio.oauth import AccessTokenFileStore
|
|
6
|
+
from lswapi.aio.oauth import LeasewebOAuthMiddleware
|
|
7
|
+
from os import environ
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_leaseweb_api(api_key=None, client_id=None, client_secret=None, base_url=None, token_url=None, token_store=None):
|
|
11
|
+
base_url = base_url or environ.get("LSW_BASE_URL", __api_base_url__)
|
|
12
|
+
token_url = token_url or environ.get("LSW_AUTH_URL", __auth_token_url__)
|
|
13
|
+
token_store = token_store or environ.get("LSW_AUTH_TOKEN_STORE")
|
|
14
|
+
api_key = api_key or environ.get("LSW_API_KEY")
|
|
15
|
+
if api_key:
|
|
16
|
+
return LeasewebHttpClient(base_url, middlewares=[LoggingMiddleware(debug=False)], headers={"X-Lsw-Auth": api_key})
|
|
17
|
+
if not client_id or not client_secret:
|
|
18
|
+
raise Exception("No authentication method specified")
|
|
19
|
+
return LeasewebHttpClient(base_url, middlewares=[
|
|
20
|
+
LeasewebOAuthMiddleware(
|
|
21
|
+
client_id,
|
|
22
|
+
client_secret,
|
|
23
|
+
token_url,
|
|
24
|
+
store=AccessTokenFileStore(token_store) if token_store else None,
|
|
25
|
+
),
|
|
26
|
+
LoggingMiddleware(debug=False),
|
|
27
|
+
])
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from aiohttp import ClientSession
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class LeasewebHttpClient:
|
|
5
|
+
def __init__(self, *args, middlewares: list[callable] = [], **kwargs):
|
|
6
|
+
self.middlewares = middlewares
|
|
7
|
+
self.session = ClientSession(*args, **kwargs)
|
|
8
|
+
|
|
9
|
+
async def _run_middlewares(self, method, url, next_func, **kwargs):
|
|
10
|
+
async def middleware_chain(index, method, url, **kwargs):
|
|
11
|
+
if index < len(self.middlewares):
|
|
12
|
+
return await self.middlewares[index](
|
|
13
|
+
method, url, lambda m, u, **k: middleware_chain(index + 1, m, u, **k), **kwargs
|
|
14
|
+
)
|
|
15
|
+
return await next_func(method, url, **kwargs)
|
|
16
|
+
return await middleware_chain(0, method, url, **kwargs)
|
|
17
|
+
|
|
18
|
+
async def _request(self, method, url, **kwargs):
|
|
19
|
+
return await self.session.request(method, url, **kwargs)
|
|
20
|
+
|
|
21
|
+
async def request(self, method, url, **kwargs):
|
|
22
|
+
return await self._run_middlewares(method, url, self._request, **kwargs)
|
|
23
|
+
|
|
24
|
+
async def get(self, url, **kwargs):
|
|
25
|
+
return await self.request("GET", url, **kwargs)
|
|
26
|
+
|
|
27
|
+
async def post(self, url, **kwargs):
|
|
28
|
+
return await self.request("POST", url, **kwargs)
|
|
29
|
+
|
|
30
|
+
async def put(self, url, **kwargs):
|
|
31
|
+
return await self.request("PUT", url, **kwargs)
|
|
32
|
+
|
|
33
|
+
async def patch(self, url, **kwargs):
|
|
34
|
+
return await self.request("PATCH", url, **kwargs)
|
|
35
|
+
|
|
36
|
+
async def delete(self, url, **kwargs):
|
|
37
|
+
return await self.request("DELETE", url, **kwargs)
|
|
38
|
+
|
|
39
|
+
async def close(self):
|
|
40
|
+
await self.session.close()
|
|
41
|
+
|
|
42
|
+
async def __aenter__(self):
|
|
43
|
+
return self
|
|
44
|
+
|
|
45
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
46
|
+
await self.close()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LoggingMiddleware:
|
|
6
|
+
def __init__(self, debug=False) -> None:
|
|
7
|
+
self.debug = debug
|
|
8
|
+
|
|
9
|
+
async def __call__(self, method, url, next_func, **kwargs):
|
|
10
|
+
start = time.monotonic()
|
|
11
|
+
response = await next_func(method, url, **kwargs)
|
|
12
|
+
end = time.monotonic()
|
|
13
|
+
logging.info(f"Request to {response.method} {response.url} took {(end - start):.3f} seconds and resulted in a {response.status} {response.reason}")
|
|
14
|
+
if self.debug:
|
|
15
|
+
for header, value in response.request_info.headers.items():
|
|
16
|
+
logging.debug(f">>> {header}: {value}")
|
|
17
|
+
logging.debug(f"<<< HTTP/{response.version.major}.{response.version.minor} {response.status} {response.reason}")
|
|
18
|
+
for header, value in response.headers.items():
|
|
19
|
+
logging.debug(f"<<< {header}: {value}")
|
|
20
|
+
return response
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
from lswapi.aio.client import LeasewebHttpClient
|
|
8
|
+
from lswapi.aio.middleware import LoggingMiddleware
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AccessTokenInMemoryStore:
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.token = None
|
|
14
|
+
|
|
15
|
+
async def load(self):
|
|
16
|
+
return self.token
|
|
17
|
+
|
|
18
|
+
async def save(self, token):
|
|
19
|
+
self.token = token
|
|
20
|
+
|
|
21
|
+
async def remove(self):
|
|
22
|
+
self.token = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AccessTokenFileStore:
|
|
26
|
+
def __init__(self, filepath):
|
|
27
|
+
self.token = None
|
|
28
|
+
self.filepath = filepath
|
|
29
|
+
self.lock = asyncio.Lock()
|
|
30
|
+
|
|
31
|
+
async def load(self):
|
|
32
|
+
async with self.lock:
|
|
33
|
+
if self.token:
|
|
34
|
+
return self.token
|
|
35
|
+
if not os.path.exists(self.filepath):
|
|
36
|
+
return None
|
|
37
|
+
with open(self.filepath, "r") as file:
|
|
38
|
+
try:
|
|
39
|
+
self.token = json.load(file)
|
|
40
|
+
except json.decoder.JSONDecodeError:
|
|
41
|
+
os.remove(self.filepath)
|
|
42
|
+
return self.token
|
|
43
|
+
|
|
44
|
+
async def save(self, token):
|
|
45
|
+
async with self.lock:
|
|
46
|
+
with open(self.filepath, "w") as file:
|
|
47
|
+
json.dump(token, file)
|
|
48
|
+
self.token = token
|
|
49
|
+
|
|
50
|
+
async def remove(self):
|
|
51
|
+
async with self.lock:
|
|
52
|
+
if os.path.exists(self.filepath):
|
|
53
|
+
os.remove(self.filepath)
|
|
54
|
+
self.token = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class LeasewebOAuthMiddleware:
|
|
58
|
+
def __init__(self, client_id, client_secret, token_url, store=None):
|
|
59
|
+
self.client_id = client_id
|
|
60
|
+
self.client_secret = client_secret
|
|
61
|
+
self.token_url = token_url
|
|
62
|
+
self.store = store or AccessTokenInMemoryStore()
|
|
63
|
+
self.lock = asyncio.Lock()
|
|
64
|
+
|
|
65
|
+
async def __call__(self, method, url, next_func, **kwargs):
|
|
66
|
+
async with self.lock:
|
|
67
|
+
token = await self.store.load()
|
|
68
|
+
if not token or token.get("expires_at") < time.time():
|
|
69
|
+
token = await self.__fetch_access_token()
|
|
70
|
+
await self.store.save(token)
|
|
71
|
+
if "headers" not in kwargs:
|
|
72
|
+
kwargs["headers"] = {}
|
|
73
|
+
kwargs["headers"]["Authorization"] = "{token_type} {access_token}".format(**token)
|
|
74
|
+
return await next_func(method, url, **kwargs)
|
|
75
|
+
|
|
76
|
+
async def __fetch_access_token(self):
|
|
77
|
+
auth = aiohttp.BasicAuth(login=self.client_id, password=self.client_secret)
|
|
78
|
+
async with LeasewebHttpClient(auth=auth, middlewares=[LoggingMiddleware(debug=False)]) as client:
|
|
79
|
+
payload = {"grant_type": "client_credentials"}
|
|
80
|
+
response = await client.post(self.token_url, data=payload)
|
|
81
|
+
assert response.status == 200
|
|
82
|
+
token = await response.json()
|
|
83
|
+
token["issued_at"] = int(time.time())
|
|
84
|
+
token["expires_at"] = token["issued_at"] + token["expires_in"] - 10
|
|
85
|
+
return token
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"""
|
|
2
2
|
LswApi auth plugin for HTTPie.
|
|
3
3
|
"""
|
|
4
|
+
from httpie.plugins import AuthPlugin
|
|
4
5
|
from json import loads, dumps
|
|
5
|
-
from
|
|
6
|
+
from lswapi import __auth_token_url__
|
|
7
|
+
from lswapi.requests import fetch_access_token
|
|
6
8
|
from os import path
|
|
7
|
-
from
|
|
8
|
-
|
|
9
|
+
from time import time
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__token_store__ = path.expanduser("~/.lswapi.token")
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
class LswApiAuth(object):
|
|
@@ -15,25 +19,25 @@ class LswApiAuth(object):
|
|
|
15
19
|
|
|
16
20
|
def __call__(self, r):
|
|
17
21
|
if path.exists(__token_store__):
|
|
18
|
-
with open(__token_store__,
|
|
22
|
+
with open(__token_store__, "r") as file:
|
|
19
23
|
token = loads(file.read())
|
|
20
|
-
if
|
|
21
|
-
r.headers[
|
|
24
|
+
if "expires_at" in token and token["expires_at"] > time():
|
|
25
|
+
r.headers["Authorization"] = "{token_type} {access_token}".format(**token)
|
|
22
26
|
return r
|
|
23
27
|
|
|
24
28
|
token = fetch_access_token(__auth_token_url__, self.client_id, self.client_secret)
|
|
25
29
|
|
|
26
|
-
with open(__token_store__,
|
|
30
|
+
with open(__token_store__, "w") as file:
|
|
27
31
|
file.write(dumps(token))
|
|
28
32
|
|
|
29
|
-
r.headers[
|
|
33
|
+
r.headers["Authorization"] = "{token_type} {access_token}".format(**token)
|
|
30
34
|
return r
|
|
31
35
|
|
|
32
36
|
|
|
33
37
|
class ApiAuthPlugin(AuthPlugin):
|
|
34
|
-
name =
|
|
35
|
-
auth_type =
|
|
36
|
-
description =
|
|
38
|
+
name = "LswApi Oauth"
|
|
39
|
+
auth_type = "lswapi"
|
|
40
|
+
description = "Leaseweb Api Oauth Authentication"
|
|
37
41
|
|
|
38
42
|
def get_auth(self, username, password):
|
|
39
43
|
return LswApiAuth(username, password)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from lswapi import __api_base_url__
|
|
2
|
+
from lswapi import __auth_token_url__
|
|
3
|
+
from lswapi.requests.session import LeasewebSession
|
|
4
|
+
from lswapi.requests.session import LeasewebApiKeyAuth
|
|
5
|
+
from os import environ
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_leaseweb_api(api_key=None, client_id=None, client_secret=None, base_url=None, token_url=None, token_store=None):
|
|
9
|
+
base_url = base_url or environ.get("LSW_BASE_URL", __api_base_url__)
|
|
10
|
+
token_url = token_url or environ.get("LSW_AUTH_URL", __auth_token_url__)
|
|
11
|
+
token_store = token_store or environ.get("LSW_AUTH_TOKEN_STORE", None)
|
|
12
|
+
api_key = api_key or environ.get("LSW_API_KEY")
|
|
13
|
+
if api_key:
|
|
14
|
+
api = LeasewebSession(base_url=base_url)
|
|
15
|
+
api.auth = (LeasewebApiKeyAuth(api_key))
|
|
16
|
+
return api
|
|
17
|
+
client_id = client_id or environ.get("LSW_CLIENT_ID")
|
|
18
|
+
client_secret = client_secret or environ.get("LSW_CLIENT_SECRET")
|
|
19
|
+
if client_id and client_secret:
|
|
20
|
+
return LeasewebSession(base_url=base_url, client_id=client_id, client_secret=client_secret, token_url=token_url, token_store=token_store)
|
|
21
|
+
raise Exception("No authentication method specified")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from requests import post
|
|
2
|
+
from time import time
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def fetch_access_token(token_url, client_id, client_secret):
|
|
6
|
+
response = post(token_url, auth=(client_id, client_secret), data={"grant_type": "client_credentials"})
|
|
7
|
+
if response.status_code != 200:
|
|
8
|
+
raise Exception("Could not obtain an access token")
|
|
9
|
+
token = response.json()
|
|
10
|
+
token["created_at"] = int(time())
|
|
11
|
+
token["expires_at"] = token["created_at"] + token["expires_in"] - 10
|
|
12
|
+
return token
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from json import load, dump
|
|
2
|
+
from lswapi import __api_base_url__
|
|
3
|
+
from lswapi import __auth_token_url__
|
|
4
|
+
from lswapi.requests.oauth import fetch_access_token
|
|
5
|
+
from os import path
|
|
6
|
+
from requests import Session
|
|
7
|
+
from requests.auth import AuthBase
|
|
8
|
+
from time import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class LeasewebApiKeyAuth(AuthBase):
|
|
12
|
+
def __init__(self, lsw_auth_key):
|
|
13
|
+
self.lsw_auth_key = lsw_auth_key
|
|
14
|
+
|
|
15
|
+
def __call__(self, r):
|
|
16
|
+
r.headers["X-Lsw-Auth"] = self.lsw_auth_key
|
|
17
|
+
return r
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class LeasewebSession(Session):
|
|
21
|
+
access_token = None
|
|
22
|
+
|
|
23
|
+
def __init__(self, client_id=None, client_secret=None, base_url=None, token_url=None, token_store=None):
|
|
24
|
+
self.base_url = base_url or __api_base_url__
|
|
25
|
+
self.token_url = token_url or __auth_token_url__
|
|
26
|
+
self.token_store = token_store
|
|
27
|
+
self.client_id = client_id
|
|
28
|
+
self.client_secret = client_secret
|
|
29
|
+
super().__init__()
|
|
30
|
+
|
|
31
|
+
def _fetch_access_token(self):
|
|
32
|
+
if not self.access_token and self.token_store:
|
|
33
|
+
if path.exists(self.token_store):
|
|
34
|
+
with open(self.token_store, "r") as file:
|
|
35
|
+
self.access_token = load(file)
|
|
36
|
+
if self.access_token and self.access_token.get("expires_at") > time():
|
|
37
|
+
return self.access_token
|
|
38
|
+
self.access_token = fetch_access_token(self.token_url, self.client_id, self.client_secret)
|
|
39
|
+
if self.token_store:
|
|
40
|
+
with open(self.token_store, "w") as file:
|
|
41
|
+
dump(self.access_token, file)
|
|
42
|
+
return self.access_token
|
|
43
|
+
|
|
44
|
+
def request(self, method, url, data=None, headers={}, **kwargs):
|
|
45
|
+
if self.client_id and self.client_secret:
|
|
46
|
+
headers["Authorization"] = "{token_type} {access_token}".format(**self._fetch_access_token())
|
|
47
|
+
if not url.startswith("http"):
|
|
48
|
+
url = "{}/{}".format(self.base_url, url.lstrip("/"))
|
|
49
|
+
return super().request(method, url, headers=headers, data=data, **kwargs)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from lswapi.aio import get_leaseweb_api
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_get_with_nothing():
|
|
8
|
+
async def fuubar():
|
|
9
|
+
with pytest.raises(Exception):
|
|
10
|
+
get_leaseweb_api()
|
|
11
|
+
asyncio.run(fuubar())
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_get_with_api_key():
|
|
15
|
+
async def fuubar():
|
|
16
|
+
assert get_leaseweb_api(api_key="xxx")
|
|
17
|
+
asyncio.run(fuubar())
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_get_with_oauth():
|
|
21
|
+
async def fuubar():
|
|
22
|
+
assert get_leaseweb_api(client_id="xxx", client_secret="yyy")
|
|
23
|
+
asyncio.run(fuubar())
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from lswapi.requests import get_leaseweb_api
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_get_with_nothing():
|
|
7
|
+
with pytest.raises(Exception):
|
|
8
|
+
get_leaseweb_api()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_get_with_api_key():
|
|
12
|
+
assert get_leaseweb_api(api_key="xxx")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_get_with_oauth():
|
|
16
|
+
assert get_leaseweb_api(client_id="xxx", client_secret="yyy")
|
lswapi-0.4.2/MANIFEST.in
DELETED
lswapi-0.4.2/PKG-INFO
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: lswapi
|
|
3
|
-
Version: 0.4.2
|
|
4
|
-
Summary: a python client library for easy leaseweb api access
|
|
5
|
-
Home-page: http://developer.leaseweb.com
|
|
6
|
-
Author: Nico Di Rocco
|
|
7
|
-
Author-email: n.dirocco@global.leaseweb.com
|
|
8
|
-
License: GPLv3
|
|
9
|
-
Download-URL: https://github.com/nrocco/lswapi/tags
|
|
10
|
-
Description: lswapi (beta)
|
|
11
|
-
=============
|
|
12
|
-
|
|
13
|
-
[](https://github.com/nrocco/lswapi/actions)
|
|
14
|
-
|
|
15
|
-
Python module to talk to LeaseWeb's API.
|
|
16
|
-
|
|
17
|
-
For more information refer to the documentation available at
|
|
18
|
-
[http://developer.leaseweb.com]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Installation
|
|
22
|
-
------------
|
|
23
|
-
|
|
24
|
-
Install the module using pip
|
|
25
|
-
|
|
26
|
-
pip install lswapi
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Usage
|
|
30
|
-
-----
|
|
31
|
-
|
|
32
|
-
The `lswapi.get_leaseweb_api` function creates an instance of the LeaseWeb Api
|
|
33
|
-
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
34
|
-
to `get_leaseweb_api`
|
|
35
|
-
|
|
36
|
-
$ python
|
|
37
|
-
>>> import lswapi
|
|
38
|
-
>>> client = lswapi.get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
39
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
40
|
-
>>> servers = response.json()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
or as an environment variable `LSW_API_KEY`
|
|
44
|
-
|
|
45
|
-
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
46
|
-
>>> import lswapi
|
|
47
|
-
>>> client = lswapi.get_leaseweb_api()
|
|
48
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
49
|
-
>>> servers = response.json()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Contribute
|
|
53
|
-
----------
|
|
54
|
-
|
|
55
|
-
1. Fork it
|
|
56
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
57
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
58
|
-
4. Make sure that tests pass (`make test`)
|
|
59
|
-
5. Push to the branch (`git push origin my-new-feature`)
|
|
60
|
-
6. Create new Pull Request
|
|
61
|
-
|
|
62
|
-
Platform: UNKNOWN
|
|
63
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
64
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
65
|
-
Classifier: Operating System :: Unix
|
|
66
|
-
Classifier: Programming Language :: Python
|
|
67
|
-
Classifier: Programming Language :: Python :: 2
|
|
68
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
69
|
-
Classifier: Programming Language :: Python :: 3
|
|
70
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
71
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
72
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
73
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
74
|
-
Classifier: Topic :: Utilities
|
lswapi-0.4.2/README.md
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
lswapi (beta)
|
|
2
|
-
=============
|
|
3
|
-
|
|
4
|
-
[](https://github.com/nrocco/lswapi/actions)
|
|
5
|
-
|
|
6
|
-
Python module to talk to LeaseWeb's API.
|
|
7
|
-
|
|
8
|
-
For more information refer to the documentation available at
|
|
9
|
-
[http://developer.leaseweb.com]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Installation
|
|
13
|
-
------------
|
|
14
|
-
|
|
15
|
-
Install the module using pip
|
|
16
|
-
|
|
17
|
-
pip install lswapi
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Usage
|
|
21
|
-
-----
|
|
22
|
-
|
|
23
|
-
The `lswapi.get_leaseweb_api` function creates an instance of the LeaseWeb Api
|
|
24
|
-
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
25
|
-
to `get_leaseweb_api`
|
|
26
|
-
|
|
27
|
-
$ python
|
|
28
|
-
>>> import lswapi
|
|
29
|
-
>>> client = lswapi.get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
30
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
31
|
-
>>> servers = response.json()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
or as an environment variable `LSW_API_KEY`
|
|
35
|
-
|
|
36
|
-
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
37
|
-
>>> import lswapi
|
|
38
|
-
>>> client = lswapi.get_leaseweb_api()
|
|
39
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
40
|
-
>>> servers = response.json()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Contribute
|
|
44
|
-
----------
|
|
45
|
-
|
|
46
|
-
1. Fork it
|
|
47
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
48
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
49
|
-
4. Make sure that tests pass (`make test`)
|
|
50
|
-
5. Push to the branch (`git push origin my-new-feature`)
|
|
51
|
-
6. Create new Pull Request
|
lswapi-0.4.2/lswapi/__init__.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from os import environ, path
|
|
2
|
-
from requests.auth import AuthBase
|
|
3
|
-
from requests import Session
|
|
4
|
-
from requests import post
|
|
5
|
-
from time import time
|
|
6
|
-
|
|
7
|
-
__version__ = '0.4.2'
|
|
8
|
-
__auth_token_url__ = 'https://auth.leaseweb.com/token'
|
|
9
|
-
__api_base_url__ = 'https://api.leaseweb.com'
|
|
10
|
-
__token_store__ = path.expanduser('~/.lswapi.token')
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def get_leaseweb_api(api_key=None, client_id=None, client_secret=None, base_url=None, token_url=None):
|
|
14
|
-
base_url = base_url or environ.get('LSW_BASE_URL', __api_base_url__)
|
|
15
|
-
token_url = token_url or environ.get('LSW_AUTH_URL', __auth_token_url__)
|
|
16
|
-
|
|
17
|
-
api_key = api_key or environ.get('LSW_API_KEY')
|
|
18
|
-
if api_key:
|
|
19
|
-
api = LeaseWebSession(base_url=base_url)
|
|
20
|
-
api.auth = (LeasewebApiKeyAuth(api_key))
|
|
21
|
-
return api
|
|
22
|
-
|
|
23
|
-
client_id = client_id or environ.get('LSW_CLIENT_ID')
|
|
24
|
-
client_secret = client_secret or environ.get('LSW_CLIENT_SECRET')
|
|
25
|
-
if client_id and client_secret:
|
|
26
|
-
return LeaseWebSession(base_url=base_url, client_id=client_id, client_secret=client_secret, token_url=token_url)
|
|
27
|
-
|
|
28
|
-
raise Exception("No authentication method specified")
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def fetch_access_token(token_url, client_id, client_secret):
|
|
32
|
-
response = post(token_url, auth=(client_id, client_secret), data={'grant_type': 'client_credentials'})
|
|
33
|
-
if response.status_code != 200:
|
|
34
|
-
raise Exception('Could not obtain an access token')
|
|
35
|
-
token = response.json()
|
|
36
|
-
token['created_at'] = int(time())
|
|
37
|
-
token['expires_at'] = token['created_at'] + token['expires_in'] - 10
|
|
38
|
-
return token
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class LeasewebApiKeyAuth(AuthBase):
|
|
42
|
-
def __init__(self, lsw_auth_key):
|
|
43
|
-
self.lsw_auth_key = lsw_auth_key
|
|
44
|
-
|
|
45
|
-
def __call__(self, r):
|
|
46
|
-
r.headers['X-Lsw-Auth'] = self.lsw_auth_key
|
|
47
|
-
return r
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class LeaseWebSession(Session):
|
|
51
|
-
access_token = None
|
|
52
|
-
|
|
53
|
-
def __init__(self, client_id=None, client_secret=None, base_url=None, token_url=None):
|
|
54
|
-
self.base_url = base_url or __api_base_url__
|
|
55
|
-
self.token_url = token_url or __auth_token_url__
|
|
56
|
-
self.client_id = client_id
|
|
57
|
-
self.client_secret = client_secret
|
|
58
|
-
super(LeaseWebSession, self).__init__()
|
|
59
|
-
|
|
60
|
-
def _fetch_access_token(self):
|
|
61
|
-
return fetch_access_token(self.token_url, self.client_id, self.client_secret)
|
|
62
|
-
|
|
63
|
-
def request(self, method, url, data=None, headers={}, **kwargs):
|
|
64
|
-
if self.client_id and self.client_secret:
|
|
65
|
-
if not self.access_token:
|
|
66
|
-
self.access_token = self._fetch_access_token()
|
|
67
|
-
if int(time()) > self.access_token['expires_at']:
|
|
68
|
-
self.access_token = self._fetch_access_token() # TODO: use refresh tokens instead
|
|
69
|
-
headers['Authorization'] = '{token_type} {access_token}'.format(**self.access_token)
|
|
70
|
-
if not url.startswith('http'):
|
|
71
|
-
url = '{}/{}'.format(self.base_url, url.lstrip('/'))
|
|
72
|
-
|
|
73
|
-
# if response.status_code == 401 and 'WWW-Authenticate' in response.headers:
|
|
74
|
-
# pass # TODO analyse the WWW-Authenticate response header
|
|
75
|
-
|
|
76
|
-
return super(LeaseWebSession, self).request(method, url, headers=headers, data=data, **kwargs)
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: lswapi
|
|
3
|
-
Version: 0.4.2
|
|
4
|
-
Summary: a python client library for easy leaseweb api access
|
|
5
|
-
Home-page: http://developer.leaseweb.com
|
|
6
|
-
Author: Nico Di Rocco
|
|
7
|
-
Author-email: n.dirocco@global.leaseweb.com
|
|
8
|
-
License: GPLv3
|
|
9
|
-
Download-URL: https://github.com/nrocco/lswapi/tags
|
|
10
|
-
Description: lswapi (beta)
|
|
11
|
-
=============
|
|
12
|
-
|
|
13
|
-
[](https://github.com/nrocco/lswapi/actions)
|
|
14
|
-
|
|
15
|
-
Python module to talk to LeaseWeb's API.
|
|
16
|
-
|
|
17
|
-
For more information refer to the documentation available at
|
|
18
|
-
[http://developer.leaseweb.com]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Installation
|
|
22
|
-
------------
|
|
23
|
-
|
|
24
|
-
Install the module using pip
|
|
25
|
-
|
|
26
|
-
pip install lswapi
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Usage
|
|
30
|
-
-----
|
|
31
|
-
|
|
32
|
-
The `lswapi.get_leaseweb_api` function creates an instance of the LeaseWeb Api
|
|
33
|
-
object with the `X-Lsw-Auth` key. You can provide the api key as an argument
|
|
34
|
-
to `get_leaseweb_api`
|
|
35
|
-
|
|
36
|
-
$ python
|
|
37
|
-
>>> import lswapi
|
|
38
|
-
>>> client = lswapi.get_leaseweb_api(api_key="xxxx-xxx-xxxxxx")
|
|
39
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
40
|
-
>>> servers = response.json()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
or as an environment variable `LSW_API_KEY`
|
|
44
|
-
|
|
45
|
-
$ LSW_API_KEY=xxxx-xxxx-xxxxx python
|
|
46
|
-
>>> import lswapi
|
|
47
|
-
>>> client = lswapi.get_leaseweb_api()
|
|
48
|
-
>>> response = client.get("/bareMetals/v2/servers")
|
|
49
|
-
>>> servers = response.json()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Contribute
|
|
53
|
-
----------
|
|
54
|
-
|
|
55
|
-
1. Fork it
|
|
56
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
57
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
58
|
-
4. Make sure that tests pass (`make test`)
|
|
59
|
-
5. Push to the branch (`git push origin my-new-feature`)
|
|
60
|
-
6. Create new Pull Request
|
|
61
|
-
|
|
62
|
-
Platform: UNKNOWN
|
|
63
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
64
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
65
|
-
Classifier: Operating System :: Unix
|
|
66
|
-
Classifier: Programming Language :: Python
|
|
67
|
-
Classifier: Programming Language :: Python :: 2
|
|
68
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
69
|
-
Classifier: Programming Language :: Python :: 3
|
|
70
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
71
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
72
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
73
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
74
|
-
Classifier: Topic :: Utilities
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
LICENSE.txt
|
|
2
|
-
MANIFEST.in
|
|
3
|
-
README.md
|
|
4
|
-
requirements.txt
|
|
5
|
-
setup.cfg
|
|
6
|
-
setup.py
|
|
7
|
-
lswapi/__init__.py
|
|
8
|
-
lswapi.egg-info/PKG-INFO
|
|
9
|
-
lswapi.egg-info/SOURCES.txt
|
|
10
|
-
lswapi.egg-info/dependency_links.txt
|
|
11
|
-
lswapi.egg-info/entry_points.txt
|
|
12
|
-
lswapi.egg-info/requires.txt
|
|
13
|
-
lswapi.egg-info/top_level.txt
|
|
14
|
-
lswapi/httpie/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
requests
|
lswapi-0.4.2/requirements.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
requests
|
lswapi-0.4.2/setup.cfg
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
[bumpversion]
|
|
2
|
-
current_version = 0.4.2
|
|
3
|
-
commit = True
|
|
4
|
-
tag = True
|
|
5
|
-
|
|
6
|
-
[wheel]
|
|
7
|
-
universal = 1
|
|
8
|
-
|
|
9
|
-
[flake8]
|
|
10
|
-
exclude = .git,__pycache__,build,dist,env
|
|
11
|
-
max-complexity = 10
|
|
12
|
-
max-line-length = 1000
|
|
13
|
-
|
|
14
|
-
[pycodestyle]
|
|
15
|
-
ignore = E501
|
|
16
|
-
|
|
17
|
-
[bumpversion:file:setup.py]
|
|
18
|
-
|
|
19
|
-
[bumpversion:file:lswapi/__init__.py]
|
|
20
|
-
|
|
21
|
-
[egg_info]
|
|
22
|
-
tag_build =
|
|
23
|
-
tag_date = 0
|
|
24
|
-
|
lswapi-0.4.2/setup.py
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
import io
|
|
3
|
-
import codecs
|
|
4
|
-
|
|
5
|
-
from setuptools import setup, find_packages
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def load_requirements(filename):
|
|
9
|
-
with io.open(filename, encoding='utf-8') as reqfile:
|
|
10
|
-
return [line.strip() for line in reqfile if not line.startswith('#')]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
setup(
|
|
14
|
-
name='lswapi',
|
|
15
|
-
description='a python client library for easy leaseweb api access',
|
|
16
|
-
version='0.4.2',
|
|
17
|
-
author='Nico Di Rocco',
|
|
18
|
-
author_email='n.dirocco@global.leaseweb.com',
|
|
19
|
-
url='http://developer.leaseweb.com',
|
|
20
|
-
license='GPLv3',
|
|
21
|
-
long_description=codecs.open('README.md', 'rb', 'utf-8').read(),
|
|
22
|
-
download_url='https://github.com/nrocco/lswapi/tags',
|
|
23
|
-
include_package_data=True,
|
|
24
|
-
install_requires=load_requirements('requirements.txt'),
|
|
25
|
-
tests_require=[
|
|
26
|
-
'httpie',
|
|
27
|
-
'coverage',
|
|
28
|
-
],
|
|
29
|
-
entry_points={
|
|
30
|
-
'httpie.plugins.auth.v1': [
|
|
31
|
-
'httpie_lswapi = lswapi.httpie:ApiAuthPlugin'
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
packages=find_packages(exclude=['tests']),
|
|
35
|
-
test_suite='tests',
|
|
36
|
-
classifiers=[
|
|
37
|
-
'Development Status :: 5 - Production/Stable',
|
|
38
|
-
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
|
39
|
-
'Operating System :: Unix',
|
|
40
|
-
'Programming Language :: Python',
|
|
41
|
-
'Programming Language :: Python :: 2',
|
|
42
|
-
'Programming Language :: Python :: 2.7',
|
|
43
|
-
'Programming Language :: Python :: 3',
|
|
44
|
-
'Programming Language :: Python :: 3.5',
|
|
45
|
-
'Programming Language :: Python :: 3.6',
|
|
46
|
-
'Programming Language :: Python :: 3.7',
|
|
47
|
-
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
48
|
-
'Topic :: Utilities'
|
|
49
|
-
],
|
|
50
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|