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.
Files changed (42) hide show
  1. {python-postman-0.2.0 → python_postman-0.6.0}/LICENSE +21 -21
  2. python_postman-0.6.0/PKG-INFO +52 -0
  3. python_postman-0.6.0/README.md +28 -0
  4. python_postman-0.6.0/pyproject.toml +59 -0
  5. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/__main__.py +17 -17
  6. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/auth.py +77 -77
  7. python_postman-0.6.0/src/python_postman/body.py +33 -0
  8. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/collection.py +36 -36
  9. python_postman-0.6.0/src/python_postman/config.py +110 -0
  10. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/environment.py +101 -101
  11. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/event.py +30 -30
  12. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/header.py +18 -18
  13. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/item.py +28 -28
  14. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/file.py +203 -203
  15. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/http.py +186 -126
  16. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/modules/logger.py +49 -49
  17. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/postman.py +143 -143
  18. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/request.py +17 -17
  19. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/template.py +5 -5
  20. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/url.py +94 -94
  21. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/utils/cli.py +62 -42
  22. python_postman-0.6.0/src/python_postman/utils/load_dotenvc.py +101 -0
  23. {python-postman-0.2.0/pypostman → python_postman-0.6.0/src/python_postman}/variable.py +62 -62
  24. python-postman-0.2.0/.gitignore +0 -131
  25. python-postman-0.2.0/PKG-INFO +0 -73
  26. python-postman-0.2.0/README.md +0 -60
  27. python-postman-0.2.0/examples/collections/Coinmarketcap.postman_collection.json +0 -107
  28. python-postman-0.2.0/examples/collections/PokeAPI.postman_collection.json +0 -66
  29. python-postman-0.2.0/examples/models/coinmarketcap_example.py +0 -61
  30. python-postman-0.2.0/examples/models/pokeapi_example.py +0 -66
  31. python-postman-0.2.0/pypostman/body.py +0 -8
  32. python-postman-0.2.0/pypostman/config.py +0 -108
  33. python-postman-0.2.0/pypostman/utils/.gitkeep +0 -0
  34. python-postman-0.2.0/pyproject.toml +0 -23
  35. python-postman-0.2.0/python_postman.egg-info/PKG-INFO +0 -73
  36. python-postman-0.2.0/python_postman.egg-info/SOURCES.txt +0 -34
  37. python-postman-0.2.0/python_postman.egg-info/dependency_links.txt +0 -1
  38. python-postman-0.2.0/python_postman.egg-info/entry_points.txt +0 -2
  39. python-postman-0.2.0/python_postman.egg-info/requires.txt +0 -16
  40. python-postman-0.2.0/python_postman.egg-info/top_level.txt +0 -1
  41. python-postman-0.2.0/setup.cfg +0 -4
  42. {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