sovereign 0.29.0__py3-none-any.whl → 0.29.0a3__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 sovereign might be problematic. Click here for more details.

sovereign/discovery.py CHANGED
@@ -23,6 +23,7 @@ except ImportError:
23
23
  from sovereign import XDS_TEMPLATES, config, logs, template_context
24
24
  from sovereign.utils.version_info import compute_hash
25
25
  from sovereign.schemas import XdsTemplate, DiscoveryRequest, ProcessedTemplate
26
+ from sovereign.tracing import Tracer
26
27
 
27
28
 
28
29
  try:
@@ -105,7 +106,8 @@ def response(request: DiscoveryRequest, xds_type: str) -> ProcessedTemplate:
105
106
  resource_names=request.resources,
106
107
  **template_context.get_context(request, template),
107
108
  )
108
- content = template(**context)
109
+ with Tracer("template rendering"):
110
+ content = template(**context)
109
111
 
110
112
  # Deserialize YAML output from Jinja2
111
113
  if not template.is_python_source:
@@ -116,13 +118,19 @@ def response(request: DiscoveryRequest, xds_type: str) -> ProcessedTemplate:
116
118
  content = deserialize_config(content)
117
119
 
118
120
  # Early return if the template is identical
119
- config_version = compute_hash(content)
120
- if config_version == request.version_info and not config.discovery_cache.enabled:
121
- return ProcessedTemplate(version_info=config_version, resources=[])
122
-
123
- if not isinstance(content, dict):
124
- raise RuntimeError(f"Attempting to filter unstructured data: {content}")
125
- resources = filter_resources(content["resources"], request.resources)
121
+ with Tracer("nested test"):
122
+ with Tracer("hashing"):
123
+ config_version = compute_hash(content)
124
+ if (
125
+ config_version == request.version_info
126
+ and not config.discovery_cache.enabled
127
+ ):
128
+ return ProcessedTemplate(version_info=config_version, resources=[])
129
+
130
+ if not isinstance(content, dict):
131
+ raise RuntimeError(f"Attempting to filter unstructured data: {content}")
132
+ with Tracer("filtering"):
133
+ resources = filter_resources(content["resources"], request.resources)
126
134
  return ProcessedTemplate(resources=resources, version_info=config_version)
127
135
 
128
136
 
@@ -1,4 +1,3 @@
1
- import inspect
2
1
  from typing import Any, Dict, Optional
3
2
 
4
3
  from pydantic import BaseModel
@@ -14,20 +13,20 @@ class Loadable(BaseModel):
14
13
  serialization: Optional[str] = None
15
14
 
16
15
  def load(self, default: Any = None) -> Any:
17
- if self.protocol not in LOADERS:
16
+ if self.protocol not in custom_loaders:
18
17
  raise KeyError(
19
- f"Could not find CustomLoader {self.protocol}. Available: {LOADERS}"
18
+ f"Could not find CustomLoader {self.protocol}. Available: {custom_loaders}"
20
19
  )
21
- loader_ = LOADERS[self.protocol]
20
+ loader_ = custom_loaders[self.protocol]
22
21
 
23
22
  ser = self.serialization
24
23
  if ser is None:
25
24
  ser = loader_.default_deser
26
- if ser not in DESERIALIZERS:
25
+ if ser not in deserializers:
27
26
  raise KeyError(
28
- f"Could not find Deserializer {ser}. Available: {DESERIALIZERS}"
27
+ f"Could not find Deserializer {ser}. Available: {deserializers}"
29
28
  )
30
- deserializer = DESERIALIZERS[ser]
29
+ deserializer = deserializers[ser]
31
30
 
32
31
  try:
33
32
  data = loader_.load(self.path)
@@ -64,25 +63,23 @@ class Loadable(BaseModel):
64
63
  )
65
64
 
66
65
 
67
- LOADERS: Dict[str, CustomLoader] = {}
68
- for entry_point in EntryPointLoader("loaders").groups["loaders"]:
66
+ custom_loaders: Dict[str, CustomLoader] = {}
67
+ loader_entry_point = EntryPointLoader("loaders")
68
+ for entry_point in loader_entry_point.groups["loaders"]:
69
69
  custom_loader = entry_point.load()
70
- func = custom_loader()
71
- method = getattr(func, "load")
72
- if not inspect.ismethod(method):
73
- raise AttributeError(
74
- f"CustomLoader {entry_point.name} does not implement .load()"
75
- )
76
- LOADERS[entry_point.name] = func
70
+ try:
71
+ func = custom_loader()
72
+ except AttributeError:
73
+ raise AttributeError("CustomLoader does not implement .load()")
74
+ custom_loaders[entry_point.name] = func
77
75
 
78
76
 
79
- DESERIALIZERS: Dict[str, ConfigDeserializer] = {}
80
- for entry_point in EntryPointLoader("deserializers").groups["deserializers"]:
77
+ deserializers: Dict[str, ConfigDeserializer] = {}
78
+ deser_entry_point = EntryPointLoader("deserializers")
79
+ for entry_point in deser_entry_point.groups["deserializers"]:
81
80
  deserializer = entry_point.load()
82
- func = deserializer()
83
- method = getattr(func, "deserialize")
84
- if not inspect.ismethod(method):
85
- raise AttributeError(
86
- f"Deserializer {entry_point.name} does not implement .deserialize()"
87
- )
88
- DESERIALIZERS[entry_point.name] = func
81
+ try:
82
+ func = deserializer()
83
+ except AttributeError:
84
+ raise AttributeError("Deserializer does not implement .deserialize()")
85
+ deserializers[entry_point.name] = func
sovereign/schemas.py CHANGED
@@ -112,7 +112,6 @@ class DiscoveryCacheConfig(BaseModel):
112
112
  suppress: bool = False # False = Don't suppress connection errors. True = suppress connection errors
113
113
  socket_keepalive: bool = True # Try to keep connections to redis around.
114
114
  ttl: int = 60
115
- extra_keys: Dict[str, Any] = {}
116
115
 
117
116
  @model_validator(mode="after")
118
117
  def set_default_protocol(self) -> Self:
@@ -117,24 +117,21 @@ async def perform_discovery(
117
117
  authenticate(req)
118
118
  if discovery_cache.enabled:
119
119
  logs.access_logger.queue_log_fields(CACHE_XDS_HIT=False)
120
- metadata_keys = discovery_cache.extra_keys.get("metadata", [])
121
- extra_metadata = [req.node.metadata.get(key, None) for key in metadata_keys]
122
- hash_keys = [
123
- api_version,
124
- resource_type,
125
- req.envoy_version,
126
- req.resource_names,
127
- req.desired_controlplane,
128
- req.hide_private_keys,
129
- req.type_url,
130
- req.node.cluster,
131
- req.node.locality,
132
- req.node.metadata.get("auth", None),
133
- req.node.metadata.get("num_cpus", None),
134
- ] + extra_metadata
135
-
136
- cache_key = compute_hash(hash_keys)
137
-
120
+ cache_key = compute_hash(
121
+ [
122
+ api_version,
123
+ resource_type,
124
+ req.envoy_version,
125
+ req.resource_names,
126
+ req.desired_controlplane,
127
+ req.hide_private_keys,
128
+ req.type_url,
129
+ req.node.cluster,
130
+ req.node.locality,
131
+ req.node.metadata.get("auth", None),
132
+ req.node.metadata.get("num_cpus", None),
133
+ ]
134
+ )
138
135
  if template := await cache.get(key=cache_key, default=None):
139
136
  logs.access_logger.queue_log_fields(CACHE_XDS_HIT=True)
140
137
  return template # type: ignore[no-any-return]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sovereign
3
- Version: 0.29.0
3
+ Version: 0.29.0a3
4
4
  Summary: Envoy Proxy control-plane written in Python
5
5
  Home-page: https://pypi.org/project/sovereign/
6
6
  License: Apache-2.0
@@ -18,7 +18,6 @@ Classifier: Natural Language :: English
18
18
  Classifier: Operating System :: POSIX :: Linux
19
19
  Classifier: Programming Language :: Python :: 3
20
20
  Classifier: Programming Language :: Python :: 3.11
21
- Classifier: Programming Language :: Python :: 3.12
22
21
  Classifier: Programming Language :: Python :: 3.10
23
22
  Classifier: Programming Language :: Python :: 3.8
24
23
  Classifier: Programming Language :: Python :: 3.9
@@ -38,7 +37,7 @@ Requires-Dist: cachelib (>=0.10.2,<0.11.0)
38
37
  Requires-Dist: cachetools (>=5.3.2,<6.0.0)
39
38
  Requires-Dist: cashews[redis] (>=6.3.0,<7.0.0) ; extra == "caching"
40
39
  Requires-Dist: croniter (>=1.4.1,<2.0.0)
41
- Requires-Dist: cryptography (>=43.0.1,<44.0.0)
40
+ Requires-Dist: cryptography (>=42.0.5,<43.0.0)
42
41
  Requires-Dist: datadog (>=0.47.0,<0.48.0) ; extra == "statsd"
43
42
  Requires-Dist: fastapi (>=0.110.0,<0.111.0)
44
43
  Requires-Dist: glom (>=23.3.0,<24.0.0)
@@ -3,8 +3,8 @@ sovereign/app.py,sha256=udDhuprAcJdYNgXufl94-oh-G74H9hXVzr8cKhgdQYI,4087
3
3
  sovereign/configuration.py,sha256=BCezlWYIpTsFRZwQIBwU-XrfBk1MdjTKMLA8huN-VPg,2484
4
4
  sovereign/constants.py,sha256=qdWD1lTvkaW5JGF7TmZhfksQHlRAJFVqbG7v6JQA9k8,46
5
5
  sovereign/context.py,sha256=Vwr-Jmo1I_05rFraxv6GoYEC83oFl87LG16px4R7IfA,6461
6
- sovereign/discovery.py,sha256=KHnWXUlceUglbR9eV5Q6LjPOpGv2dcrGOSus9-QLQJM,5952
7
- sovereign/dynamic_config/__init__.py,sha256=QoRNcuCAqV26zeyHm0iavsR55K3TwMohabWpPGIq_rM,2838
6
+ sovereign/discovery.py,sha256=iS34aeJHSTqGY4i0jIQG9Yd0LKS63VQELaMSyvJk6Y8,6198
7
+ sovereign/dynamic_config/__init__.py,sha256=kxthEPcB-fiVZ-5qudkct5bphsAo3LuGAE7rU0J9M7Q,2781
8
8
  sovereign/dynamic_config/deser.py,sha256=CYTP9UNx8falCXU_bEaWGNatyQlYrV4T57NPXNhTn0o,1842
9
9
  sovereign/dynamic_config/loaders.py,sha256=HxDT-6hlqg_ewPjrFu2RaWi6O1mmJ_Mpnu8AQk_enNg,2923
10
10
  sovereign/error_info.py,sha256=r2KXBYq9Fo7AI2pmIpATWFm0pykr2MqfrKH0WWW5Sfk,1488
@@ -17,7 +17,7 @@ sovereign/middlewares.py,sha256=UoLdfhqMj_E6jXgtr-n0maQIBYe9n95s3BwaQZfebHo,3097
17
17
  sovereign/modifiers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  sovereign/modifiers/lib.py,sha256=DbXsxrrjnFE4Y7rbwpeiM5tS5w5NBwSdYH58AtDTP0I,2884
19
19
  sovereign/response_class.py,sha256=beMAFV-4L6DwyWzJzy71GkEW4gb7fzH1jd8-Tul13cU,427
20
- sovereign/schemas.py,sha256=nkpMVLwdtODmyfbwu5PEExxFKFLY3H0Oj4mqB9HJnfI,31552
20
+ sovereign/schemas.py,sha256=wikM9mt42lbbxKEC60N8emG8fLrwnDp9ikkbJMECGXQ,31516
21
21
  sovereign/server.py,sha256=z8Uz1UYIZix0S40Srk774WIMDN2jl2SozO8irib0wc4,1402
22
22
  sovereign/sources/__init__.py,sha256=g9hEpFk8j5i1ApHQpbc9giTyJW41Ppgsqv5P9zGxOJk,78
23
23
  sovereign/sources/file.py,sha256=prUThsDCSPNwZaZpkKXhAm-GVRZWbBoGKGU0It4HHXs,690
@@ -55,11 +55,11 @@ sovereign/utils/weighted_clusters.py,sha256=bPzuRE7Qgvv04HcR2AhMDvBrFlZ8AfteweLK
55
55
  sovereign/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
56
  sovereign/views/admin.py,sha256=9jUI3YqaU42AtzCCOCKDcfj_2JXoaMU6eOAD6WYPjoI,4312
57
57
  sovereign/views/crypto.py,sha256=o8NSyiUBy7v1pMOXt_1UBi68FNcGkXSlEVg9C18y8kY,3324
58
- sovereign/views/discovery.py,sha256=9TyXfS3nW7I7Bkeg-KdsTeCm1N9WSCvDj_pTAi1V4bo,6067
58
+ sovereign/views/discovery.py,sha256=TVvWTMzWydsC-SNKL9WsSss_Hfnt2Ed4SVC2A8Na7Jo,5932
59
59
  sovereign/views/healthchecks.py,sha256=_WkMunlrFpqGTLgtNtRr7gCsDCv5kiuYxCyTi-dMEKM,1357
60
60
  sovereign/views/interface.py,sha256=TFXbYp5oXZPRkVnAo-NWQFBb8XMtB519FaV78ludCcI,7055
61
- sovereign-0.29.0.dist-info/LICENSE.txt,sha256=2X125zvAb9AYLjCgdMDQZuufhm0kwcg31A8pGKj_-VY,560
62
- sovereign-0.29.0.dist-info/METADATA,sha256=M3LgSzH5wpBmLWUwWy_bPFclUSmnsz5SfnoH3WJ8fZ4,6607
63
- sovereign-0.29.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
64
- sovereign-0.29.0.dist-info/entry_points.txt,sha256=2mUHQjqeXEokMF6ZjDmvqQ9Fxk-Or2S4eC0h70ZxKmk,1201
65
- sovereign-0.29.0.dist-info/RECORD,,
61
+ sovereign-0.29.0a3.dist-info/LICENSE.txt,sha256=2X125zvAb9AYLjCgdMDQZuufhm0kwcg31A8pGKj_-VY,560
62
+ sovereign-0.29.0a3.dist-info/METADATA,sha256=pvrbBMc76iClWyj0-xIP5vcy0T6XTmzBYNCHF9qeEEg,6558
63
+ sovereign-0.29.0a3.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
64
+ sovereign-0.29.0a3.dist-info/entry_points.txt,sha256=2mUHQjqeXEokMF6ZjDmvqQ9Fxk-Or2S4eC0h70ZxKmk,1201
65
+ sovereign-0.29.0a3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 1.7.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any