ominfra 0.0.0.dev103__tar.gz → 0.0.0.dev104__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. {ominfra-0.0.0.dev103/ominfra.egg-info → ominfra-0.0.0.dev104}/PKG-INFO +3 -3
  2. ominfra-0.0.0.dev104/ominfra/clouds/gcp/auth.py +48 -0
  3. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/_executor.py +68 -27
  4. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/pyremote/_runcommands.py +68 -27
  5. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/scripts/journald2aws.py +68 -27
  6. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/scripts/supervisor.py +68 -27
  7. ominfra-0.0.0.dev104/ominfra/tools/__init__.py +0 -0
  8. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104/ominfra.egg-info}/PKG-INFO +3 -3
  9. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra.egg-info/SOURCES.txt +2 -0
  10. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra.egg-info/requires.txt +2 -2
  11. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/pyproject.toml +3 -3
  12. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/LICENSE +0 -0
  13. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/MANIFEST.in +0 -0
  14. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/README.rst +0 -0
  15. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/.manifests.json +0 -0
  16. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/__about__.py +0 -0
  17. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/__init__.py +0 -0
  18. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/__init__.py +0 -0
  19. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/__init__.py +0 -0
  20. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/__main__.py +0 -0
  21. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/auth.py +0 -0
  22. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/cli.py +0 -0
  23. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/dataclasses.py +0 -0
  24. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/journald2aws/__init__.py +0 -0
  25. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/journald2aws/cursor.py +0 -0
  26. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/journald2aws/driver.py +0 -0
  27. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/journald2aws/main.py +0 -0
  28. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/journald2aws/poster.py +0 -0
  29. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/logs.py +0 -0
  30. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/clouds/aws/metadata.py +0 -0
  31. {ominfra-0.0.0.dev103/ominfra/deploy → ominfra-0.0.0.dev104/ominfra/clouds/gcp}/__init__.py +0 -0
  32. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/cmds.py +0 -0
  33. {ominfra-0.0.0.dev103/ominfra/deploy/executor/concerns → ominfra-0.0.0.dev104/ominfra/deploy}/__init__.py +0 -0
  34. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/configs.py +0 -0
  35. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/__init__.py +0 -0
  36. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/base.py +0 -0
  37. {ominfra-0.0.0.dev103/ominfra/journald → ominfra-0.0.0.dev104/ominfra/deploy/executor/concerns}/__init__.py +0 -0
  38. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/dirs.py +0 -0
  39. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/nginx.py +0 -0
  40. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/repo.py +0 -0
  41. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/supervisor.py +0 -0
  42. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/systemd.py +0 -0
  43. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/user.py +0 -0
  44. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/concerns/venv.py +0 -0
  45. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/executor/main.py +0 -0
  46. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/__init__.py +0 -0
  47. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/_main.py +0 -0
  48. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/base.py +0 -0
  49. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/configs.py +0 -0
  50. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/deploy.py +0 -0
  51. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/main.py +0 -0
  52. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/nginx.py +0 -0
  53. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/repo.py +0 -0
  54. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/runtime.py +0 -0
  55. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/site.py +0 -0
  56. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/supervisor.py +0 -0
  57. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/poly/venv.py +0 -0
  58. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/deploy/remote.py +0 -0
  59. {ominfra-0.0.0.dev103/ominfra/manage → ominfra-0.0.0.dev104/ominfra/journald}/__init__.py +0 -0
  60. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/journald/genmessages.py +0 -0
  61. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/journald/messages.py +0 -0
  62. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/journald/tailer.py +0 -0
  63. {ominfra-0.0.0.dev103/ominfra/pyremote → ominfra-0.0.0.dev104/ominfra/manage}/__init__.py +0 -0
  64. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/manage/manage.py +0 -0
  65. {ominfra-0.0.0.dev103/ominfra/scripts → ominfra-0.0.0.dev104/ominfra/pyremote}/__init__.py +0 -0
  66. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/pyremote/bootstrap.py +0 -0
  67. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/pyremote/runcommands.py +0 -0
  68. {ominfra-0.0.0.dev103/ominfra/tailscale → ominfra-0.0.0.dev104/ominfra/scripts}/__init__.py +0 -0
  69. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/ssh.py +0 -0
  70. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/__init__.py +0 -0
  71. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/__main__.py +0 -0
  72. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/compat.py +0 -0
  73. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/configs.py +0 -0
  74. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/context.py +0 -0
  75. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/datatypes.py +0 -0
  76. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/dispatchers.py +0 -0
  77. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/events.py +0 -0
  78. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/exceptions.py +0 -0
  79. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/poller.py +0 -0
  80. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/process.py +0 -0
  81. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/states.py +0 -0
  82. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/supervisor.py +0 -0
  83. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/supervisor/types.py +0 -0
  84. {ominfra-0.0.0.dev103/ominfra/tools → ominfra-0.0.0.dev104/ominfra/tailscale}/__init__.py +0 -0
  85. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/tailscale/api.py +0 -0
  86. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/tailscale/cli.py +0 -0
  87. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/threadworkers.py +0 -0
  88. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra/tools/listresources.py +0 -0
  89. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra.egg-info/dependency_links.txt +0 -0
  90. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra.egg-info/entry_points.txt +0 -0
  91. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/ominfra.egg-info/top_level.txt +0 -0
  92. {ominfra-0.0.0.dev103 → ominfra-0.0.0.dev104}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ominfra
3
- Version: 0.0.0.dev103
3
+ Version: 0.0.0.dev104
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omdev==0.0.0.dev103
16
- Requires-Dist: omlish==0.0.0.dev103
15
+ Requires-Dist: omdev==0.0.0.dev104
16
+ Requires-Dist: omlish==0.0.0.dev104
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko~=3.5; extra == "all"
19
19
  Requires-Dist: asyncssh~=2.18; extra == "all"
@@ -0,0 +1,48 @@
1
+ import json
2
+ import time
3
+ import typing as ta
4
+
5
+ from omlish import check
6
+ from omlish import http
7
+ from omlish.http import jwt
8
+
9
+
10
+ DEFAULT_JWT_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'
11
+
12
+
13
+ def generate_gcp_jwt(
14
+ creds_dct: ta.Mapping[str, ta.Any],
15
+ *,
16
+ issued_at: int | None = None,
17
+ lifetime_s: int = 3600,
18
+ scope: str = DEFAULT_JWT_SCOPE,
19
+ ) -> str:
20
+ return jwt.generate_jwt(
21
+ issuer=creds_dct['client_email'],
22
+ subject=creds_dct['client_email'],
23
+ audience=creds_dct['token_uri'],
24
+ issued_at=(issued_at := int(issued_at if issued_at is not None else time.time())),
25
+ expires_at=issued_at + lifetime_s,
26
+ scope=scope,
27
+ key=creds_dct['private_key'],
28
+ algorithm='RS256',
29
+ )
30
+
31
+
32
+ def get_gcp_access_token(
33
+ creds_dct: ta.Mapping[str, ta.Any],
34
+ *,
35
+ client: http.HttpClient | None = None,
36
+ ) -> str:
37
+ signed_jwt = generate_gcp_jwt(creds_dct)
38
+ resp = http.request(
39
+ creds_dct['token_uri'],
40
+ 'POST',
41
+ data=jwt.build_get_token_body(signed_jwt).encode('utf-8'),
42
+ headers={
43
+ http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_FORM_URLENCODED,
44
+ },
45
+ client=client,
46
+ )
47
+ resp_dct = json.loads(check.not_none(resp.data).decode('utf-8'))
48
+ return resp_dct['access_token']
@@ -725,7 +725,10 @@ class UuidObjMarshaler(ObjMarshaler):
725
725
  return uuid.UUID(o)
726
726
 
727
727
 
728
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
728
+ ##
729
+
730
+
731
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
729
732
  **{t: NopObjMarshaler() for t in (type(None),)},
730
733
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
731
734
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -754,20 +757,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
754
757
  }
755
758
 
756
759
 
757
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
758
- if ty in _OBJ_MARSHALERS:
759
- raise KeyError(ty)
760
- _OBJ_MARSHALERS[ty] = m
761
-
762
-
763
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
760
+ def _make_obj_marshaler(
761
+ ty: ta.Any,
762
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
763
+ *,
764
+ nonstrict_dataclasses: bool = False,
765
+ ) -> ObjMarshaler:
764
766
  if isinstance(ty, type):
765
767
  if abc.ABC in ty.__bases__:
766
768
  impls = [ # type: ignore
767
769
  PolymorphicObjMarshaler.Impl(
768
770
  ity,
769
771
  ity.__qualname__,
770
- get_obj_marshaler(ity),
772
+ rec(ity),
771
773
  )
772
774
  for ity in deep_subclasses(ty)
773
775
  if abc.ABC not in ity.__bases__
@@ -783,7 +785,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
783
785
  if dc.is_dataclass(ty):
784
786
  return DataclassObjMarshaler(
785
787
  ty,
786
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
788
+ {f.name: rec(f.type) for f in dc.fields(ty)},
789
+ nonstrict=nonstrict_dataclasses,
787
790
  )
788
791
 
789
792
  if is_generic_alias(ty):
@@ -793,7 +796,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
793
796
  pass
794
797
  else:
795
798
  k, v = ta.get_args(ty)
796
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
799
+ return MappingObjMarshaler(mt, rec(k), rec(v))
797
800
 
798
801
  try:
799
802
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -801,33 +804,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
801
804
  pass
802
805
  else:
803
806
  [e] = ta.get_args(ty)
804
- return IterableObjMarshaler(st, get_obj_marshaler(e))
807
+ return IterableObjMarshaler(st, rec(e))
805
808
 
806
809
  if is_union_alias(ty):
807
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
810
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
808
811
 
809
812
  raise TypeError(ty)
810
813
 
811
814
 
812
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
813
- try:
814
- return _OBJ_MARSHALERS[ty]
815
- except KeyError:
816
- pass
815
+ ##
817
816
 
818
- p = ProxyObjMarshaler()
819
- _OBJ_MARSHALERS[ty] = p
820
- try:
821
- m = _make_obj_marshaler(ty)
822
- except Exception:
823
- del _OBJ_MARSHALERS[ty]
824
- raise
825
- else:
826
- p.m = m
817
+
818
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
819
+
820
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
821
+
822
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
823
+
824
+
825
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
826
+ with _OBJ_MARSHALERS_LOCK:
827
+ if ty in _OBJ_MARSHALERS:
828
+ raise KeyError(ty)
827
829
  _OBJ_MARSHALERS[ty] = m
830
+
831
+
832
+ def get_obj_marshaler(
833
+ ty: ta.Any,
834
+ *,
835
+ no_cache: bool = False,
836
+ **kwargs: ta.Any,
837
+ ) -> ObjMarshaler:
838
+ with _OBJ_MARSHALERS_LOCK:
839
+ if not no_cache:
840
+ try:
841
+ return _OBJ_MARSHALERS[ty]
842
+ except KeyError:
843
+ pass
844
+
845
+ try:
846
+ return _OBJ_MARSHALER_PROXIES[ty]
847
+ except KeyError:
848
+ pass
849
+
850
+ rec = functools.partial(
851
+ get_obj_marshaler,
852
+ no_cache=no_cache,
853
+ **kwargs,
854
+ )
855
+
856
+ p = ProxyObjMarshaler()
857
+ _OBJ_MARSHALER_PROXIES[ty] = p
858
+ try:
859
+ m = _make_obj_marshaler(ty, rec, **kwargs)
860
+ finally:
861
+ del _OBJ_MARSHALER_PROXIES[ty]
862
+ p.m = m
863
+
864
+ if not no_cache:
865
+ _OBJ_MARSHALERS[ty] = m
828
866
  return m
829
867
 
830
868
 
869
+ ##
870
+
871
+
831
872
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
832
873
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
833
874
 
@@ -808,7 +808,10 @@ class UuidObjMarshaler(ObjMarshaler):
808
808
  return uuid.UUID(o)
809
809
 
810
810
 
811
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
811
+ ##
812
+
813
+
814
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
812
815
  **{t: NopObjMarshaler() for t in (type(None),)},
813
816
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
814
817
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -837,20 +840,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
837
840
  }
838
841
 
839
842
 
840
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
841
- if ty in _OBJ_MARSHALERS:
842
- raise KeyError(ty)
843
- _OBJ_MARSHALERS[ty] = m
844
-
845
-
846
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
843
+ def _make_obj_marshaler(
844
+ ty: ta.Any,
845
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
846
+ *,
847
+ nonstrict_dataclasses: bool = False,
848
+ ) -> ObjMarshaler:
847
849
  if isinstance(ty, type):
848
850
  if abc.ABC in ty.__bases__:
849
851
  impls = [ # type: ignore
850
852
  PolymorphicObjMarshaler.Impl(
851
853
  ity,
852
854
  ity.__qualname__,
853
- get_obj_marshaler(ity),
855
+ rec(ity),
854
856
  )
855
857
  for ity in deep_subclasses(ty)
856
858
  if abc.ABC not in ity.__bases__
@@ -866,7 +868,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
866
868
  if dc.is_dataclass(ty):
867
869
  return DataclassObjMarshaler(
868
870
  ty,
869
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
871
+ {f.name: rec(f.type) for f in dc.fields(ty)},
872
+ nonstrict=nonstrict_dataclasses,
870
873
  )
871
874
 
872
875
  if is_generic_alias(ty):
@@ -876,7 +879,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
876
879
  pass
877
880
  else:
878
881
  k, v = ta.get_args(ty)
879
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
882
+ return MappingObjMarshaler(mt, rec(k), rec(v))
880
883
 
881
884
  try:
882
885
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -884,33 +887,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
884
887
  pass
885
888
  else:
886
889
  [e] = ta.get_args(ty)
887
- return IterableObjMarshaler(st, get_obj_marshaler(e))
890
+ return IterableObjMarshaler(st, rec(e))
888
891
 
889
892
  if is_union_alias(ty):
890
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
893
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
891
894
 
892
895
  raise TypeError(ty)
893
896
 
894
897
 
895
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
896
- try:
897
- return _OBJ_MARSHALERS[ty]
898
- except KeyError:
899
- pass
898
+ ##
900
899
 
901
- p = ProxyObjMarshaler()
902
- _OBJ_MARSHALERS[ty] = p
903
- try:
904
- m = _make_obj_marshaler(ty)
905
- except Exception:
906
- del _OBJ_MARSHALERS[ty]
907
- raise
908
- else:
909
- p.m = m
900
+
901
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
902
+
903
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
904
+
905
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
906
+
907
+
908
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
909
+ with _OBJ_MARSHALERS_LOCK:
910
+ if ty in _OBJ_MARSHALERS:
911
+ raise KeyError(ty)
910
912
  _OBJ_MARSHALERS[ty] = m
913
+
914
+
915
+ def get_obj_marshaler(
916
+ ty: ta.Any,
917
+ *,
918
+ no_cache: bool = False,
919
+ **kwargs: ta.Any,
920
+ ) -> ObjMarshaler:
921
+ with _OBJ_MARSHALERS_LOCK:
922
+ if not no_cache:
923
+ try:
924
+ return _OBJ_MARSHALERS[ty]
925
+ except KeyError:
926
+ pass
927
+
928
+ try:
929
+ return _OBJ_MARSHALER_PROXIES[ty]
930
+ except KeyError:
931
+ pass
932
+
933
+ rec = functools.partial(
934
+ get_obj_marshaler,
935
+ no_cache=no_cache,
936
+ **kwargs,
937
+ )
938
+
939
+ p = ProxyObjMarshaler()
940
+ _OBJ_MARSHALER_PROXIES[ty] = p
941
+ try:
942
+ m = _make_obj_marshaler(ty, rec, **kwargs)
943
+ finally:
944
+ del _OBJ_MARSHALER_PROXIES[ty]
945
+ p.m = m
946
+
947
+ if not no_cache:
948
+ _OBJ_MARSHALERS[ty] = m
911
949
  return m
912
950
 
913
951
 
952
+ ##
953
+
954
+
914
955
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
915
956
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
916
957
 
@@ -1343,7 +1343,10 @@ class UuidObjMarshaler(ObjMarshaler):
1343
1343
  return uuid.UUID(o)
1344
1344
 
1345
1345
 
1346
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1346
+ ##
1347
+
1348
+
1349
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1347
1350
  **{t: NopObjMarshaler() for t in (type(None),)},
1348
1351
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
1349
1352
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -1372,20 +1375,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
1372
1375
  }
1373
1376
 
1374
1377
 
1375
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1376
- if ty in _OBJ_MARSHALERS:
1377
- raise KeyError(ty)
1378
- _OBJ_MARSHALERS[ty] = m
1379
-
1380
-
1381
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1378
+ def _make_obj_marshaler(
1379
+ ty: ta.Any,
1380
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
1381
+ *,
1382
+ nonstrict_dataclasses: bool = False,
1383
+ ) -> ObjMarshaler:
1382
1384
  if isinstance(ty, type):
1383
1385
  if abc.ABC in ty.__bases__:
1384
1386
  impls = [ # type: ignore
1385
1387
  PolymorphicObjMarshaler.Impl(
1386
1388
  ity,
1387
1389
  ity.__qualname__,
1388
- get_obj_marshaler(ity),
1390
+ rec(ity),
1389
1391
  )
1390
1392
  for ity in deep_subclasses(ty)
1391
1393
  if abc.ABC not in ity.__bases__
@@ -1401,7 +1403,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1401
1403
  if dc.is_dataclass(ty):
1402
1404
  return DataclassObjMarshaler(
1403
1405
  ty,
1404
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
1406
+ {f.name: rec(f.type) for f in dc.fields(ty)},
1407
+ nonstrict=nonstrict_dataclasses,
1405
1408
  )
1406
1409
 
1407
1410
  if is_generic_alias(ty):
@@ -1411,7 +1414,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1411
1414
  pass
1412
1415
  else:
1413
1416
  k, v = ta.get_args(ty)
1414
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
1417
+ return MappingObjMarshaler(mt, rec(k), rec(v))
1415
1418
 
1416
1419
  try:
1417
1420
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -1419,33 +1422,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1419
1422
  pass
1420
1423
  else:
1421
1424
  [e] = ta.get_args(ty)
1422
- return IterableObjMarshaler(st, get_obj_marshaler(e))
1425
+ return IterableObjMarshaler(st, rec(e))
1423
1426
 
1424
1427
  if is_union_alias(ty):
1425
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
1428
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1426
1429
 
1427
1430
  raise TypeError(ty)
1428
1431
 
1429
1432
 
1430
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1431
- try:
1432
- return _OBJ_MARSHALERS[ty]
1433
- except KeyError:
1434
- pass
1433
+ ##
1435
1434
 
1436
- p = ProxyObjMarshaler()
1437
- _OBJ_MARSHALERS[ty] = p
1438
- try:
1439
- m = _make_obj_marshaler(ty)
1440
- except Exception:
1441
- del _OBJ_MARSHALERS[ty]
1442
- raise
1443
- else:
1444
- p.m = m
1435
+
1436
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
1437
+
1438
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1439
+
1440
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1441
+
1442
+
1443
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1444
+ with _OBJ_MARSHALERS_LOCK:
1445
+ if ty in _OBJ_MARSHALERS:
1446
+ raise KeyError(ty)
1445
1447
  _OBJ_MARSHALERS[ty] = m
1448
+
1449
+
1450
+ def get_obj_marshaler(
1451
+ ty: ta.Any,
1452
+ *,
1453
+ no_cache: bool = False,
1454
+ **kwargs: ta.Any,
1455
+ ) -> ObjMarshaler:
1456
+ with _OBJ_MARSHALERS_LOCK:
1457
+ if not no_cache:
1458
+ try:
1459
+ return _OBJ_MARSHALERS[ty]
1460
+ except KeyError:
1461
+ pass
1462
+
1463
+ try:
1464
+ return _OBJ_MARSHALER_PROXIES[ty]
1465
+ except KeyError:
1466
+ pass
1467
+
1468
+ rec = functools.partial(
1469
+ get_obj_marshaler,
1470
+ no_cache=no_cache,
1471
+ **kwargs,
1472
+ )
1473
+
1474
+ p = ProxyObjMarshaler()
1475
+ _OBJ_MARSHALER_PROXIES[ty] = p
1476
+ try:
1477
+ m = _make_obj_marshaler(ty, rec, **kwargs)
1478
+ finally:
1479
+ del _OBJ_MARSHALER_PROXIES[ty]
1480
+ p.m = m
1481
+
1482
+ if not no_cache:
1483
+ _OBJ_MARSHALERS[ty] = m
1446
1484
  return m
1447
1485
 
1448
1486
 
1487
+ ##
1488
+
1489
+
1449
1490
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
1450
1491
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1451
1492
 
@@ -1470,7 +1470,10 @@ class UuidObjMarshaler(ObjMarshaler):
1470
1470
  return uuid.UUID(o)
1471
1471
 
1472
1472
 
1473
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1473
+ ##
1474
+
1475
+
1476
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1474
1477
  **{t: NopObjMarshaler() for t in (type(None),)},
1475
1478
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
1476
1479
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -1499,20 +1502,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
1499
1502
  }
1500
1503
 
1501
1504
 
1502
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1503
- if ty in _OBJ_MARSHALERS:
1504
- raise KeyError(ty)
1505
- _OBJ_MARSHALERS[ty] = m
1506
-
1507
-
1508
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1505
+ def _make_obj_marshaler(
1506
+ ty: ta.Any,
1507
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
1508
+ *,
1509
+ nonstrict_dataclasses: bool = False,
1510
+ ) -> ObjMarshaler:
1509
1511
  if isinstance(ty, type):
1510
1512
  if abc.ABC in ty.__bases__:
1511
1513
  impls = [ # type: ignore
1512
1514
  PolymorphicObjMarshaler.Impl(
1513
1515
  ity,
1514
1516
  ity.__qualname__,
1515
- get_obj_marshaler(ity),
1517
+ rec(ity),
1516
1518
  )
1517
1519
  for ity in deep_subclasses(ty)
1518
1520
  if abc.ABC not in ity.__bases__
@@ -1528,7 +1530,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1528
1530
  if dc.is_dataclass(ty):
1529
1531
  return DataclassObjMarshaler(
1530
1532
  ty,
1531
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
1533
+ {f.name: rec(f.type) for f in dc.fields(ty)},
1534
+ nonstrict=nonstrict_dataclasses,
1532
1535
  )
1533
1536
 
1534
1537
  if is_generic_alias(ty):
@@ -1538,7 +1541,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1538
1541
  pass
1539
1542
  else:
1540
1543
  k, v = ta.get_args(ty)
1541
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
1544
+ return MappingObjMarshaler(mt, rec(k), rec(v))
1542
1545
 
1543
1546
  try:
1544
1547
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -1546,33 +1549,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1546
1549
  pass
1547
1550
  else:
1548
1551
  [e] = ta.get_args(ty)
1549
- return IterableObjMarshaler(st, get_obj_marshaler(e))
1552
+ return IterableObjMarshaler(st, rec(e))
1550
1553
 
1551
1554
  if is_union_alias(ty):
1552
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
1555
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1553
1556
 
1554
1557
  raise TypeError(ty)
1555
1558
 
1556
1559
 
1557
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1558
- try:
1559
- return _OBJ_MARSHALERS[ty]
1560
- except KeyError:
1561
- pass
1560
+ ##
1562
1561
 
1563
- p = ProxyObjMarshaler()
1564
- _OBJ_MARSHALERS[ty] = p
1565
- try:
1566
- m = _make_obj_marshaler(ty)
1567
- except Exception:
1568
- del _OBJ_MARSHALERS[ty]
1569
- raise
1570
- else:
1571
- p.m = m
1562
+
1563
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
1564
+
1565
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1566
+
1567
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1568
+
1569
+
1570
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1571
+ with _OBJ_MARSHALERS_LOCK:
1572
+ if ty in _OBJ_MARSHALERS:
1573
+ raise KeyError(ty)
1572
1574
  _OBJ_MARSHALERS[ty] = m
1575
+
1576
+
1577
+ def get_obj_marshaler(
1578
+ ty: ta.Any,
1579
+ *,
1580
+ no_cache: bool = False,
1581
+ **kwargs: ta.Any,
1582
+ ) -> ObjMarshaler:
1583
+ with _OBJ_MARSHALERS_LOCK:
1584
+ if not no_cache:
1585
+ try:
1586
+ return _OBJ_MARSHALERS[ty]
1587
+ except KeyError:
1588
+ pass
1589
+
1590
+ try:
1591
+ return _OBJ_MARSHALER_PROXIES[ty]
1592
+ except KeyError:
1593
+ pass
1594
+
1595
+ rec = functools.partial(
1596
+ get_obj_marshaler,
1597
+ no_cache=no_cache,
1598
+ **kwargs,
1599
+ )
1600
+
1601
+ p = ProxyObjMarshaler()
1602
+ _OBJ_MARSHALER_PROXIES[ty] = p
1603
+ try:
1604
+ m = _make_obj_marshaler(ty, rec, **kwargs)
1605
+ finally:
1606
+ del _OBJ_MARSHALER_PROXIES[ty]
1607
+ p.m = m
1608
+
1609
+ if not no_cache:
1610
+ _OBJ_MARSHALERS[ty] = m
1573
1611
  return m
1574
1612
 
1575
1613
 
1614
+ ##
1615
+
1616
+
1576
1617
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
1577
1618
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1578
1619
 
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ominfra
3
- Version: 0.0.0.dev103
3
+ Version: 0.0.0.dev104
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omdev==0.0.0.dev103
16
- Requires-Dist: omlish==0.0.0.dev103
15
+ Requires-Dist: omdev==0.0.0.dev104
16
+ Requires-Dist: omlish==0.0.0.dev104
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko~=3.5; extra == "all"
19
19
  Requires-Dist: asyncssh~=2.18; extra == "all"
@@ -27,6 +27,8 @@ ominfra/clouds/aws/journald2aws/cursor.py
27
27
  ominfra/clouds/aws/journald2aws/driver.py
28
28
  ominfra/clouds/aws/journald2aws/main.py
29
29
  ominfra/clouds/aws/journald2aws/poster.py
30
+ ominfra/clouds/gcp/__init__.py
31
+ ominfra/clouds/gcp/auth.py
30
32
  ominfra/deploy/__init__.py
31
33
  ominfra/deploy/_executor.py
32
34
  ominfra/deploy/configs.py
@@ -1,5 +1,5 @@
1
- omdev==0.0.0.dev103
2
- omlish==0.0.0.dev103
1
+ omdev==0.0.0.dev104
2
+ omlish==0.0.0.dev104
3
3
 
4
4
  [all]
5
5
  paramiko~=3.5
@@ -12,7 +12,7 @@ authors = [
12
12
  urls = {source = 'https://github.com/wrmsr/omlish'}
13
13
  license = {text = 'BSD-3-Clause'}
14
14
  requires-python = '>=3.12'
15
- version = '0.0.0.dev103'
15
+ version = '0.0.0.dev104'
16
16
  classifiers = [
17
17
  'License :: OSI Approved :: BSD License',
18
18
  'Development Status :: 2 - Pre-Alpha',
@@ -22,8 +22,8 @@ classifiers = [
22
22
  ]
23
23
  description = 'ominfra'
24
24
  dependencies = [
25
- 'omdev == 0.0.0.dev103',
26
- 'omlish == 0.0.0.dev103',
25
+ 'omdev == 0.0.0.dev104',
26
+ 'omlish == 0.0.0.dev104',
27
27
  ]
28
28
 
29
29
  [project.optional-dependencies]
File without changes
File without changes