clear-skies 1.22.21__py3-none-any.whl → 1.22.23__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.1
2
2
  Name: clear-skies
3
- Version: 1.22.21
3
+ Version: 1.22.23
4
4
  Summary: A framework for building backends in the cloud
5
5
  Home-page: https://github.com/cmancone/clearskies
6
6
  License: MIT
@@ -1,14 +1,14 @@
1
1
  clearskies/__init__.py,sha256=Iz_VxSgiqM6VtGXoUsB_yVKFy_uWvcf071w803wJ8EE,832
2
2
  clearskies/application.py,sha256=_gYGIUGdVE5fAS9dwxRZ1gDpDjqGo7-twVt_VxI6XVE,966
3
- clearskies/authentication/__init__.py,sha256=e8hJ_gKdKn7dIzHe4Hg3jdUYIzGGSr5aJKnQa3zh-MU,997
3
+ clearskies/authentication/__init__.py,sha256=UY72kSNfUOINCqd_X4SyizyTlPiAO_1MM30xvp5MpqY,1069
4
4
  clearskies/authentication/auth0_jwks.py,sha256=bzqNaEoG_iPndwttRXuaKpgkDtgOCLAooyifl0I0ACI,4447
5
5
  clearskies/authentication/auth_exception.py,sha256=8Tay3Sim2K8vAZ6ldisSJyRyN0cwX7iyGHwfglSKW_A,41
6
6
  clearskies/authentication/authorization.py,sha256=eLzBrXMNr1gYoIBZTd8I6uH3R0CfMMjhvimkJt4Amrs,601
7
- clearskies/authentication/authorization_pass_through.py,sha256=wrRSY0RyRFifeyRgNn9D-3ptCXjPSbytHB8xAyyFSWE,737
7
+ clearskies/authentication/authorization_pass_through.py,sha256=t8-IrgQtKwBqZFhUS6e9Gg72jF_NAV-R2Xid3-Svdxo,752
8
8
  clearskies/authentication/jwks.py,sha256=AOrCkL7pVznTM6mbrQ3RVHCccws0b_yEtqEOe6NRw5k,3368
9
- clearskies/authentication/jwks_jwcrypto.py,sha256=PqyQNJZY7P98qgdxNltwCWoPxsaWLDqPuMknB4u2mDc,1732
10
- clearskies/authentication/public.py,sha256=zNpglAILTU7koz22YaGpMOAtTn_dG8dAP4Q9REdbaOk,630
11
- clearskies/authentication/secret_bearer.py,sha256=OBkjvw4n-ZLRRtZEKyzdael03DYIwacvUxrj5V9h0Ow,2968
9
+ clearskies/authentication/jwks_jwcrypto.py,sha256=UBoRVvTo6g3A8RvmXTWpg2lbysqA4mxlrSc6mKppDqw,1737
10
+ clearskies/authentication/public.py,sha256=SdU0dawwvC3b6YPPznWQBcCqqMWh8h-yRckD0PCMLfI,1006
11
+ clearskies/authentication/secret_bearer.py,sha256=DviRGNjp0FXIdBmD4daw_cqQ9NUUxZ5i5i4DEOY_zZw,3355
12
12
  clearskies/autodoc/__init__.py,sha256=JRUAmd0he8iGlgiZvxewLMIXJqnOFEdvlaKAtHpC2lo,124
13
13
  clearskies/autodoc/formats/__init__.py,sha256=3rhoLKmEwT6PljaHvOl9qdeMIXyD7PQBZbqZKy5Mb5I,56
14
14
  clearskies/autodoc/formats/oai3_json/__init__.py,sha256=O4kkUc9RbqEc5C5wjirGRjfXdD-0yWXUxjC2E-Cit60,142
@@ -46,7 +46,7 @@ clearskies/autodoc/schema/object.py,sha256=GJ5zLw2CzhezQiNuIhVgRyk0esXqfHD5fxZrc
46
46
  clearskies/autodoc/schema/password.py,sha256=Ptj8OeddAL4h69KWqZ6ubZ2awR13xdDIrNe2N0T1jic,196
47
47
  clearskies/autodoc/schema/string.py,sha256=oxZPCxYYhWnNHdbtwD3QuniStbj8XbBBpDTFXgPR1VU,244
48
48
  clearskies/backends/__init__.py,sha256=ATNzuDYREx-VBWemPmG95FR8EzO2X0--7tkErUuF9Qc,832
49
- clearskies/backends/api_backend.py,sha256=3a7geSrqMWEE3lIgeG9LmH3QlcFFoL96AHyNS0Kf1Es,15175
49
+ clearskies/backends/api_backend.py,sha256=RVf1Lr45GvL5fxRfR8cj4rFe7J_eP9ELmRyKea1N43E,15578
50
50
  clearskies/backends/api_get_only_backend.py,sha256=KfFF72l31KBK--90lIkDqE5gcTnolSkShUqNaaWZ_gc,1690
51
51
  clearskies/backends/backend.py,sha256=fkL-De0MUdzcS2JG_spSUQZIVL9oRFvaL6SP26JPpcI,7399
52
52
  clearskies/backends/cursor_backend.py,sha256=VntlPS6z6bnZOC3XRJ-WFf5gK3pFUhH_qJpnZn8hl9U,11278
@@ -75,7 +75,7 @@ clearskies/column_types/datetime_micro.py,sha256=P3iFDtFlwRT1FazFSNnnpeDUzCX4Ss0
75
75
  clearskies/column_types/email.py,sha256=qq0Yo_C3KxUqT68q2HWXocBBR4xwMqjxcIdgZRv218U,584
76
76
  clearskies/column_types/float.py,sha256=j8jJeBueSOusPtAFCWgLHYBncfLnqT1U7bh1zcAkYiA,1332
77
77
  clearskies/column_types/has_many.py,sha256=vcx6QU-LH-4hh_-LNfDBePt80hIFebSpTreGLh86pVc,7681
78
- clearskies/column_types/has_one.py,sha256=uphIPUuHLwwmhljLMaKKPujR6TYTT7onn-hHUF6S_IY,2230
78
+ clearskies/column_types/has_one.py,sha256=jji9DXYw6P9r0pKsVxz5dTsNtjM7WtkzIzmzKavaRIQ,2322
79
79
  clearskies/column_types/integer.py,sha256=dGIluusPmhLRNg7PplOJLbQI2AXojqRBUHt8ekYWNVI,1386
80
80
  clearskies/column_types/json.py,sha256=TbZkdwCoZYhbALUxof2jENGfaq2i5TlcyBcmo7XzDGQ,652
81
81
  clearskies/column_types/many_to_many.py,sha256=AGFz0T6oCJFQyxZqPCNDgF8M0yjVctN37B3tUSl8dNA,11978
@@ -208,7 +208,7 @@ clearskies/tests/simple_api/models/__init__.py,sha256=nUA0W6fgXw_Bxa9CudkaDkC80t
208
208
  clearskies/tests/simple_api/models/status.py,sha256=PEhPbaQh5qdUNHp8O0gz91LOLENAEBtqSaHxUPXchaM,699
209
209
  clearskies/tests/simple_api/models/user.py,sha256=5_P4Tp1tTdX7PkMJ__epPM5MA7JAeVYGas69vcWloLc,819
210
210
  clearskies/tests/simple_api/users_api.py,sha256=KYXCgEofDxHeRdQK67txN5oYUPvxxmB8JTku7L-apk4,2344
211
- clear_skies-1.22.21.dist-info/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
212
- clear_skies-1.22.21.dist-info/METADATA,sha256=u9hQLRGWgB9PXfeyxJd1bpP2nd9T1-Bv14zQ1gCU_YY,1920
213
- clear_skies-1.22.21.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
214
- clear_skies-1.22.21.dist-info/RECORD,,
211
+ clear_skies-1.22.23.dist-info/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
212
+ clear_skies-1.22.23.dist-info/METADATA,sha256=oxhPi7eJ9xWxBII7IoYn92uT5ox5eiWk-zK0in2xV3Q,1920
213
+ clear_skies-1.22.23.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
214
+ clear_skies-1.22.23.dist-info/RECORD,,
@@ -1,11 +1,11 @@
1
1
  from ..binding_config import BindingConfig
2
- from .secret_bearer import SecretBearer
3
- from .public import Public
4
2
  from .auth0_jwks import Auth0JWKS
5
3
  from .authorization import Authorization
4
+ from .authorization_pass_through import AuthorizationPassThrough
6
5
  from .jwks import JWKS
7
6
  from .jwks_jwcrypto import JWKSJwCrypto
8
- from .authorization_pass_through import AuthorizationPassThrough
7
+ from .public import Public, PublicAuth
8
+ from .secret_bearer import SecretBearer, SecretBearerAuth
9
9
 
10
10
 
11
11
  def public():
@@ -34,8 +34,10 @@ __all__ = [
34
34
  "BindingConfig",
35
35
  "public",
36
36
  "Public",
37
+ "PublicAuth",
37
38
  "secret_bearer",
38
39
  "SecretBearer",
40
+ "SecretBearerAuth",
39
41
  "auth0_jwks",
40
42
  "Auth0JWKS",
41
43
  "authorization",
@@ -1,7 +1,7 @@
1
- from clearskies.authentication import JWKSJwCrypto
1
+ from clearskies.authentication import jwks_jwcrypto
2
2
 
3
3
 
4
- class AuthorizationPassThrough(JWKSJwCrypto):
4
+ class AuthorizationPassThrough(jwks_jwcrypto.JWKSJwCrypto):
5
5
  """
6
6
  This authentication class takes the authentication header from the incoming request and reflects
7
7
  it on outgoing requests.
@@ -1,18 +1,18 @@
1
1
  import datetime
2
2
  import json
3
3
 
4
- from clearskies.authentication import JWKS
4
+ from clearskies.authentication import jwks
5
5
  from clearskies.handlers.exceptions import ClientError
6
6
 
7
7
 
8
- class JWKSJwCrypto(JWKS):
8
+ class JWKSJwCrypto(jwks.JWKS):
9
9
  def __init__(self, environment, requests):
10
10
  # the third parameter is supposed to be jose_jwt, but we're going to override all
11
11
  # the functions that use it
12
12
  super().__init__(environment, requests, {})
13
13
 
14
14
  def validate_jwt(self, raw_jwt):
15
- from jwcrypto import jws, jwk, jwt
15
+ from jwcrypto import jwk, jws, jwt
16
16
  from jwcrypto.common import JWException
17
17
 
18
18
  keys = jwk.JWKSet()
@@ -1,3 +1,7 @@
1
+ from requests.auth import AuthBase
2
+ from requests.models import PreparedRequest
3
+
4
+
1
5
  class Public:
2
6
  is_public = True
3
7
  can_authorize = False
@@ -26,3 +30,11 @@ class Public:
26
30
 
27
31
  def documentation_security_scheme_name(self):
28
32
  return ""
33
+
34
+
35
+ class PublicAuth(AuthBase, Public):
36
+ """Wrapper around SecretBearer to allow for the use of the SecretBearer class as an AuthBase class"""
37
+
38
+ def __call__(self, r: PreparedRequest) -> PreparedRequest:
39
+ r.headers = {**r.headers, **self.headers()}
40
+ return super().__call__(r)
@@ -1,3 +1,6 @@
1
+ from requests.auth import AuthBase
2
+ from requests.models import PreparedRequest
3
+
1
4
  from .. import autodoc
2
5
 
3
6
 
@@ -78,3 +81,11 @@ class SecretBearer:
78
81
 
79
82
  def documentation_security_scheme_name(self):
80
83
  return self._documentation_security_name if self._documentation_security_name is not None else "ApiKey"
84
+
85
+
86
+ class SecretBearerAuth(AuthBase, SecretBearer):
87
+ """Wrapper around SecretBearer to allow for the use of the SecretBearer class as an AuthBase class"""
88
+
89
+ def __call__(self, r: PreparedRequest) -> PreparedRequest:
90
+ r.headers = {**r.headers, **self.headers()}
91
+ return super().__call__(r)
@@ -1,10 +1,30 @@
1
- from .backend import Backend
1
+ import re
2
2
  from typing import Any, Callable, Dict, List, Tuple
3
- from ..autodoc.schema import Integer as AutoDocInteger
3
+
4
+ from requests import Session
5
+ from requests.auth import AuthBase
6
+
4
7
  from .. import model
8
+ from ..autodoc.schema import Integer as AutoDocInteger
5
9
  from ..column_types import JSON, DateTime
6
- import re
7
- from requests import Session
10
+ from .backend import Backend
11
+
12
+
13
+ class NullAuth(AuthBase):
14
+ """force requests to ignore the ``.netrc``
15
+
16
+ Some sites do not support regular authentication, but we still
17
+ want to store credentials in the ``.netrc`` file and submit them
18
+ as form elements. Without this, requests would otherwise use the
19
+ .netrc which leads, on some sites, to a 401 error.
20
+
21
+ Use with::
22
+
23
+ requests.get(url, auth=NullAuth())
24
+ """
25
+
26
+ def __call__(self, r):
27
+ return r
8
28
 
9
29
 
10
30
  class ApiBackend(Backend):
@@ -152,28 +172,21 @@ class ApiBackend(Backend):
152
172
  raise ValueError("Unexpected response from records request")
153
173
  return json["data"]
154
174
 
155
- def _execute_request(self, url: str, method: str, json: dict[str,Any]= {}, headers: dict[str,Any]= {}, is_retry: bool = False):
156
- if self._auth:
157
- headers = {**headers, **self._auth.headers(retry_auth=is_retry)}
175
+ def _execute_request(
176
+ self, url: str, method: str, json: dict[str, Any] = {}, headers: dict[str, Any] = {}, is_retry: bool = False
177
+ ):
158
178
  # the requests library seems to build a slightly different request if you specify the json parameter,
159
179
  # even if it is null, and this causes trouble for some picky servers
160
180
  if not json:
161
- response = self._requests.request(
162
- method,
163
- url,
164
- headers=headers,
165
- )
181
+ response = self._requests.request(method, url, headers=headers, auth=self._auth if self._auth else NullAuth())
166
182
  else:
167
183
  response = self._requests.request(
168
- method,
169
- url,
170
- headers=headers,
171
- json=json,
184
+ method, url, headers=headers, json=json, auth=self._auth if self._auth else NullAuth()
172
185
  )
173
186
 
174
187
  if not response.ok:
175
188
  if self._auth and self._auth.has_dynamic_credentials and not is_retry:
176
- return self._execute_request(url, method, json=json, headers=headers, is_retry=True)
189
+ return self._execute_request(url, method, json=json, headers=headers, auth=self._auth, is_retry=True)
177
190
  if not response.ok:
178
191
  raise ValueError(f"Failed request. Status code: {response.status_code}, message: {response.content!r}")
179
192
 
@@ -23,6 +23,8 @@ class HasOne(HasMany):
23
23
  def provide(self, data, column_name):
24
24
  foreign_column_name = self.config("foreign_column_name")
25
25
  id_column_name = self.config("parent_id_column_name")
26
+ if not data.get(id_column_name):
27
+ return self.child_models.empty_model()
26
28
  return self.child_models.find(f"{foreign_column_name}={data[id_column_name]}")
27
29
 
28
30
  def to_json(self, model):