From 852a1cfee0786a7dc26fb5eda2b4231b608a9c7b Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 9 Feb 2021 11:12:59 -0600 Subject: [PATCH 01/12] Make propagators a namespace Fixes #1590 --- .../src/opentelemetry/propagators/__init__.py | 154 ------------------ .../propagators/test_global_httptextformat.py | 3 +- .../tests/propagators/test_propagators.py | 8 +- 3 files changed, 5 insertions(+), 160 deletions(-) delete mode 100644 opentelemetry-api/src/opentelemetry/propagators/__init__.py diff --git a/opentelemetry-api/src/opentelemetry/propagators/__init__.py b/opentelemetry-api/src/opentelemetry/propagators/__init__.py deleted file mode 100644 index 6050b5f4ff8..00000000000 --- a/opentelemetry-api/src/opentelemetry/propagators/__init__.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -API for propagation of context. - -The propagators for the -``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined -via configuration in the ``OTEL_PROPAGATORS`` environment variable. This -variable should be set to a comma-separated string of names of values for the -``opentelemetry_propagator`` entry point. For example, setting -``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) -would instantiate -``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2 -propagators, one of type -``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` -and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``. -Notice that these propagator classes are defined as -``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of -``opentelemetry``. - -Example:: - - import flask - import requests - from opentelemetry import propagators - - - PROPAGATOR = propagators.get_global_textmap() - - - def get_header_from_flask_request(request, key): - return request.headers.get_all(key) - - def set_header_into_requests_request(request: requests.Request, - key: str, value: str): - request.headers[key] = value - - def example_route(): - context = PROPAGATOR.extract( - get_header_from_flask_request, - flask.request - ) - request_to_downstream = requests.Request( - "GET", "http://httpbin.org/get" - ) - PROPAGATOR.inject( - set_header_into_requests_request, - request_to_downstream, - context=context - ) - session = requests.Session() - session.send(request_to_downstream.prepare()) - - -.. _Propagation API Specification: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md -""" - -import typing -from logging import getLogger -from os import environ - -from pkg_resources import iter_entry_points - -from opentelemetry.context.context import Context -from opentelemetry.environment_variables import OTEL_PROPAGATORS -from opentelemetry.propagators import composite -from opentelemetry.trace.propagation import textmap - -logger = getLogger(__name__) - - -def extract( - getter: textmap.Getter[textmap.TextMapPropagatorT], - carrier: textmap.TextMapPropagatorT, - context: typing.Optional[Context] = None, -) -> Context: - """Uses the configured propagator to extract a Context from the carrier. - - Args: - getter: an object which contains a get function that can retrieve zero - or more values from the carrier and a keys function that can get all the keys - from carrier. - carrier: and object which contains values that are - used to construct a Context. This object - must be paired with an appropriate getter - which understands how to extract a value from it. - context: an optional Context to use. Defaults to current - context if not set. - """ - return get_global_textmap().extract(getter, carrier, context) - - -def inject( - set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT], - carrier: textmap.TextMapPropagatorT, - context: typing.Optional[Context] = None, -) -> None: - """Uses the configured propagator to inject a Context into the carrier. - - Args: - set_in_carrier: A setter function that can set values - on the carrier. - carrier: An object that contains a representation of HTTP - headers. Should be paired with set_in_carrier, which - should know how to set header values on the carrier. - context: an optional Context to use. Defaults to current - context if not set. - """ - get_global_textmap().inject(set_in_carrier, carrier, context) - - -try: - - propagators = [] - - # Single use variable here to hack black and make lint pass - environ_propagators = environ.get( - OTEL_PROPAGATORS, "tracecontext,baggage", - ) - - for propagator in environ_propagators.split(","): - propagators.append( # type: ignore - next( # type: ignore - iter_entry_points("opentelemetry_propagator", propagator) - ).load()() - ) - -except Exception: # pylint: disable=broad-except - logger.exception("Failed to load configured propagators") - raise - -_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators) # type: ignore - - -def get_global_textmap() -> textmap.TextMapPropagator: - return _HTTP_TEXT_FORMAT - - -def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None: - global _HTTP_TEXT_FORMAT # pylint:disable=global-statement - _HTTP_TEXT_FORMAT = http_text_format # type: ignore diff --git a/opentelemetry-api/tests/propagators/test_global_httptextformat.py b/opentelemetry-api/tests/propagators/test_global_httptextformat.py index b704207ed5f..7eabc9552cc 100644 --- a/opentelemetry-api/tests/propagators/test_global_httptextformat.py +++ b/opentelemetry-api/tests/propagators/test_global_httptextformat.py @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import typing import unittest from opentelemetry import baggage, trace -from opentelemetry.propagators import extract, inject +from opentelemetry.propagators.util import extract, inject from opentelemetry.trace import get_current_span, set_span_in_context from opentelemetry.trace.propagation.textmap import DictGetter diff --git a/opentelemetry-api/tests/propagators/test_propagators.py b/opentelemetry-api/tests/propagators/test_propagators.py index 9fceb91a0b7..65bd51662cc 100644 --- a/opentelemetry-api/tests/propagators/test_propagators.py +++ b/opentelemetry-api/tests/propagators/test_propagators.py @@ -40,9 +40,9 @@ def test_propagators(propagators): **{"side_effect": test_propagators} ) - import opentelemetry.propagators + import opentelemetry.propagators.util - reload(opentelemetry.propagators) + reload(opentelemetry.propagators.util) @patch.dict(environ, {OTEL_PROPAGATORS: "a,b,c"}) @patch("opentelemetry.propagators.composite.CompositeHTTPPropagator") @@ -75,6 +75,6 @@ def test_propagators(propagators): **{"side_effect": test_propagators} ) - import opentelemetry.propagators + import opentelemetry.propagators.util - reload(opentelemetry.propagators) + reload(opentelemetry.propagators.util) From af15e4750e28469f7662b7c04739a74eb9c69ac3 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 9 Feb 2021 11:58:53 -0600 Subject: [PATCH 02/12] Fix paths --- .../auto-instrumentation/server_instrumented.py | 5 +++-- docs/examples/datadog_exporter/client.py | 5 +++-- docs/examples/datadog_exporter/server.py | 16 ++++++++++------ docs/examples/django/client.py | 5 +++-- docs/getting-started.rst | 4 ++-- .../shim/opentracing_shim/__init__.py | 6 +++--- .../tests/test_shim.py | 17 ++++++++++------- 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/docs/examples/auto-instrumentation/server_instrumented.py b/docs/examples/auto-instrumentation/server_instrumented.py index 6212ec33336..88ffe9937ac 100644 --- a/docs/examples/auto-instrumentation/server_instrumented.py +++ b/docs/examples/auto-instrumentation/server_instrumented.py @@ -14,7 +14,8 @@ from flask import Flask, request -from opentelemetry import propagators, trace +from opentelemetry import trace +from opentelemetry.propagators.util import extract from opentelemetry.instrumentation.wsgi import collect_request_attributes from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( @@ -37,7 +38,7 @@ def server_request(): with tracer.start_as_current_span( "server_request", - context=propagators.extract(DictGetter(), request.headers), + context=extract(DictGetter(), request.headers), kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ), ): diff --git a/docs/examples/datadog_exporter/client.py b/docs/examples/datadog_exporter/client.py index a5ddf2843c4..c0ad5a24523 100644 --- a/docs/examples/datadog_exporter/client.py +++ b/docs/examples/datadog_exporter/client.py @@ -16,7 +16,8 @@ from requests import get -from opentelemetry import propagators, trace +from opentelemetry import trace +from opentelemetry.propagators.util import inject from opentelemetry.exporter.datadog import ( DatadogExportSpanProcessor, DatadogSpanExporter, @@ -46,7 +47,7 @@ with tracer.start_as_current_span("client-server"): headers = {} - propagators.inject(dict.__setitem__, headers) + inject(dict.__setitem__, headers) requested = get( "http://localhost:8082/server_request", params={"param": argv[1]}, diff --git a/docs/examples/datadog_exporter/server.py b/docs/examples/datadog_exporter/server.py index 9c83de8bb87..a3abf4c6707 100644 --- a/docs/examples/datadog_exporter/server.py +++ b/docs/examples/datadog_exporter/server.py @@ -14,7 +14,11 @@ from flask import Flask, request -from opentelemetry import propagators, trace +from opentelemetry import trace +from opentelemetry.propagators.util import ( + get_global_textmap, set_global_textmap +) +from opentelemetry.propagators.composite import CompositeHTTPPropagator from opentelemetry.exporter.datadog import ( DatadogExportSpanProcessor, DatadogSpanExporter, @@ -35,19 +39,19 @@ ) # append Datadog format for propagation to and from Datadog instrumented services -global_textmap = propagators.get_global_textmap() +global_textmap = get_global_textmap() if isinstance( - global_textmap, propagators.composite.CompositeHTTPPropagator + global_textmap, CompositeHTTPPropagator ) and not any( isinstance(p, DatadogFormat) for p in global_textmap._propagators ): - propagators.set_global_textmap( - propagators.composite.CompositeHTTPPropagator( + set_global_textmap( + CompositeHTTPPropagator( global_textmap._propagators + [DatadogFormat()] ) ) else: - propagators.set_global_textmap(DatadogFormat()) + set_global_textmap(DatadogFormat()) tracer = trace.get_tracer(__name__) diff --git a/docs/examples/django/client.py b/docs/examples/django/client.py index e65285c35d2..c8f08da8fd1 100644 --- a/docs/examples/django/client.py +++ b/docs/examples/django/client.py @@ -16,7 +16,8 @@ from requests import get -from opentelemetry import propagators, trace +from opentelemetry import trace +from opentelemetry.propagators.util import inject from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, @@ -35,7 +36,7 @@ with tracer.start_as_current_span("client-server"): headers = {} - propagators.inject(dict.__setitem__, headers) + inject(dict.__setitem__, headers) requested = get( "http://localhost:8000", params={"param": argv[1]}, diff --git a/docs/getting-started.rst b/docs/getting-started.rst index dce074e8971..333a8e1d6f2 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -195,10 +195,10 @@ Following the installation of the package containing the b3 propagator, configur .. code-block:: python - from opentelemetry import propagators + from opentelemetry.propagators.util import set_global_textmap from opentelemetry.propagators.b3 import B3Format - propagators.set_global_textmap(B3Format()) + set_global_textmap(B3Format()) Use the OpenTelemetry Collector for traces ------------------------------------------ diff --git a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py index 74c8952664e..87ff9ff83b6 100644 --- a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py +++ b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py @@ -99,7 +99,7 @@ UnsupportedFormatException, ) -from opentelemetry import propagators +from opentelemetry.propagators.util import get_global_textmap from opentelemetry.baggage import get_baggage, set_baggage from opentelemetry.context import Context, attach, detach, get_value, set_value from opentelemetry.shim.opentracing_shim import util @@ -682,7 +682,7 @@ def inject(self, span_context, format: object, carrier: object): if format not in self._supported_formats: raise UnsupportedFormatException - propagator = propagators.get_global_textmap() + propagator = get_global_textmap() ctx = set_span_in_context(DefaultSpan(span_context.unwrap())) propagator.inject(type(carrier).__setitem__, carrier, context=ctx) @@ -712,7 +712,7 @@ def extract(self, format: object, carrier: object): if format not in self._supported_formats: raise UnsupportedFormatException - propagator = propagators.get_global_textmap() + propagator = get_global_textmap() ctx = propagator.extract(self._carrier_getter, carrier) span = get_current_span(ctx) if span is not None: diff --git a/shim/opentelemetry-opentracing-shim/tests/test_shim.py b/shim/opentelemetry-opentracing-shim/tests/test_shim.py index 54f1caa92c5..41c94f2d0cc 100644 --- a/shim/opentelemetry-opentracing-shim/tests/test_shim.py +++ b/shim/opentelemetry-opentracing-shim/tests/test_shim.py @@ -21,7 +21,10 @@ import opentracing -from opentelemetry import propagators, trace +from opentelemetry import trace +from opentelemetry.propagators.util import ( + set_global_textmap, get_global_textmap +) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.shim.opentracing_shim import ( SpanContextShim, @@ -46,15 +49,15 @@ def setUp(self): @classmethod def setUpClass(cls): # Save current propagator to be restored on teardown. - cls._previous_propagator = propagators.get_global_textmap() + cls._previous_propagator = get_global_textmap() # Set mock propagator for testing. - propagators.set_global_textmap(MockTextMapPropagator()) + set_global_textmap(MockTextMapPropagator()) @classmethod def tearDownClass(cls): # Restore previous propagator. - propagators.set_global_textmap(cls._previous_propagator) + set_global_textmap(cls._previous_propagator) def test_shim_type(self): # Verify shim is an OpenTracing tracer. @@ -542,15 +545,15 @@ def test_extract_empty_context_returns_invalid_context(self): """In the case where the propagator cannot extract a SpanContext, extract should return and invalid span context. """ - _old_propagator = propagators.get_global_textmap() - propagators.set_global_textmap(NOOPTextMapPropagator()) + _old_propagator = get_global_textmap() + set_global_textmap(NOOPTextMapPropagator()) try: carrier = {} ctx = self.shim.extract(opentracing.Format.HTTP_HEADERS, carrier) self.assertEqual(ctx.unwrap(), trace.INVALID_SPAN_CONTEXT) finally: - propagators.set_global_textmap(_old_propagator) + set_global_textmap(_old_propagator) def test_extract_text_map(self): """Test `extract()` method for Format.TEXT_MAP.""" From 6851d261d07f277e02d0b8c93154846c2cdc770c Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 9 Feb 2021 14:39:50 -0600 Subject: [PATCH 03/12] Move to util --- .../src/opentelemetry/propagators/util.py | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 opentelemetry-api/src/opentelemetry/propagators/util.py diff --git a/opentelemetry-api/src/opentelemetry/propagators/util.py b/opentelemetry-api/src/opentelemetry/propagators/util.py new file mode 100644 index 00000000000..6050b5f4ff8 --- /dev/null +++ b/opentelemetry-api/src/opentelemetry/propagators/util.py @@ -0,0 +1,154 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +API for propagation of context. + +The propagators for the +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined +via configuration in the ``OTEL_PROPAGATORS`` environment variable. This +variable should be set to a comma-separated string of names of values for the +``opentelemetry_propagator`` entry point. For example, setting +``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) +would instantiate +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2 +propagators, one of type +``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` +and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``. +Notice that these propagator classes are defined as +``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of +``opentelemetry``. + +Example:: + + import flask + import requests + from opentelemetry import propagators + + + PROPAGATOR = propagators.get_global_textmap() + + + def get_header_from_flask_request(request, key): + return request.headers.get_all(key) + + def set_header_into_requests_request(request: requests.Request, + key: str, value: str): + request.headers[key] = value + + def example_route(): + context = PROPAGATOR.extract( + get_header_from_flask_request, + flask.request + ) + request_to_downstream = requests.Request( + "GET", "http://httpbin.org/get" + ) + PROPAGATOR.inject( + set_header_into_requests_request, + request_to_downstream, + context=context + ) + session = requests.Session() + session.send(request_to_downstream.prepare()) + + +.. _Propagation API Specification: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md +""" + +import typing +from logging import getLogger +from os import environ + +from pkg_resources import iter_entry_points + +from opentelemetry.context.context import Context +from opentelemetry.environment_variables import OTEL_PROPAGATORS +from opentelemetry.propagators import composite +from opentelemetry.trace.propagation import textmap + +logger = getLogger(__name__) + + +def extract( + getter: textmap.Getter[textmap.TextMapPropagatorT], + carrier: textmap.TextMapPropagatorT, + context: typing.Optional[Context] = None, +) -> Context: + """Uses the configured propagator to extract a Context from the carrier. + + Args: + getter: an object which contains a get function that can retrieve zero + or more values from the carrier and a keys function that can get all the keys + from carrier. + carrier: and object which contains values that are + used to construct a Context. This object + must be paired with an appropriate getter + which understands how to extract a value from it. + context: an optional Context to use. Defaults to current + context if not set. + """ + return get_global_textmap().extract(getter, carrier, context) + + +def inject( + set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT], + carrier: textmap.TextMapPropagatorT, + context: typing.Optional[Context] = None, +) -> None: + """Uses the configured propagator to inject a Context into the carrier. + + Args: + set_in_carrier: A setter function that can set values + on the carrier. + carrier: An object that contains a representation of HTTP + headers. Should be paired with set_in_carrier, which + should know how to set header values on the carrier. + context: an optional Context to use. Defaults to current + context if not set. + """ + get_global_textmap().inject(set_in_carrier, carrier, context) + + +try: + + propagators = [] + + # Single use variable here to hack black and make lint pass + environ_propagators = environ.get( + OTEL_PROPAGATORS, "tracecontext,baggage", + ) + + for propagator in environ_propagators.split(","): + propagators.append( # type: ignore + next( # type: ignore + iter_entry_points("opentelemetry_propagator", propagator) + ).load()() + ) + +except Exception: # pylint: disable=broad-except + logger.exception("Failed to load configured propagators") + raise + +_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators) # type: ignore + + +def get_global_textmap() -> textmap.TextMapPropagator: + return _HTTP_TEXT_FORMAT + + +def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None: + global _HTTP_TEXT_FORMAT # pylint:disable=global-statement + _HTTP_TEXT_FORMAT = http_text_format # type: ignore From 5ade75b9648a4a59db3e85aad51eb5c23f982656 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 11:54:46 -0600 Subject: [PATCH 04/12] Fix conflicts --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b60727d00d0..dca45000811 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 370afa618c30a9773b0594c2ea469518c8b2c274 + CONTRIB_REPO_SHA: 24bab77d4d6070998d634a07f88aed6ea2378b25 jobs: build: From 3d52cdd27e26535af352da5a29d2c04e11e8e32b Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 9 Feb 2021 16:27:33 -0600 Subject: [PATCH 05/12] Fix lint --- .../auto-instrumentation/server_instrumented.py | 2 +- docs/examples/datadog_exporter/client.py | 2 +- docs/examples/datadog_exporter/server.py | 13 ++++++------- .../opentelemetry/shim/opentracing_shim/__init__.py | 2 +- .../tests/test_shim.py | 3 ++- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/examples/auto-instrumentation/server_instrumented.py b/docs/examples/auto-instrumentation/server_instrumented.py index 88ffe9937ac..c61dd584af9 100644 --- a/docs/examples/auto-instrumentation/server_instrumented.py +++ b/docs/examples/auto-instrumentation/server_instrumented.py @@ -15,8 +15,8 @@ from flask import Flask, request from opentelemetry import trace -from opentelemetry.propagators.util import extract from opentelemetry.instrumentation.wsgi import collect_request_attributes +from opentelemetry.propagators.util import extract from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, diff --git a/docs/examples/datadog_exporter/client.py b/docs/examples/datadog_exporter/client.py index c0ad5a24523..9132eaba277 100644 --- a/docs/examples/datadog_exporter/client.py +++ b/docs/examples/datadog_exporter/client.py @@ -17,11 +17,11 @@ from requests import get from opentelemetry import trace -from opentelemetry.propagators.util import inject from opentelemetry.exporter.datadog import ( DatadogExportSpanProcessor, DatadogSpanExporter, ) +from opentelemetry.propagators.util import inject from opentelemetry.sdk import resources from opentelemetry.sdk.trace import TracerProvider diff --git a/docs/examples/datadog_exporter/server.py b/docs/examples/datadog_exporter/server.py index a3abf4c6707..b908f408389 100644 --- a/docs/examples/datadog_exporter/server.py +++ b/docs/examples/datadog_exporter/server.py @@ -15,15 +15,16 @@ from flask import Flask, request from opentelemetry import trace -from opentelemetry.propagators.util import ( - get_global_textmap, set_global_textmap -) -from opentelemetry.propagators.composite import CompositeHTTPPropagator from opentelemetry.exporter.datadog import ( DatadogExportSpanProcessor, DatadogSpanExporter, ) from opentelemetry.exporter.datadog.propagator import DatadogFormat +from opentelemetry.propagators.composite import CompositeHTTPPropagator +from opentelemetry.propagators.util import ( + get_global_textmap, + set_global_textmap, +) from opentelemetry.sdk.trace import TracerProvider app = Flask(__name__) @@ -40,9 +41,7 @@ # append Datadog format for propagation to and from Datadog instrumented services global_textmap = get_global_textmap() -if isinstance( - global_textmap, CompositeHTTPPropagator -) and not any( +if isinstance(global_textmap, CompositeHTTPPropagator) and not any( isinstance(p, DatadogFormat) for p in global_textmap._propagators ): set_global_textmap( diff --git a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py index 87ff9ff83b6..aa7ae2aaf7d 100644 --- a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py +++ b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py @@ -99,9 +99,9 @@ UnsupportedFormatException, ) -from opentelemetry.propagators.util import get_global_textmap from opentelemetry.baggage import get_baggage, set_baggage from opentelemetry.context import Context, attach, detach, get_value, set_value +from opentelemetry.propagators.util import get_global_textmap from opentelemetry.shim.opentracing_shim import util from opentelemetry.shim.opentracing_shim.version import __version__ from opentelemetry.trace import INVALID_SPAN_CONTEXT, DefaultSpan, Link diff --git a/shim/opentelemetry-opentracing-shim/tests/test_shim.py b/shim/opentelemetry-opentracing-shim/tests/test_shim.py index 41c94f2d0cc..110551e27e0 100644 --- a/shim/opentelemetry-opentracing-shim/tests/test_shim.py +++ b/shim/opentelemetry-opentracing-shim/tests/test_shim.py @@ -23,7 +23,8 @@ from opentelemetry import trace from opentelemetry.propagators.util import ( - set_global_textmap, get_global_textmap + get_global_textmap, + set_global_textmap, ) from opentelemetry.sdk.trace import TracerProvider from opentelemetry.shim.opentracing_shim import ( From 3a95178db055ef041c7a83d6f7639c2fa1ce74e6 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 10 Feb 2021 11:02:22 -0600 Subject: [PATCH 06/12] Downgrade cache version This is needed to make the PR pass its tests in CI. This requires the version to be updated back later in a separate PR. --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dca45000811..7e2e2cbdda3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 24bab77d4d6070998d634a07f88aed6ea2378b25 + CONTRIB_REPO_SHA: 99d6a2d7987d0f2cdde04319627c86fc0a465351 jobs: build: @@ -109,7 +109,7 @@ jobs: run: pip install -U tox - name: Cache tox environment # Preserves .tox directory between runs for faster installs - uses: actions/cache@v2 + uses: actions/cache@v1 with: path: .tox key: tox-cache-${{ matrix.tox-environment }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core From 1bd0b005b288d9206731c2fde2ed0cd71f57cf5e Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 11:29:03 -0600 Subject: [PATCH 07/12] Revert version --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e2e2cbdda3..d5477b17496 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,7 +109,7 @@ jobs: run: pip install -U tox - name: Cache tox environment # Preserves .tox directory between runs for faster installs - uses: actions/cache@v1 + uses: actions/cache@v2 with: path: .tox key: tox-cache-${{ matrix.tox-environment }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core From e34505a36a3ee08733be1584f13bf567f32c2240 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 11:38:08 -0600 Subject: [PATCH 08/12] Rename to propagate --- .../server_instrumented.py | 2 +- docs/examples/datadog_exporter/client.py | 2 +- docs/examples/datadog_exporter/server.py | 2 +- docs/examples/django/client.py | 2 +- docs/getting-started.rst | 2 +- .../src/opentelemetry/propagators/util.py | 154 ------------------ .../propagators/test_global_httptextformat.py | 2 +- .../tests/propagators/test_propagators.py | 8 +- .../shim/opentracing_shim/__init__.py | 2 +- .../tests/test_shim.py | 2 +- 10 files changed, 12 insertions(+), 166 deletions(-) delete mode 100644 opentelemetry-api/src/opentelemetry/propagators/util.py diff --git a/docs/examples/auto-instrumentation/server_instrumented.py b/docs/examples/auto-instrumentation/server_instrumented.py index c61dd584af9..66bb0b584a9 100644 --- a/docs/examples/auto-instrumentation/server_instrumented.py +++ b/docs/examples/auto-instrumentation/server_instrumented.py @@ -16,7 +16,7 @@ from opentelemetry import trace from opentelemetry.instrumentation.wsgi import collect_request_attributes -from opentelemetry.propagators.util import extract +from opentelemetry.propagate import extract from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, diff --git a/docs/examples/datadog_exporter/client.py b/docs/examples/datadog_exporter/client.py index 9132eaba277..6b4b5d00ec1 100644 --- a/docs/examples/datadog_exporter/client.py +++ b/docs/examples/datadog_exporter/client.py @@ -21,7 +21,7 @@ DatadogExportSpanProcessor, DatadogSpanExporter, ) -from opentelemetry.propagators.util import inject +from opentelemetry.propagate import inject from opentelemetry.sdk import resources from opentelemetry.sdk.trace import TracerProvider diff --git a/docs/examples/datadog_exporter/server.py b/docs/examples/datadog_exporter/server.py index b908f408389..ce5a8ae6294 100644 --- a/docs/examples/datadog_exporter/server.py +++ b/docs/examples/datadog_exporter/server.py @@ -21,7 +21,7 @@ ) from opentelemetry.exporter.datadog.propagator import DatadogFormat from opentelemetry.propagators.composite import CompositeHTTPPropagator -from opentelemetry.propagators.util import ( +from opentelemetry.propagate import ( get_global_textmap, set_global_textmap, ) diff --git a/docs/examples/django/client.py b/docs/examples/django/client.py index c8f08da8fd1..d32be31a851 100644 --- a/docs/examples/django/client.py +++ b/docs/examples/django/client.py @@ -17,7 +17,7 @@ from requests import get from opentelemetry import trace -from opentelemetry.propagators.util import inject +from opentelemetry.propagate import inject from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 333a8e1d6f2..6432e021037 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -195,7 +195,7 @@ Following the installation of the package containing the b3 propagator, configur .. code-block:: python - from opentelemetry.propagators.util import set_global_textmap + from opentelemetry.propagate import set_global_textmap from opentelemetry.propagators.b3 import B3Format set_global_textmap(B3Format()) diff --git a/opentelemetry-api/src/opentelemetry/propagators/util.py b/opentelemetry-api/src/opentelemetry/propagators/util.py deleted file mode 100644 index 6050b5f4ff8..00000000000 --- a/opentelemetry-api/src/opentelemetry/propagators/util.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -API for propagation of context. - -The propagators for the -``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined -via configuration in the ``OTEL_PROPAGATORS`` environment variable. This -variable should be set to a comma-separated string of names of values for the -``opentelemetry_propagator`` entry point. For example, setting -``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) -would instantiate -``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2 -propagators, one of type -``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` -and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``. -Notice that these propagator classes are defined as -``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of -``opentelemetry``. - -Example:: - - import flask - import requests - from opentelemetry import propagators - - - PROPAGATOR = propagators.get_global_textmap() - - - def get_header_from_flask_request(request, key): - return request.headers.get_all(key) - - def set_header_into_requests_request(request: requests.Request, - key: str, value: str): - request.headers[key] = value - - def example_route(): - context = PROPAGATOR.extract( - get_header_from_flask_request, - flask.request - ) - request_to_downstream = requests.Request( - "GET", "http://httpbin.org/get" - ) - PROPAGATOR.inject( - set_header_into_requests_request, - request_to_downstream, - context=context - ) - session = requests.Session() - session.send(request_to_downstream.prepare()) - - -.. _Propagation API Specification: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md -""" - -import typing -from logging import getLogger -from os import environ - -from pkg_resources import iter_entry_points - -from opentelemetry.context.context import Context -from opentelemetry.environment_variables import OTEL_PROPAGATORS -from opentelemetry.propagators import composite -from opentelemetry.trace.propagation import textmap - -logger = getLogger(__name__) - - -def extract( - getter: textmap.Getter[textmap.TextMapPropagatorT], - carrier: textmap.TextMapPropagatorT, - context: typing.Optional[Context] = None, -) -> Context: - """Uses the configured propagator to extract a Context from the carrier. - - Args: - getter: an object which contains a get function that can retrieve zero - or more values from the carrier and a keys function that can get all the keys - from carrier. - carrier: and object which contains values that are - used to construct a Context. This object - must be paired with an appropriate getter - which understands how to extract a value from it. - context: an optional Context to use. Defaults to current - context if not set. - """ - return get_global_textmap().extract(getter, carrier, context) - - -def inject( - set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT], - carrier: textmap.TextMapPropagatorT, - context: typing.Optional[Context] = None, -) -> None: - """Uses the configured propagator to inject a Context into the carrier. - - Args: - set_in_carrier: A setter function that can set values - on the carrier. - carrier: An object that contains a representation of HTTP - headers. Should be paired with set_in_carrier, which - should know how to set header values on the carrier. - context: an optional Context to use. Defaults to current - context if not set. - """ - get_global_textmap().inject(set_in_carrier, carrier, context) - - -try: - - propagators = [] - - # Single use variable here to hack black and make lint pass - environ_propagators = environ.get( - OTEL_PROPAGATORS, "tracecontext,baggage", - ) - - for propagator in environ_propagators.split(","): - propagators.append( # type: ignore - next( # type: ignore - iter_entry_points("opentelemetry_propagator", propagator) - ).load()() - ) - -except Exception: # pylint: disable=broad-except - logger.exception("Failed to load configured propagators") - raise - -_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators) # type: ignore - - -def get_global_textmap() -> textmap.TextMapPropagator: - return _HTTP_TEXT_FORMAT - - -def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None: - global _HTTP_TEXT_FORMAT # pylint:disable=global-statement - _HTTP_TEXT_FORMAT = http_text_format # type: ignore diff --git a/opentelemetry-api/tests/propagators/test_global_httptextformat.py b/opentelemetry-api/tests/propagators/test_global_httptextformat.py index 7eabc9552cc..88b1920468e 100644 --- a/opentelemetry-api/tests/propagators/test_global_httptextformat.py +++ b/opentelemetry-api/tests/propagators/test_global_httptextformat.py @@ -15,7 +15,7 @@ import unittest from opentelemetry import baggage, trace -from opentelemetry.propagators.util import extract, inject +from opentelemetry.propagate import extract, inject from opentelemetry.trace import get_current_span, set_span_in_context from opentelemetry.trace.propagation.textmap import DictGetter diff --git a/opentelemetry-api/tests/propagators/test_propagators.py b/opentelemetry-api/tests/propagators/test_propagators.py index 65bd51662cc..5e2abaed1a4 100644 --- a/opentelemetry-api/tests/propagators/test_propagators.py +++ b/opentelemetry-api/tests/propagators/test_propagators.py @@ -40,9 +40,9 @@ def test_propagators(propagators): **{"side_effect": test_propagators} ) - import opentelemetry.propagators.util + import opentelemetry.propagate - reload(opentelemetry.propagators.util) + reload(opentelemetry.propagate) @patch.dict(environ, {OTEL_PROPAGATORS: "a,b,c"}) @patch("opentelemetry.propagators.composite.CompositeHTTPPropagator") @@ -75,6 +75,6 @@ def test_propagators(propagators): **{"side_effect": test_propagators} ) - import opentelemetry.propagators.util + import opentelemetry.propagate - reload(opentelemetry.propagators.util) + reload(opentelemetry.propagate) diff --git a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py index aa7ae2aaf7d..1083e682633 100644 --- a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py +++ b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py @@ -101,7 +101,7 @@ from opentelemetry.baggage import get_baggage, set_baggage from opentelemetry.context import Context, attach, detach, get_value, set_value -from opentelemetry.propagators.util import get_global_textmap +from opentelemetry.propagate import get_global_textmap from opentelemetry.shim.opentracing_shim import util from opentelemetry.shim.opentracing_shim.version import __version__ from opentelemetry.trace import INVALID_SPAN_CONTEXT, DefaultSpan, Link diff --git a/shim/opentelemetry-opentracing-shim/tests/test_shim.py b/shim/opentelemetry-opentracing-shim/tests/test_shim.py index 110551e27e0..98fb9dd8bac 100644 --- a/shim/opentelemetry-opentracing-shim/tests/test_shim.py +++ b/shim/opentelemetry-opentracing-shim/tests/test_shim.py @@ -22,7 +22,7 @@ import opentracing from opentelemetry import trace -from opentelemetry.propagators.util import ( +from opentelemetry.propagate import ( get_global_textmap, set_global_textmap, ) From b3f77350097d8c3956d9903c183d9d48e4230780 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 11:43:57 -0600 Subject: [PATCH 09/12] Add propagate --- .../src/opentelemetry/propagate/__init__.py | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 opentelemetry-api/src/opentelemetry/propagate/__init__.py diff --git a/opentelemetry-api/src/opentelemetry/propagate/__init__.py b/opentelemetry-api/src/opentelemetry/propagate/__init__.py new file mode 100644 index 00000000000..6050b5f4ff8 --- /dev/null +++ b/opentelemetry-api/src/opentelemetry/propagate/__init__.py @@ -0,0 +1,154 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +API for propagation of context. + +The propagators for the +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` can be defined +via configuration in the ``OTEL_PROPAGATORS`` environment variable. This +variable should be set to a comma-separated string of names of values for the +``opentelemetry_propagator`` entry point. For example, setting +``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) +would instantiate +``opentelemetry.propagators.composite.CompositeHTTPPropagator`` with 2 +propagators, one of type +``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` +and other of type ``opentelemetry.baggage.propagation.BaggagePropagator``. +Notice that these propagator classes are defined as +``opentelemetry_propagator`` entry points in the ``setup.cfg`` file of +``opentelemetry``. + +Example:: + + import flask + import requests + from opentelemetry import propagators + + + PROPAGATOR = propagators.get_global_textmap() + + + def get_header_from_flask_request(request, key): + return request.headers.get_all(key) + + def set_header_into_requests_request(request: requests.Request, + key: str, value: str): + request.headers[key] = value + + def example_route(): + context = PROPAGATOR.extract( + get_header_from_flask_request, + flask.request + ) + request_to_downstream = requests.Request( + "GET", "http://httpbin.org/get" + ) + PROPAGATOR.inject( + set_header_into_requests_request, + request_to_downstream, + context=context + ) + session = requests.Session() + session.send(request_to_downstream.prepare()) + + +.. _Propagation API Specification: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md +""" + +import typing +from logging import getLogger +from os import environ + +from pkg_resources import iter_entry_points + +from opentelemetry.context.context import Context +from opentelemetry.environment_variables import OTEL_PROPAGATORS +from opentelemetry.propagators import composite +from opentelemetry.trace.propagation import textmap + +logger = getLogger(__name__) + + +def extract( + getter: textmap.Getter[textmap.TextMapPropagatorT], + carrier: textmap.TextMapPropagatorT, + context: typing.Optional[Context] = None, +) -> Context: + """Uses the configured propagator to extract a Context from the carrier. + + Args: + getter: an object which contains a get function that can retrieve zero + or more values from the carrier and a keys function that can get all the keys + from carrier. + carrier: and object which contains values that are + used to construct a Context. This object + must be paired with an appropriate getter + which understands how to extract a value from it. + context: an optional Context to use. Defaults to current + context if not set. + """ + return get_global_textmap().extract(getter, carrier, context) + + +def inject( + set_in_carrier: textmap.Setter[textmap.TextMapPropagatorT], + carrier: textmap.TextMapPropagatorT, + context: typing.Optional[Context] = None, +) -> None: + """Uses the configured propagator to inject a Context into the carrier. + + Args: + set_in_carrier: A setter function that can set values + on the carrier. + carrier: An object that contains a representation of HTTP + headers. Should be paired with set_in_carrier, which + should know how to set header values on the carrier. + context: an optional Context to use. Defaults to current + context if not set. + """ + get_global_textmap().inject(set_in_carrier, carrier, context) + + +try: + + propagators = [] + + # Single use variable here to hack black and make lint pass + environ_propagators = environ.get( + OTEL_PROPAGATORS, "tracecontext,baggage", + ) + + for propagator in environ_propagators.split(","): + propagators.append( # type: ignore + next( # type: ignore + iter_entry_points("opentelemetry_propagator", propagator) + ).load()() + ) + +except Exception: # pylint: disable=broad-except + logger.exception("Failed to load configured propagators") + raise + +_HTTP_TEXT_FORMAT = composite.CompositeHTTPPropagator(propagators) # type: ignore + + +def get_global_textmap() -> textmap.TextMapPropagator: + return _HTTP_TEXT_FORMAT + + +def set_global_textmap(http_text_format: textmap.TextMapPropagator,) -> None: + global _HTTP_TEXT_FORMAT # pylint:disable=global-statement + _HTTP_TEXT_FORMAT = http_text_format # type: ignore From 77a0b3fe0e4ea15a82eff48dc1637017d9958727 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 11:51:37 -0600 Subject: [PATCH 10/12] Fix isort --- docs/examples/datadog_exporter/server.py | 5 +---- shim/opentelemetry-opentracing-shim/tests/test_shim.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/examples/datadog_exporter/server.py b/docs/examples/datadog_exporter/server.py index ce5a8ae6294..662d3ebe97c 100644 --- a/docs/examples/datadog_exporter/server.py +++ b/docs/examples/datadog_exporter/server.py @@ -20,11 +20,8 @@ DatadogSpanExporter, ) from opentelemetry.exporter.datadog.propagator import DatadogFormat +from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.propagators.composite import CompositeHTTPPropagator -from opentelemetry.propagate import ( - get_global_textmap, - set_global_textmap, -) from opentelemetry.sdk.trace import TracerProvider app = Flask(__name__) diff --git a/shim/opentelemetry-opentracing-shim/tests/test_shim.py b/shim/opentelemetry-opentracing-shim/tests/test_shim.py index 98fb9dd8bac..a27d30de718 100644 --- a/shim/opentelemetry-opentracing-shim/tests/test_shim.py +++ b/shim/opentelemetry-opentracing-shim/tests/test_shim.py @@ -22,10 +22,7 @@ import opentracing from opentelemetry import trace -from opentelemetry.propagate import ( - get_global_textmap, - set_global_textmap, -) +from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk.trace import TracerProvider from opentelemetry.shim.opentracing_shim import ( SpanContextShim, From 94142089ab479addc2374c052464897af94148d2 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 15:31:22 -0600 Subject: [PATCH 11/12] Update SHA --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d5477b17496..71c3f7a18ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 99d6a2d7987d0f2cdde04319627c86fc0a465351 + CONTRIB_REPO_SHA: 028feb486f3db29dc2f9727bde0433392ac3329b jobs: build: From 9788a678950bc4d7fdd4ad0ecf4a8b172fb2f041 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Tue, 16 Feb 2021 16:32:57 -0600 Subject: [PATCH 12/12] Update SHA --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71c3f7a18ae..4a48de8eaf7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: 028feb486f3db29dc2f9727bde0433392ac3329b + CONTRIB_REPO_SHA: 8e1dd27be3a2101c9034e480560fd5ceb6712d51 jobs: build: