clear-skies 2.0.8__py3-none-any.whl → 2.0.10__py3-none-any.whl

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.

Potentially problematic release.


This version of clear-skies might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clear-skies
3
- Version: 2.0.8
3
+ Version: 2.0.10
4
4
  Summary: A framework for building backends in the cloud
5
5
  Project-URL: Documentation, https://clearskies.io/
6
6
  Project-URL: Repository, https://github.com/clearskies-py/clearskies
@@ -103,7 +103,7 @@ clearskies/columns/timestamp.py,sha256=nIEbvg1YqKPjtEeFyYRnPPPSYB_lYIIUUm8zNoE8d
103
103
  clearskies/columns/updated.py,sha256=BFan3JnO2IEbryTGC2rR_RD1ruDcev49owPBYyjjSVI,3340
104
104
  clearskies/columns/uuid.py,sha256=QE1UKHA9zt7bYd59rYRmzIHSonq9-sZeQbAIQtoJC54,2265
105
105
  clearskies/configs/README.md,sha256=4-r2FvkrBTrKkcKgJ5O3Qj1RZ7nnkknenKze4XYlQDs,4827
106
- clearskies/configs/__init__.py,sha256=nfaevClmzwsTMYDH4R_6t2VRg4OoeInIocvclIQ-8kY,5079
106
+ clearskies/configs/__init__.py,sha256=X3U5l_oXYh9JTeiI7IZuzz1rq5TTO4HHIvcz5gLGa9s,5357
107
107
  clearskies/configs/actions.py,sha256=5OwrokU8uTSSQ_6SvL94SOP5JVkvRRFGAXNcCdMt8aQ,1388
108
108
  clearskies/configs/any.py,sha256=QSLOO955Lbg8NqYeyxdQGXTTyfFc5P036LORUa7avHc,388
109
109
  clearskies/configs/any_dict.py,sha256=LECTIcCF22JXbAaZdWSmKh9UShRuRt8PydNCuj05ijI,907
@@ -118,6 +118,10 @@ clearskies/configs/conditions.py,sha256=a09bVac4-10ZtKPQGSu_e9VnHnwITwy_7_T4NekX
118
118
  clearskies/configs/config.py,sha256=2qsF3ZBc8tsTXDgNLL7vT01kjWanbJH3oXO9R2S6GnU,909
119
119
  clearskies/configs/datetime.py,sha256=QJxqRyFkb0YByHmaH_Rd_geUiyvBpk5xdBdRDj28278,689
120
120
  clearskies/configs/datetime_or_callable.py,sha256=hp6ay-958DWoPy8Ryf1VS4R5NPKoF9LceiUhSB7I_wg,835
121
+ clearskies/configs/email.py,sha256=BbXGvZnO9wwT8LHexAq0ibwDNLVvv_8yUJEOThzJVE4,317
122
+ clearskies/configs/email_list.py,sha256=cTgdQTz4HYkqbdTEHPy8LcLjPGqFWY5TOIH8cHbfXXI,582
123
+ clearskies/configs/email_list_or_callable.py,sha256=jowDly4ZKLOYJ73aJ8VoNX338jzqTZyIcY91ANvrgt0,679
124
+ clearskies/configs/email_or_email_list_or_callable.py,sha256=tFdAsI1sTDMOheb3h8nQhIVxnl9xzZPwZtKjYEHjkKM,2470
121
125
  clearskies/configs/endpoint.py,sha256=NEDthtdPzejAot7yzUjC01PvQJR9BIyk5YnWXCi1w9I,759
122
126
  clearskies/configs/endpoint_list.py,sha256=9xtXmZpdOh7uk9Sm3MF9xi1_N-n2DZ-F4s0zrNfEKng,1200
123
127
  clearskies/configs/float.py,sha256=7HwDMf-3VfrZxTmXwpnwDgXyzujUBpz1xPi1StdjB1Q,621
@@ -139,10 +143,10 @@ clearskies/configs/searchable_model_columns.py,sha256=PVSe9J6cGyWRCAFwqstVIVTEGT
139
143
  clearskies/configs/security_headers.py,sha256=wNtoUsghhec-NNZl9dSIRxTTApYw2vukbslYI-YY968,1403
140
144
  clearskies/configs/select.py,sha256=TaiCbNGaSsLc6lJ_0_67PXgYDXhoDwd_T_KygKSPB-0,1057
141
145
  clearskies/configs/select_list.py,sha256=ctqJW523C7UEhjahn_sWL1nlK-4OZrP01n_y1PV770s,1925
142
- clearskies/configs/string.py,sha256=vGTkah9Ml1Y0gw7OIu9B6C_b2lsYcOh_AKrrPrCzS_E,1129
146
+ clearskies/configs/string.py,sha256=T65R8zvftpn-SZDxjS4ZqStBp1LWYwK9KkqH7WMK19o,1117
143
147
  clearskies/configs/string_dict.py,sha256=vE1Q9HImvu5erMvCFnU73M4SUAhL6nnYr3-szp-axRg,1392
144
- clearskies/configs/string_list.py,sha256=4o-p18c7VTVj5WNuqnHEtYx0aNZjvn25X0S3fbf4R28,1238
145
- clearskies/configs/string_list_or_callable.py,sha256=V9yuLiotQStZcAm_-dWzXW5PG8gZMSYyjerQc4RaP2E,1491
148
+ clearskies/configs/string_list.py,sha256=qJQFn0QxVfs3WeMfKTK40GQV-zeKQSJ-wvnhAjj8uqY,1760
149
+ clearskies/configs/string_list_or_callable.py,sha256=dOMwWAkDrQf2we3Sn7GkNBqxhvEXqtQIOoIib52YIZg,2020
146
150
  clearskies/configs/string_or_callable.py,sha256=2Bg05AYN6j3v4ttFOmD-EBGfYpok67yiuFXnTTUhhNo,702
147
151
  clearskies/configs/timedelta.py,sha256=Seuu9PexoWPqayybBjHlsDlx_EEe50BTfGOGKKecONc,703
148
152
  clearskies/configs/timezone.py,sha256=JL6bjrCS4XdJzrRdhO5kZrMIhvxfNxsvvQ7EQrT0DOo,719
@@ -158,7 +162,7 @@ clearskies/contexts/wsgi_ref.py,sha256=Z4oBIYeSsLp93dR1eBsZTaevzVYB0QrR-ugp1CQVl
158
162
  clearskies/di/__init__.py,sha256=Ab8GNv9ZksnCABq8n2gCcyLEAXD-5-kX4O8PweTJIFs,474
159
163
  clearskies/di/additional_config.py,sha256=65INxw8aqTZQsyaKPj-aQmd6FBe4_4DwibXGgWYBy14,5139
160
164
  clearskies/di/additional_config_auto_import.py,sha256=XYw0Kcnp6hp-ee-c0YjiATwJvRb2E82xk9PuoX9dGRY,758
161
- clearskies/di/di.py,sha256=XHlsyzWyU1adlvQlRYLcygDT3XGJptP4_qtHqSE4o-I,45461
165
+ clearskies/di/di.py,sha256=KEIzsaM0TF1N2UcwDFhsxtYjaCSte2e0koUxuHd2rME,46044
162
166
  clearskies/di/injectable.py,sha256=TTgqhx494470I61-88BUQmHmevfat-wXVseKl8pQOEk,852
163
167
  clearskies/di/injectable_properties.py,sha256=yJP0J7l7tjG2soyXtrfDgktE7M8tQHaP-55Cmtq0b7M,6466
164
168
  clearskies/di/inject/__init__.py,sha256=plEkWId-VyhvqX5KM2HhdCqi7_ZJzPmFz69cPAo812Y,643
@@ -216,8 +220,8 @@ clearskies/query/join.py,sha256=4lrDUQzck7klKY_VYkc4SVK95SVwyy3SVTvasnsAEyc,4713
216
220
  clearskies/query/query.py,sha256=0XR3fNhOpDNJY0US2oseAS3p3Y0jxxVs86P6vWEvUcA,6063
217
221
  clearskies/query/sort.py,sha256=c-EtIkjg3kLjwSTdXD7sfyx-mNUhAepUV-2izprh3iY,754
218
222
  clearskies/secrets/__init__.py,sha256=G-A8YhCMlS_OdboSeKzCZp6iwfqwU4BPEnB5HvD88wY,142
219
- clearskies/secrets/akeyless.py,sha256=HNNTHCLjfvS5Uz9b6O8yzqeDJ18Zig94Pkl1fA7XOzE,7060
220
- clearskies/secrets/secrets.py,sha256=20Oq-PogMbFCPB6b4HyowlDD9QNY4r4BVKVm9hTrGxs,1724
223
+ clearskies/secrets/akeyless.py,sha256=4SwnVNzMAijZtzR0Q25dizEw-q7nbS4G5s0CoGyc-G0,7219
224
+ clearskies/secrets/secrets.py,sha256=9sYrI0PmxXAzyDCfylOmb8svXqPc9IefaWKaBPHrjxE,1815
221
225
  clearskies/secrets/additional_configs/__init__.py,sha256=cFCrbtKF5nuR061S2y1iKZp349x-y8Srdwe3VZbfSFU,1119
222
226
  clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py,sha256=CnIiXLVQdUnUey3dbCTXuNNP7Mmw1gjjNjZiBtfgGto,2757
223
227
  clearskies/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py,sha256=N8ruxrTNhvYlp3cYXq6V78KPPr4n40LM7QoXHvD8IZg,6235
@@ -246,7 +250,7 @@ clearskies/validators/minimum_value.py,sha256=NDLcG6xCemlv3kfr-RiUaM3x2INS1GJGMB
246
250
  clearskies/validators/required.py,sha256=GWxyexwj-K6DunZWNEnZxW6tQGAFd4oOCvQrW1s1K9k,1308
247
251
  clearskies/validators/timedelta.py,sha256=DJ0pTm-SSUtjZ7phGoD6vjb086vXPzvLLijkU-jQlOs,1892
248
252
  clearskies/validators/unique.py,sha256=GFEQOMYRIO9pSGHHj6zf1GdnJ0UM7Dm4ZO4uGn19BZo,991
249
- clear_skies-2.0.8.dist-info/METADATA,sha256=jCJOYBO5aC6oExboDjy6JO5CdoGsZlUboVpkpvhakEg,2113
250
- clear_skies-2.0.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
251
- clear_skies-2.0.8.dist-info/licenses/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
252
- clear_skies-2.0.8.dist-info/RECORD,,
253
+ clear_skies-2.0.10.dist-info/METADATA,sha256=tuBiBiOYS2L-LJgp6Ud75P-_BM4JGbNk5hGO_rxojAs,2114
254
+ clear_skies-2.0.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
255
+ clear_skies-2.0.10.dist-info/licenses/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
256
+ clear_skies-2.0.10.dist-info/RECORD,,
@@ -79,6 +79,10 @@ from .conditions import Conditions
79
79
  from .config import Config
80
80
  from .datetime import Datetime
81
81
  from .datetime_or_callable import DatetimeOrCallable
82
+ from .email import Email
83
+ from .email_list import EmailList
84
+ from .email_list_or_callable import EmailListOrCallable
85
+ from .email_or_email_list_or_callable import EmailOrEmailListOrCallable
82
86
  from .endpoint import Endpoint
83
87
  from .endpoint_list import EndpointList
84
88
  from .float import Float
@@ -127,6 +131,10 @@ __all__ = [
127
131
  "Config",
128
132
  "Datetime",
129
133
  "DatetimeOrCallable",
134
+ "Email",
135
+ "EmailList",
136
+ "EmailListOrCallable",
137
+ "EmailOrEmailListOrCallable",
130
138
  "Endpoint",
131
139
  "EndpointList",
132
140
  "Float",
@@ -0,0 +1,10 @@
1
+ from __future__ import annotations
2
+
3
+ from clearskies.configs import string
4
+
5
+
6
+ class Email(string.String):
7
+ def __init__(
8
+ self, required=False, default=None, regexp: str = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
9
+ ):
10
+ super().__init__(required=required, default=default, regexp=regexp)
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from clearskies.configs import string_list
4
+
5
+
6
+ class EmailList(string_list.StringList):
7
+ """
8
+ This is for a configuration that should be a list of strings in email format.
9
+
10
+ This is different than StringList, which also accepts a list of strings, but
11
+ validates that all of those values match the required format.
12
+ """
13
+
14
+ def __init__(
15
+ self, required=False, default=None, regexp: str = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
16
+ ):
17
+ super().__init__(required=required, default=default, regexp=regexp)
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Callable
4
+
5
+ from clearskies.configs import string_list_or_callable
6
+
7
+
8
+ class EmailListOrCallable(string_list_or_callable.StringListOrCallable):
9
+ """
10
+ This is for a configuration that should be a list of emails or a callable that returns a list of emails.
11
+
12
+ This is different than StringList, which also accepts a list of strings, but
13
+ validates that all of those values match the email format.
14
+ """
15
+
16
+ def __init__(
17
+ self, required=False, default=None, regexp: str = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
18
+ ):
19
+ super().__init__(required=required, default=default, regexp=regexp)
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Callable
4
+
5
+ from clearskies.configs import config
6
+
7
+
8
+ class EmailOrEmailListOrCallable(config.Config):
9
+ """
10
+ This is for a configuration that should be an email or a list of emails or a callable that returns a list of emails.
11
+
12
+ This is a combination of Email and EmailListOrCallable.
13
+ """
14
+
15
+ def __init__(
16
+ self, required=False, default=None, regexp: str = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
17
+ ):
18
+ self.required = required
19
+ self.default = default
20
+ self.regexp = regexp
21
+
22
+ def __set__(self, instance, value: str | list[str] | Callable[..., list[str]]):
23
+ if value is None:
24
+ return
25
+ if self.regexp:
26
+ import re
27
+ if isinstance(value, str):
28
+ if self.regexp and not re.match(self.regexp, value):
29
+ error_prefix = self._error_prefix(instance)
30
+ raise ValueError(
31
+ f"{error_prefix} attempt to set a value of '{value}' but this does not match the required regexp: '{self.regexp}'."
32
+ )
33
+ value = [value]
34
+ elif not isinstance(value, list) and not callable(value):
35
+ error_prefix = self._error_prefix(instance)
36
+ raise TypeError(
37
+ f"{error_prefix} attempt to set a value of type '{value.__class__.__name__}' to a parameter that should be a list or a callable"
38
+ )
39
+ if isinstance(value, list):
40
+ if self.regexp:
41
+ import re
42
+
43
+ for index, item in enumerate(value):
44
+ if not isinstance(item, str):
45
+ error_prefix = self._error_prefix(instance)
46
+ raise TypeError(
47
+ f"{error_prefix} attempt to set a value of type '{item.__class__.__name__}' for item #{index + 1}. A string was expected."
48
+ )
49
+ if not re.match(self.regexp, item):
50
+ error_prefix = self._error_prefix(instance)
51
+ raise ValueError(
52
+ f"{error_prefix} attempt to set a value of '{item}' for item #{index + 1} but this does not match the required regexp: '{self.regexp}'."
53
+ )
54
+ instance._set_config(self, value)
55
+
56
+ def __get__(self, instance, parent) -> list[str] | Callable[..., list[str]]:
57
+ if not instance:
58
+ return self # type: ignore
59
+ return instance._get_config(self)
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
4
+
3
5
  from clearskies.configs import config
4
6
 
5
7
 
@@ -16,8 +18,6 @@ class String(config.Config):
16
18
  f"{error_prefix} attempt to set a value of type '{value.__class__.__name__}' to a parameter that requires a string."
17
19
  )
18
20
  if self.regexp:
19
- import re
20
-
21
21
  if not re.match(self.regexp, value):
22
22
  error_prefix = self._error_prefix(instance)
23
23
  raise ValueError(
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
4
+
3
5
  from clearskies.configs import config
4
6
 
5
7
 
@@ -11,6 +13,11 @@ class StringList(config.Config):
11
13
  valdiates that all of those values match against an allow list.
12
14
  """
13
15
 
16
+ def __init__(self, required=False, default=None, regexp: str = ""):
17
+ self.required = required
18
+ self.default = default
19
+ self.regexp = regexp
20
+
14
21
  def __set__(self, instance, value: list[str]):
15
22
  if value is None:
16
23
  return
@@ -18,13 +25,19 @@ class StringList(config.Config):
18
25
  if not isinstance(value, list):
19
26
  error_prefix = self._error_prefix(instance)
20
27
  raise TypeError(
21
- f"{error_prefix} attempt to set a value of type '{value.__class__.__name__}' to a list parameter"
28
+ f"{error_prefix} attempt to set a value of type '{value.__class__.__name__}' to a list of strings parameter."
22
29
  )
30
+
23
31
  for index, item in enumerate(value):
24
32
  if not isinstance(item, str):
25
33
  error_prefix = self._error_prefix(instance)
26
34
  raise TypeError(
27
- f"{error_prefix} attempt to set a value of type '{item.__class__.__name__}' for item #{index + 1}. A string was expected."
35
+ f"{error_prefix} attempt to set a value of type '{item.__class__.__name__}' for item #{index + 1}. A string was expected."
36
+ )
37
+ if self.regexp and not re.match(self.regexp, item):
38
+ error_prefix = self._error_prefix(instance)
39
+ raise ValueError(
40
+ f"{error_prefix} attempt to set a value of '{item}' for item #{index + 1} but this does not match the required regexp: '{self.regexp}'."
28
41
  )
29
42
  instance._set_config(self, value)
30
43
 
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
3
4
  from typing import Callable
4
5
 
5
6
  from clearskies.configs import config
@@ -13,6 +14,11 @@ class StringListOrCallable(config.Config):
13
14
  valdiates that all of those values match against an allow list.
14
15
  """
15
16
 
17
+ def __init__(self, required=False, default=None, regexp: str = ""):
18
+ self.required = required
19
+ self.default = default
20
+ self.regexp = regexp
21
+
16
22
  def __set__(self, instance, value: list[str] | Callable[..., list[str]]):
17
23
  if value is None:
18
24
  return
@@ -29,6 +35,11 @@ class StringListOrCallable(config.Config):
29
35
  raise TypeError(
30
36
  f"{error_prefix} attempt to set a value of type '{item.__class__.__name__}' for item #{index + 1}. A string was expected."
31
37
  )
38
+ if self.regexp and not re.match(self.regexp, item):
39
+ error_prefix = self._error_prefix(instance)
40
+ raise ValueError(
41
+ f"{error_prefix} attempt to set a value of '{item}' for item #{index + 1} but this does not match the required regexp: '{self.regexp}'."
42
+ )
32
43
  instance._set_config(self, value)
33
44
 
34
45
  def __get__(self, instance, parent) -> list[str] | Callable[..., list[str]]:
clearskies/di/di.py CHANGED
@@ -535,8 +535,7 @@ class Di:
535
535
  override = self._class_overrides_by_class[object_to_override.__class__]
536
536
  if inspect.isclass(override):
537
537
  return self.build_class(override)
538
- if hasattr(override, "injectable_properties"):
539
- override.injectable_properties(self)
538
+ self.inject_properties(override.__class__)
540
539
  return override
541
540
 
542
541
  def add_override(self, name: str, replacement_class: type) -> None:
@@ -670,8 +669,7 @@ class Di:
670
669
  # ignore the first argument because that is just `self`
671
670
  build_arguments = init_args.args[1:]
672
671
  if not build_arguments:
673
- if hasattr(class_to_build, "injectable_properties"):
674
- class_to_build.injectable_properties(self)
672
+ self.inject_properties(class_to_build)
675
673
  built_value = class_to_build()
676
674
  if cache:
677
675
  self._prepared[class_to_build] = built_value # type: ignore
@@ -703,9 +701,8 @@ class Di:
703
701
 
704
702
  del self._building[class_id]
705
703
 
704
+ self.inject_properties(class_to_build)
706
705
  built_value = class_to_build(*args)
707
- if hasattr(built_value, "injectable_properties"):
708
- built_value.injectable_properties(self)
709
706
  if cache:
710
707
  self._prepared[class_to_build] = built_value # type: ignore
711
708
  return built_value
@@ -844,6 +841,23 @@ class Di:
844
841
  return False
845
842
  return True
846
843
 
844
+ def inject_properties(self, cls):
845
+ if hasattr(cls, "injectable_properties"):
846
+ cls.injectable_properties(self)
847
+ return
848
+
849
+ if not hasattr(cls, "__injectable_properties_sanity_check"):
850
+ return
851
+
852
+ for attribute_name in dir(cls):
853
+ attribute = getattr(cls, attribute_name)
854
+ if hasattr(attribute, "initiated_guard") and hasattr(attribute, "set_di"):
855
+ raise ValueError(
856
+ f"Class '{cls.__name__}' has an injectable property attached, but does not include clearskies.di.injectable_properties.InjectableProperties in it's parent classes. You must include this as a parent class."
857
+ )
858
+ cls.__injectable_properties_sanity_check = True
859
+ return
860
+
847
861
  def provide_di(self):
848
862
  return self
849
863
 
@@ -138,6 +138,7 @@ class Akeyless(secrets.Secrets):
138
138
  return res.token
139
139
 
140
140
  def auth_saml(self):
141
+ import json
141
142
  import os
142
143
  from pathlib import Path
143
144
 
@@ -145,7 +146,9 @@ class Akeyless(secrets.Secrets):
145
146
  home = str(Path.home())
146
147
  with open(f"{home}/.akeyless/.tmp_creds/{self.profile}-{self.access_id}", "r") as creds_file:
147
148
  credentials = creds_file.read()
148
-
149
+ credentials_json = json.loads(credentials)
150
+ if "token" in credentials_json:
151
+ return credentials_json["token"]
149
152
  # and now we can turn that into a token
150
153
  response = self.requests.post(
151
154
  "https://rest.akeyless.io/",
@@ -4,9 +4,10 @@ from abc import ABC
4
4
  from typing import Any
5
5
 
6
6
  import clearskies.configurable
7
+ from clearskies.di.injectable_properties import InjectableProperties
7
8
 
8
9
 
9
- class Secrets(ABC, clearskies.configurable.Configurable):
10
+ class Secrets(ABC, clearskies.configurable.Configurable, InjectableProperties):
10
11
  def create(self, path: str, value: str) -> bool:
11
12
  raise NotImplementedError(
12
13
  "It looks like you tried to use the secret system in clearskies, but didn't specify a secret manager."