koichi12 commited on
Commit
26afd33
·
verified ·
1 Parent(s): 596addb

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .venv/lib/python3.11/site-packages/opencensus/common/__pycache__/__init__.cpython-311.pyc +0 -0
  2. .venv/lib/python3.11/site-packages/opencensus/common/backports/__init__.py +79 -0
  3. .venv/lib/python3.11/site-packages/opencensus/common/backports/__pycache__/__init__.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/opencensus/common/configuration/__init__.py +46 -0
  5. .venv/lib/python3.11/site-packages/opencensus/common/configuration/__pycache__/__init__.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/__init__.py +0 -0
  7. .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/gcp_metadata_config.py +115 -0
  8. .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/k8s_utils.py +64 -0
  9. .venv/lib/python3.11/site-packages/opencensus/common/version/__init__.py +15 -0
  10. .venv/lib/python3.11/site-packages/opencensus/common/version/__pycache__/__init__.cpython-311.pyc +0 -0
  11. .venv/lib/python3.11/site-packages/opencensus/metrics/__init__.py +0 -0
  12. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__init__.py +0 -0
  13. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/__init__.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/cumulative.cpython-311.pyc +0 -0
  15. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/gauge.cpython-311.pyc +0 -0
  16. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/metric.cpython-311.pyc +0 -0
  17. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/point.cpython-311.pyc +0 -0
  18. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/summary.cpython-311.pyc +0 -0
  19. .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/time_series.cpython-311.pyc +0 -0
  20. .venv/lib/python3.11/site-packages/opencensus/metrics/export/cumulative.py +87 -0
  21. .venv/lib/python3.11/site-packages/opencensus/metrics/export/gauge.py +513 -0
  22. .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric.py +79 -0
  23. .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_descriptor.py +174 -0
  24. .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_producer.py +81 -0
  25. .venv/lib/python3.11/site-packages/opencensus/metrics/export/point.py +47 -0
  26. .venv/lib/python3.11/site-packages/opencensus/metrics/export/summary.py +144 -0
  27. .venv/lib/python3.11/site-packages/opencensus/metrics/export/time_series.py +90 -0
  28. .venv/lib/python3.11/site-packages/opencensus/metrics/export/value.py +307 -0
  29. .venv/lib/python3.11/site-packages/opencensus/metrics/label_key.py +51 -0
  30. .venv/lib/python3.11/site-packages/opencensus/metrics/transport.py +145 -0
  31. .venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/__init__.cpython-311.pyc +0 -0
  32. .venv/lib/python3.11/site-packages/proto/__init__.py +72 -0
  33. .venv/lib/python3.11/site-packages/proto/__pycache__/__init__.cpython-311.pyc +0 -0
  34. .venv/lib/python3.11/site-packages/proto/__pycache__/datetime_helpers.cpython-311.pyc +0 -0
  35. .venv/lib/python3.11/site-packages/proto/__pycache__/enums.cpython-311.pyc +0 -0
  36. .venv/lib/python3.11/site-packages/proto/__pycache__/fields.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/proto/enums.py +163 -0
  38. .venv/lib/python3.11/site-packages/proto/marshal/__init__.py +18 -0
  39. .venv/lib/python3.11/site-packages/proto/marshal/collections/__init__.py +24 -0
  40. .venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/maps.cpython-311.pyc +0 -0
  41. .venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/repeated.cpython-311.pyc +0 -0
  42. .venv/lib/python3.11/site-packages/proto/marshal/collections/maps.py +82 -0
  43. .venv/lib/python3.11/site-packages/proto/marshal/collections/repeated.py +189 -0
  44. .venv/lib/python3.11/site-packages/proto/marshal/compat.py +64 -0
  45. .venv/lib/python3.11/site-packages/proto/marshal/marshal.py +297 -0
  46. .venv/lib/python3.11/site-packages/proto/marshal/rules/__init__.py +13 -0
  47. .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/__init__.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/bytes.cpython-311.pyc +0 -0
  49. .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/dates.cpython-311.pyc +0 -0
  50. .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/enums.cpython-311.pyc +0 -0
.venv/lib/python3.11/site-packages/opencensus/common/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (328 Bytes). View file
 
.venv/lib/python3.11/site-packages/opencensus/common/backports/__init__.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import six
16
+
17
+ import weakref
18
+
19
+
20
+ class WeakMethod(weakref.ref): # pragma: NO COVER
21
+ """
22
+ A custom `weakref.ref` subclass which simulates a weak reference to
23
+ a bound method, working around the lifetime problem of bound methods.
24
+
25
+ This is a copy of the WeakMethod class that ships with weakref in the
26
+ python 3.7 standard library, adapted to work in 2.6. See:
27
+ https://github.com/python/cpython/blob/a31f4cc881992e84d351957bd9ac1a92f882fa39/Lib/weakref.py#L36-L87
28
+ """ # noqa
29
+
30
+ __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__"
31
+
32
+ def __new__(cls, meth, callback=None):
33
+ try:
34
+ obj = meth.__self__
35
+ func = meth.__func__
36
+ except AttributeError:
37
+ error = TypeError("argument should be a bound method, not {}"
38
+ .format(type(meth)))
39
+ six.raise_from(error, None)
40
+
41
+ def _cb(arg):
42
+ # The self-weakref trick is needed to avoid creating a reference
43
+ # cycle.
44
+ self = self_wr()
45
+ if self._alive:
46
+ self._alive = False
47
+ if callback is not None:
48
+ callback(self)
49
+ self = weakref.ref.__new__(cls, obj, _cb)
50
+ self._func_ref = weakref.ref(func, _cb)
51
+ self._meth_type = type(meth)
52
+ self._alive = True
53
+ self_wr = weakref.ref(self)
54
+ return self
55
+
56
+ def __call__(self):
57
+ obj = super(WeakMethod, self).__call__()
58
+ func = self._func_ref()
59
+ if obj is None or func is None:
60
+ return None
61
+ return self._meth_type(func, obj)
62
+
63
+ def __eq__(self, other):
64
+ if isinstance(other, WeakMethod):
65
+ if not self._alive or not other._alive:
66
+ return self is other
67
+ return (weakref.ref.__eq__(self, other)
68
+ and self._func_ref == other._func_ref)
69
+ return False
70
+
71
+ def __ne__(self, other):
72
+ if isinstance(other, WeakMethod):
73
+ if not self._alive or not other._alive:
74
+ return self is not other
75
+ return (weakref.ref.__ne__(self, other)
76
+ or self._func_ref != other._func_ref)
77
+ return True
78
+
79
+ __hash__ = weakref.ref.__hash__
.venv/lib/python3.11/site-packages/opencensus/common/backports/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (3.7 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/common/configuration/__init__.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import importlib
16
+
17
+ __all__ = ['Namespace', 'load']
18
+
19
+
20
+ class Namespace(object):
21
+ def __init__(self, name, parent=None):
22
+ self.parent = parent
23
+ self.name = name
24
+
25
+ def __getattr__(self, name):
26
+ return type(self)(name, self)
27
+
28
+ def __str__(self):
29
+ if self.parent is None:
30
+ return self.name
31
+ return '{!s}.{}'.format(self.parent, self.name)
32
+
33
+ def __call__(self, *args, **kwargs):
34
+ ctor = getattr(importlib.import_module(str(self.parent)), self.name)
35
+ return ctor(*args, **kwargs)
36
+
37
+ @classmethod
38
+ def eval(cls, expr):
39
+ return eval(expr, {}, {'opencensus': cls('opencensus')})
40
+
41
+
42
+ def load(expr):
43
+ """Dynamically import OpenCensus components and evaluate the provided
44
+ configuration expression.
45
+ """
46
+ return Namespace.eval(expr)
.venv/lib/python3.11/site-packages/opencensus/common/configuration/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (2.17 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/gcp_metadata_config.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from opencensus.common.http_handler import get_request
16
+
17
+ _GCP_METADATA_URI = 'http://metadata.google.internal/computeMetadata/v1/'
18
+ _GCP_METADATA_URI_HEADER = {'Metadata-Flavor': 'Google'}
19
+
20
+ # ID of the GCP project associated with this resource, such as "my-project"
21
+ PROJECT_ID_KEY = 'project_id'
22
+
23
+ # Numeric VM instance identifier assigned by GCE
24
+ INSTANCE_ID_KEY = 'instance_id'
25
+
26
+ # The GCE zone in which the VM is running
27
+ ZONE_KEY = 'zone'
28
+
29
+ # GKE cluster name
30
+ CLUSTER_NAME_KEY = 'instance/attributes/cluster-name'
31
+
32
+ # GCE common attributes
33
+ # See: https://cloud.google.com/appengine/docs/flexible/python/runtime#environment_variables # noqa
34
+ _GCE_ATTRIBUTES = {
35
+ PROJECT_ID_KEY: 'project/project-id',
36
+ INSTANCE_ID_KEY: 'instance/id',
37
+ ZONE_KEY: 'instance/zone'
38
+ }
39
+
40
+ _ATTRIBUTE_URI_TRANSFORMATIONS = {
41
+ _GCE_ATTRIBUTES[ZONE_KEY]:
42
+ lambda v: v[v.rfind('/') + 1:] if '/' in v else v
43
+ }
44
+
45
+ _GCP_METADATA_MAP = {}
46
+
47
+
48
+ class GcpMetadataConfig(object):
49
+ """GcpMetadata represents metadata retrieved from GCP (GKE and GCE)
50
+ environment. Some attributes are retrieved from the system environment.
51
+ see : <a href="https://cloud.google.com/compute/docs/
52
+ storing-retrieving-metadata"> https://cloud.google.com/compute/docs/storing
53
+ -retrieving-metadata</a>
54
+ """
55
+ inited = False
56
+ is_running = False
57
+
58
+ @classmethod
59
+ def _initialize_metadata_service(cls):
60
+ """Initialize metadata service once and load gcp metadata into map
61
+ This method should only be called once.
62
+ """
63
+ if cls.inited:
64
+ return
65
+
66
+ instance_id = cls.get_attribute('instance/id')
67
+
68
+ if instance_id is not None:
69
+ cls.is_running = True
70
+
71
+ _GCP_METADATA_MAP['instance_id'] = instance_id
72
+
73
+ # fetch attributes from metadata request
74
+ for attribute_key, attribute_uri in _GCE_ATTRIBUTES.items():
75
+ if attribute_key not in _GCP_METADATA_MAP:
76
+ attribute_value = cls.get_attribute(attribute_uri)
77
+ if attribute_value is not None: # pragma: NO COVER
78
+ _GCP_METADATA_MAP[attribute_key] = attribute_value
79
+
80
+ cls.inited = True
81
+
82
+ @classmethod
83
+ def is_running_on_gcp(cls):
84
+ cls._initialize_metadata_service()
85
+ return cls.is_running
86
+
87
+ def get_gce_metadata(self):
88
+ """for GCP GCE instance"""
89
+ if self.is_running_on_gcp():
90
+ return _GCP_METADATA_MAP
91
+
92
+ return dict()
93
+
94
+ @staticmethod
95
+ def get_attribute(attribute_uri):
96
+ """
97
+ Fetch the requested instance metadata entry.
98
+ :param attribute_uri: attribute_uri: attribute name relative to the
99
+ computeMetadata/v1 prefix
100
+ :return: The value read from the metadata service or None
101
+ """
102
+ attribute_value = get_request(_GCP_METADATA_URI + attribute_uri,
103
+ _GCP_METADATA_URI_HEADER)
104
+
105
+ if attribute_value is not None and isinstance(attribute_value, bytes):
106
+ # At least in python3, bytes are are returned from
107
+ # urllib (although the response is text), convert
108
+ # to a normal string:
109
+ attribute_value = attribute_value.decode('utf-8')
110
+
111
+ transformation = _ATTRIBUTE_URI_TRANSFORMATIONS.get(attribute_uri)
112
+ if transformation is not None:
113
+ attribute_value = transformation(attribute_value)
114
+
115
+ return attribute_value
.venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/k8s_utils.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import os
16
+
17
+ from opencensus.common.monitored_resource import gcp_metadata_config
18
+
19
+ # Env var that signals that we're in a kubernetes container
20
+ _KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST'
21
+
22
+ # Name of the cluster the container is running in
23
+ CLUSTER_NAME_KEY = 'k8s.io/cluster/name'
24
+
25
+ # ID of the instance the container is running on
26
+ NAMESPACE_NAME_KEY = 'k8s.io/namespace/name'
27
+
28
+ # Container pod ID
29
+ POD_NAME_KEY = 'k8s.io/pod/name'
30
+
31
+ # Container name
32
+ CONTAINER_NAME_KEY = 'k8s.io/container/name'
33
+
34
+ # Attributes set from environment variables
35
+ _K8S_ENV_ATTRIBUTES = {
36
+ CONTAINER_NAME_KEY: 'CONTAINER_NAME',
37
+ NAMESPACE_NAME_KEY: 'NAMESPACE',
38
+ POD_NAME_KEY: 'HOSTNAME'
39
+ }
40
+
41
+
42
+ def is_k8s_environment():
43
+ """Whether the environment is a kubernetes container.
44
+
45
+ The KUBERNETES_SERVICE_HOST environment variable must be set.
46
+ """
47
+ return _KUBERNETES_SERVICE_HOST in os.environ
48
+
49
+
50
+ def get_k8s_metadata():
51
+ """Get kubernetes container metadata, as on GCP GKE."""
52
+ k8s_metadata = {}
53
+
54
+ gcp_cluster = (gcp_metadata_config.GcpMetadataConfig
55
+ .get_attribute(gcp_metadata_config.CLUSTER_NAME_KEY))
56
+ if gcp_cluster is not None:
57
+ k8s_metadata[CLUSTER_NAME_KEY] = gcp_cluster
58
+
59
+ for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items():
60
+ attribute_value = os.environ.get(attribute_env)
61
+ if attribute_value is not None:
62
+ k8s_metadata[attribute_key] = attribute_value
63
+
64
+ return k8s_metadata
.venv/lib/python3.11/site-packages/opencensus/common/version/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ __version__ = '0.11.4'
.venv/lib/python3.11/site-packages/opencensus/common/version/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (221 Bytes). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (198 Bytes). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/cumulative.cpython-311.pyc ADDED
Binary file (5.04 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/gauge.cpython-311.pyc ADDED
Binary file (26.9 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/metric.cpython-311.pyc ADDED
Binary file (3.87 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/point.cpython-311.pyc ADDED
Binary file (1.78 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/summary.cpython-311.pyc ADDED
Binary file (5.7 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/time_series.cpython-311.pyc ADDED
Binary file (4.18 kB). View file
 
.venv/lib/python3.11/site-packages/opencensus/metrics/export/cumulative.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import six
16
+
17
+ from opencensus.metrics.export import gauge, metric_descriptor
18
+
19
+
20
+ class CumulativePointLong(gauge.GaugePointLong):
21
+ """A `GaugePointLong` that cannot decrease."""
22
+
23
+ def _set(self, val):
24
+ if not isinstance(val, six.integer_types):
25
+ raise ValueError("CumulativePointLong only supports integer types")
26
+ if val > self.get_value():
27
+ super(CumulativePointLong, self)._set(val)
28
+
29
+ def add(self, val):
30
+ """Add `val` to the current value if it's positive.
31
+
32
+ Return without adding if `val` is not positive.
33
+
34
+ :type val: int
35
+ :param val: Value to add.
36
+ """
37
+ if not isinstance(val, six.integer_types):
38
+ raise ValueError("CumulativePointLong only supports integer types")
39
+ if val > 0:
40
+ super(CumulativePointLong, self).add(val)
41
+
42
+
43
+ class CumulativePointDouble(gauge.GaugePointDouble):
44
+ """A `GaugePointDouble` that cannot decrease."""
45
+
46
+ def _set(self, val):
47
+ if val > self.get_value():
48
+ super(CumulativePointDouble, self)._set(val)
49
+
50
+ def add(self, val):
51
+ """Add `val` to the current value if it's positive.
52
+
53
+ Return without adding if `val` is not positive.
54
+
55
+ :type val: float
56
+ :param val: Value to add.
57
+ """
58
+ if val > 0:
59
+ super(CumulativePointDouble, self).add(val)
60
+
61
+
62
+ class LongCumulativeMixin(object):
63
+ """Type mixin for long-valued cumulative measures."""
64
+ descriptor_type = metric_descriptor.MetricDescriptorType.CUMULATIVE_INT64
65
+ point_type = CumulativePointLong
66
+
67
+
68
+ class DoubleCumulativeMixin(object):
69
+ """Type mixin for float-valued cumulative measures."""
70
+ descriptor_type = metric_descriptor.MetricDescriptorType.CUMULATIVE_DOUBLE
71
+ point_type = CumulativePointDouble
72
+
73
+
74
+ class LongCumulative(LongCumulativeMixin, gauge.Gauge):
75
+ """Records cumulative int-valued measurements."""
76
+
77
+
78
+ class DoubleCumulative(DoubleCumulativeMixin, gauge.Gauge):
79
+ """Records cumulative float-valued measurements."""
80
+
81
+
82
+ class DerivedLongCumulative(LongCumulativeMixin, gauge.DerivedGauge):
83
+ """Records derived cumulative int-valued measurements."""
84
+
85
+
86
+ class DerivedDoubleCumulative(DoubleCumulativeMixin, gauge.DerivedGauge):
87
+ """Records derived cumulative float-valued measurements."""
.venv/lib/python3.11/site-packages/opencensus/metrics/export/gauge.py ADDED
@@ -0,0 +1,513 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import six
16
+
17
+ import threading
18
+ from collections import OrderedDict
19
+ from datetime import datetime
20
+
21
+ from opencensus.common import utils
22
+ from opencensus.metrics.export import (
23
+ metric,
24
+ metric_descriptor,
25
+ metric_producer,
26
+ )
27
+ from opencensus.metrics.export import point as point_module
28
+ from opencensus.metrics.export import time_series
29
+ from opencensus.metrics.export import value as value_module
30
+
31
+
32
+ def get_timeseries_list(points, timestamp):
33
+ """Convert a list of `GaugePoint`s into a list of `TimeSeries`.
34
+
35
+ Get a :class:`opencensus.metrics.export.time_series.TimeSeries` for each
36
+ measurement in `points`. Each series contains a single
37
+ :class:`opencensus.metrics.export.point.Point` that represents the last
38
+ recorded value of the measurement.
39
+
40
+ :type points: list(:class:`GaugePoint`)
41
+ :param points: The list of measurements to convert.
42
+
43
+ :type timestamp: :class:`datetime.datetime`
44
+ :param timestamp: Recording time to report, usually the current time.
45
+
46
+ :rtype: list(:class:`opencensus.metrics.export.time_series.TimeSeries`)
47
+ :return: A list of one `TimeSeries` for each point in `points`.
48
+ """
49
+ ts_list = []
50
+ for lv, gp in points.items():
51
+ point = point_module.Point(gp.to_point_value(), timestamp)
52
+ ts_list.append(time_series.TimeSeries(lv, [point], timestamp))
53
+ return ts_list
54
+
55
+
56
+ class GaugePoint(object):
57
+
58
+ def to_point_value(self):
59
+ raise NotImplementedError # pragma: NO COVER
60
+
61
+ def get_value(self):
62
+ raise NotImplementedError # pragma: NO COVER
63
+
64
+
65
+ class GaugePointLong(GaugePoint):
66
+ """An instantaneous measurement from a LongGauge.
67
+
68
+ A GaugePointLong represents the most recent measurement from a
69
+ :class:`LongGauge` for a given set of label values.
70
+ """
71
+
72
+ def __init__(self):
73
+ self.value = 0
74
+ self._value_lock = threading.Lock()
75
+
76
+ def __repr__(self):
77
+ return ("{}({})"
78
+ .format(
79
+ type(self).__name__,
80
+ self.value
81
+ ))
82
+
83
+ def add(self, val):
84
+ """Add `val` to the current value.
85
+
86
+ :type val: int
87
+ :param val: Value to add.
88
+ """
89
+ if not isinstance(val, six.integer_types):
90
+ raise ValueError("GaugePointLong only supports integer types")
91
+ with self._value_lock:
92
+ self.value += val
93
+
94
+ def _set(self, val):
95
+ if not isinstance(val, six.integer_types):
96
+ raise ValueError("GaugePointLong only supports integer types")
97
+ with self._value_lock:
98
+ self.value = val
99
+
100
+ def set(self, val):
101
+ """Set the current value to `val`.
102
+
103
+ :type val: int
104
+ :param val: Value to set.
105
+ """
106
+ self._set(val)
107
+
108
+ def get_value(self):
109
+ """Get the current value.
110
+
111
+ :rtype: int
112
+ :return: The current value of the measurement.
113
+ """
114
+ return self.value
115
+
116
+ def to_point_value(self):
117
+ """Get a point value conversion of the current value.
118
+
119
+ :rtype: :class:`opencensus.metrics.export.value.ValueLong`
120
+ :return: A converted `ValueLong`.
121
+ """
122
+ return value_module.ValueLong(self.value)
123
+
124
+
125
+ class GaugePointDouble(GaugePoint):
126
+ """An instantaneous measurement from a DoubleGauge.
127
+
128
+ A `GaugePointDouble` represents the most recent measurement from a
129
+ :class:`DoubleGauge` for a given set of label values.
130
+ """
131
+
132
+ def __init__(self):
133
+ self.value = 0.0
134
+ self._value_lock = threading.Lock()
135
+
136
+ def __repr__(self):
137
+ return ("{}({})"
138
+ .format(
139
+ type(self).__name__,
140
+ self.value
141
+ ))
142
+
143
+ def add(self, val):
144
+ """Add `val` to the current value.
145
+
146
+ :type val: float
147
+ :param val: Value to add.
148
+ """
149
+ with self._value_lock:
150
+ self.value += val
151
+
152
+ def _set(self, val):
153
+ with self._value_lock:
154
+ self.value = float(val)
155
+
156
+ def set(self, val):
157
+ """Set the current value to `val`.
158
+
159
+ :type val: float
160
+ :param val: Value to set.
161
+ """
162
+ self._set(val)
163
+
164
+ def get_value(self):
165
+ """Get the current value.
166
+
167
+ :rtype: float
168
+ :return: The current value of the measurement.
169
+ """
170
+ return self.value
171
+
172
+ def to_point_value(self):
173
+ """Get a point value conversion of the current value.
174
+
175
+ :rtype: :class:`opencensus.metrics.export.value.ValueDouble`
176
+ :return: A converted `ValueDouble`.
177
+ """
178
+ return value_module.ValueDouble(self.value)
179
+
180
+
181
+ class DerivedGaugePoint(GaugePoint):
182
+ """Wraps a `GaugePoint` to automatically track the value of a function.
183
+
184
+ A `DerivedGaugePoint` is a read-only measure that stores the most recently
185
+ read value of a given function in a mutable `GaugePoint`. Calling
186
+ `get_value` or `to_point_value` calls the tracked function and updates the
187
+ wrapped `GaugePoint`.
188
+
189
+ :type func: function
190
+ :param func: The function to track.
191
+
192
+ :type gauge_point: :class:`GaugePointLong`, :class:`GaugePointDouble`,
193
+ :class:`opencensus.metrics.export.cumulative.CumulativePointLong`, or
194
+ :class:`opencensus.metrics.export.cumulative.CumulativePointDouble`
195
+ :param gauge_point: The underlying `GaugePoint`.
196
+ """
197
+ def __init__(self, func, gauge_point, **kwargs):
198
+ self.gauge_point = gauge_point
199
+ self.func = utils.get_weakref(func)
200
+ self._kwargs = kwargs
201
+
202
+ def __repr__(self):
203
+ return ("{}({})({})"
204
+ .format(
205
+ type(self).__name__,
206
+ self.func(),
207
+ self._kwargs
208
+ ))
209
+
210
+ def get_value(self):
211
+ """Get the current value of the underlying measurement.
212
+
213
+ Calls the tracked function and stores the value in the wrapped
214
+ measurement as a side-effect.
215
+
216
+ :rtype: int, float, or None
217
+ :return: The current value of the wrapped function, or `None` if it no
218
+ longer exists.
219
+ """
220
+ try:
221
+ val = self.func()(**self._kwargs)
222
+ except TypeError: # The underlying function has been GC'd
223
+ return None
224
+
225
+ self.gauge_point._set(val)
226
+ return self.gauge_point.get_value()
227
+
228
+ def to_point_value(self):
229
+ """Get a point value conversion of the current value.
230
+
231
+ Calls the tracked function and stores the value in the wrapped
232
+ measurement as a side-effect.
233
+
234
+ :rtype: :class:`opencensus.metrics.export.value.ValueLong`,
235
+ :class:`opencensus.metrics.export.value.ValueDouble`, or None
236
+ :return: The point value conversion of the underlying `GaugePoint`, or
237
+ None if the tracked function no longer exists.
238
+ """
239
+ if self.get_value() is None:
240
+ return None
241
+ return self.gauge_point.to_point_value()
242
+
243
+
244
+ class BaseGauge(object):
245
+ """Base class for sets instantaneous measurements."""
246
+
247
+ def __init__(self, name, description, unit, label_keys):
248
+ self._len_label_keys = len(label_keys)
249
+ self.default_label_values = [None] * self._len_label_keys
250
+ self.descriptor = metric_descriptor.MetricDescriptor(
251
+ name, description, unit, self.descriptor_type, label_keys)
252
+ self.points = OrderedDict()
253
+ self._points_lock = threading.Lock()
254
+
255
+ def __repr__(self):
256
+ return ('{}(descriptor.name="{}", points={})'
257
+ .format(
258
+ type(self).__name__,
259
+ self.descriptor.name,
260
+ self.points
261
+ ))
262
+
263
+ def _remove_time_series(self, label_values):
264
+ with self._points_lock:
265
+ try:
266
+ del self.points[tuple(label_values)]
267
+ except KeyError:
268
+ pass
269
+
270
+ def remove_time_series(self, label_values):
271
+ """Remove the time series for specific label values.
272
+
273
+ :type label_values: list(:class:`LabelValue`)
274
+ :param label_values: Label values of the time series to remove.
275
+ """
276
+ if label_values is None:
277
+ raise ValueError
278
+ if any(lv is None for lv in label_values):
279
+ raise ValueError
280
+ if len(label_values) != self._len_label_keys:
281
+ raise ValueError
282
+ self._remove_time_series(label_values)
283
+
284
+ def remove_default_time_series(self):
285
+ """Remove the default time series for this gauge."""
286
+ self._remove_time_series(self.default_label_values)
287
+
288
+ def clear(self):
289
+ """Remove all points from this gauge."""
290
+ with self._points_lock:
291
+ self.points = OrderedDict()
292
+
293
+ def get_metric(self, timestamp):
294
+ """Get a metric including all current time series.
295
+
296
+ Get a :class:`opencensus.metrics.export.metric.Metric` with one
297
+ :class:`opencensus.metrics.export.time_series.TimeSeries` for each
298
+ set of label values with a recorded measurement. Each `TimeSeries`
299
+ has a single point that represents the last recorded value.
300
+
301
+ :type timestamp: :class:`datetime.datetime`
302
+ :param timestamp: Recording time to report, usually the current time.
303
+
304
+ :rtype: :class:`opencensus.metrics.export.metric.Metric` or None
305
+ :return: A converted metric for all current measurements.
306
+ """
307
+ if not self.points:
308
+ return None
309
+
310
+ with self._points_lock:
311
+ ts_list = get_timeseries_list(self.points, timestamp)
312
+ return metric.Metric(self.descriptor, ts_list)
313
+
314
+ @property
315
+ def descriptor_type(self): # pragma: NO COVER
316
+ raise NotImplementedError
317
+
318
+ @property
319
+ def point_type(self): # pragma: NO COVER
320
+ raise NotImplementedError
321
+
322
+
323
+ class Gauge(BaseGauge):
324
+ """A set of mutable, instantaneous measurements of the same type.
325
+
326
+ End users should use :class:`LongGauge`, :class:`DoubleGauge`,
327
+ :class:`opencensus.metrics.export.cumulative.LongCumulative`, or
328
+ :class:`opencensus.metrics.export.cumulative.DoubleCumulative` instead of
329
+ using this class directly.
330
+
331
+ The constructor arguments are used to create a
332
+ :class:`opencensus.metrics.export.metric_descriptor.MetricDescriptor` for
333
+ converted metrics. See that class for details.
334
+ """
335
+
336
+ def _get_or_create_time_series(self, label_values):
337
+ with self._points_lock:
338
+ return self.points.setdefault(
339
+ tuple(label_values), self.point_type())
340
+
341
+ def get_or_create_time_series(self, label_values):
342
+ """Get a mutable measurement for the given set of label values.
343
+
344
+ :type label_values: list(:class:`LabelValue`)
345
+ :param label_values: The measurement's label values.
346
+
347
+ :rtype: :class:`GaugePointLong`, :class:`GaugePointDouble`
348
+ :class:`opencensus.metrics.export.cumulative.CumulativePointLong`,
349
+ or
350
+ :class:`opencensus.metrics.export.cumulative.CumulativePointDouble`
351
+ :return: A mutable point that represents the last value of the
352
+ measurement.
353
+ """
354
+ if label_values is None:
355
+ raise ValueError
356
+ if any(lv is None for lv in label_values):
357
+ raise ValueError
358
+ if len(label_values) != self._len_label_keys:
359
+ raise ValueError
360
+ return self._get_or_create_time_series(label_values)
361
+
362
+ def get_or_create_default_time_series(self):
363
+ """Get the default measurement for this gauge.
364
+
365
+ Each gauge has a default point not associated with any specific label
366
+ values. When this gauge is exported as a metric via `get_metric` the
367
+ time series associated with this point will have null label values.
368
+
369
+ :rtype: :class:`GaugePointLong`, :class:`GaugePointDouble`
370
+ :class:`opencensus.metrics.export.cumulative.CumulativePointLong`,
371
+ or
372
+ :class:`opencensus.metrics.export.cumulative.CumulativePointDouble`
373
+ :return: A mutable point that represents the last value of the
374
+ measurement.
375
+ """
376
+ return self._get_or_create_time_series(self.default_label_values)
377
+
378
+
379
+ class LongGaugeMixin(object):
380
+ """Type mixin for long-valued gauges."""
381
+ descriptor_type = metric_descriptor.MetricDescriptorType.GAUGE_INT64
382
+ point_type = GaugePointLong
383
+
384
+
385
+ class DoubleGaugeMixin(object):
386
+ """Type mixin for float-valued gauges."""
387
+ descriptor_type = metric_descriptor.MetricDescriptorType.GAUGE_DOUBLE
388
+ point_type = GaugePointDouble
389
+
390
+
391
+ class LongGauge(LongGaugeMixin, Gauge):
392
+ """Gauge for recording int-valued measurements."""
393
+
394
+
395
+ class DoubleGauge(DoubleGaugeMixin, Gauge):
396
+ """Gauge for recording float-valued measurements."""
397
+
398
+
399
+ class DerivedGauge(BaseGauge):
400
+ """Gauge that tracks values of other functions.
401
+
402
+ Each of a `DerivedGauge`'s measurements are associated with a function
403
+ which is called when the gauge is exported.
404
+
405
+ End users should use :class:`DerivedLongGauge`, :class:`DerivedDoubleGauge`
406
+ :class:`opencensus.metrics.export.cumulative.DerivedLongCumulative`, or
407
+ :class:`opencensus.metrics.export.cumulative.DerivedDoubleCumulative`
408
+ instead of using this class directly.
409
+ """
410
+
411
+ def _create_time_series(self, label_values, func, **kwargs):
412
+ with self._points_lock:
413
+ return self.points.setdefault(
414
+ tuple(label_values),
415
+ DerivedGaugePoint(func, self.point_type(), **kwargs))
416
+
417
+ def create_time_series(self, label_values, func, **kwargs):
418
+ """Create a derived measurement to trac `func`.
419
+
420
+ :type label_values: list(:class:`LabelValue`)
421
+ :param label_values: The measurement's label values.
422
+
423
+ :type func: function
424
+ :param func: The function to track.
425
+
426
+ :rtype: :class:`DerivedGaugePoint`
427
+ :return: A read-only measurement that tracks `func`.
428
+ """
429
+ if label_values is None:
430
+ raise ValueError
431
+ if any(lv is None for lv in label_values):
432
+ raise ValueError
433
+ if len(label_values) != self._len_label_keys:
434
+ raise ValueError
435
+ if func is None:
436
+ raise ValueError
437
+ return self._create_time_series(label_values, func, **kwargs)
438
+
439
+ def create_default_time_series(self, func):
440
+ """Create the default derived measurement for this gauge.
441
+
442
+ :type func: function
443
+ :param func: The function to track.
444
+
445
+ :rtype: :class:`DerivedGaugePoint`
446
+ :return: A read-only measurement that tracks `func`.
447
+ """
448
+ if func is None:
449
+ raise ValueError
450
+ return self._create_time_series(self.default_label_values, func)
451
+
452
+
453
+ class DerivedLongGauge(LongGaugeMixin, DerivedGauge):
454
+ """Gauge for derived int-valued measurements."""
455
+
456
+
457
+ class DerivedDoubleGauge(DoubleGaugeMixin, DerivedGauge):
458
+ """Gauge for derived float-valued measurements."""
459
+
460
+
461
+ class Registry(metric_producer.MetricProducer):
462
+ """A collection of gauges to be exported together.
463
+
464
+ Each registered gauge must have a unique `descriptor.name`.
465
+ """
466
+
467
+ def __init__(self):
468
+ self.gauges = {}
469
+ self._gauges_lock = threading.Lock()
470
+
471
+ def __repr__(self):
472
+ return ('{}(gauges={}'
473
+ .format(
474
+ type(self).__name__,
475
+ self.gauges
476
+ ))
477
+
478
+ def add_gauge(self, gauge):
479
+ """Add `gauge` to the registry.
480
+
481
+ Raises a `ValueError` if another gauge with the same name already
482
+ exists in the registry.
483
+
484
+ :type gauge: class:`LongGauge`, class:`DoubleGauge`,
485
+ :class:`opencensus.metrics.export.cumulative.LongCumulative`,
486
+ :class:`opencensus.metrics.export.cumulative.DoubleCumulative`,
487
+ :class:`DerivedLongGauge`, :class:`DerivedDoubleGauge`
488
+ :class:`opencensus.metrics.export.cumulative.DerivedLongCumulative`,
489
+ or
490
+ :class:`opencensus.metrics.export.cumulative.DerivedDoubleCumulative`
491
+ :param gauge: The gauge to add to the registry.
492
+ """
493
+ if gauge is None:
494
+ raise ValueError
495
+ name = gauge.descriptor.name
496
+ with self._gauges_lock:
497
+ if name in self.gauges:
498
+ raise ValueError(
499
+ 'Another gauge named "{}" is already registered'
500
+ .format(name))
501
+ self.gauges[name] = gauge
502
+
503
+ def get_metrics(self):
504
+ """Get a metric for each gauge in the registry at the current time.
505
+
506
+ :rtype: set(:class:`opencensus.metrics.export.metric.Metric`)
507
+ :return: A set of `Metric`s, one for each registered gauge.
508
+ """
509
+ now = datetime.utcnow()
510
+ metrics = set()
511
+ for gauge in self.gauges.values():
512
+ metrics.add(gauge.get_metric(now))
513
+ return metrics
.venv/lib/python3.11/site-packages/opencensus/metrics/export/metric.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from opencensus.metrics.export import metric_descriptor
16
+
17
+
18
+ class Metric(object):
19
+ """A collection of time series data and label metadata.
20
+
21
+ This class implements the spec for v1 Metrics as of opencensus-proto
22
+ release v0.1.0. See opencensus-proto for details:
23
+
24
+ https://github.com/census-instrumentation/opencensus-proto/blob/v0.1.0/src/opencensus/proto/metrics/v1/metrics.proto#L35
25
+
26
+ Defines a Metric which has one or more timeseries.
27
+
28
+ :type descriptor: class: '~opencensus.metrics.export.metric_descriptor.MetricDescriptor'
29
+ :param descriptor: The metric's descriptor.
30
+
31
+ :type timeseries: list(:class: '~opencensus.metrics.export.time_series.TimeSeries')
32
+ :param timeseries: One or more timeseries for a single metric, where each
33
+ timeseries has one or more points.
34
+ """ # noqa
35
+
36
+ def __init__(self, descriptor, time_series):
37
+ if not time_series:
38
+ raise ValueError("time_series must not be empty or null")
39
+ if descriptor is None:
40
+ raise ValueError("descriptor must not be null")
41
+ self._time_series = time_series
42
+ self._descriptor = descriptor
43
+ self._check_type()
44
+
45
+ def __repr__(self):
46
+ return ('{}(time_series={}, descriptor.name="{}")'
47
+ .format(
48
+ type(self).__name__,
49
+ "<{} TimeSeries>".format(len(self.time_series)),
50
+ self.descriptor.name,
51
+ ))
52
+
53
+ @property
54
+ def time_series(self):
55
+ return self._time_series
56
+
57
+ @property
58
+ def descriptor(self):
59
+ return self._descriptor
60
+
61
+ def _check_type(self):
62
+ """Check that point value types match the descriptor type."""
63
+ check_type = metric_descriptor.MetricDescriptorType.to_type_class(
64
+ self.descriptor.type)
65
+ for ts in self.time_series:
66
+ if not ts.check_points_type(check_type):
67
+ raise ValueError("Invalid point value type")
68
+
69
+ def _check_start_timestamp(self):
70
+ """Check that starting timestamp exists for cumulative metrics."""
71
+ if self.descriptor.type in (
72
+ metric_descriptor.MetricDescriptorType.CUMULATIVE_INT64,
73
+ metric_descriptor.MetricDescriptorType.CUMULATIVE_DOUBLE,
74
+ metric_descriptor.MetricDescriptorType.CUMULATIVE_DISTRIBUTION,
75
+ ):
76
+ for ts in self.time_series:
77
+ if ts.start_timestamp is None:
78
+ raise ValueError("time_series.start_timestamp must exist "
79
+ "for cumulative metrics")
.venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_descriptor.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import six
16
+
17
+ from opencensus.metrics.export import value
18
+
19
+
20
+ class _MetricDescriptorTypeMeta(type):
21
+ """Helper for `x in MetricDescriptorType`."""
22
+
23
+ def __contains__(cls, item):
24
+ return item in {
25
+ MetricDescriptorType.GAUGE_INT64,
26
+ MetricDescriptorType.GAUGE_DOUBLE,
27
+ MetricDescriptorType.GAUGE_DISTRIBUTION,
28
+ MetricDescriptorType.CUMULATIVE_INT64,
29
+ MetricDescriptorType.CUMULATIVE_DOUBLE,
30
+ MetricDescriptorType.CUMULATIVE_DISTRIBUTION
31
+ }
32
+
33
+
34
+ @six.add_metaclass(_MetricDescriptorTypeMeta)
35
+ class MetricDescriptorType(object):
36
+ """The kind of metric. It describes how the data is reported.
37
+
38
+ MetricDescriptorType is an enum of valid MetricDescriptor type values. See
39
+ opencensus-proto for details:
40
+
41
+ https://github.com/census-instrumentation/opencensus-proto/blob/v0.1.0/src/opencensus/proto/metrics/v1/metrics.proto#L79
42
+
43
+ A gauge is an instantaneous measurement of a value.
44
+
45
+ A cumulative measurement is a value accumulated over a time interval. In a
46
+ time series, cumulative measurements should have the same start time and
47
+ increasing end times, until an event resets the cumulative value to zero
48
+ and sets a new start time for the following points.
49
+
50
+ """
51
+ # Integer gauge. The value can go both up and down.
52
+ GAUGE_INT64 = 1
53
+
54
+ # Floating point gauge. The value can go both up and down.
55
+ GAUGE_DOUBLE = 2
56
+
57
+ # Distribution gauge measurement. The count and sum can go both up and
58
+ # down. Recorded values are always >= 0.
59
+ # Used in scenarios like a snapshot of time the current items in a queue
60
+ # have spent there.
61
+ GAUGE_DISTRIBUTION = 3
62
+
63
+ # Integer cumulative measurement. The value cannot decrease, if resets then
64
+ # the start_time should also be reset.
65
+ CUMULATIVE_INT64 = 4
66
+
67
+ # Floating point cumulative measurement. The value cannot decrease, if
68
+ # resets then the start_time should also be reset. Recorded values are
69
+ # always >= 0.
70
+ CUMULATIVE_DOUBLE = 5
71
+
72
+ # Distribution cumulative measurement. The count and sum cannot decrease,
73
+ # if resets then the start_time should also be reset.
74
+ CUMULATIVE_DISTRIBUTION = 6
75
+
76
+ # Some frameworks implemented Histograms as a summary of observations
77
+ # (usually things like request durations and response sizes). While it also
78
+ # provides a total count of observations and a sum of all observed values,
79
+ # it calculates configurable percentiles over a sliding time window. This
80
+ # is not recommended, since it cannot be aggregated.
81
+ SUMMARY = 7
82
+
83
+ _type_map = {
84
+ GAUGE_INT64: value.ValueLong,
85
+ GAUGE_DOUBLE: value.ValueDouble,
86
+ GAUGE_DISTRIBUTION: value.ValueDistribution,
87
+ CUMULATIVE_INT64: value.ValueLong,
88
+ CUMULATIVE_DOUBLE: value.ValueDouble,
89
+ CUMULATIVE_DISTRIBUTION: value.ValueDistribution,
90
+ SUMMARY: value.ValueSummary
91
+ }
92
+
93
+ @classmethod
94
+ def to_type_class(cls, metric_descriptor_type):
95
+ try:
96
+ return cls._type_map[metric_descriptor_type]
97
+ except KeyError:
98
+ raise ValueError("Unknown MetricDescriptorType value")
99
+
100
+
101
+ class MetricDescriptor(object):
102
+ """Defines a metric type and its schema.
103
+
104
+ This class implements the spec for v1 MetricDescriptors, as of
105
+ opencensus-proto release v0.1.0. See opencensus-proto for details:
106
+
107
+ https://github.com/census-instrumentation/opencensus-proto/blob/v0.1.0/src/opencensus/proto/metrics/v1/metrics.proto#L59
108
+
109
+ :type name: str
110
+ :param name: The metric type, including its DNS name prefix. It must be
111
+ unique.
112
+
113
+ :type description: str
114
+ :param description: A detailed description of the metric, which can be used
115
+ in documentation.
116
+
117
+ :type unit: str
118
+ :param unit: The unit in which the metric value is reported. Follows the
119
+ format described by http://unitsofmeasure.org/ucum.html.
120
+
121
+ :type type_: int
122
+ :param type_: The type of metric. MetricDescriptorType enumerates the valid
123
+ options.
124
+
125
+ :type label_keys: list(:class: '~opencensus.metrics.label_key.LabelKey')
126
+ :param label_keys: The label keys associated with the metric descriptor.
127
+ """
128
+
129
+ def __init__(self, name, description, unit, type_, label_keys):
130
+ if type_ not in MetricDescriptorType:
131
+ raise ValueError("Invalid type")
132
+
133
+ if label_keys is None:
134
+ raise ValueError("label_keys must not be None")
135
+
136
+ if any(key is None for key in label_keys):
137
+ raise ValueError("label_keys must not contain null keys")
138
+
139
+ self._name = name
140
+ self._description = description
141
+ self._unit = unit
142
+ self._type = type_
143
+ self._label_keys = label_keys
144
+
145
+ def __repr__(self):
146
+ type_name = MetricDescriptorType.to_type_class(self.type).__name__
147
+ return ('{}(name="{}", description="{}", unit={}, type={})'
148
+ .format(
149
+ type(self).__name__,
150
+ self.name,
151
+ self.description,
152
+ self.unit,
153
+ type_name,
154
+ ))
155
+
156
+ @property
157
+ def name(self):
158
+ return self._name
159
+
160
+ @property
161
+ def description(self):
162
+ return self._description
163
+
164
+ @property
165
+ def unit(self):
166
+ return self._unit
167
+
168
+ @property
169
+ def type(self):
170
+ return self._type
171
+
172
+ @property
173
+ def label_keys(self):
174
+ return self._label_keys
.venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_producer.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import threading
16
+
17
+
18
+ class MetricProducer(object):
19
+ """Produces a set of metrics for export."""
20
+
21
+ def get_metrics(self):
22
+ """Get a set of metrics to be exported.
23
+
24
+ :rtype: set(:class: `opencensus.metrics.export.metric.Metric`)
25
+ :return: A set of metrics to be exported.
26
+ """
27
+ raise NotImplementedError # pragma: NO COVER
28
+
29
+
30
+ class MetricProducerManager(object):
31
+ """Container class for MetricProducers to be used by exporters.
32
+
33
+ :type metric_producers: iterable(class: 'MetricProducer')
34
+ :param metric_producers: Optional initial metric producers.
35
+ """
36
+
37
+ def __init__(self, metric_producers=None):
38
+ if metric_producers is None:
39
+ self.metric_producers = set()
40
+ else:
41
+ self.metric_producers = set(metric_producers)
42
+ self.mp_lock = threading.Lock()
43
+
44
+ def add(self, metric_producer):
45
+ """Add a metric producer.
46
+
47
+ :type metric_producer: :class: 'MetricProducer'
48
+ :param metric_producer: The metric producer to add.
49
+ """
50
+ if metric_producer is None:
51
+ raise ValueError
52
+ with self.mp_lock:
53
+ self.metric_producers.add(metric_producer)
54
+
55
+ def remove(self, metric_producer):
56
+ """Remove a metric producer.
57
+
58
+ :type metric_producer: :class: 'MetricProducer'
59
+ :param metric_producer: The metric producer to remove.
60
+ """
61
+ if metric_producer is None:
62
+ raise ValueError
63
+ try:
64
+ with self.mp_lock:
65
+ self.metric_producers.remove(metric_producer)
66
+ except KeyError:
67
+ pass
68
+
69
+ def get_all(self):
70
+ """Get the set of all metric producers.
71
+
72
+ Get a copy of `metric_producers`. Prefer this method to using the
73
+ attribute directly to avoid other threads adding/removing producers
74
+ while you're reading it.
75
+
76
+ :rtype: set(:class: `MetricProducer`)
77
+ :return: A set of all metric producers at the time of the call.
78
+ """
79
+ with self.mp_lock:
80
+ mps_copy = set(self.metric_producers)
81
+ return mps_copy
.venv/lib/python3.11/site-packages/opencensus/metrics/export/point.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class Point(object):
17
+ """A timestamped measurement of a TimeSeries.
18
+
19
+ :type value: :class:`opencensus.metrics.export.value.ValueDouble` or
20
+ :class:`opencensus.metrics.export.value.ValueLong` or
21
+ :class:`opencensus.metrics.export.value.ValueSummary` or
22
+ :class:`opencensus.metrics.export.value.ValueDistribution`
23
+ :param value: the point value.
24
+
25
+ :type timestamp: time
26
+ :param timestamp: the timestamp when the `Point` was recorded.
27
+ """
28
+
29
+ def __init__(self, value, timestamp):
30
+ self._value = value
31
+ self._timestamp = timestamp
32
+
33
+ @property
34
+ def value(self):
35
+ return self._value
36
+
37
+ @property
38
+ def timestamp(self):
39
+ return self._timestamp
40
+
41
+ def __repr__(self):
42
+ return ("{}(value={}, timestamp={})"
43
+ .format(
44
+ type(self).__name__,
45
+ self.value,
46
+ self.timestamp
47
+ ))
.venv/lib/python3.11/site-packages/opencensus/metrics/export/summary.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class Summary(object):
17
+ """Implementation of the Summary as a summary of observations.
18
+
19
+ :type count: long
20
+ :param count: the count of the population values.
21
+
22
+ :type sum_data: float
23
+ :param sum_data: the sum of the population values.
24
+
25
+ :type snapshot: Snapshot
26
+ :param snapshot: the values calculated over a sliding time window.
27
+ """
28
+
29
+ def __init__(self, count, sum_data, snapshot):
30
+ check_count_and_sum(count, sum_data)
31
+ self._count = count
32
+ self._sum_data = sum_data
33
+
34
+ if snapshot is None:
35
+ raise ValueError('snapshot must not be none')
36
+
37
+ self._snapshot = snapshot
38
+
39
+ @property
40
+ def count(self):
41
+ """Returns the count of the population values"""
42
+ return self._count
43
+
44
+ @property
45
+ def sum_data(self):
46
+ """Returns the sum of the population values."""
47
+ return self._sum_data
48
+
49
+ @property
50
+ def snapshot(self):
51
+ """Returns the values calculated over a sliding time window."""
52
+ return self._snapshot
53
+
54
+
55
+ class Snapshot(object):
56
+ """Represents the summary observation of the recorded events over a
57
+ sliding time window.
58
+
59
+ :type count: long
60
+ :param count: the number of values in the snapshot.
61
+
62
+ :type sum_data: float
63
+ :param sum_data: the sum of values in the snapshot.
64
+
65
+ :type value_at_percentiles: ValueAtPercentile
66
+ :param value_at_percentiles: a list of values at different percentiles
67
+ of the distribution calculated from the current snapshot. The percentiles
68
+ must be strictly increasing.
69
+ """
70
+
71
+ def __init__(self, count, sum_data, value_at_percentiles=None):
72
+ check_count_and_sum(count, sum_data)
73
+ self._count = count
74
+ self._sum_data = sum_data
75
+
76
+ if value_at_percentiles is None:
77
+ value_at_percentiles = []
78
+
79
+ if not isinstance(value_at_percentiles, list):
80
+ raise ValueError('value_at_percentiles must be an '
81
+ 'instance of list')
82
+
83
+ self._value_at_percentiles = value_at_percentiles
84
+
85
+ @property
86
+ def count(self):
87
+ """Returns the number of values in the snapshot"""
88
+ return self._count
89
+
90
+ @property
91
+ def sum_data(self):
92
+ """Returns the sum of values in the snapshot."""
93
+ return self._sum_data
94
+
95
+ @property
96
+ def value_at_percentiles(self):
97
+ """Returns a list of values at different percentiles
98
+ of the distribution calculated from the current snapshot.
99
+ """
100
+ return self._value_at_percentiles
101
+
102
+
103
+ class ValueAtPercentile(object):
104
+ """Represents the value at a given percentile of a distribution.
105
+
106
+ :type percentile: float
107
+ :param percentile: the percentile in the ValueAtPercentile.
108
+
109
+ :type value: float
110
+ :param value: the value in the ValueAtPercentile.
111
+ """
112
+
113
+ def __init__(self, percentile, value):
114
+
115
+ if not 0 < percentile <= 100.0:
116
+ raise ValueError("percentile must be in the interval (0.0, 100.0]")
117
+
118
+ self._percentile = percentile
119
+
120
+ if value < 0:
121
+ raise ValueError('value must be non-negative')
122
+
123
+ self._value = value
124
+
125
+ @property
126
+ def percentile(self):
127
+ """Returns the percentile in the ValueAtPercentile"""
128
+ return self._percentile
129
+
130
+ @property
131
+ def value(self):
132
+ """Returns the value in the ValueAtPercentile"""
133
+ return self._value
134
+
135
+
136
+ def check_count_and_sum(count, sum_data):
137
+ if not (count is None or count >= 0):
138
+ raise ValueError('count must be non-negative')
139
+
140
+ if not (sum_data is None or sum_data >= 0):
141
+ raise ValueError('sum_data must be non-negative')
142
+
143
+ if count == 0 and sum_data != 0:
144
+ raise ValueError('sum_data must be 0 if count is 0')
.venv/lib/python3.11/site-packages/opencensus/metrics/export/time_series.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class TimeSeries(object):
17
+ """Time series data for a given metric and time interval.
18
+
19
+ This class implements the spec for v1 TimeSeries structs as of
20
+ opencensus-proto release v0.1.0. See opencensus-proto for details:
21
+
22
+ https://github.com/census-instrumentation/opencensus-proto/blob/v0.1.0/src/opencensus/proto/metrics/v1/metrics.proto#L132
23
+
24
+ A TimeSeries is a collection of data points that describes the time-varying
25
+ values of a metric.
26
+
27
+ :type label_values: list(:class:
28
+ '~opencensus.metrics.label_value.LabelValue')
29
+ :param label_values: The set of label values that uniquely identify this
30
+ timeseries.
31
+
32
+ :type points: list(:class: '~opencensus.metrics.export.point.Point')
33
+ :param points: The data points of this timeseries.
34
+
35
+ :type start_timestamp: str
36
+ :param start_timestamp: The time when the cumulative value was reset to
37
+ zero, must be set for cumulative metrics.
38
+ """ # noqa
39
+
40
+ def __init__(self, label_values, points, start_timestamp):
41
+ if label_values is None:
42
+ raise ValueError("label_values must not be None")
43
+ if not points:
44
+ raise ValueError("points must not be null or empty")
45
+ self._label_values = label_values
46
+ self._points = points
47
+ self._start_timestamp = start_timestamp
48
+
49
+ def __repr__(self):
50
+ points_repr = '[{}]'.format(
51
+ ', '.join(repr(point.value) for point in self.points))
52
+
53
+ lv_repr = tuple(lv.value for lv in self.label_values)
54
+ return ('{}({}, label_values={}, start_timestamp={})'
55
+ .format(
56
+ type(self).__name__,
57
+ points_repr,
58
+ lv_repr,
59
+ self.start_timestamp
60
+ ))
61
+
62
+ @property
63
+ def start_timestamp(self):
64
+ return self._start_timestamp
65
+
66
+ @property
67
+ def label_values(self):
68
+ return self._label_values
69
+
70
+ @property
71
+ def points(self):
72
+ return self._points
73
+
74
+ def check_points_type(self, type_class):
75
+ """Check that each point's value is an instance of `type_class`.
76
+
77
+ `type_class` should typically be a Value type, i.e. one that extends
78
+ :class: `opencensus.metrics.export.value.Value`.
79
+
80
+ :type type_class: type
81
+ :param type_class: Type to check against.
82
+
83
+ :rtype: bool
84
+ :return: Whether all points are instances of `type_class`.
85
+ """
86
+ for point in self.points:
87
+ if (point.value is not None
88
+ and not isinstance(point.value, type_class)):
89
+ return False
90
+ return True
.venv/lib/python3.11/site-packages/opencensus/metrics/export/value.py ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """
15
+ The classes in this module implement the spec for v1 Metrics as of
16
+ opencensus-proto release v0.1.0. See opencensus-proto for details:
17
+
18
+ https://github.com/census-instrumentation/opencensus-proto/blob/v0.1.0/src/opencensus/proto/metrics/v1/metrics.proto
19
+ """ # noqa
20
+
21
+ from copy import copy
22
+
23
+
24
+ class ValueDouble(object):
25
+ """A 64-bit double-precision floating-point number.
26
+
27
+ :type value: float
28
+ :param value: the value in float.
29
+ """
30
+
31
+ def __init__(self, value):
32
+ self._value = value
33
+
34
+ def __repr__(self):
35
+ return ("{}({})"
36
+ .format(
37
+ type(self).__name__,
38
+ self.value,
39
+ ))
40
+
41
+ @property
42
+ def value(self):
43
+ return self._value
44
+
45
+
46
+ class ValueLong(object):
47
+ """A 64-bit integer.
48
+
49
+ :type value: long
50
+ :param value: the value in long.
51
+ """
52
+
53
+ def __init__(self, value):
54
+ self._value = value
55
+
56
+ def __repr__(self):
57
+ return ("{}({})"
58
+ .format(
59
+ type(self).__name__,
60
+ self.value,
61
+ ))
62
+
63
+ @property
64
+ def value(self):
65
+ return self._value
66
+
67
+
68
+ class ValueSummary(object):
69
+ """Represents a snapshot values calculated over an arbitrary time window.
70
+
71
+ :type value: summary
72
+ :param value: the value in summary.
73
+ """
74
+
75
+ def __init__(self, value):
76
+ self._value = value
77
+
78
+ def __repr__(self):
79
+ return ("{}({})"
80
+ .format(
81
+ type(self).__name__,
82
+ self.value,
83
+ ))
84
+
85
+ @property
86
+ def value(self):
87
+ return self._value
88
+
89
+
90
+ class Exemplar(object):
91
+ """An example point to annotate a given value in a bucket.
92
+
93
+ Exemplars are example points that may be used to annotate aggregated
94
+ Distribution values. They are metadata that gives information about a
95
+ particular value added to a Distribution bucket.
96
+
97
+ :type value: double
98
+ :param value: Value of the exemplar point, determines which bucket the
99
+ exemplar belongs to.
100
+
101
+ :type timestamp: str
102
+ :param timestamp: The observation (sampling) time of the exemplar value.
103
+
104
+ :type attachments: dict(str, str)
105
+ :param attachments: Contextual information about the example value.
106
+ """
107
+
108
+ def __init__(self, value, timestamp, attachments):
109
+ self._value = value
110
+ self._timestamp = timestamp
111
+ self._attachments = attachments
112
+
113
+ def __repr__(self):
114
+ return ("{}({})"
115
+ .format(
116
+ type(self).__name__,
117
+ self.value,
118
+ ))
119
+
120
+ @property
121
+ def value(self):
122
+ return self._value
123
+
124
+ @property
125
+ def timestamp(self):
126
+ return self._timestamp
127
+
128
+ @property
129
+ def attachments(self):
130
+ return self._attachments
131
+
132
+
133
+ class Bucket(object):
134
+ """A bucket of a histogram.
135
+
136
+ :type count: int
137
+ :param count: The number of values in each bucket of the histogram.
138
+
139
+ :type exemplar: Exemplar
140
+ :param exemplar: Optional exemplar for this bucket, omit if the
141
+ distribution does not have a histogram.
142
+ """
143
+
144
+ def __init__(self, count, exemplar=None):
145
+ self._count = count
146
+ self._exemplar = exemplar
147
+
148
+ def __repr__(self):
149
+ return ("{}({})"
150
+ .format(
151
+ type(self).__name__,
152
+ self.count,
153
+ ))
154
+
155
+ @property
156
+ def count(self):
157
+ return self._count
158
+
159
+ @property
160
+ def exemplar(self):
161
+ return self._exemplar
162
+
163
+
164
+ class Explicit(object):
165
+ """Set of explicit bucket boundaries.
166
+
167
+ Specifies a set of buckets with arbitrary upper-bounds. This defines
168
+ size(bounds) + 1 (= N) buckets. The boundaries for bucket index i are:
169
+
170
+ - [0, bounds[i]) for i == 0
171
+ - [bounds[i-1], bounds[i]) for 0 < i < N-1
172
+ - [bounds[i-1], +infinity) for i == N-1
173
+ """
174
+
175
+ def __init__(self, bounds):
176
+ if not bounds:
177
+ raise ValueError("Bounds must not be null or empty")
178
+ if bounds != sorted(set(bounds)):
179
+ raise ValueError("Bounds must be strictly increasing")
180
+ if bounds[0] <= 0:
181
+ raise ValueError("Bounds must be positive")
182
+ self._bounds = bounds
183
+
184
+ @property
185
+ def bounds(self):
186
+ return copy(self._bounds)
187
+
188
+
189
+ class BucketOptions(object):
190
+ """Container for bucket options, including explicit boundaries.
191
+
192
+ A Distribution may optionally contain a histogram of the values in the
193
+ population. The bucket boundaries for that histogram are described by
194
+ BucketOptions.
195
+
196
+ If bucket_options has no type, then there is no histogram associated with
197
+ the Distribution.
198
+ """
199
+
200
+ def __init__(self, type_=None):
201
+ self._type = type_
202
+
203
+ def __repr__(self):
204
+ return ("{}({})"
205
+ .format(
206
+ type(self).__name__,
207
+ self.type_,
208
+ ))
209
+
210
+ @property
211
+ def type_(self):
212
+ return self._type
213
+
214
+
215
+ class ValueDistribution(object):
216
+ """Summary statistics for a population of values.
217
+
218
+ Distribution contains summary statistics for a population of values. It
219
+ optionally contains a histogram representing the distribution of those
220
+ values across a set of buckets.
221
+
222
+ :type count: int
223
+ :param count: The number of values in the population.
224
+
225
+ :type sum_: float
226
+ :param sum_: The sum of the values in the population.
227
+
228
+ :type sum_of_squared_deviation: float
229
+ :param sum_of_squared_deviation: The sum of squared deviations from the
230
+ mean of the values in the population.
231
+
232
+ :type bucket_options: :class: 'BucketOptions'
233
+ :param bucket_options: Bucket boundaries for the histogram of the values in
234
+ the population.
235
+
236
+ :type buckets: list(:class: 'Bucket')
237
+ :param buckets: Histogram buckets for the given bucket boundaries.
238
+ """
239
+
240
+ def __init__(self,
241
+ count,
242
+ sum_,
243
+ sum_of_squared_deviation,
244
+ bucket_options,
245
+ buckets=None):
246
+ if count < 0:
247
+ raise ValueError("count must be non-negative")
248
+ elif count == 0:
249
+ if sum_ != 0:
250
+ raise ValueError("sum_ must be 0 if count is 0")
251
+ if sum_of_squared_deviation != 0:
252
+ raise ValueError("sum_of_squared_deviation must be 0 if count "
253
+ "is 0")
254
+ if bucket_options is None:
255
+ raise ValueError("bucket_options must not be null")
256
+ if bucket_options.type_ is None:
257
+ if buckets is not None:
258
+ raise ValueError("buckets must be null if the distribution "
259
+ "has no histogram (i.e. bucket_options.type "
260
+ "is null)")
261
+ else:
262
+ if len(buckets) != len(bucket_options.type_.bounds) + 1:
263
+ # Note that this includes the implicit 0 and positive-infinity
264
+ # boundaries, so bounds [1, 2] implies three buckets: [[0, 1),
265
+ # [1, 2), [2, inf)].
266
+ raise ValueError("There must be one bucket for each pair of "
267
+ "boundaries")
268
+ if count != sum(bucket.count for bucket in buckets):
269
+ raise ValueError("The distribution count must equal the sum "
270
+ "of bucket counts")
271
+ self._count = count
272
+ self._sum = sum_
273
+ self._sum_of_squared_deviation = sum_of_squared_deviation
274
+ self._bucket_options = bucket_options
275
+ self._buckets = buckets
276
+
277
+ def __repr__(self):
278
+ try:
279
+ bounds = self.bucket_options.type_.bounds,
280
+ except AttributeError:
281
+ bounds = None
282
+
283
+ return ("{}({})"
284
+ .format(
285
+ type(self).__name__,
286
+ bounds
287
+ ))
288
+
289
+ @property
290
+ def count(self):
291
+ return self._count
292
+
293
+ @property
294
+ def sum(self):
295
+ return self._sum
296
+
297
+ @property
298
+ def sum_of_squared_deviation(self):
299
+ return self._sum_of_squared_deviation
300
+
301
+ @property
302
+ def bucket_options(self):
303
+ return self._bucket_options
304
+
305
+ @property
306
+ def buckets(self):
307
+ return self._buckets
.venv/lib/python3.11/site-packages/opencensus/metrics/label_key.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class LabelKey(object):
17
+ """The label keys associated with the metric descriptor.
18
+
19
+ :type key: str
20
+ :param key: the key for the label
21
+
22
+ :type description: str
23
+ :param description: description of the label
24
+ """
25
+ def __init__(self, key, description):
26
+ self._key = key
27
+ self._description = description
28
+
29
+ def __repr__(self):
30
+ if self.description:
31
+ return ('{}({}, description="{}")'
32
+ .format(
33
+ type(self).__name__,
34
+ self.key,
35
+ self.description
36
+ ))
37
+ return ("{}({})"
38
+ .format(
39
+ type(self).__name__,
40
+ self.key,
41
+ ))
42
+
43
+ @property
44
+ def key(self):
45
+ """the key for the label"""
46
+ return self._key
47
+
48
+ @property
49
+ def description(self):
50
+ """a human-readable description of what this label key represents"""
51
+ return self._description
.venv/lib/python3.11/site-packages/opencensus/metrics/transport.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019, OpenCensus Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import itertools
16
+ import logging
17
+
18
+ from opencensus.common import utils
19
+ from opencensus.common.schedule import PeriodicTask
20
+ from opencensus.trace import execution_context
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+ DEFAULT_INTERVAL = 60
25
+ GRACE_PERIOD = 5
26
+
27
+
28
+ class TransportError(Exception):
29
+ pass
30
+
31
+
32
+ class PeriodicMetricTask(PeriodicTask):
33
+ """Thread that periodically calls a given function.
34
+
35
+ :type interval: int or float
36
+ :param interval: Seconds between calls to the function.
37
+
38
+ :type function: function
39
+ :param function: The function to call.
40
+
41
+ :type args: list
42
+ :param args: The args passed in while calling `function`.
43
+
44
+ :type kwargs: dict
45
+ :param args: The kwargs passed in while calling `function`.
46
+
47
+ :type name: str
48
+ :param name: The source of the worker. Used for naming.
49
+ """
50
+
51
+ daemon = True
52
+
53
+ def __init__(
54
+ self,
55
+ interval=None,
56
+ function=None,
57
+ args=None,
58
+ kwargs=None,
59
+ name=None
60
+ ):
61
+ if interval is None:
62
+ interval = DEFAULT_INTERVAL
63
+
64
+ self.func = function
65
+ self.args = args
66
+ self.kwargs = kwargs
67
+
68
+ def func(*aa, **kw):
69
+ try:
70
+ return self.func(*aa, **kw)
71
+ except TransportError as ex:
72
+ logger.exception(ex)
73
+ self.cancel()
74
+ except Exception as ex:
75
+ logger.exception("Error handling metric export: {}".format(ex))
76
+
77
+ super(PeriodicMetricTask, self).__init__(
78
+ interval, func, args, kwargs, '{} Worker'.format(name)
79
+ )
80
+
81
+ def run(self):
82
+ # Indicate that this thread is an exporter thread.
83
+ # Used to suppress tracking of requests in this thread
84
+ execution_context.set_is_exporter(True)
85
+ super(PeriodicMetricTask, self).run()
86
+
87
+ def close(self):
88
+ try:
89
+ # Suppress request tracking on flush
90
+ execution_context.set_is_exporter(True)
91
+ self.func(*self.args, **self.kwargs)
92
+ execution_context.set_is_exporter(False)
93
+ except Exception as ex:
94
+ logger.exception("Error handling metric flush: {}".format(ex))
95
+ self.cancel()
96
+
97
+
98
+ def get_exporter_thread(metric_producers, exporter, interval=None):
99
+ """Get a running task that periodically exports metrics.
100
+
101
+ Get a `PeriodicTask` that periodically calls:
102
+
103
+ export(itertools.chain(*all_gets))
104
+
105
+ where all_gets is the concatenation of all metrics produced by the metric
106
+ producers in metric_producers, each calling metric_producer.get_metrics()
107
+
108
+ :type metric_producers:
109
+ list(:class:`opencensus.metrics.export.metric_producer.MetricProducer`)
110
+ :param metric_producers: The list of metric producers to use to get metrics
111
+
112
+ :type exporter: :class:`opencensus.stats.base_exporter.MetricsExporter`
113
+ :param exporter: The exporter to use to export metrics.
114
+
115
+ :type interval: int or float
116
+ :param interval: Seconds between export calls.
117
+
118
+ :rtype: :class:`PeriodicTask`
119
+ :return: A running thread responsible calling the exporter.
120
+
121
+ """
122
+ weak_gets = [utils.get_weakref(producer.get_metrics)
123
+ for producer in metric_producers]
124
+ weak_export = utils.get_weakref(exporter.export_metrics)
125
+
126
+ def export_all():
127
+ all_gets = []
128
+ for weak_get in weak_gets:
129
+ get = weak_get()
130
+ if get is None:
131
+ raise TransportError("Metric producer is not available")
132
+ all_gets.append(get())
133
+ export = weak_export()
134
+ if export is None:
135
+ raise TransportError("Metric exporter is not available")
136
+
137
+ export(itertools.chain(*all_gets))
138
+
139
+ tt = PeriodicMetricTask(
140
+ interval,
141
+ export_all,
142
+ name=exporter.__class__.__name__
143
+ )
144
+ tt.start()
145
+ return tt
.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (197 Bytes). View file
 
.venv/lib/python3.11/site-packages/proto/__init__.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .enums import Enum
16
+ from .fields import Field
17
+ from .fields import MapField
18
+ from .fields import RepeatedField
19
+ from .marshal import Marshal
20
+ from .message import Message
21
+ from .modules import define_module as module
22
+ from .primitives import ProtoType
23
+ from .version import __version__
24
+
25
+
26
+ DOUBLE = ProtoType.DOUBLE
27
+ FLOAT = ProtoType.FLOAT
28
+ INT64 = ProtoType.INT64
29
+ UINT64 = ProtoType.UINT64
30
+ INT32 = ProtoType.INT32
31
+ FIXED64 = ProtoType.FIXED64
32
+ FIXED32 = ProtoType.FIXED32
33
+ BOOL = ProtoType.BOOL
34
+ STRING = ProtoType.STRING
35
+ MESSAGE = ProtoType.MESSAGE
36
+ BYTES = ProtoType.BYTES
37
+ UINT32 = ProtoType.UINT32
38
+ ENUM = ProtoType.ENUM
39
+ SFIXED32 = ProtoType.SFIXED32
40
+ SFIXED64 = ProtoType.SFIXED64
41
+ SINT32 = ProtoType.SINT32
42
+ SINT64 = ProtoType.SINT64
43
+
44
+
45
+ __all__ = (
46
+ "__version__",
47
+ "Enum",
48
+ "Field",
49
+ "MapField",
50
+ "RepeatedField",
51
+ "Marshal",
52
+ "Message",
53
+ "module",
54
+ # Expose the types directly.
55
+ "DOUBLE",
56
+ "FLOAT",
57
+ "INT64",
58
+ "UINT64",
59
+ "INT32",
60
+ "FIXED64",
61
+ "FIXED32",
62
+ "BOOL",
63
+ "STRING",
64
+ "MESSAGE",
65
+ "BYTES",
66
+ "UINT32",
67
+ "ENUM",
68
+ "SFIXED32",
69
+ "SFIXED64",
70
+ "SINT32",
71
+ "SINT64",
72
+ )
.venv/lib/python3.11/site-packages/proto/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (1.33 kB). View file
 
.venv/lib/python3.11/site-packages/proto/__pycache__/datetime_helpers.cpython-311.pyc ADDED
Binary file (8.82 kB). View file
 
.venv/lib/python3.11/site-packages/proto/__pycache__/enums.cpython-311.pyc ADDED
Binary file (7.04 kB). View file
 
.venv/lib/python3.11/site-packages/proto/__pycache__/fields.cpython-311.pyc ADDED
Binary file (5.49 kB). View file
 
.venv/lib/python3.11/site-packages/proto/enums.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2019 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import enum
16
+
17
+ from google.protobuf import descriptor_pb2
18
+
19
+ from proto import _file_info
20
+ from proto import _package_info
21
+ from proto.marshal.rules.enums import EnumRule
22
+
23
+
24
+ class ProtoEnumMeta(enum.EnumMeta):
25
+ """A metaclass for building and registering protobuf enums."""
26
+
27
+ def __new__(mcls, name, bases, attrs):
28
+ # Do not do any special behavior for `proto.Enum` itself.
29
+ if bases[0] == enum.IntEnum:
30
+ return super().__new__(mcls, name, bases, attrs)
31
+
32
+ # Get the essential information about the proto package, and where
33
+ # this component belongs within the file.
34
+ package, marshal = _package_info.compile(name, attrs)
35
+
36
+ # Determine the local path of this proto component within the file.
37
+ local_path = tuple(attrs.get("__qualname__", name).split("."))
38
+
39
+ # Sanity check: We get the wrong full name if a class is declared
40
+ # inside a function local scope; correct this.
41
+ if "<locals>" in local_path:
42
+ ix = local_path.index("<locals>")
43
+ local_path = local_path[: ix - 1] + local_path[ix + 1 :]
44
+
45
+ # Determine the full name in protocol buffers.
46
+ full_name = ".".join((package,) + local_path).lstrip(".")
47
+ filename = _file_info._FileInfo.proto_file_name(
48
+ attrs.get("__module__", name.lower())
49
+ )
50
+
51
+ # Retrieve any enum options.
52
+ # We expect something that looks like an EnumOptions message,
53
+ # either an actual instance or a dict-like representation.
54
+ pb_options = "_pb_options"
55
+ opts = attrs.pop(pb_options, {})
56
+ # This is the only portable way to remove the _pb_options name
57
+ # from the enum attrs.
58
+ # In 3.7 onwards, we can define an _ignore_ attribute and do some
59
+ # mucking around with that.
60
+ if pb_options in attrs._member_names:
61
+ if isinstance(attrs._member_names, list):
62
+ idx = attrs._member_names.index(pb_options)
63
+ attrs._member_names.pop(idx)
64
+ else: # Python 3.11.0b3
65
+ del attrs._member_names[pb_options]
66
+
67
+ # Make the descriptor.
68
+ enum_desc = descriptor_pb2.EnumDescriptorProto(
69
+ name=name,
70
+ # Note: the superclass ctor removes the variants, so get them now.
71
+ # Note: proto3 requires that the first variant value be zero.
72
+ value=sorted(
73
+ (
74
+ descriptor_pb2.EnumValueDescriptorProto(name=name, number=number)
75
+ # Minor hack to get all the enum variants out.
76
+ # Use the `_member_names` property to get only the enum members
77
+ # See https://github.com/googleapis/proto-plus-python/issues/490
78
+ for name, number in attrs.items()
79
+ if name in attrs._member_names and isinstance(number, int)
80
+ ),
81
+ key=lambda v: v.number,
82
+ ),
83
+ options=opts,
84
+ )
85
+
86
+ file_info = _file_info._FileInfo.maybe_add_descriptor(filename, package)
87
+ if len(local_path) == 1:
88
+ file_info.descriptor.enum_type.add().MergeFrom(enum_desc)
89
+ else:
90
+ file_info.nested_enum[local_path] = enum_desc
91
+
92
+ # Run the superclass constructor.
93
+ cls = super().__new__(mcls, name, bases, attrs)
94
+
95
+ # We can't just add a "_meta" element to attrs because the Enum
96
+ # machinery doesn't know what to do with a non-int value.
97
+ # The pb is set later, in generate_file_pb
98
+ cls._meta = _EnumInfo(full_name=full_name, pb=None)
99
+
100
+ file_info.enums[full_name] = cls
101
+
102
+ # Register the enum with the marshal.
103
+ marshal.register(cls, EnumRule(cls))
104
+
105
+ # Generate the descriptor for the file if it is ready.
106
+ if file_info.ready(new_class=cls):
107
+ file_info.generate_file_pb(new_class=cls, fallback_salt=full_name)
108
+
109
+ # Done; return the class.
110
+ return cls
111
+
112
+
113
+ class Enum(enum.IntEnum, metaclass=ProtoEnumMeta):
114
+ """A enum object that also builds a protobuf enum descriptor."""
115
+
116
+ def _comparable(self, other):
117
+ # Avoid 'isinstance' to prevent other IntEnums from matching
118
+ return type(other) in (type(self), int)
119
+
120
+ def __hash__(self):
121
+ return hash(self.value)
122
+
123
+ def __eq__(self, other):
124
+ if not self._comparable(other):
125
+ return NotImplemented
126
+
127
+ return self.value == int(other)
128
+
129
+ def __ne__(self, other):
130
+ if not self._comparable(other):
131
+ return NotImplemented
132
+
133
+ return self.value != int(other)
134
+
135
+ def __lt__(self, other):
136
+ if not self._comparable(other):
137
+ return NotImplemented
138
+
139
+ return self.value < int(other)
140
+
141
+ def __le__(self, other):
142
+ if not self._comparable(other):
143
+ return NotImplemented
144
+
145
+ return self.value <= int(other)
146
+
147
+ def __ge__(self, other):
148
+ if not self._comparable(other):
149
+ return NotImplemented
150
+
151
+ return self.value >= int(other)
152
+
153
+ def __gt__(self, other):
154
+ if not self._comparable(other):
155
+ return NotImplemented
156
+
157
+ return self.value > int(other)
158
+
159
+
160
+ class _EnumInfo:
161
+ def __init__(self, *, full_name: str, pb):
162
+ self.full_name = full_name
163
+ self.pb = pb
.venv/lib/python3.11/site-packages/proto/marshal/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .marshal import Marshal
16
+
17
+
18
+ __all__ = ("Marshal",)
.venv/lib/python3.11/site-packages/proto/marshal/collections/__init__.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .maps import MapComposite
16
+ from .repeated import Repeated
17
+ from .repeated import RepeatedComposite
18
+
19
+
20
+ __all__ = (
21
+ "MapComposite",
22
+ "Repeated",
23
+ "RepeatedComposite",
24
+ )
.venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/maps.cpython-311.pyc ADDED
Binary file (3.59 kB). View file
 
.venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/repeated.cpython-311.pyc ADDED
Binary file (9.05 kB). View file
 
.venv/lib/python3.11/site-packages/proto/marshal/collections/maps.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import collections
16
+
17
+ from proto.utils import cached_property
18
+ from google.protobuf.message import Message
19
+
20
+
21
+ class MapComposite(collections.abc.MutableMapping):
22
+ """A view around a mutable sequence in protocol buffers.
23
+
24
+ This implements the full Python MutableMapping interface, but all methods
25
+ modify the underlying field container directly.
26
+ """
27
+
28
+ @cached_property
29
+ def _pb_type(self):
30
+ """Return the protocol buffer type for this sequence."""
31
+ # Huzzah, another hack. Still less bad than RepeatedComposite.
32
+ return type(self.pb.GetEntryClass()().value)
33
+
34
+ def __init__(self, sequence, *, marshal):
35
+ """Initialize a wrapper around a protobuf map.
36
+
37
+ Args:
38
+ sequence: A protocol buffers map.
39
+ marshal (~.MarshalRegistry): An instantiated marshal, used to
40
+ convert values going to and from this map.
41
+ """
42
+ self._pb = sequence
43
+ self._marshal = marshal
44
+
45
+ def __contains__(self, key):
46
+ # Protocol buffers is so permissive that querying for the existence
47
+ # of a key will in of itself create it.
48
+ #
49
+ # By taking a tuple of the keys and querying that, we avoid sending
50
+ # the lookup to protocol buffers and therefore avoid creating the key.
51
+ return key in tuple(self.keys())
52
+
53
+ def __getitem__(self, key):
54
+ # We handle raising KeyError ourselves, because otherwise protocol
55
+ # buffers will create the key if it does not exist.
56
+ if key not in self:
57
+ raise KeyError(key)
58
+ return self._marshal.to_python(self._pb_type, self.pb[key])
59
+
60
+ def __setitem__(self, key, value):
61
+ pb_value = self._marshal.to_proto(self._pb_type, value, strict=True)
62
+ # Directly setting a key is not allowed; however, protocol buffers
63
+ # is so permissive that querying for the existence of a key will in
64
+ # of itself create it.
65
+ #
66
+ # Therefore, we create a key that way (clearing any fields that may
67
+ # be set) and then merge in our values.
68
+ self.pb[key].Clear()
69
+ self.pb[key].MergeFrom(pb_value)
70
+
71
+ def __delitem__(self, key):
72
+ self.pb.pop(key)
73
+
74
+ def __len__(self):
75
+ return len(self.pb)
76
+
77
+ def __iter__(self):
78
+ return iter(self.pb)
79
+
80
+ @property
81
+ def pb(self):
82
+ return self._pb
.venv/lib/python3.11/site-packages/proto/marshal/collections/repeated.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import collections
16
+ import copy
17
+ from typing import Iterable
18
+
19
+ from proto.utils import cached_property
20
+
21
+
22
+ class Repeated(collections.abc.MutableSequence):
23
+ """A view around a mutable sequence in protocol buffers.
24
+
25
+ This implements the full Python MutableSequence interface, but all methods
26
+ modify the underlying field container directly.
27
+ """
28
+
29
+ def __init__(self, sequence, *, marshal, proto_type=None):
30
+ """Initialize a wrapper around a protobuf repeated field.
31
+
32
+ Args:
33
+ sequence: A protocol buffers repeated field.
34
+ marshal (~.MarshalRegistry): An instantiated marshal, used to
35
+ convert values going to and from this map.
36
+ """
37
+ self._pb = sequence
38
+ self._marshal = marshal
39
+ self._proto_type = proto_type
40
+
41
+ def __copy__(self):
42
+ """Copy this object and return the copy."""
43
+ return type(self)(self.pb[:], marshal=self._marshal)
44
+
45
+ def __delitem__(self, key):
46
+ """Delete the given item."""
47
+ del self.pb[key]
48
+
49
+ def __eq__(self, other):
50
+ if hasattr(other, "pb"):
51
+ return tuple(self.pb) == tuple(other.pb)
52
+ return tuple(self.pb) == tuple(other) if isinstance(other, Iterable) else False
53
+
54
+ def __getitem__(self, key):
55
+ """Return the given item."""
56
+ return self.pb[key]
57
+
58
+ def __len__(self):
59
+ """Return the length of the sequence."""
60
+ return len(self.pb)
61
+
62
+ def __ne__(self, other):
63
+ return not self == other
64
+
65
+ def __repr__(self):
66
+ return repr([*self])
67
+
68
+ def __setitem__(self, key, value):
69
+ self.pb[key] = value
70
+
71
+ def insert(self, index: int, value):
72
+ """Insert ``value`` in the sequence before ``index``."""
73
+ self.pb.insert(index, value)
74
+
75
+ def sort(self, *, key: str = None, reverse: bool = False):
76
+ """Stable sort *IN PLACE*."""
77
+ self.pb.sort(key=key, reverse=reverse)
78
+
79
+ @property
80
+ def pb(self):
81
+ return self._pb
82
+
83
+
84
+ class RepeatedComposite(Repeated):
85
+ """A view around a mutable sequence of messages in protocol buffers.
86
+
87
+ This implements the full Python MutableSequence interface, but all methods
88
+ modify the underlying field container directly.
89
+ """
90
+
91
+ @cached_property
92
+ def _pb_type(self):
93
+ """Return the protocol buffer type for this sequence."""
94
+ # Provide the marshal-given proto_type, if any.
95
+ # Used for RepeatedComposite of Enum.
96
+ if self._proto_type is not None:
97
+ return self._proto_type
98
+
99
+ # There is no public-interface mechanism to determine the type
100
+ # of what should go in the list (and the C implementation seems to
101
+ # have no exposed mechanism at all).
102
+ #
103
+ # If the list has members, use the existing list members to
104
+ # determine the type.
105
+ if len(self.pb) > 0:
106
+ return type(self.pb[0])
107
+
108
+ # We have no members in the list, so we get the type from the attributes.
109
+ if hasattr(self.pb, "_message_descriptor") and hasattr(
110
+ self.pb._message_descriptor, "_concrete_class"
111
+ ):
112
+ return self.pb._message_descriptor._concrete_class
113
+
114
+ # Fallback logic in case attributes are not available
115
+ # In order to get the type, we create a throw-away copy and add a
116
+ # blank member to it.
117
+ canary = copy.deepcopy(self.pb).add()
118
+ return type(canary)
119
+
120
+ def __eq__(self, other):
121
+ if super().__eq__(other):
122
+ return True
123
+ return (
124
+ tuple([i for i in self]) == tuple(other)
125
+ if isinstance(other, Iterable)
126
+ else False
127
+ )
128
+
129
+ def __getitem__(self, key):
130
+ return self._marshal.to_python(self._pb_type, self.pb[key])
131
+
132
+ def __setitem__(self, key, value):
133
+ # The underlying protocol buffer does not define __setitem__, so we
134
+ # have to implement all the operations on our own.
135
+
136
+ # If ``key`` is an integer, as in list[index] = value:
137
+ if isinstance(key, int):
138
+ if -len(self) <= key < len(self):
139
+ self.pop(key) # Delete the old item.
140
+ self.insert(key, value) # Insert the new item in its place.
141
+ else:
142
+ raise IndexError("list assignment index out of range")
143
+
144
+ # If ``key`` is a slice object, as in list[start:stop:step] = [values]:
145
+ elif isinstance(key, slice):
146
+ start, stop, step = key.indices(len(self))
147
+
148
+ if not isinstance(value, collections.abc.Iterable):
149
+ raise TypeError("can only assign an iterable")
150
+
151
+ if step == 1: # Is not an extended slice.
152
+ # Assign all the new values to the sliced part, replacing the
153
+ # old values, if any, and unconditionally inserting those
154
+ # values whose indices already exceed the slice length.
155
+ for index, item in enumerate(value):
156
+ if start + index < stop:
157
+ self.pop(start + index)
158
+ self.insert(start + index, item)
159
+
160
+ # If there are less values than the length of the slice, remove
161
+ # the remaining elements so that the slice adapts to the
162
+ # newly provided values.
163
+ for _ in range(stop - start - len(value)):
164
+ self.pop(start + len(value))
165
+
166
+ else: # Is an extended slice.
167
+ indices = range(start, stop, step)
168
+
169
+ if len(value) != len(indices): # XXX: Use PEP 572 on 3.8+
170
+ raise ValueError(
171
+ f"attempt to assign sequence of size "
172
+ f"{len(value)} to extended slice of size "
173
+ f"{len(indices)}"
174
+ )
175
+
176
+ # Assign each value to its index, calling this function again
177
+ # with individual integer indexes that get processed above.
178
+ for index, item in zip(indices, value):
179
+ self[index] = item
180
+
181
+ else:
182
+ raise TypeError(
183
+ f"list indices must be integers or slices, not {type(key).__name__}"
184
+ )
185
+
186
+ def insert(self, index: int, value):
187
+ """Insert ``value`` in the sequence before ``index``."""
188
+ pb_value = self._marshal.to_proto(self._pb_type, value)
189
+ self.pb.insert(index, pb_value)
.venv/lib/python3.11/site-packages/proto/marshal/compat.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # This file pulls in the container types from internal protocol buffers,
16
+ # and exports the types available.
17
+ #
18
+ # If the C extensions were not installed, then their container types will
19
+ # not be included.
20
+
21
+ from google.protobuf.internal import containers
22
+
23
+ # Import all message types to ensure that pyext types are recognized
24
+ # when upb types exist. Conda's protobuf defaults to pyext despite upb existing.
25
+ # See https://github.com/googleapis/proto-plus-python/issues/470
26
+ try:
27
+ from google._upb import _message as _message_upb
28
+ except ImportError:
29
+ _message_upb = None
30
+
31
+ try:
32
+ from google.protobuf.pyext import _message as _message_pyext
33
+ except ImportError:
34
+ _message_pyext = None
35
+
36
+
37
+ repeated_composite_types = (containers.RepeatedCompositeFieldContainer,)
38
+ repeated_scalar_types = (containers.RepeatedScalarFieldContainer,)
39
+ map_composite_types = (containers.MessageMap,)
40
+
41
+ # In `proto/marshal.py`, for compatibility with protobuf 5.x,
42
+ # we'll use `map_composite_type_names` to check whether
43
+ # the name of the class of a protobuf type is
44
+ # `MessageMapContainer`, and, if `True`, return a MapComposite.
45
+ # See https://github.com/protocolbuffers/protobuf/issues/16596
46
+ map_composite_type_names = ("MessageMapContainer",)
47
+
48
+ for message in [_message_upb, _message_pyext]:
49
+ if message:
50
+ repeated_composite_types += (message.RepeatedCompositeContainer,)
51
+ repeated_scalar_types += (message.RepeatedScalarContainer,)
52
+
53
+ try:
54
+ map_composite_types += (message.MessageMapContainer,)
55
+ except AttributeError:
56
+ # The `MessageMapContainer` attribute is not available in Protobuf 5.x+
57
+ pass
58
+
59
+ __all__ = (
60
+ "repeated_composite_types",
61
+ "repeated_scalar_types",
62
+ "map_composite_types",
63
+ "map_composite_type_names",
64
+ )
.venv/lib/python3.11/site-packages/proto/marshal/marshal.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import abc
16
+ import enum
17
+
18
+ from google.protobuf import message
19
+ from google.protobuf import duration_pb2
20
+ from google.protobuf import timestamp_pb2
21
+ from google.protobuf import field_mask_pb2
22
+ from google.protobuf import struct_pb2
23
+ from google.protobuf import wrappers_pb2
24
+
25
+ from proto.marshal import compat
26
+ from proto.marshal.collections import MapComposite
27
+ from proto.marshal.collections import Repeated
28
+ from proto.marshal.collections import RepeatedComposite
29
+
30
+ from proto.marshal.rules import bytes as pb_bytes
31
+ from proto.marshal.rules import stringy_numbers
32
+ from proto.marshal.rules import dates
33
+ from proto.marshal.rules import struct
34
+ from proto.marshal.rules import wrappers
35
+ from proto.marshal.rules import field_mask
36
+ from proto.primitives import ProtoType
37
+
38
+
39
+ class Rule(abc.ABC):
40
+ """Abstract class definition for marshal rules."""
41
+
42
+ @classmethod
43
+ def __subclasshook__(cls, C):
44
+ if hasattr(C, "to_python") and hasattr(C, "to_proto"):
45
+ return True
46
+ return NotImplemented
47
+
48
+
49
+ class BaseMarshal:
50
+ """The base class to translate between protobuf and Python classes.
51
+
52
+ Protocol buffers defines many common types (e.g. Timestamp, Duration)
53
+ which also exist in the Python standard library. The marshal essentially
54
+ translates between these: it keeps a registry of common protocol buffers
55
+ and their Python representations, and translates back and forth.
56
+
57
+ The protocol buffer class is always the "key" in this relationship; when
58
+ presenting a message, the declared field types are used to determine
59
+ whether a value should be transformed into another class. Similarly,
60
+ when accepting a Python value (when setting a field, for example),
61
+ the declared field type is still used. This means that, if appropriate,
62
+ multiple protocol buffer types may use the same Python type.
63
+
64
+ The primary implementation of this is :class:`Marshal`, which should
65
+ usually be used instead of this class directly.
66
+ """
67
+
68
+ def __init__(self):
69
+ self._rules = {}
70
+ self._noop = NoopRule()
71
+ self.reset()
72
+
73
+ def register(self, proto_type: type, rule: Rule = None):
74
+ """Register a rule against the given ``proto_type``.
75
+
76
+ This function expects a ``proto_type`` (the descriptor class) and
77
+ a ``rule``; an object with a ``to_python`` and ``to_proto`` method.
78
+ Each method should return the appropriate Python or protocol buffer
79
+ type, and be idempotent (e.g. accept either type as input).
80
+
81
+ This function can also be used as a decorator::
82
+
83
+ @marshal.register(timestamp_pb2.Timestamp)
84
+ class TimestampRule:
85
+ ...
86
+
87
+ In this case, the class will be initialized for you with zero
88
+ arguments.
89
+
90
+ Args:
91
+ proto_type (type): A protocol buffer message type.
92
+ rule: A marshal object
93
+ """
94
+ # If a rule was provided, register it and be done.
95
+ if rule:
96
+ # Ensure the rule implements Rule.
97
+ if not isinstance(rule, Rule):
98
+ raise TypeError(
99
+ "Marshal rule instances must implement "
100
+ "`to_proto` and `to_python` methods."
101
+ )
102
+
103
+ # Register the rule.
104
+ self._rules[proto_type] = rule
105
+ return
106
+
107
+ # Create an inner function that will register an instance of the
108
+ # marshal class to this object's registry, and return it.
109
+ def register_rule_class(rule_class: type):
110
+ # Ensure the rule class is a valid rule.
111
+ if not issubclass(rule_class, Rule):
112
+ raise TypeError(
113
+ "Marshal rule subclasses must implement "
114
+ "`to_proto` and `to_python` methods."
115
+ )
116
+
117
+ # Register the rule class.
118
+ self._rules[proto_type] = rule_class()
119
+ return rule_class
120
+
121
+ return register_rule_class
122
+
123
+ def reset(self):
124
+ """Reset the registry to its initial state."""
125
+ self._rules.clear()
126
+
127
+ # Register date and time wrappers.
128
+ self.register(timestamp_pb2.Timestamp, dates.TimestampRule())
129
+ self.register(duration_pb2.Duration, dates.DurationRule())
130
+
131
+ # Register FieldMask wrappers.
132
+ self.register(field_mask_pb2.FieldMask, field_mask.FieldMaskRule())
133
+
134
+ # Register nullable primitive wrappers.
135
+ self.register(wrappers_pb2.BoolValue, wrappers.BoolValueRule())
136
+ self.register(wrappers_pb2.BytesValue, wrappers.BytesValueRule())
137
+ self.register(wrappers_pb2.DoubleValue, wrappers.DoubleValueRule())
138
+ self.register(wrappers_pb2.FloatValue, wrappers.FloatValueRule())
139
+ self.register(wrappers_pb2.Int32Value, wrappers.Int32ValueRule())
140
+ self.register(wrappers_pb2.Int64Value, wrappers.Int64ValueRule())
141
+ self.register(wrappers_pb2.StringValue, wrappers.StringValueRule())
142
+ self.register(wrappers_pb2.UInt32Value, wrappers.UInt32ValueRule())
143
+ self.register(wrappers_pb2.UInt64Value, wrappers.UInt64ValueRule())
144
+
145
+ # Register the google.protobuf.Struct wrappers.
146
+ #
147
+ # These are aware of the marshal that created them, because they
148
+ # create RepeatedComposite and MapComposite instances directly and
149
+ # need to pass the marshal to them.
150
+ self.register(struct_pb2.Value, struct.ValueRule(marshal=self))
151
+ self.register(struct_pb2.ListValue, struct.ListValueRule(marshal=self))
152
+ self.register(struct_pb2.Struct, struct.StructRule(marshal=self))
153
+
154
+ # Special case for bytes to allow base64 encode/decode
155
+ self.register(ProtoType.BYTES, pb_bytes.BytesRule())
156
+
157
+ # Special case for int64 from strings because of dict round trip.
158
+ # See https://github.com/protocolbuffers/protobuf/issues/2679
159
+ for rule_class in stringy_numbers.STRINGY_NUMBER_RULES:
160
+ self.register(rule_class._proto_type, rule_class())
161
+
162
+ def get_rule(self, proto_type):
163
+ # Rules are needed to convert values between proto-plus and pb.
164
+ # Retrieve the rule for the specified proto type.
165
+ # The NoopRule will be used when a rule is not found.
166
+ rule = self._rules.get(proto_type, self._noop)
167
+
168
+ # If we don't find a rule, also check under `_instances`
169
+ # in case there is a rule in another package.
170
+ # See https://github.com/googleapis/proto-plus-python/issues/349
171
+ if rule == self._noop and hasattr(self, "_instances"):
172
+ for _, instance in self._instances.items():
173
+ rule = instance._rules.get(proto_type, self._noop)
174
+ if rule != self._noop:
175
+ break
176
+ return rule
177
+
178
+ def to_python(self, proto_type, value, *, absent: bool = None):
179
+ # Internal protobuf has its own special type for lists of values.
180
+ # Return a view around it that implements MutableSequence.
181
+ value_type = type(value) # Minor performance boost over isinstance
182
+ if value_type in compat.repeated_composite_types:
183
+ return RepeatedComposite(value, marshal=self)
184
+ if value_type in compat.repeated_scalar_types:
185
+ if isinstance(proto_type, type):
186
+ return RepeatedComposite(value, marshal=self, proto_type=proto_type)
187
+ else:
188
+ return Repeated(value, marshal=self)
189
+
190
+ # Same thing for maps of messages.
191
+ # See https://github.com/protocolbuffers/protobuf/issues/16596
192
+ # We need to look up the name of the type in compat.map_composite_type_names
193
+ # as class `MessageMapContainer` is no longer exposed
194
+ # This is done to avoid taking a breaking change in proto-plus.
195
+ if (
196
+ value_type in compat.map_composite_types
197
+ or value_type.__name__ in compat.map_composite_type_names
198
+ ):
199
+ return MapComposite(value, marshal=self)
200
+ return self.get_rule(proto_type=proto_type).to_python(value, absent=absent)
201
+
202
+ def to_proto(self, proto_type, value, *, strict: bool = False):
203
+ # The protos in google/protobuf/struct.proto are exceptional cases,
204
+ # because they can and should represent themselves as lists and dicts.
205
+ # These cases are handled in their rule classes.
206
+ if proto_type not in (
207
+ struct_pb2.Value,
208
+ struct_pb2.ListValue,
209
+ struct_pb2.Struct,
210
+ ):
211
+ # For our repeated and map view objects, simply return the
212
+ # underlying pb.
213
+ if isinstance(value, (Repeated, MapComposite)):
214
+ return value.pb
215
+
216
+ # Convert lists and tuples recursively.
217
+ if isinstance(value, (list, tuple)):
218
+ return type(value)(self.to_proto(proto_type, i) for i in value)
219
+
220
+ # Convert dictionaries recursively when the proto type is a map.
221
+ # This is slightly more complicated than converting a list or tuple
222
+ # because we have to step through the magic that protocol buffers does.
223
+ #
224
+ # Essentially, a type of map<string, Foo> will show up here as
225
+ # a FoosEntry with a `key` field, `value` field, and a `map_entry`
226
+ # annotation. We need to do the conversion based on the `value`
227
+ # field's type.
228
+ if isinstance(value, dict) and (
229
+ proto_type.DESCRIPTOR.has_options
230
+ and proto_type.DESCRIPTOR.GetOptions().map_entry
231
+ ):
232
+ recursive_type = type(proto_type().value)
233
+ return {k: self.to_proto(recursive_type, v) for k, v in value.items()}
234
+
235
+ pb_value = self.get_rule(proto_type=proto_type).to_proto(value)
236
+
237
+ # Sanity check: If we are in strict mode, did we get the value we want?
238
+ if strict and not isinstance(pb_value, proto_type):
239
+ raise TypeError(
240
+ "Parameter must be instance of the same class; "
241
+ "expected {expected}, got {got}".format(
242
+ expected=proto_type.__name__,
243
+ got=pb_value.__class__.__name__,
244
+ ),
245
+ )
246
+ # Return the final value.
247
+ return pb_value
248
+
249
+
250
+ class Marshal(BaseMarshal):
251
+ """The translator between protocol buffer and Python instances.
252
+
253
+ The bulk of the implementation is in :class:`BaseMarshal`. This class
254
+ adds identity tracking: multiple instantiations of :class:`Marshal` with
255
+ the same name will provide the same instance.
256
+ """
257
+
258
+ _instances = {}
259
+
260
+ def __new__(cls, *, name: str):
261
+ """Create a marshal instance.
262
+
263
+ Args:
264
+ name (str): The name of the marshal. Instantiating multiple
265
+ marshals with the same ``name`` argument will provide the
266
+ same marshal each time.
267
+ """
268
+ klass = cls._instances.get(name)
269
+ if klass is None:
270
+ klass = cls._instances[name] = super().__new__(cls)
271
+
272
+ return klass
273
+
274
+ def __init__(self, *, name: str):
275
+ """Instantiate a marshal.
276
+
277
+ Args:
278
+ name (str): The name of the marshal. Instantiating multiple
279
+ marshals with the same ``name`` argument will provide the
280
+ same marshal each time.
281
+ """
282
+ self._name = name
283
+ if not hasattr(self, "_rules"):
284
+ super().__init__()
285
+
286
+
287
+ class NoopRule:
288
+ """A catch-all rule that does nothing."""
289
+
290
+ def to_python(self, pb_value, *, absent: bool = None):
291
+ return pb_value
292
+
293
+ def to_proto(self, value):
294
+ return value
295
+
296
+
297
+ __all__ = ("Marshal",)
.venv/lib/python3.11/site-packages/proto/marshal/rules/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
.venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (192 Bytes). View file
 
.venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/bytes.cpython-311.pyc ADDED
Binary file (1.8 kB). View file
 
.venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/dates.cpython-311.pyc ADDED
Binary file (4.17 kB). View file
 
.venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/enums.cpython-311.pyc ADDED
Binary file (1.96 kB). View file