-
Notifications
You must be signed in to change notification settings - Fork 617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Context Prop #325
[WIP] Context Prop #325
Changes from 1 commit
5f84c2b
6bea6ec
bbb583d
c3f408b
8ec6106
9788f69
6a46a25
5ef40df
0442f29
622d787
317e937
64cfe9b
22a5c64
375b78e
5ca5328
b475933
c4829c4
c7610fa
7489eb5
a4c4150
0946846
033e27e
cc813bb
7391372
fa6d437
5fa8e02
164ef68
b37c3b0
4ddac90
f500132
93e88de
72c0dbd
f3c8076
d82e4c5
8927455
a4b7d0c
3b8bf5d
9efb6e4
5272bed
ea0905c
4c2c4de
1447d7f
1cd03c5
7c9597c
4ca46d9
48c2a7d
c7130a1
5169723
673224c
4f008a4
66d67b8
4442a04
17bb4b1
b82dc78
b850f99
33a5b78
be91061
f84c4d3
b1ba228
c3906ea
8d0b142
6965c33
c129e82
0a6c385
57ad2d2
cfdfc62
257627c
b210df8
73dbfab
b9be7bd
d70a47c
1e3ee56
47f521f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Signed-off-by: Alex Boten <aboten@lightstep.com>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ | |
Getter = typing.Callable[[ContextT, str], typing.List[str]] | ||
|
||
|
||
class HTTPExtractor(abc.ABC): | ||
class Extractor(abc.ABC): | ||
"""API for propagation of span context via headers. | ||
|
||
TODO: update docs to reflect split into extractor/injector | ||
|
@@ -38,7 +38,7 @@ class HTTPExtractor(abc.ABC): | |
|
||
import flask | ||
import requests | ||
from opentelemetry.context.propagation import HTTPExtractor | ||
from opentelemetry.context.propagation import Extractor | ||
|
||
PROPAGATOR = HTTPTextFormat() | ||
|
||
|
@@ -80,27 +80,27 @@ def extract( | |
context: typing.Optional[Context] = None, | ||
get_from_carrier: typing.Optional[Getter[ContextT]] = None, | ||
) -> Context: | ||
"""Create a SpanContext from values in the carrier. | ||
"""Create a Context from values in the carrier. | ||
|
||
The extract function should retrieve values from the carrier | ||
object using get_from_carrier, and use values to populate a | ||
SpanContext value and return it. | ||
object using get_from_carrier, use values to populate a | ||
Context value and return it. | ||
|
||
Args: | ||
get_from_carrier: a function that can retrieve zero | ||
or more values from the carrier. In the case that | ||
the value does not exist, return an empty list. | ||
carrier: and object which contains values that are | ||
used to construct a SpanContext. This object | ||
used to construct a Context. This object | ||
must be paired with an appropriate get_from_carrier | ||
which understands how to extract a value from it. | ||
context: The Context to read values from. | ||
get_from_carrier: a function that can retrieve zero | ||
or more values from the carrier. In the case that | ||
the value does not exist, return an empty list. | ||
Returns: | ||
A SpanContext with configuration found in the carrier. | ||
|
||
A Context with configuration found in the carrier. | ||
""" | ||
|
||
|
||
class HTTPInjector(abc.ABC): | ||
class Injector(abc.ABC): | ||
@classmethod | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why make these classmethods? Is it an error to ever instantiate an injector/extractor? |
||
@abc.abstractmethod | ||
def inject( | ||
|
@@ -109,71 +109,27 @@ def inject( | |
context: typing.Optional[Context] = None, | ||
set_in_carrier: typing.Optional[Setter[ContextT]] = None, | ||
) -> None: | ||
"""Inject values from a SpanContext into a carrier. | ||
"""Inject values from a Context into a carrier. | ||
|
||
inject enables the propagation of values into HTTP clients or | ||
other objects which perform an HTTP request. Implementations | ||
should use the set_in_carrier method to set values on the | ||
carrier. | ||
|
||
Args: | ||
context: The SpanContext to read values from. | ||
set_in_carrier: A setter function that can set values | ||
on the carrier. | ||
carrier: An object that a place to define HTTP headers. | ||
Should be paired with set_in_carrier, which should | ||
know how to set header values on the carrier. | ||
|
||
context: The Context to read values from. | ||
set_in_carrier: A setter function that can set values | ||
on the carrier. | ||
""" | ||
|
||
|
||
class DefaultHTTPExtractor(HTTPExtractor): | ||
"""API for propagation of span context via headers. | ||
|
||
TODO: update docs to reflect split into extractor/injector | ||
|
||
This class provides an interface that enables extracting and injecting | ||
span context into headers of HTTP requests. HTTP frameworks and clients | ||
can integrate with HTTPTextFormat by providing the object containing the | ||
headers, and a getter and setter function for the extraction and | ||
injection of values, respectively. | ||
|
||
Example:: | ||
|
||
import flask | ||
import requests | ||
from opentelemetry.context.propagation import HTTPExtractor | ||
|
||
PROPAGATOR = HTTPTextFormat() | ||
|
||
|
||
|
||
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(): | ||
span_context = PROPAGATOR.extract( | ||
get_header_from_flask_request, | ||
flask.request | ||
) | ||
request_to_downstream = requests.Request( | ||
"GET", "http://httpbin.org/get" | ||
) | ||
PROPAGATOR.inject( | ||
span_context, | ||
set_header_into_requests_request, | ||
request_to_downstream | ||
) | ||
session = requests.Session() | ||
session.send(request_to_downstream.prepare()) | ||
|
||
class DefaultExtractor(Extractor): | ||
"""The default Extractor that is used when no Extractor implementation is configured. | ||
|
||
.. _Propagation API Specification: | ||
https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-propagators.md | ||
All operations are no-ops. | ||
""" | ||
|
||
@classmethod | ||
|
@@ -183,51 +139,22 @@ def extract( | |
context: typing.Optional[Context] = None, | ||
get_from_carrier: typing.Optional[Getter[ContextT]] = None, | ||
) -> Context: | ||
"""Create a SpanContext from values in the carrier. | ||
|
||
The extract function should retrieve values from the carrier | ||
object using get_from_carrier, and use values to populate a | ||
SpanContext value and return it. | ||
|
||
Args: | ||
get_from_carrier: a function that can retrieve zero | ||
or more values from the carrier. In the case that | ||
the value does not exist, return an empty list. | ||
carrier: and object which contains values that are | ||
used to construct a SpanContext. This object | ||
must be paired with an appropriate get_from_carrier | ||
which understands how to extract a value from it. | ||
Returns: | ||
A SpanContext with configuration found in the carrier. | ||
|
||
""" | ||
if context: | ||
return context | ||
return Context.current() | ||
|
||
|
||
class DefaultHTTPInjector(HTTPInjector): | ||
class DefaultInjector(Injector): | ||
"""The default Injector that is used when no Injector implementation is configured. | ||
|
||
All operations are no-ops. | ||
""" | ||
|
||
@classmethod | ||
def inject( | ||
cls, | ||
carrier: ContextT, | ||
context: typing.Optional[Context] = None, | ||
set_in_carrier: typing.Optional[Setter[ContextT]] = None, | ||
) -> None: | ||
"""Inject values from a SpanContext into a carrier. | ||
|
||
inject enables the propagation of values into HTTP clients or | ||
other objects which perform an HTTP request. Implementations | ||
should use the set_in_carrier method to set values on the | ||
carrier. | ||
|
||
Args: | ||
context: The SpanContext to read values from. | ||
set_in_carrier: A setter function that can set values | ||
on the carrier. | ||
carrier: An object that a place to define HTTP headers. | ||
Should be paired with set_in_carrier, which should | ||
know how to set header values on the carrier. | ||
|
||
""" | ||
return None |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,8 +19,8 @@ | |
from opentelemetry.context import Context | ||
from opentelemetry.context.propagation import ( | ||
ContextT, | ||
DefaultHTTPExtractor, | ||
DefaultHTTPInjector, | ||
DefaultExtractor, | ||
DefaultInjector, | ||
Getter, | ||
Setter, | ||
) | ||
|
@@ -29,14 +29,12 @@ | |
def extract( | ||
carrier: ContextT, | ||
context: typing.Optional[Context] = None, | ||
extractors: typing.Optional[ | ||
typing.List[httptextformat.HTTPExtractor] | ||
] = None, | ||
extractors: typing.Optional[typing.List[httptextformat.Extractor]] = None, | ||
get_from_carrier: typing.Optional[Getter[ContextT]] = None, | ||
) -> typing.Optional[Context]: | ||
"""Load the parent SpanContext from values in the carrier. | ||
|
||
Using the specified HTTPExtractor, the propagator will | ||
Using the specified Extractor, the propagator will | ||
extract a SpanContext from the carrier. If one is found, | ||
it will be set as the parent context of the current span. | ||
|
||
|
@@ -69,9 +67,7 @@ def extract( | |
|
||
def inject( | ||
carrier: ContextT, | ||
injectors: typing.Optional[ | ||
typing.List[httptextformat.HTTPInjector] | ||
] = None, | ||
injectors: typing.Optional[typing.List[httptextformat.Injector]] = None, | ||
context: typing.Optional[Context] = None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Good catch, thanks! |
||
) -> None: | ||
"""Inject values from the current context into the carrier. | ||
|
@@ -98,16 +94,16 @@ def inject( | |
|
||
|
||
_HTTP_TEXT_INJECTORS = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any specific reason to use a list instead of a tuple? |
||
DefaultHTTPInjector | ||
] # typing.List[httptextformat.HTTPInjector] | ||
DefaultInjector | ||
] # typing.List[httptextformat.Injector] | ||
|
||
_HTTP_TEXT_EXTRACTORS = [ | ||
DefaultHTTPExtractor | ||
] # typing.List[httptextformat.HTTPExtractor] | ||
DefaultExtractor | ||
] # typing.List[httptextformat.Extractor] | ||
|
||
|
||
def set_http_extractors( | ||
extractor_list: typing.List[httptextformat.HTTPExtractor], | ||
extractor_list: typing.List[httptextformat.Extractor], | ||
) -> None: | ||
""" | ||
To update the global extractor, the Propagation API provides a | ||
|
@@ -118,7 +114,7 @@ def set_http_extractors( | |
|
||
|
||
def set_http_injectors( | ||
injector_list: typing.List[httptextformat.HTTPInjector], | ||
injector_list: typing.List[httptextformat.Injector], | ||
) -> None: | ||
""" | ||
To update the global injector, the Propagation API provides a | ||
|
@@ -128,15 +124,15 @@ def set_http_injectors( | |
_HTTP_TEXT_INJECTORS = injector_list # type: ignore | ||
|
||
|
||
def get_http_extractors() -> typing.List[httptextformat.HTTPExtractor]: | ||
def get_http_extractors() -> typing.List[httptextformat.Extractor]: | ||
""" | ||
To access the global extractor, the Propagation API provides | ||
a function which returns an extractor. | ||
""" | ||
return _HTTP_TEXT_EXTRACTORS # type: ignore | ||
|
||
|
||
def get_http_injectors() -> typing.List[httptextformat.HTTPInjector]: | ||
def get_http_injectors() -> typing.List[httptextformat.Injector]: | ||
""" | ||
To access the global injector, the Propagation API provides a | ||
function which returns an injector. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the goal here to change these classes' import paths?
For example, I see
opentelemetry-api/src/opentelemetry/propagation/__init__.py
does:instead of
Why do this?