-
-
Notifications
You must be signed in to change notification settings - Fork 0
β‘ Bolt: Implement secret caching in EventBridge handler #74
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
e8c14e9
perf(eventbridge): implement secret caching for API token
google-labs-jules[bot] f6760ed
perf(eventbridge): advanced connection mgmt and model refactor
google-labs-jules[bot] 0c6664c
perf(eventbridge): implement advanced connection mgmt and model refactor
google-labs-jules[bot] cfedc86
perf(eventbridge): robust connection mgmt and model refactor
google-labs-jules[bot] cc07708
perf(eventbridge): robust connection management and model refactor
google-labs-jules[bot] b08dd30
perf(eventbridge): robust connection mgmt and model architecture
google-labs-jules[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,10 @@ | ||
| from typing import Any | ||
| from pydantic import Field | ||
|
|
||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from templates.models import Entity | ||
|
|
||
|
|
||
| class Item(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
| class Item(Entity): | ||
| """Model representing an item managed by the agent.""" | ||
|
|
||
| id: str = Field(description="Unique identifier for the item.", min_length=1, max_length=50) | ||
| name: str = Field(description="Name of the item.", min_length=1, max_length=100) | ||
| description: str | None = Field(description="Description of the item.", default=None, max_length=500) | ||
|
|
||
| def dump(self, **kwargs: Any) -> dict: | ||
| """Dump the model to a dictionary with default settings for responses.""" | ||
| kwargs.setdefault("by_alias", True) | ||
| kwargs.setdefault("exclude_none", True) | ||
| return self.model_dump(**kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,7 @@ | ||
| from typing import Any | ||
| from uuid import uuid4 | ||
| from pydantic import Field | ||
|
|
||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from templates.models import Entity | ||
|
|
||
|
|
||
| class Item(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
| id: str = Field( | ||
| description="Unique item identifier", default_factory=lambda: str(uuid4()), min_length=1, max_length=50 | ||
| ) | ||
| class Item(Entity): | ||
| name: str = Field(description="Human-readable item name", min_length=1, max_length=100) | ||
|
|
||
| def dump(self, **kwargs: Any) -> str: | ||
| """Dump the model to a JSON string with default settings for API responses.""" | ||
| kwargs.setdefault("by_alias", True) | ||
| kwargs.setdefault("exclude_none", True) | ||
| return self.model_dump_json(**kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from pydantic import Field | ||
|
|
||
| from templates.models import Entity | ||
|
|
||
| class ApiResponse(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
| id: str = Field(description="Unique identifier of the API response record", min_length=1, max_length=50) | ||
|
|
||
| class ApiResponse(Entity): | ||
| message: str = Field(description="Message returned by the external API", min_length=1, max_length=1000) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| from aws_lambda_powertools.utilities.parameters import SecretsProvider | ||
| from botocore.config import Config | ||
|
|
||
|
|
||
| class SecretManager: | ||
| """Wrapper around SecretsProvider with configurable retries and caching.""" | ||
|
|
||
| def __init__(self, max_retries: int = 3, max_age: int = 60) -> None: | ||
| """Initialize the SecretManager. | ||
|
|
||
| Args: | ||
| max_retries: Maximum number of retry attempts for AWS service calls. | ||
| max_age: Maximum age of the cached secret in seconds. | ||
| """ | ||
| self._max_age = max_age | ||
| config = Config(tcp_keepalive=True, retries={"max_attempts": max_retries, "mode": "standard"}) | ||
| self._provider = SecretsProvider(boto_config=config) | ||
|
|
||
| def get(self, name: str) -> str: | ||
| """Retrieve a secret by name. | ||
|
|
||
| Args: | ||
| name: The name of the secret to retrieve. | ||
|
|
||
| Returns: | ||
| The secret value as a string. | ||
| """ | ||
| return self._provider.get(name, max_age=self._max_age) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| from typing import Any | ||
|
|
||
| from requests import Response, Session | ||
| from requests.adapters import HTTPAdapter | ||
| from urllib3.util import Retry | ||
|
|
||
|
|
||
| class ApiSession: | ||
| """Manages a configured requests Session with retries and connection pooling.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| max_retries: int = 3, | ||
| backoff_factor: float = 0.3, | ||
| timeout: int = 10, | ||
| status_forcelist: list[int] | None = None, | ||
| pool_connections: int = 10, | ||
| pool_maxsize: int = 10, | ||
| ) -> None: | ||
| """Initialize the ApiSession. | ||
|
|
||
| Args: | ||
| max_retries: Maximum number of retries. | ||
| backoff_factor: Backoff factor for retries. | ||
| timeout: Preset timeout for requests in seconds. | ||
| status_forcelist: List of HTTP status codes to retry on. | ||
| pool_connections: Number of connection pools to cache. | ||
| pool_maxsize: Maximum number of connections to save in the pool. | ||
| """ | ||
| self._timeout = timeout | ||
| self._session = Session() | ||
| retry_strategy = Retry( | ||
| total=max_retries, | ||
| backoff_factor=backoff_factor, | ||
| status_forcelist=status_forcelist or [429, 500, 502, 503, 504], | ||
| ) | ||
| adapter = HTTPAdapter( | ||
| max_retries=retry_strategy, | ||
| pool_connections=pool_connections, | ||
| pool_maxsize=pool_maxsize, | ||
| ) | ||
| self._session.mount("http://", adapter) | ||
| self._session.mount("https://", adapter) | ||
|
|
||
| def get(self, url: str, **kwargs: Any) -> Response: | ||
| """Perform a GET request with the preset timeout. | ||
|
|
||
| Args: | ||
| url: The URL to request. | ||
| **kwargs: Additional arguments passed to the session.get call. | ||
|
|
||
| Returns: | ||
| The Response object. | ||
| """ | ||
| kwargs.setdefault("timeout", self._timeout) | ||
| return self._session.get(url, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,7 @@ | ||
| from typing import Any | ||
| from uuid import uuid4 | ||
| from pydantic import Field | ||
|
|
||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from templates.models import Entity | ||
|
|
||
|
|
||
| class Item(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
| id: str = Field( | ||
| description="Unique item identifier", default_factory=lambda: str(uuid4()), min_length=1, max_length=50 | ||
| ) | ||
| class Item(Entity): | ||
| name: str = Field(description="Human-readable item name", min_length=1, max_length=100) | ||
|
|
||
| def dump(self, **kwargs: Any) -> dict: | ||
| kwargs.setdefault("by_alias", True) | ||
| kwargs.setdefault("exclude_none", True) | ||
| return self.model_dump(**kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| from typing import Any | ||
| from uuid import uuid4 | ||
|
|
||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
|
|
||
|
|
||
| class Object(BaseModel, populate_by_name=True, alias_generator=to_camel, from_attributes=True): | ||
| """Base model for all data objects with common configuration and helper methods.""" | ||
|
|
||
| def dump(self, **kwargs: Any) -> dict[str, Any]: | ||
| """Dump the model to a dictionary with default settings (camelCase, exclude None).""" | ||
| kwargs.setdefault("by_alias", True) | ||
| kwargs.setdefault("exclude_none", True) | ||
| return self.model_dump(**kwargs) | ||
|
|
||
| def dump_json(self, **kwargs: Any) -> str: | ||
| """Dump the model to a JSON string with default settings (camelCase, exclude None).""" | ||
| kwargs.setdefault("by_alias", True) | ||
| kwargs.setdefault("exclude_none", True) | ||
| return self.model_dump_json(**kwargs) | ||
|
|
||
|
|
||
| class Entity(Object): | ||
| """Base model for entities with a unique identifier.""" | ||
|
|
||
| id: str = Field( | ||
| description="Unique identifier for the entity.", | ||
| default_factory=lambda: str(uuid4()), | ||
| min_length=1, | ||
| max_length=50, | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,16 @@ | ||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from pydantic import Field | ||
|
|
||
| from templates.models import Entity | ||
|
|
||
| class SqsMessage(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
|
|
||
| class SqsMessage(Entity): | ||
| """Model representing the expected SQS message body.""" | ||
|
|
||
| id: str = Field(description="Unique identifier for the message.", min_length=1, max_length=50) | ||
| content: str = Field(description="The main content of the message.", min_length=1, max_length=1000) | ||
|
|
||
|
|
||
| class ProcessedItem(BaseModel, populate_by_name=True, alias_generator=to_camel): | ||
| class ProcessedItem(Entity): | ||
| """Model representing the item to be stored in DynamoDB.""" | ||
|
|
||
| id: str = Field(description="Unique identifier for the item (partition key).", min_length=1, max_length=50) | ||
| content: str = Field(description="The processed content.", min_length=1, max_length=1000) | ||
| status: str = Field(description="Processing status.", min_length=1, max_length=50) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,13 @@ | ||
| from pydantic import BaseModel, Field | ||
| from pydantic.alias_generators import to_camel | ||
| from pydantic import Field | ||
|
|
||
| from templates.models import Entity | ||
|
|
||
| class SourceItem(BaseModel, populate_by_name=True, alias_generator=to_camel, from_attributes=True): | ||
|
|
||
| class SourceItem(Entity): | ||
| id: str = Field(description="Unique item identifier", min_length=1, max_length=50) | ||
| name: str | None = Field(default=None, description="Human-readable item name", min_length=1, max_length=100) | ||
|
|
||
|
|
||
| class DestinationItem(BaseModel, populate_by_name=True, alias_generator=to_camel, from_attributes=True): | ||
| class DestinationItem(Entity): | ||
| id: str = Field(description="Unique item identifier", min_length=1, max_length=50) | ||
| name: str | None = Field(default=None, description="Human-readable item name", min_length=1, max_length=100) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.