Contentstack 1.11.2__tar.gz → 2.0.1__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.
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/PKG-INFO +1 -1
- {contentstack-1.11.2 → contentstack-2.0.1}/PKG-INFO +1 -1
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/__init__.py +3 -3
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/asset.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/assetquery.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/basequery.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/contenttype.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/entry.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/entryqueryable.py +2 -4
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/https_connection.py +0 -3
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/image_transform.py +2 -3
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/query.py +2 -3
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/stack.py +2 -2
- contentstack-2.0.1/contentstack/utility.py +93 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/tests/test_stack.py +23 -1
- contentstack-1.11.2/contentstack/utility.py +0 -76
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/SOURCES.txt +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/dependency_links.txt +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/not-zip-safe +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/requires.txt +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/Contentstack.egg-info/top_level.txt +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/LICENSE +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/README.md +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/controller.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/contentstack/deep_merge_lp.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/setup.cfg +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/setup.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/tests/test_assets.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/tests/test_entry.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/tests/test_live_preview.py +0 -0
- {contentstack-1.11.2 → contentstack-2.0.1}/tests/test_query.py +0 -0
|
@@ -22,8 +22,8 @@ __all__ = (
|
|
|
22
22
|
__title__ = 'contentstack-delivery-python'
|
|
23
23
|
__author__ = 'contentstack'
|
|
24
24
|
__status__ = 'debug'
|
|
25
|
-
__version__ = '
|
|
25
|
+
__version__ = 'v2.0.1'
|
|
26
26
|
__endpoint__ = 'cdn.contentstack.io'
|
|
27
|
-
__email__ = '
|
|
28
|
-
__developer_email__ = '
|
|
27
|
+
__email__ = 'support@contentstack.com'
|
|
28
|
+
__developer_email__ = 'mobile@contentstack.com'
|
|
29
29
|
__license__ = "MIT"
|
|
@@ -7,13 +7,10 @@ These files can be attached and used in multiple entries.
|
|
|
7
7
|
import logging
|
|
8
8
|
from urllib import parse
|
|
9
9
|
|
|
10
|
-
log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
class Asset:
|
|
14
11
|
r"""`Asset` refer to all the media files (images, videos, PDFs, audio files, and so on)."""
|
|
15
12
|
|
|
16
|
-
def __init__(self, http_instance, uid=None):
|
|
13
|
+
def __init__(self, http_instance, uid=None, logger=None):
|
|
17
14
|
self.http_instance = http_instance
|
|
18
15
|
self.asset_params = {}
|
|
19
16
|
self.__uid = uid
|
|
@@ -22,6 +19,7 @@ class Asset:
|
|
|
22
19
|
self.base_url = f'{self.http_instance.endpoint}/assets/{self.__uid}'
|
|
23
20
|
if 'environment' in self.http_instance.headers:
|
|
24
21
|
self.asset_params['environment'] = self.http_instance.headers['environment']
|
|
22
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
25
23
|
|
|
26
24
|
def environment(self, environment):
|
|
27
25
|
r"""Provide the name of the environment if you wish to retrieve the assets published
|
|
@@ -9,15 +9,12 @@ import logging
|
|
|
9
9
|
from contentstack.basequery import BaseQuery
|
|
10
10
|
from contentstack.utility import Utils
|
|
11
11
|
|
|
12
|
-
log = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
12
|
class AssetQuery(BaseQuery):
|
|
16
13
|
"""
|
|
17
14
|
This call fetches the list of all the assets of a particular stack.
|
|
18
15
|
"""
|
|
19
16
|
|
|
20
|
-
def __init__(self, http_instance):
|
|
17
|
+
def __init__(self, http_instance, logger=None):
|
|
21
18
|
super().__init__()
|
|
22
19
|
self.http_instance = http_instance
|
|
23
20
|
self.asset_query_params = {}
|
|
@@ -25,6 +22,7 @@ class AssetQuery(BaseQuery):
|
|
|
25
22
|
if "environment" in self.http_instance.headers:
|
|
26
23
|
env = self.http_instance.headers["environment"]
|
|
27
24
|
self.base_url = f"{self.base_url}?environment={env}"
|
|
25
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
28
26
|
|
|
29
27
|
def environment(self, environment):
|
|
30
28
|
r"""Provide the name of the environment if you wish to retrieve the assets published
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
log = logging.getLogger(__name__)
|
|
5
|
-
|
|
6
|
-
|
|
7
4
|
class QueryOperation(enum.Enum):
|
|
8
5
|
"""
|
|
9
6
|
QueryOperation is enum that Provides Options to perform operation to query the result.
|
|
@@ -38,9 +35,10 @@ class BaseQuery:
|
|
|
38
35
|
Common Query class works for Query As well as Asset
|
|
39
36
|
"""
|
|
40
37
|
|
|
41
|
-
def __init__(self):
|
|
38
|
+
def __init__(self, logger=None):
|
|
42
39
|
self.parameters = {}
|
|
43
40
|
self.query_params = {}
|
|
41
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
44
42
|
|
|
45
43
|
def where(self, field_uid: str, query_operation: QueryOperation, fields=None):
|
|
46
44
|
"""
|
|
@@ -14,9 +14,6 @@ from urllib import parse
|
|
|
14
14
|
from contentstack.entry import Entry
|
|
15
15
|
from contentstack.query import Query
|
|
16
16
|
|
|
17
|
-
log = logging.getLogger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
17
|
class ContentType:
|
|
21
18
|
"""
|
|
22
19
|
Content type defines the structure or schema of a page or a
|
|
@@ -26,10 +23,11 @@ class ContentType:
|
|
|
26
23
|
content type.
|
|
27
24
|
"""
|
|
28
25
|
|
|
29
|
-
def __init__(self, http_instance, content_type_uid):
|
|
26
|
+
def __init__(self, http_instance, content_type_uid, logger=None):
|
|
30
27
|
self.http_instance = http_instance
|
|
31
28
|
self.__content_type_uid = content_type_uid
|
|
32
29
|
self.local_param = {}
|
|
30
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
33
31
|
|
|
34
32
|
def entry(self, entry_uid: str):
|
|
35
33
|
r"""
|
|
@@ -9,9 +9,6 @@ from urllib import parse
|
|
|
9
9
|
from contentstack.deep_merge_lp import DeepMergeMixin
|
|
10
10
|
from contentstack.entryqueryable import EntryQueryable
|
|
11
11
|
|
|
12
|
-
log = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
12
|
class Entry(EntryQueryable):
|
|
16
13
|
"""
|
|
17
14
|
An entry is the actual piece of content that you want to publish.
|
|
@@ -23,7 +20,7 @@ class Entry(EntryQueryable):
|
|
|
23
20
|
locale={locale_code}
|
|
24
21
|
"""
|
|
25
22
|
|
|
26
|
-
def __init__(self, http_instance, content_type_uid, entry_uid):
|
|
23
|
+
def __init__(self, http_instance, content_type_uid, entry_uid, logger=None):
|
|
27
24
|
super().__init__()
|
|
28
25
|
EntryQueryable.__init__(self)
|
|
29
26
|
self.entry_param = {}
|
|
@@ -31,6 +28,7 @@ class Entry(EntryQueryable):
|
|
|
31
28
|
self.content_type_id = content_type_uid
|
|
32
29
|
self.entry_uid = entry_uid
|
|
33
30
|
self.base_url = self.__get_base_url()
|
|
31
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
34
32
|
|
|
35
33
|
def environment(self, environment):
|
|
36
34
|
"""
|
|
@@ -4,16 +4,14 @@ that is used as parents class for the query and entry classes
|
|
|
4
4
|
"""
|
|
5
5
|
import logging
|
|
6
6
|
|
|
7
|
-
log = logging.getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
|
|
10
7
|
class EntryQueryable:
|
|
11
8
|
"""
|
|
12
9
|
This class is base class for the Entry and Query class that shares common functions
|
|
13
10
|
"""
|
|
14
11
|
|
|
15
|
-
def __init__(self):
|
|
12
|
+
def __init__(self, logger=None):
|
|
16
13
|
self.entry_queryable_param = {}
|
|
14
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
17
15
|
|
|
18
16
|
def locale(self, locale: str):
|
|
19
17
|
"""
|
|
@@ -8,8 +8,6 @@ different transform_params in second parameter in array form
|
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
10
|
|
|
11
|
-
log = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
11
|
|
|
14
12
|
class ImageTransform: # pylint: disable=too-few-public-methods
|
|
15
13
|
"""
|
|
@@ -17,7 +15,7 @@ class ImageTransform: # pylint: disable=too-few-public-methods
|
|
|
17
15
|
files
|
|
18
16
|
"""
|
|
19
17
|
|
|
20
|
-
def __init__(self, http_instance, image_url, **kwargs):
|
|
18
|
+
def __init__(self, http_instance, image_url, logger=None, **kwargs):
|
|
21
19
|
"""
|
|
22
20
|
creates instance of the ImageTransform class
|
|
23
21
|
:param httpInstance: instance of HttpsConnection
|
|
@@ -35,6 +33,7 @@ class ImageTransform: # pylint: disable=too-few-public-methods
|
|
|
35
33
|
self.http_instance = http_instance
|
|
36
34
|
self.image_url = image_url
|
|
37
35
|
self.image_params = kwargs
|
|
36
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
38
37
|
|
|
39
38
|
def get_url(self):
|
|
40
39
|
"""
|
|
@@ -12,8 +12,6 @@ from contentstack.basequery import BaseQuery
|
|
|
12
12
|
from contentstack.deep_merge_lp import DeepMergeMixin
|
|
13
13
|
from contentstack.entryqueryable import EntryQueryable
|
|
14
14
|
|
|
15
|
-
log = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
15
|
|
|
18
16
|
class QueryType(enum.Enum):
|
|
19
17
|
"""
|
|
@@ -40,7 +38,7 @@ class Query(BaseQuery, EntryQueryable):
|
|
|
40
38
|
>>> result = query.locale('locale-code').excepts('field_uid').limit(4).skip(5).find()
|
|
41
39
|
"""
|
|
42
40
|
|
|
43
|
-
def __init__(self, http_instance, content_type_uid):
|
|
41
|
+
def __init__(self, http_instance, content_type_uid, logger=None):
|
|
44
42
|
super().__init__()
|
|
45
43
|
EntryQueryable.__init__(self)
|
|
46
44
|
self.content_type_uid = content_type_uid
|
|
@@ -50,6 +48,7 @@ class Query(BaseQuery, EntryQueryable):
|
|
|
50
48
|
'You are not allowed here without content_type_uid')
|
|
51
49
|
self.base_url = f'{self.http_instance.endpoint}/content_types/{self.content_type_uid}/entries'
|
|
52
50
|
self.base_url = self.__get_base_url()
|
|
51
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
53
52
|
|
|
54
53
|
def __get_base_url(self, endpoint=''):
|
|
55
54
|
if endpoint is not None and endpoint.strip(): # .strip() removes leading/trailing whitespace
|
|
@@ -9,7 +9,6 @@ from contentstack.contenttype import ContentType
|
|
|
9
9
|
from contentstack.https_connection import HTTPSConnection
|
|
10
10
|
from contentstack.image_transform import ImageTransform
|
|
11
11
|
|
|
12
|
-
log = logging.getLogger(__name__)
|
|
13
12
|
DEFAULT_HOST = 'cdn.contentstack.io'
|
|
14
13
|
|
|
15
14
|
|
|
@@ -42,6 +41,7 @@ class Stack:
|
|
|
42
41
|
live_preview=None,
|
|
43
42
|
branch=None,
|
|
44
43
|
early_access = None,
|
|
44
|
+
logger=None,
|
|
45
45
|
):
|
|
46
46
|
"""
|
|
47
47
|
# Class that wraps the credentials of the authenticated user. Think of
|
|
@@ -78,7 +78,7 @@ class Stack:
|
|
|
78
78
|
live_preview={enable=True, authorization='your auth token'}, retry_strategy= _strategy)
|
|
79
79
|
```
|
|
80
80
|
"""
|
|
81
|
-
|
|
81
|
+
self.logger = logger or logging.getLogger(__name__)
|
|
82
82
|
self.headers = {}
|
|
83
83
|
self._query_params = {}
|
|
84
84
|
self.sync_param = {}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility functions for logging and URL manipulation.
|
|
3
|
+
Last modified by ishaileshmishra on 06/08/20.
|
|
4
|
+
Copyright 2019 Contentstack. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
from urllib.parse import urlencode
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def setup_logging(logging_type=logging.INFO, filename='app.log'):
|
|
13
|
+
"""
|
|
14
|
+
Global one-time logging configuration.
|
|
15
|
+
Should be called from your main application entry point.
|
|
16
|
+
"""
|
|
17
|
+
logging.basicConfig(
|
|
18
|
+
filename=filename,
|
|
19
|
+
level=logging_type,
|
|
20
|
+
format='[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
|
|
21
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Utils:
|
|
26
|
+
@staticmethod
|
|
27
|
+
def setup_logger(name="AppLogger", level=logging.INFO, filename='app.log'):
|
|
28
|
+
"""
|
|
29
|
+
Creates and configures a named logger with file and console output.
|
|
30
|
+
Prevents duplicate handlers.
|
|
31
|
+
"""
|
|
32
|
+
logger = logging.getLogger(name)
|
|
33
|
+
if not logger.handlers:
|
|
34
|
+
logger.setLevel(level)
|
|
35
|
+
|
|
36
|
+
formatter = logging.Formatter(
|
|
37
|
+
'[%(asctime)s] %(levelname)s - %(name)s - %(message)s',
|
|
38
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
file_handler = logging.FileHandler(filename)
|
|
42
|
+
file_handler.setFormatter(formatter)
|
|
43
|
+
logger.addHandler(file_handler)
|
|
44
|
+
|
|
45
|
+
console_handler = logging.StreamHandler()
|
|
46
|
+
console_handler.setFormatter(formatter)
|
|
47
|
+
logger.addHandler(console_handler)
|
|
48
|
+
|
|
49
|
+
return logger
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def log(message, level=logging.DEBUG):
|
|
53
|
+
"""
|
|
54
|
+
Log a message with the specified level.
|
|
55
|
+
Default is DEBUG.
|
|
56
|
+
"""
|
|
57
|
+
logger = logging.getLogger("AppLogger")
|
|
58
|
+
logger.log(level, message)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def do_url_encode(params):
|
|
62
|
+
"""
|
|
63
|
+
Encode query parameters to URL-safe format.
|
|
64
|
+
:param params: Dictionary of parameters
|
|
65
|
+
:return: Encoded URL query string
|
|
66
|
+
"""
|
|
67
|
+
if not isinstance(params, dict):
|
|
68
|
+
raise ValueError("params must be a dictionary")
|
|
69
|
+
return urlencode(params, doseq=True)
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def get_complete_url(base_url: str, params: dict, skip_encoding=False) -> str:
|
|
73
|
+
"""
|
|
74
|
+
Construct a full URL by combining base URL and encoded parameters.
|
|
75
|
+
Handles JSON stringification for the `query` key.
|
|
76
|
+
:param base_url: Base API URL
|
|
77
|
+
:param params: Dictionary of query parameters
|
|
78
|
+
:param skip_encoding: Set True to skip URL encoding
|
|
79
|
+
:return: Complete URL
|
|
80
|
+
"""
|
|
81
|
+
if not isinstance(base_url, str) or not isinstance(params, dict):
|
|
82
|
+
raise ValueError("base_url must be a string and params must be a dictionary")
|
|
83
|
+
|
|
84
|
+
if 'query' in params and not skip_encoding:
|
|
85
|
+
params["query"] = json.dumps(params["query"], separators=(',', ':'))
|
|
86
|
+
|
|
87
|
+
if not skip_encoding:
|
|
88
|
+
query_string = urlencode(params, doseq=True)
|
|
89
|
+
else:
|
|
90
|
+
query_string = "&".join(f"{k}={v}" for k, v in params.items())
|
|
91
|
+
|
|
92
|
+
# Append with appropriate separator
|
|
93
|
+
return f'{base_url}&{query_string}' if '?' in base_url else f'{base_url}?{query_string}'
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
import config
|
|
3
3
|
import contentstack
|
|
4
|
+
import logging
|
|
5
|
+
import io
|
|
4
6
|
from contentstack.stack import ContentstackRegion
|
|
7
|
+
from contentstack.stack import Stack
|
|
5
8
|
|
|
6
9
|
API_KEY = config.APIKEY
|
|
7
10
|
DELIVERY_TOKEN = config.DELIVERYTOKEN
|
|
@@ -182,4 +185,23 @@ class TestStack(unittest.TestCase):
|
|
|
182
185
|
def test_23_get_early_access(self):
|
|
183
186
|
stack = contentstack.Stack(
|
|
184
187
|
config.APIKEY, config.DELIVERYTOKEN, config.ENVIRONMENT, early_access=["taxonomy", "teams"])
|
|
185
|
-
self.assertEqual(self.early_access, stack.get_early_access)
|
|
188
|
+
self.assertEqual(self.early_access, stack.get_early_access)
|
|
189
|
+
|
|
190
|
+
def test_stack_with_custom_logger(self):
|
|
191
|
+
log_stream = io.StringIO()
|
|
192
|
+
custom_logger = logging.getLogger("contentstack.custom.test_logger")
|
|
193
|
+
custom_logger.setLevel(logging.INFO)
|
|
194
|
+
|
|
195
|
+
if custom_logger.hasHandlers():
|
|
196
|
+
custom_logger.handlers.clear()
|
|
197
|
+
|
|
198
|
+
handler = logging.StreamHandler(log_stream)
|
|
199
|
+
formatter = logging.Formatter('%(levelname)s - %(name)s - %(message)s')
|
|
200
|
+
handler.setFormatter(formatter)
|
|
201
|
+
custom_logger.addHandler(handler)
|
|
202
|
+
Stack("api_key", "delivery_token", "dev", logger=custom_logger)
|
|
203
|
+
custom_logger.info("INFO - contentstack.custom.test_logger - Test log entry")
|
|
204
|
+
handler.flush()
|
|
205
|
+
logs = log_stream.getvalue()
|
|
206
|
+
print("\nCaptured Logs:\n", logs)
|
|
207
|
+
self.assertIn("INFO - contentstack.custom.test_logger - Test log entry", logs)
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Last modified by ishaileshmishra on 06/08/20.
|
|
3
|
-
Copyright 2019 Contentstack. All rights reserved.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
import logging
|
|
8
|
-
from urllib.parse import urlencode, urljoin
|
|
9
|
-
|
|
10
|
-
log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def config_logging(logging_type: logging.WARNING):
|
|
14
|
-
"""
|
|
15
|
-
This is to create logging config
|
|
16
|
-
:param logging_type: Level of the logging
|
|
17
|
-
:return: basicConfig instance
|
|
18
|
-
"""
|
|
19
|
-
logging.basicConfig(
|
|
20
|
-
filename='app.log',
|
|
21
|
-
level=logging_type,
|
|
22
|
-
format='[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
|
|
23
|
-
datefmt='%H:%M:%S'
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class Utils:
|
|
28
|
-
|
|
29
|
-
@staticmethod
|
|
30
|
-
def config_logging():
|
|
31
|
-
""" Setting up logging """
|
|
32
|
-
logging.basicConfig(
|
|
33
|
-
filename='report_log.log',
|
|
34
|
-
format='%(asctime)s - %(message)s',
|
|
35
|
-
level=logging.INFO
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
@staticmethod
|
|
39
|
-
def setup_logger():
|
|
40
|
-
"""setup logger for the application"""
|
|
41
|
-
return logging.getLogger("Config")
|
|
42
|
-
|
|
43
|
-
@staticmethod
|
|
44
|
-
def log(message):
|
|
45
|
-
"""this generates log message"""
|
|
46
|
-
logging.debug(message)
|
|
47
|
-
|
|
48
|
-
@staticmethod
|
|
49
|
-
def do_url_encode(params):
|
|
50
|
-
"""
|
|
51
|
-
To encode url with query parameters
|
|
52
|
-
:param params:
|
|
53
|
-
:return: encoded url
|
|
54
|
-
"""
|
|
55
|
-
return parse.urlencode(params)
|
|
56
|
-
|
|
57
|
-
@staticmethod
|
|
58
|
-
def get_complete_url(base_url: str, params: dict) -> str:
|
|
59
|
-
"""
|
|
60
|
-
Creates a complete URL using base_url and their respective parameters.
|
|
61
|
-
:param base_url: The base URL to which parameters are appended.
|
|
62
|
-
:param params: A dictionary of parameters to be included in the URL.
|
|
63
|
-
:return: A complete URL with encoded parameters.
|
|
64
|
-
"""
|
|
65
|
-
# Ensure 'query' is properly serialized as a JSON string without extra quotes
|
|
66
|
-
if 'query' in params:
|
|
67
|
-
params["query"] = json.dumps(params["query"], separators=(',', ':'))
|
|
68
|
-
|
|
69
|
-
# Encode parameters
|
|
70
|
-
query_string = urlencode(params, doseq=True)
|
|
71
|
-
|
|
72
|
-
# Join base_url and query_string
|
|
73
|
-
if '?' in base_url:
|
|
74
|
-
return f'{base_url}&{query_string}'
|
|
75
|
-
else:
|
|
76
|
-
return f'{base_url}?{query_string}'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|