Skip to content

Commit 1b33c9e

Browse files
authored
Merge branch 'awslabs:develop' into develop
2 parents 20be2f6 + e1927d5 commit 1b33c9e

File tree

20 files changed

+541
-401
lines changed

20 files changed

+541
-401
lines changed

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
with:
4949
fetch-depth: 0
5050
- name: Set up Python
51-
uses: actions/setup-python@v2.2.2
51+
uses: actions/setup-python@v2.3.1
5252
with:
5353
python-version: "3.8"
5454
- name: Set release notes tag

.github/workflows/python_build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
steps:
2424
- uses: actions/checkout@v1
2525
- name: Set up Python ${{ matrix.python-version }}
26-
uses: actions/setup-python@v2.2.2
26+
uses: actions/setup-python@v2.3.1
2727
with:
2828
python-version: ${{ matrix.python-version }}
2929
- name: Install dependencies

.github/workflows/python_docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
with:
1818
fetch-depth: 0
1919
- name: Set up Python
20-
uses: actions/setup-python@v2.2.2
20+
uses: actions/setup-python@v2.3.1
2121
with:
2222
python-version: "3.8"
2323
- name: Install dependencies

.github/workflows/rebuild_latest_docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
with:
2626
fetch-depth: 0
2727
- name: Set up Python
28-
uses: actions/setup-python@v2.2.2
28+
uses: actions/setup-python@v2.3.1
2929
with:
3030
python-version: "3.8"
3131
- name: Set release notes tag

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ test:
2020
poetry run pytest -m "not perf" --cov=aws_lambda_powertools --cov-report=xml
2121
poetry run pytest --cache-clear tests/performance
2222

23+
unit-test:
24+
poetry run pytest tests/unit
25+
2326
coverage-html:
2427
poetry run pytest -m "not perf" --cov=aws_lambda_powertools --cov-report=html
2528

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ With [pip](https://pip.pypa.io/en/latest/index.html) installed, run: ``pip insta
4747

4848
## Connect
4949

50-
* **AWS Developers Slack**: `#lambda-powertools`** - **[Invite, if you don't have an account](https://join.slack.com/t/awsdevelopers/shared_invite/zt-gu30gquv-EhwIYq3kHhhysaZ2aIX7ew)**
50+
* **AWS Developers Slack**: `#lambda-powertools`** - **[Invite, if you don't have an account](https://join.slack.com/t/awsdevelopers/shared_invite/zt-yryddays-C9fkWrmguDv0h2EEDzCqvw)**
5151
* **Email**: [email protected]
5252

5353
## License

aws_lambda_powertools/event_handler/api_gateway.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,10 @@ def include_router(self, router: "Router", prefix: Optional[str] = None) -> None
664664
prefix : str, optional
665665
An optional prefix to be added to the originally defined rule
666666
"""
667+
668+
# Add reference to parent ApiGatewayResolver to support use cases where people subclass it to add custom logic
669+
router.api_resolver = self
670+
667671
for route, func in router._routes.items():
668672
if prefix:
669673
rule = route[0]
@@ -678,6 +682,7 @@ class Router(BaseRouter):
678682

679683
def __init__(self):
680684
self._routes: Dict[tuple, Callable] = {}
685+
self.api_resolver: Optional[BaseRouter] = None
681686

682687
def route(
683688
self,

aws_lambda_powertools/metrics/metric.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
import logging
33
from contextlib import contextmanager
4-
from typing import Dict, Optional, Union
4+
from typing import Dict, Optional, Union, Generator
55

66
from .base import MetricManager, MetricUnit
77

@@ -61,7 +61,7 @@ def add_metric(self, name: str, unit: Union[MetricUnit, str], value: float) -> N
6161

6262

6363
@contextmanager
64-
def single_metric(name: str, unit: MetricUnit, value: float, namespace: Optional[str] = None):
64+
def single_metric(name: str, unit: MetricUnit, value: float, namespace: Optional[str] = None) -> Generator[SingleMetric, None, None]:
6565
"""Context manager to simplify creation of a single metric
6666
6767
Example

aws_lambda_powertools/tracing/tracer.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
logger = logging.getLogger(__name__)
1818

1919
aws_xray_sdk = LazyLoader(constants.XRAY_SDK_MODULE, globals(), constants.XRAY_SDK_MODULE)
20-
aws_xray_sdk.core = LazyLoader(constants.XRAY_SDK_CORE_MODULE, globals(), constants.XRAY_SDK_CORE_MODULE) # type: ignore # noqa: E501
2120

2221

2322
class Tracer:
@@ -137,7 +136,7 @@ def handler(event: dict, context: Any) -> Dict:
137136
"""
138137

139138
_default_config: Dict[str, Any] = {
140-
"service": "service_undefined",
139+
"service": "",
141140
"disabled": False,
142141
"auto_patch": True,
143142
"patch_modules": None,
@@ -156,7 +155,7 @@ def __init__(
156155
self.__build_config(
157156
service=service, disabled=disabled, auto_patch=auto_patch, patch_modules=patch_modules, provider=provider
158157
)
159-
self.provider: BaseProvider = self._config["provider"]
158+
self.provider = self._config["provider"]
160159
self.disabled = self._config["disabled"]
161160
self.service = self._config["service"]
162161
self.auto_patch = self._config["auto_patch"]
@@ -167,10 +166,8 @@ def __init__(
167166
if self.auto_patch:
168167
self.patch(modules=patch_modules)
169168

170-
# Set the streaming threshold to 0 on the default recorder to force sending
171-
# subsegments individually, rather than batching them.
172-
# See https://github.com/awslabs/aws-lambda-powertools-python/issues/283
173-
aws_xray_sdk.core.xray_recorder.configure(streaming_threshold=0) # noqa: E800
169+
if self._is_xray_provider():
170+
self._disable_xray_trace_batching()
174171

175172
def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]):
176173
"""Adds annotation to existing segment or subsegment
@@ -239,9 +236,9 @@ def patch(self, modules: Optional[Sequence[str]] = None):
239236
return
240237

241238
if modules is None:
242-
aws_xray_sdk.core.patch_all()
239+
self.provider.patch_all()
243240
else:
244-
aws_xray_sdk.core.patch(modules)
241+
self.provider.patch(modules)
245242

246243
def capture_lambda_handler(
247244
self,
@@ -304,11 +301,15 @@ def handler(event, context):
304301
def decorate(event, context, **kwargs):
305302
with self.provider.in_subsegment(name=f"## {lambda_handler_name}") as subsegment:
306303
global is_cold_start
304+
logger.debug("Annotating cold start")
305+
subsegment.put_annotation(key="ColdStart", value=is_cold_start)
306+
307307
if is_cold_start:
308-
logger.debug("Annotating cold start")
309-
subsegment.put_annotation(key="ColdStart", value=True)
310308
is_cold_start = False
311309

310+
if self.service:
311+
subsegment.put_annotation(key="Service", value=self.service)
312+
312313
try:
313314
logger.debug("Calling lambda handler")
314315
response = lambda_handler(event, context, **kwargs)
@@ -742,7 +743,8 @@ def __build_config(
742743
is_disabled = disabled if disabled is not None else self._is_tracer_disabled()
743744
is_service = resolve_env_var_choice(choice=service, env=os.getenv(constants.SERVICE_NAME_ENV))
744745

745-
self._config["provider"] = provider or self._config["provider"] or aws_xray_sdk.core.xray_recorder
746+
# Logic: Choose overridden option first, previously cached config, or default if available
747+
self._config["provider"] = provider or self._config["provider"] or self._patch_xray_provider()
746748
self._config["auto_patch"] = auto_patch if auto_patch is not None else self._config["auto_patch"]
747749
self._config["service"] = is_service or self._config["service"]
748750
self._config["disabled"] = is_disabled or self._config["disabled"]
@@ -751,3 +753,28 @@ def __build_config(
751753
@classmethod
752754
def _reset_config(cls):
753755
cls._config = copy.copy(cls._default_config)
756+
757+
def _patch_xray_provider(self):
758+
# Due to Lazy Import, we need to activate `core` attrib via import
759+
# we also need to include `patch`, `patch_all` methods
760+
# to ensure patch calls are done via the provider
761+
from aws_xray_sdk.core import xray_recorder
762+
763+
provider = xray_recorder
764+
provider.patch = aws_xray_sdk.core.patch
765+
provider.patch_all = aws_xray_sdk.core.patch_all
766+
767+
return provider
768+
769+
def _disable_xray_trace_batching(self):
770+
"""Configure X-Ray SDK to send subsegment individually over batching
771+
Known issue: https://github.com/awslabs/aws-lambda-powertools-python/issues/283
772+
"""
773+
if self.disabled:
774+
logger.debug("Tracing has been disabled, aborting streaming override")
775+
return
776+
777+
aws_xray_sdk.core.xray_recorder.configure(streaming_threshold=0)
778+
779+
def _is_xray_provider(self):
780+
return "aws_xray_sdk" in self.provider.__module__

aws_lambda_powertools/utilities/idempotency/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(
5656
self.fn_args = function_args
5757
self.fn_kwargs = function_kwargs
5858

59-
persistence_store.configure(config)
59+
persistence_store.configure(config, self.function.__name__)
6060
self.persistence_store = persistence_store
6161

6262
def handle(self) -> Any:

0 commit comments

Comments
 (0)