Skip to content

Commit 31ea127

Browse files
author
Maria Korlotian
authored
CAS-5562/Add singleton configuration and configuration (#96)
1 parent 5934a8c commit 31ea127

18 files changed

+275
-105
lines changed

README.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ import and configure the library with your Castle API secret.
8888
8989
# *Note: the default list of proxies that are always marked as "trusted" can be found in: Castle::Configuration::TRUSTED_PROXIES
9090
91+
Multi-environment configuration
92+
-------------------------------
93+
94+
It is also possible to define multiple configs within one application.
95+
96+
.. code:: python
97+
98+
from castle.configuration import Configuration
99+
100+
# Initialize new instance of Castle::Configuration
101+
config = Configuration()
102+
config.api_secret = ':YOUR-API-SECRET'
103+
104+
After a successful setup, you can pass the config to any API command as follows:
105+
106+
.. code:: python
107+
108+
from castle.api.get_device import APIGetDevice
109+
110+
# Get device data
111+
APIGetDevice.call(device_token, config)
112+
91113
Tracking
92114
--------
93115

castle/api/approve_device.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from castle.api_request import APIRequest
22
from castle.commands.approve_device import CommandsApproveDevice
3+
from castle.configuration import configuration
34

45

56
class APIApproveDevice(object):
67
@staticmethod
7-
def call(device_token):
8-
return APIRequest().call(CommandsApproveDevice.call(device_token))
8+
def call(device_token, config=configuration):
9+
return APIRequest(config).call(CommandsApproveDevice.call(device_token))

castle/api/get_device.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from castle.api_request import APIRequest
22
from castle.commands.get_device import CommandsGetDevice
3+
from castle.configuration import configuration
34

45

56
class APIGetDevice(object):
67
@staticmethod
7-
def call(device_token):
8-
return APIRequest().call(CommandsGetDevice.call(device_token))
8+
def call(device_token, config=configuration):
9+
return APIRequest(config).call(CommandsGetDevice.call(device_token))

castle/api/get_devices_for_user.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from castle.api_request import APIRequest
22
from castle.commands.get_devices_for_user import CommandsGetDevicesForUser
3+
from castle.configuration import configuration
34

45

56
class APIGetDevicesForUser(object):
67
@staticmethod
7-
def call(user_id):
8-
return APIRequest().call(CommandsGetDevicesForUser.call(user_id))
8+
def call(user_id, config=configuration):
9+
return APIRequest(config).call(CommandsGetDevicesForUser.call(user_id))

castle/api/report_device.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from castle.api_request import APIRequest
22
from castle.commands.report_device import CommandsReportDevice
3+
from castle.configuration import configuration
34

45

56
class APIReportDevice(object):
67
@staticmethod
7-
def call(device_token):
8-
return APIRequest().call(CommandsReportDevice.call(device_token))
8+
def call(device_token, config=configuration):
9+
return APIRequest(config).call(CommandsReportDevice.call(device_token))

castle/api/review.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from castle.api_request import APIRequest
22
from castle.commands.review import CommandsReview
3+
from castle.configuration import configuration
34

45

56
class APIReview(object):
67
@staticmethod
7-
def call(review_id):
8-
return APIRequest().call(CommandsReview.call(review_id))
8+
def call(review_id, config=configuration):
9+
return APIRequest(config).call(CommandsReview.call(review_id))

castle/api_request.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66

77
class APIRequest(object):
8-
def __init__(self):
8+
def __init__(self, config=configuration):
99
self.req = CoreSendRequest({'Content-Type': 'application/json'})
10+
self.config = config
1011

1112
def request(self, command):
12-
if not configuration.isValid():
13+
if not self.config.isValid():
1314
raise ConfigurationError
14-
return self.req.build_query(command.method, command.path, command.data)
15+
return self.req.build_query(command.method, command.path, command.data, self.config)
1516

1617
def call(self, command):
1718
return CoreProcessResponse(self.request(command)).call()

castle/configuration.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,14 @@ def logger(self, value):
174174
self.__logger = value
175175

176176

177-
# pylint: disable=invalid-name
178-
configuration = Configuration()
177+
class SingletonConfiguration(Configuration):
178+
179+
instance = None
180+
181+
def __new__(cls, *args, **kwargs):
182+
if not SingletonConfiguration.instance:
183+
SingletonConfiguration.instance = super().__new__(cls, *args, **kwargs)
184+
return SingletonConfiguration.instance
185+
186+
187+
configuration = SingletonConfiguration()

castle/core/send_request.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ def __init__(self, headers=None):
1212
self.base_url = CoreSendRequest.build_base_url()
1313
self.session = Session()
1414

15-
def build_query(self, method, path, params):
15+
def build_query(self, method, path, params, config=configuration):
1616
url = self.build_url(path)
1717
request_data = {
18-
"auth": ('', configuration.api_secret),
19-
"timeout": configuration.request_timeout / 1000.0,
18+
"auth": ('', config.api_secret),
19+
"timeout": config.request_timeout / 1000.0,
2020
"headers": self.headers,
2121
"verify": CoreSendRequest.verify(),
2222
"data": None if params is None else json.dumps(params)

castle/headers/extract.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66

77
class HeadersExtract(object):
8-
def __init__(self, headers):
8+
def __init__(self, headers, config=configuration):
99
self.headers = headers
10-
self.no_whitelist = len(configuration.allowlisted) == 0
10+
self.config = config
11+
self.no_whitelist = len(config.allowlisted) == 0
1112

1213
def call(self):
1314
result = dict()
@@ -22,9 +23,9 @@ def _header_value(self, name, value):
2223
return True
2324
if name in ALWAYS_ALLOWLISTED:
2425
return value
25-
if name in configuration.denylisted:
26+
if name in self.config.denylisted:
2627
return True
27-
if self.no_whitelist or (name in configuration.allowlisted):
28+
if self.no_whitelist or (name in self.config.allowlisted):
2829
return value
2930

3031
return True

0 commit comments

Comments
 (0)