Skip to content

Commit 5a9c04a

Browse files
committed
feat(sdk): allow for multi config
allow each client to have a seperate config
1 parent cfdd181 commit 5a9c04a

10 files changed

Lines changed: 8746 additions & 11240 deletions

File tree

staxapp/api.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88

99
class Api:
10-
_requests_auth = None
11-
1210
@classmethod
1311
def _headers(cls, custom_headers) -> dict:
1412
headers = {
@@ -17,12 +15,6 @@ def _headers(cls, custom_headers) -> dict:
1715
}
1816
return headers
1917

20-
@classmethod
21-
def _auth(cls, **kwargs):
22-
if not cls._requests_auth:
23-
cls._requests_auth = Config.get_auth_class().requests_auth
24-
return cls._requests_auth(Config.access_key, Config.secret_key, **kwargs)
25-
2618
@staticmethod
2719
def handle_api_response(response):
2820
try:
@@ -31,13 +23,12 @@ def handle_api_response(response):
3123
raise ApiException(str(e), response)
3224

3325
@classmethod
34-
def get(cls, url_frag, params={}, **kwargs):
35-
url_frag = url_frag.replace(f"/{Config.API_VERSION}", "")
36-
url = f"{Config.api_base_url()}/{url_frag.lstrip('/')}"
37-
26+
def get(cls, url_frag, auth, config, params={}, **kwargs):
27+
url_frag = url_frag.replace(f"/{config.API_VERSION}", "")
28+
url = f"{config.api_base_url()}/{url_frag.lstrip('/')}"
3829
response = requests.get(
3930
url,
40-
auth=cls._auth(),
31+
auth=auth,
4132
params=params,
4233
headers=cls._headers(kwargs.get("headers", {})),
4334
**kwargs,
@@ -46,43 +37,43 @@ def get(cls, url_frag, params={}, **kwargs):
4637
return response.json()
4738

4839
@classmethod
49-
def post(cls, url_frag, payload={}, **kwargs):
50-
url_frag = url_frag.replace(f"/{Config.API_VERSION}", "")
51-
url = f"{Config.api_base_url()}/{url_frag.lstrip('/')}"
40+
def post(cls, url_frag, auth, config, payload={}, **kwargs):
41+
url_frag = url_frag.replace(f"/{config.API_VERSION}", "")
42+
url = f"{config.api_base_url()}/{url_frag.lstrip('/')}"
5243

5344
response = requests.post(
5445
url,
5546
json=payload,
56-
auth=cls._auth(),
47+
auth=auth,
5748
headers=cls._headers(kwargs.get("headers", {})),
5849
**kwargs,
5950
)
6051
cls.handle_api_response(response)
6152
return response.json()
6253

6354
@classmethod
64-
def put(cls, url_frag, payload={}, **kwargs):
65-
url_frag = url_frag.replace(f"/{Config.API_VERSION}", "")
66-
url = f"{Config.api_base_url()}/{url_frag.lstrip('/')}"
55+
def put(cls, url_frag, auth, config, payload={}, **kwargs):
56+
url_frag = url_frag.replace(f"/{config.API_VERSION}", "")
57+
url = f"{config.api_base_url()}/{url_frag.lstrip('/')}"
6758

6859
response = requests.put(
6960
url,
7061
json=payload,
71-
auth=cls._auth(),
62+
auth=auth,
7263
headers=cls._headers(kwargs.get("headers", {})),
7364
**kwargs,
7465
)
7566
cls.handle_api_response(response)
7667
return response.json()
7768

7869
@classmethod
79-
def delete(cls, url_frag, params={}, **kwargs):
80-
url_frag = url_frag.replace(f"/{Config.API_VERSION}", "")
81-
url = f"{Config.api_base_url()}/{url_frag.lstrip('/')}"
70+
def delete(cls, url_frag, auth, config, params={}, **kwargs):
71+
url_frag = url_frag.replace(f"/{config.API_VERSION}", "")
72+
url = f"{config.api_base_url()}/{url_frag.lstrip('/')}"
8273

8374
response = requests.delete(
8475
url,
85-
auth=cls._auth(),
76+
auth=auth,
8677
params=params,
8778
headers=cls._headers(kwargs.get("headers", {})),
8879
**kwargs,

staxapp/auth.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@
1414

1515

1616
class StaxAuth:
17-
def __init__(self, config_branch, max_retries: int = 3):
18-
config = StaxConfig.api_config
19-
20-
self.identity_pool = config.get(config_branch).get("identityPoolId")
21-
self.user_pool = config.get(config_branch).get("userPoolId")
22-
self.client_id = config.get(config_branch).get("userPoolWebClientId")
23-
self.aws_region = config.get(config_branch).get("region")
17+
def __init__(self, config_branch: str, config: StaxConfig, max_retries: int = 3):
18+
self.config = config
19+
api_config = self.config.api_config
20+
self.identity_pool = api_config.get(config_branch).get("identityPoolId")
21+
self.user_pool = api_config.get(config_branch).get("userPoolId")
22+
self.client_id = api_config.get(config_branch).get("userPoolWebClientId")
23+
self.aws_region = api_config.get(config_branch).get("region")
2424
self.max_retries = max_retries
2525

26-
def requests_auth(self, username, password, **kwargs):
26+
def requests_auth(self, **kwargs):
27+
username = self.config.access_key
28+
password = self.config.secret_key
2729
if username is None:
2830
raise InvalidCredentialsException(
2931
"Please provide an Access Key to your config"
@@ -37,10 +39,10 @@ def requests_auth(self, username, password, **kwargs):
3739
id_creds = self.sts_from_cognito_identity_pool(id_token, **kwargs)
3840
auth = self.sigv4_signed_auth_headers(id_creds)
3941

40-
StaxConfig.expiration = id_creds.get("Credentials").get("Expiration")
41-
StaxConfig.auth = auth
42+
self.config.expiration = id_creds.get("Credentials").get("Expiration")
43+
self.config.auth = auth
4244

43-
return StaxConfig.auth
45+
return self.config.auth
4446

4547
def id_token_from_cognito(
4648
self, username=None, password=None, srp_client=None, **kwargs
@@ -69,7 +71,7 @@ def id_token_from_cognito(
6971
elif e.response["Error"]["Code"] == "UserNotFoundException":
7072
raise InvalidCredentialsException(
7173
message=str(e),
72-
detail="Please check your Access Key, that you have created your Api Token and that you are using the right STAX REGION",
74+
detail=f"Please check your Access Key {username} {password}, that you have created your Api Token and that you are using the right STAX REGION {self.config.hostname} {self.aws_region}",
7375
)
7476
else:
7577
raise InvalidCredentialsException(
@@ -121,7 +123,7 @@ def sigv4_signed_auth_headers(self, id_creds):
121123
aws_access_key=id_creds.get("Credentials").get("AccessKeyId"),
122124
aws_secret_access_key=id_creds.get("Credentials").get("SecretKey"),
123125
aws_token=id_creds.get("Credentials").get("SessionToken"),
124-
aws_host=f"{StaxConfig.hostname}",
126+
aws_host=f"{self.config.hostname}",
125127
aws_region=self.aws_region,
126128
aws_service="execute-api",
127129
)
@@ -139,11 +141,11 @@ def requests_auth(username, password, **kwargs):
139141

140142
class ApiTokenAuth:
141143
@staticmethod
142-
def requests_auth(username, password, **kwargs):
144+
def requests_auth(config: StaxConfig, **kwargs):
143145
# Minimize the potentical for token to expire while still being used for auth (say within a lambda function)
144-
if StaxConfig.expiration and StaxConfig.expiration - timedelta(
146+
if config.expiration and config.expiration - timedelta(
145147
minutes=int(environ.get("TOKEN_EXPIRY_THRESHOLD_IN_MINS", 1))
146148
) > datetime.now(timezone.utc):
147-
return StaxConfig.auth
149+
return config.auth
148150

149-
return StaxAuth("ApiAuth").requests_auth(username, password, **kwargs)
151+
return StaxAuth("ApiAuth", config).requests_auth(**kwargs)

staxapp/config.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Config:
2424
auth_class = None
2525
_initialized = False
2626
base_url = None
27-
hostname = f"api.{STAX_REGION}"
27+
_hostname = f"api.{STAX_REGION}"
2828
org_id = None
2929
auth = None
3030
expiration = None
@@ -34,10 +34,9 @@ class Config:
3434
python_version = sysinfo.python_version()
3535
sdk_version = staxapp.__version__
3636

37-
@classmethod
38-
def set_config(cls):
39-
cls.base_url = f"https://{cls.hostname}/{cls.API_VERSION}"
40-
config_url = f"{cls.api_base_url()}/public/config"
37+
def set_config(self):
38+
self.base_url = f"https://{self.hostname}/{self.API_VERSION}"
39+
config_url = f"{self.api_base_url()}/public/config"
4140
config_response = requests.get(config_url)
4241
try:
4342
config_response.raise_for_status()
@@ -47,29 +46,33 @@ def set_config(cls):
4746
str(e), config_response, detail=" Could not load API config."
4847
)
4948

50-
cls.api_config = config_response.json()
49+
self.api_config = config_response.json()
5150

52-
@classmethod
53-
def init(cls, config=None):
54-
if cls._initialized:
51+
def init(self, config=None, hostname=None):
52+
if hostname is not None and self.hostname is None:
53+
self.hostname = hostname
54+
if self._initialized:
5555
return
5656

5757
if not config:
58-
cls.set_config()
58+
self.set_config()
5959

60-
cls._initialized = True
60+
self._initialized = True
6161

62-
@classmethod
63-
def api_base_url(cls):
64-
return cls.base_url
62+
def api_base_url(self):
63+
return self.base_url
6564

6665
@classmethod
66+
def GetDefaultConfig(cls):
67+
config = Config()
68+
return config
69+
6770
def branch(cls):
6871
return os.getenv("STAX_BRANCH", "master")
6972

7073
@classmethod
7174
def schema_url(cls):
72-
return f"{cls.base_url}/public/api-document"
75+
return f"https://{cls.hostname}/{cls.API_VERSION}/public/api-document"
7376

7477
@classmethod
7578
def get_auth_class(cls):
@@ -78,6 +81,3 @@ def get_auth_class(cls):
7881

7982
cls.auth_class = ApiTokenAuth
8083
return cls.auth_class
81-
82-
83-
Config.init()

staxapp/contract.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def validate(cls, data, component):
5454
@staticmethod
5555
def default_swagger_template() -> dict:
5656
# Get the default swagger template from https://api.au1.staxapp.cloud/20190206/public/api-document
57-
schema_response = requests.get(Config.schema_url()).json()
57+
schema_response = requests.get(Config.GetDefaultConfig().schema_url()).json()
5858
template = dict(
5959
openapi="3.0.0",
6060
info={

0 commit comments

Comments
 (0)