Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .venv/lib/python3.11/site-packages/opencensus/common/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/common/backports/__init__.py +79 -0
- .venv/lib/python3.11/site-packages/opencensus/common/backports/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/common/configuration/__init__.py +46 -0
- .venv/lib/python3.11/site-packages/opencensus/common/configuration/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/__init__.py +0 -0
- .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/gcp_metadata_config.py +115 -0
- .venv/lib/python3.11/site-packages/opencensus/common/monitored_resource/k8s_utils.py +64 -0
- .venv/lib/python3.11/site-packages/opencensus/common/version/__init__.py +15 -0
- .venv/lib/python3.11/site-packages/opencensus/common/version/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/__init__.py +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__init__.py +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/cumulative.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/gauge.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/metric.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/point.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/summary.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/__pycache__/time_series.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/cumulative.py +87 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/gauge.py +513 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric.py +79 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_descriptor.py +174 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/metric_producer.py +81 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/point.py +47 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/summary.py +144 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/time_series.py +90 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/export/value.py +307 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/label_key.py +51 -0
- .venv/lib/python3.11/site-packages/opencensus/metrics/transport.py +145 -0
- .venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/__init__.py +72 -0
- .venv/lib/python3.11/site-packages/proto/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/__pycache__/datetime_helpers.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/__pycache__/enums.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/__pycache__/fields.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/enums.py +163 -0
- .venv/lib/python3.11/site-packages/proto/marshal/__init__.py +18 -0
- .venv/lib/python3.11/site-packages/proto/marshal/collections/__init__.py +24 -0
- .venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/maps.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/marshal/collections/__pycache__/repeated.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/marshal/collections/maps.py +82 -0
- .venv/lib/python3.11/site-packages/proto/marshal/collections/repeated.py +189 -0
- .venv/lib/python3.11/site-packages/proto/marshal/compat.py +64 -0
- .venv/lib/python3.11/site-packages/proto/marshal/marshal.py +297 -0
- .venv/lib/python3.11/site-packages/proto/marshal/rules/__init__.py +13 -0
- .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/bytes.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/proto/marshal/rules/__pycache__/dates.cpython-311.pyc +0 -0
- .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
|
|
|