python-postman 0.2.0__tar.gz → 0.6.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.
- {python-postman-0.2.0 → python_postman-0.6.0}/LICENSE +21 -21
- python_postman-0.6.0/PKG-INFO +52 -0
- python_postman-0.6.0/README.md +28 -0
- python_postman-0.6.0/pyproject.toml +59 -0
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/__main__.py +17 -17
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/auth.py +77 -77
- python_postman-0.6.0/src/python_postman/body.py +33 -0
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/collection.py +36 -36
- python_postman-0.6.0/src/python_postman/config.py +110 -0
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/environment.py +101 -101
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/event.py +30 -30
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/header.py +18 -18
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/item.py +28 -28
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/file.py +203 -203
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/http.py +186 -126
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/logger.py +49 -49
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/postman.py +143 -143
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/request.py +17 -17
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/template.py +5 -5
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/url.py +94 -94
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/utils/cli.py +62 -42
- python_postman-0.6.0/src/python_postman/utils/load_dotenvc.py +101 -0
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/variable.py +62 -62
- python-postman-0.2.0/.gitignore +0 -131
- python-postman-0.2.0/PKG-INFO +0 -73
- python-postman-0.2.0/README.md +0 -60
- python-postman-0.2.0/examples/collections/Coinmarketcap.postman_collection.json +0 -107
- python-postman-0.2.0/examples/collections/PokeAPI.postman_collection.json +0 -66
- python-postman-0.2.0/examples/models/coinmarketcap_example.py +0 -61
- python-postman-0.2.0/examples/models/pokeapi_example.py +0 -66
- python-postman-0.2.0/pypostman/body.py +0 -8
- python-postman-0.2.0/pypostman/config.py +0 -108
- python-postman-0.2.0/pypostman/utils/.gitkeep +0 -0
- python-postman-0.2.0/pyproject.toml +0 -23
- python-postman-0.2.0/python_postman.egg-info/PKG-INFO +0 -73
- python-postman-0.2.0/python_postman.egg-info/SOURCES.txt +0 -34
- python-postman-0.2.0/python_postman.egg-info/dependency_links.txt +0 -1
- python-postman-0.2.0/python_postman.egg-info/entry_points.txt +0 -2
- python-postman-0.2.0/python_postman.egg-info/requires.txt +0 -16
- python-postman-0.2.0/python_postman.egg-info/top_level.txt +0 -1
- python-postman-0.2.0/setup.cfg +0 -4
- {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/__init__.py +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 Yudiell
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Yudiell
|
|
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,52 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-postman
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Pypostman allows users to parse postman environments and postman collections.
|
|
5
|
+
Author: Data Engineering Team
|
|
6
|
+
Author-email: DataEngineering@loves.com
|
|
7
|
+
Requires-Python: >=3.8.1,<4.0.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Requires-Dist: boto3 (>=1.34.67,<2.0.0)
|
|
14
|
+
Requires-Dist: cryptography (>=42.0.5,<43.0.0)
|
|
15
|
+
Requires-Dist: logbook (>=1.7.0.post0,<2.0.0)
|
|
16
|
+
Requires-Dist: pendulum (>=3.0.0,<4.0.0)
|
|
17
|
+
Requires-Dist: pydantic (>=2.6.4,<3.0.0)
|
|
18
|
+
Requires-Dist: pytz (>=2024.1,<2025.0)
|
|
19
|
+
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
20
|
+
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
21
|
+
Requires-Dist: urllib3 (>=1.25.4,<2.0.0)
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Python Postman
|
|
25
|
+
|
|
26
|
+
**pypostman** is a command-line interface that allows to `automate` multiple api calls from postman collections, additionally it also allow you to `compress` and `save` the response to a local directory or to an AWS S3 bucket.
|
|
27
|
+
Thereby allowing you to manage your api calls using postman, then `automate` and `process` their response using python.
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
https://github.com/yudiell/energy-apis
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Included Modules
|
|
36
|
+
- http.py
|
|
37
|
+
- logger.py
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
See the example.
|
|
41
|
+
|
|
42
|
+
### Python >= 3.8.1
|
|
43
|
+
|
|
44
|
+
Pypi:
|
|
45
|
+
```
|
|
46
|
+
pip install python-postman
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## How to Use It
|
|
50
|
+
|
|
51
|
+
See example
|
|
52
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python Postman
|
|
2
|
+
|
|
3
|
+
**pypostman** is a command-line interface that allows to `automate` multiple api calls from postman collections, additionally it also allow you to `compress` and `save` the response to a local directory or to an AWS S3 bucket.
|
|
4
|
+
Thereby allowing you to manage your api calls using postman, then `automate` and `process` their response using python.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
https://github.com/yudiell/energy-apis
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Included Modules
|
|
13
|
+
- http.py
|
|
14
|
+
- logger.py
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
See the example.
|
|
18
|
+
|
|
19
|
+
### Python >= 3.8.1
|
|
20
|
+
|
|
21
|
+
Pypi:
|
|
22
|
+
```
|
|
23
|
+
pip install python-postman
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## How to Use It
|
|
27
|
+
|
|
28
|
+
See example
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "python-postman"
|
|
3
|
+
version = "0.6.0"
|
|
4
|
+
description = "Pypostman allows users to parse postman environments and postman collections."
|
|
5
|
+
authors = ["Data Engineering Team <DataEngineering@loves.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
|
|
8
|
+
[tool.isort]
|
|
9
|
+
profile = "black"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
[tool.poetry.dependencies]
|
|
13
|
+
python = "^3.8.1"
|
|
14
|
+
requests = "^2.32.3"
|
|
15
|
+
pyyaml = "^6.0.1"
|
|
16
|
+
pydantic = "^2.6.4"
|
|
17
|
+
cryptography = "^42.0.5"
|
|
18
|
+
urllib3 = "^1.25.4"
|
|
19
|
+
logbook = "^1.7.0.post0"
|
|
20
|
+
pendulum = "^3.0.0"
|
|
21
|
+
boto3 = "^1.34.67"
|
|
22
|
+
pytz = "^2024.1"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
[tool.poetry.group.lint.dependencies]
|
|
26
|
+
flake8-annotations = "^3.0.1"
|
|
27
|
+
flake8-builtins = "^2.1.0"
|
|
28
|
+
flake8-docstrings = "^1.7.0"
|
|
29
|
+
flake8-eradicate = "^1.5.0"
|
|
30
|
+
flake8-future-annotations = "^1.1.0"
|
|
31
|
+
flake8-isort = "^6.0.0"
|
|
32
|
+
flake8-new-union-types = "^0.4.1"
|
|
33
|
+
flake8-pep585 = "^0.1.7"
|
|
34
|
+
flake8-secure-coding-standard = "^1.4.0"
|
|
35
|
+
flake8-type-checking = "^2.4.1"
|
|
36
|
+
flake8-use-pathlib = "^0.3.0"
|
|
37
|
+
flake8-variables-names = "^0.0.6"
|
|
38
|
+
pep8-naming = "^0.13.3"
|
|
39
|
+
black = "^24.3.0"
|
|
40
|
+
isort = "^5.12.0"
|
|
41
|
+
pip-audit = "^2.6.1"
|
|
42
|
+
mypy = "^1.9.0"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
[tool.poetry.group.test.dependencies]
|
|
46
|
+
pytest = "^7.4.0"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
[tool.poetry.group.dev.dependencies]
|
|
50
|
+
pre-commit = "^3.3.3"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
[build-system]
|
|
54
|
+
requires = ["poetry-core"]
|
|
55
|
+
build-backend = "poetry.core.masonry.api"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
[tool.poetry.scripts]
|
|
59
|
+
pypostman = "pypostman.__main__:main"
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
from pypostman import postman
|
|
4
|
-
from .environment import Environment
|
|
5
|
-
from .collection import Collection
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def main():
|
|
9
|
-
environments_dir = "pypostman/environments"
|
|
10
|
-
environments: List[Environment] = postman._get_environments(dir=environments_dir)
|
|
11
|
-
|
|
12
|
-
collections_dir = "pypostman/collections"
|
|
13
|
-
collections: List[Collection] = postman._get_collections(dir=collections_dir)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if __name__ == "__main__":
|
|
17
|
-
main()
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from pypostman import postman
|
|
4
|
+
from .environment import Environment
|
|
5
|
+
from .collection import Collection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
environments_dir = "pypostman/environments"
|
|
10
|
+
environments: List[Environment] = postman._get_environments(dir=environments_dir)
|
|
11
|
+
|
|
12
|
+
collections_dir = "pypostman/collections"
|
|
13
|
+
collections: List[Collection] = postman._get_collections(dir=collections_dir)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
main()
|
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
from requests.auth import HTTPBasicAuth, AuthBase
|
|
2
|
-
|
|
3
|
-
from .config import Auth as ConfigAuth
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BearerAuth(AuthBase):
|
|
7
|
-
def __init__(self, token):
|
|
8
|
-
self.token = token
|
|
9
|
-
|
|
10
|
-
def __call__(self, r):
|
|
11
|
-
r.headers["Authorization"] = f"Bearer {self.token}"
|
|
12
|
-
return r
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ApiKeyAuth(AuthBase):
|
|
16
|
-
def __init__(self, apikey):
|
|
17
|
-
self.apikey = apikey
|
|
18
|
-
|
|
19
|
-
def __call__(self, r):
|
|
20
|
-
"""
|
|
21
|
-
The postman collection auth determines
|
|
22
|
-
where the apikey should be applied.
|
|
23
|
-
1. Query: Is to be added to the query params.
|
|
24
|
-
2. Header: Is to be added to the header.
|
|
25
|
-
The postman collection auth apikey is to be applied to -
|
|
26
|
-
the query params if the auth api key contains the key "in".
|
|
27
|
-
"""
|
|
28
|
-
key = self.apikey["key"]
|
|
29
|
-
value = self.apikey["value"]
|
|
30
|
-
if self.apikey.get("in") is not None:
|
|
31
|
-
r.prepare_url(url=r.url, params={key: value})
|
|
32
|
-
else:
|
|
33
|
-
r.headers[key] = value
|
|
34
|
-
return r
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class Auth:
|
|
38
|
-
def __init__(self, auth: ConfigAuth):
|
|
39
|
-
self.type = auth.type if auth else None
|
|
40
|
-
self.__auth_config = (
|
|
41
|
-
auth.noauth or auth.basic or auth.apikey or auth.bearer if auth else None
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
self.http_auth = (
|
|
45
|
-
self.noauth or self.basic or self.apikey or self.bearer if auth else None
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
@property
|
|
49
|
-
def noauth(self) -> None:
|
|
50
|
-
if self.__auth_config and self.type == "noauth":
|
|
51
|
-
return None
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def basic(self) -> HTTPBasicAuth:
|
|
55
|
-
if self.__auth_config and self.type == "basic":
|
|
56
|
-
basic = {}
|
|
57
|
-
for item in self.__auth_config:
|
|
58
|
-
basic[item.key] = item.value
|
|
59
|
-
# print(basic)
|
|
60
|
-
return HTTPBasicAuth(username=basic["username"], password=basic["password"])
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def apikey(self) -> ApiKeyAuth:
|
|
64
|
-
if self.__auth_config and self.type == "apikey":
|
|
65
|
-
apikey = {}
|
|
66
|
-
for item in self.__auth_config:
|
|
67
|
-
apikey[item.key] = item.value
|
|
68
|
-
return ApiKeyAuth(apikey=apikey)
|
|
69
|
-
|
|
70
|
-
@property
|
|
71
|
-
def bearer(self) -> BearerAuth:
|
|
72
|
-
if self.__auth_config and self.type == "bearer":
|
|
73
|
-
bearer = {}
|
|
74
|
-
for item in self.__auth_config:
|
|
75
|
-
bearer[item.key] = item.value
|
|
76
|
-
# print(bearer)
|
|
77
|
-
return BearerAuth(token=bearer["token"])
|
|
1
|
+
from requests.auth import HTTPBasicAuth, AuthBase
|
|
2
|
+
|
|
3
|
+
from .config import Auth as ConfigAuth
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BearerAuth(AuthBase):
|
|
7
|
+
def __init__(self, token):
|
|
8
|
+
self.token = token
|
|
9
|
+
|
|
10
|
+
def __call__(self, r):
|
|
11
|
+
r.headers["Authorization"] = f"Bearer {self.token}"
|
|
12
|
+
return r
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ApiKeyAuth(AuthBase):
|
|
16
|
+
def __init__(self, apikey):
|
|
17
|
+
self.apikey = apikey
|
|
18
|
+
|
|
19
|
+
def __call__(self, r):
|
|
20
|
+
"""
|
|
21
|
+
The postman collection auth determines
|
|
22
|
+
where the apikey should be applied.
|
|
23
|
+
1. Query: Is to be added to the query params.
|
|
24
|
+
2. Header: Is to be added to the header.
|
|
25
|
+
The postman collection auth apikey is to be applied to -
|
|
26
|
+
the query params if the auth api key contains the key "in".
|
|
27
|
+
"""
|
|
28
|
+
key = self.apikey["key"]
|
|
29
|
+
value = self.apikey["value"]
|
|
30
|
+
if self.apikey.get("in") is not None:
|
|
31
|
+
r.prepare_url(url=r.url, params={key: value})
|
|
32
|
+
else:
|
|
33
|
+
r.headers[key] = value
|
|
34
|
+
return r
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Auth:
|
|
38
|
+
def __init__(self, auth: ConfigAuth):
|
|
39
|
+
self.type = auth.type if auth else None
|
|
40
|
+
self.__auth_config = (
|
|
41
|
+
auth.noauth or auth.basic or auth.apikey or auth.bearer if auth else None
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
self.http_auth = (
|
|
45
|
+
self.noauth or self.basic or self.apikey or self.bearer if auth else None
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def noauth(self) -> None:
|
|
50
|
+
if self.__auth_config and self.type == "noauth":
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def basic(self) -> HTTPBasicAuth:
|
|
55
|
+
if self.__auth_config and self.type == "basic":
|
|
56
|
+
basic = {}
|
|
57
|
+
for item in self.__auth_config:
|
|
58
|
+
basic[item.key] = item.value
|
|
59
|
+
# print(basic)
|
|
60
|
+
return HTTPBasicAuth(username=basic["username"], password=basic["password"])
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def apikey(self) -> ApiKeyAuth:
|
|
64
|
+
if self.__auth_config and self.type == "apikey":
|
|
65
|
+
apikey = {}
|
|
66
|
+
for item in self.__auth_config:
|
|
67
|
+
apikey[item.key] = item.value
|
|
68
|
+
return ApiKeyAuth(apikey=apikey)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bearer(self) -> BearerAuth:
|
|
72
|
+
if self.__auth_config and self.type == "bearer":
|
|
73
|
+
bearer = {}
|
|
74
|
+
for item in self.__auth_config:
|
|
75
|
+
bearer[item.key] = item.value
|
|
76
|
+
# print(bearer)
|
|
77
|
+
return BearerAuth(token=bearer["token"])
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
from .config import Body
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Body:
|
|
6
|
+
def __init__(self, body: Body) -> None:
|
|
7
|
+
self.mode = body.mode
|
|
8
|
+
self.raw = body.raw
|
|
9
|
+
self.options = body.options
|
|
10
|
+
self.formdata = body.formdata
|
|
11
|
+
self.urlencoded = body.urlencoded
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def urlencoded_as_dict(self) -> Dict[str, str]:
|
|
15
|
+
if not self.urlencoded:
|
|
16
|
+
return None
|
|
17
|
+
|
|
18
|
+
body = {}
|
|
19
|
+
for option in self.urlencoded:
|
|
20
|
+
if not option.get("disabled", False):
|
|
21
|
+
body[option["key"]] = option["value"]
|
|
22
|
+
return body
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def formdata_as_dict(self) -> Dict[str, str]:
|
|
26
|
+
if not self.formdata:
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
body = {}
|
|
30
|
+
for option in self.formdata:
|
|
31
|
+
if not option.get("disabled", False):
|
|
32
|
+
body[option["key"]] = option["value"]
|
|
33
|
+
return body
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import json
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from .config import Config
|
|
6
|
-
from .variable import Variables
|
|
7
|
-
from .auth import Auth
|
|
8
|
-
from .event import Events
|
|
9
|
-
from .item import Items
|
|
10
|
-
from .template import CustomTemplate
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Collection:
|
|
14
|
-
def __init__(self, collection_file) -> None:
|
|
15
|
-
with open(Path(collection_file)) as file:
|
|
16
|
-
text = file.read().replace("{{", "${").replace("}}", "}")
|
|
17
|
-
template: str = CustomTemplate(text).safe_substitute(os.environ)
|
|
18
|
-
data: dict = json.loads(template)
|
|
19
|
-
|
|
20
|
-
self._template = template
|
|
21
|
-
self._collection = Config(**data)
|
|
22
|
-
self._info = self._collection.info
|
|
23
|
-
self._variables: Variables = Variables(variables=self._collection.variables)
|
|
24
|
-
self._auth: Auth = Auth(auth=self._collection.auth)
|
|
25
|
-
self._events = Events(events=self._collection.events)
|
|
26
|
-
self._test = self._events.test
|
|
27
|
-
self._prerequest = self._events.prerequest
|
|
28
|
-
self._items: Items = Items(items=self._collection.items)
|
|
29
|
-
self._requests = self._items.requests()
|
|
30
|
-
for request in self._requests:
|
|
31
|
-
request.auth = self._auth if not request.auth else request.auth
|
|
32
|
-
if request.url:
|
|
33
|
-
template: str = CustomTemplate(request.url.base).safe_substitute(
|
|
34
|
-
self._variables.as_dict
|
|
35
|
-
)
|
|
36
|
-
request.url.base_url = template
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .config import Config
|
|
6
|
+
from .variable import Variables
|
|
7
|
+
from .auth import Auth
|
|
8
|
+
from .event import Events
|
|
9
|
+
from .item import Items
|
|
10
|
+
from .template import CustomTemplate
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Collection:
|
|
14
|
+
def __init__(self, collection_file) -> None:
|
|
15
|
+
with open(Path(collection_file)) as file:
|
|
16
|
+
text = file.read().replace("{{", "${").replace("}}", "}")
|
|
17
|
+
template: str = CustomTemplate(text).safe_substitute(os.environ)
|
|
18
|
+
data: dict = json.loads(template)
|
|
19
|
+
|
|
20
|
+
self._template = template
|
|
21
|
+
self._collection = Config(**data)
|
|
22
|
+
self._info = self._collection.info
|
|
23
|
+
self._variables: Variables = Variables(variables=self._collection.variables)
|
|
24
|
+
self._auth: Auth = Auth(auth=self._collection.auth)
|
|
25
|
+
self._events = Events(events=self._collection.events)
|
|
26
|
+
self._test = self._events.test
|
|
27
|
+
self._prerequest = self._events.prerequest
|
|
28
|
+
self._items: Items = Items(items=self._collection.items)
|
|
29
|
+
self._requests = self._items.requests()
|
|
30
|
+
for request in self._requests:
|
|
31
|
+
request.auth = self._auth if not request.auth else request.auth
|
|
32
|
+
if request.url:
|
|
33
|
+
template: str = CustomTemplate(request.url.base).safe_substitute(
|
|
34
|
+
self._variables.as_dict
|
|
35
|
+
)
|
|
36
|
+
request.url.base_url = template
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from typing import List, Dict, Union, Optional
|
|
2
|
+
from pydantic import Field, BaseModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Info(BaseModel):
|
|
6
|
+
postman_id: str = Field(None, alias="_postman_id")
|
|
7
|
+
name: str
|
|
8
|
+
postman_schema: str = Field(None, alias="schema")
|
|
9
|
+
exporter_id: str = Field(None, alias="_exporter_id")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Variable Related Objects
|
|
13
|
+
class Variables(BaseModel):
|
|
14
|
+
key: Optional[str] = None
|
|
15
|
+
value: Optional[str] = None
|
|
16
|
+
type: Optional[str] = None
|
|
17
|
+
disabled: Optional[bool] = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Auth Related Objects
|
|
21
|
+
class AuthValues(BaseModel):
|
|
22
|
+
key: str
|
|
23
|
+
value: str
|
|
24
|
+
type: str
|
|
25
|
+
disabled: Optional[bool] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Auth(BaseModel):
|
|
29
|
+
type: str
|
|
30
|
+
noauth: Optional[List[AuthValues]] = None
|
|
31
|
+
basic: Optional[List[AuthValues]] = None
|
|
32
|
+
apikey: Optional[List[AuthValues]] = None
|
|
33
|
+
bearer: Optional[List[AuthValues]] = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Collection and Request Related Objects
|
|
37
|
+
class Script(BaseModel):
|
|
38
|
+
type: Optional[str] = None
|
|
39
|
+
exec: List[str]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Event(BaseModel):
|
|
43
|
+
listen: Optional[str] = None
|
|
44
|
+
script: Optional[Script] = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Request Related Objects
|
|
48
|
+
class Header(BaseModel):
|
|
49
|
+
key: Optional[str] = None
|
|
50
|
+
value: Optional[str] = None
|
|
51
|
+
description: Optional[str] = None
|
|
52
|
+
disabled: Optional[bool] = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class Variable(BaseModel):
|
|
56
|
+
key: Optional[str] = None
|
|
57
|
+
value: Optional[str] = None
|
|
58
|
+
description: Optional[str] = None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Param(BaseModel):
|
|
62
|
+
key: Optional[str] = None
|
|
63
|
+
value: Optional[str] = None
|
|
64
|
+
description: Optional[str] = None
|
|
65
|
+
disabled: Optional[bool] = None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Body(BaseModel):
|
|
69
|
+
mode: Optional[str] = None
|
|
70
|
+
raw: Optional[str] = None
|
|
71
|
+
formdata: Optional[List[Dict[str, Union[str, bool]]]] = None
|
|
72
|
+
urlencoded: Optional[List[Dict[str, Union[str, bool]]]] = None
|
|
73
|
+
options: Optional[Dict[str, Dict[str, Union[str, bool]]]] = None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Url(BaseModel):
|
|
77
|
+
raw: Optional[str] = None
|
|
78
|
+
protocol: Optional[str] = None
|
|
79
|
+
host: Optional[List[str]] = None
|
|
80
|
+
path: Optional[List[str]] = None
|
|
81
|
+
variable: Optional[List[Variable]] = None
|
|
82
|
+
query: Optional[List[Param]] = None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class Request(BaseModel):
|
|
86
|
+
auth: Optional[Auth] = None
|
|
87
|
+
method: str
|
|
88
|
+
headers: List[Header] = Field(None, alias="header")
|
|
89
|
+
url: Optional[Url] = None
|
|
90
|
+
body: Optional[Body] = None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Collection Related Objects
|
|
94
|
+
class Item(BaseModel):
|
|
95
|
+
name: str
|
|
96
|
+
item: Optional[List["Item"]] = None
|
|
97
|
+
events: Optional[List[Event]] = Field(None, alias="event")
|
|
98
|
+
request: Optional[Request] = None
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def type(self):
|
|
102
|
+
return "request" if self.request else "folder"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class Config(BaseModel):
|
|
106
|
+
info: Optional[Info] = None
|
|
107
|
+
items: Optional[List[Item]] = Field(None, alias="item")
|
|
108
|
+
variables: Optional[List[Variables]] = Field(None, alias="variable")
|
|
109
|
+
events: Optional[List[Event]] = Field(None, alias="event")
|
|
110
|
+
auth: Optional[Auth] = None
|