lfx-amazon 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
lfx_amazon/__init__.py ADDED
@@ -0,0 +1,19 @@
1
+ """lfx-amazon: Amazon bundle.
2
+
3
+ Distribution unit ``lfx-amazon``. At runtime Langflow's loader
4
+ discovers ``extension.json`` shipped alongside this ``__init__.py`` and
5
+ registers the bundle's components under the namespaced IDs
6
+ ``ext:amazon:<Class>@official``.
7
+ """
8
+
9
+ from lfx_amazon.components.amazon.amazon_bedrock_converse import AmazonBedrockConverseComponent
10
+ from lfx_amazon.components.amazon.amazon_bedrock_embedding import AmazonBedrockEmbeddingsComponent
11
+ from lfx_amazon.components.amazon.amazon_bedrock_model import AmazonBedrockComponent
12
+ from lfx_amazon.components.amazon.s3_bucket_uploader import S3BucketUploaderComponent
13
+
14
+ __all__ = [
15
+ "AmazonBedrockComponent",
16
+ "AmazonBedrockConverseComponent",
17
+ "AmazonBedrockEmbeddingsComponent",
18
+ "S3BucketUploaderComponent",
19
+ ]
File without changes
@@ -0,0 +1,51 @@
1
+ """Lazy component re-exports for the ``amazon`` bundle.
2
+
3
+ Mirrors the pre-extraction layout of ``lfx.components.amazon`` so saved
4
+ flows that referenced the module-level class
5
+ (e.g. ``lfx.components.amazon.<Class>``) keep resolving via the
6
+ migration table after rewrite to
7
+ ``lfx_amazon.components.amazon.<Class>``.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ from lfx.utils.lazy_import import import_mod
15
+
16
+ if TYPE_CHECKING:
17
+ from .amazon_bedrock_converse import AmazonBedrockConverseComponent
18
+ from .amazon_bedrock_embedding import AmazonBedrockEmbeddingsComponent
19
+ from .amazon_bedrock_model import AmazonBedrockComponent
20
+ from .s3_bucket_uploader import S3BucketUploaderComponent
21
+
22
+ _dynamic_imports = {
23
+ "AmazonBedrockComponent": "amazon_bedrock_model",
24
+ "AmazonBedrockConverseComponent": "amazon_bedrock_converse",
25
+ "AmazonBedrockEmbeddingsComponent": "amazon_bedrock_embedding",
26
+ "S3BucketUploaderComponent": "s3_bucket_uploader",
27
+ }
28
+
29
+ __all__ = [
30
+ "AmazonBedrockComponent",
31
+ "AmazonBedrockConverseComponent",
32
+ "AmazonBedrockEmbeddingsComponent",
33
+ "S3BucketUploaderComponent",
34
+ ]
35
+
36
+
37
+ def __getattr__(attr_name: str) -> Any:
38
+ if attr_name not in _dynamic_imports:
39
+ msg = f"module {__name__!r} has no attribute {attr_name!r}"
40
+ raise AttributeError(msg)
41
+ try:
42
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
43
+ except (ModuleNotFoundError, ImportError, AttributeError) as e:
44
+ msg = f"Could not import {attr_name!r} from {__name__!r}: {e}"
45
+ raise AttributeError(msg) from e
46
+ globals()[attr_name] = result
47
+ return result
48
+
49
+
50
+ def __dir__() -> list[str]:
51
+ return list(__all__)
@@ -0,0 +1,194 @@
1
+ from lfx.base.models.aws_constants import AWS_REGIONS, AWS_MODEL_IDs
2
+ from lfx.base.models.model import LCModelComponent
3
+ from lfx.field_typing import LanguageModel
4
+ from lfx.inputs.inputs import BoolInput, FloatInput, IntInput, MessageTextInput, SecretStrInput
5
+ from lfx.io import DictInput, DropdownInput
6
+
7
+
8
+ class AmazonBedrockConverseComponent(LCModelComponent):
9
+ display_name: str = "Amazon Bedrock Converse"
10
+ description: str = (
11
+ "Generate text using Amazon Bedrock LLMs with the modern Converse API for improved conversation handling."
12
+ )
13
+ icon = "Amazon"
14
+ name = "AmazonBedrockConverseModel"
15
+ beta = True
16
+
17
+ inputs = [
18
+ *LCModelComponent.get_base_inputs(),
19
+ DropdownInput(
20
+ name="model_id",
21
+ display_name="Model ID",
22
+ options=AWS_MODEL_IDs,
23
+ value="anthropic.claude-3-5-sonnet-20241022-v2:0",
24
+ info="List of available model IDs to choose from.",
25
+ ),
26
+ SecretStrInput(
27
+ name="aws_access_key_id",
28
+ display_name="AWS Access Key ID",
29
+ info="The access key for your AWS account. "
30
+ "Usually set in Python code as the environment variable 'AWS_ACCESS_KEY_ID'.",
31
+ value="AWS_ACCESS_KEY_ID",
32
+ required=True,
33
+ ),
34
+ SecretStrInput(
35
+ name="aws_secret_access_key",
36
+ display_name="AWS Secret Access Key",
37
+ info="The secret key for your AWS account. "
38
+ "Usually set in Python code as the environment variable 'AWS_SECRET_ACCESS_KEY'.",
39
+ value="AWS_SECRET_ACCESS_KEY",
40
+ required=True,
41
+ ),
42
+ SecretStrInput(
43
+ name="aws_session_token",
44
+ display_name="AWS Session Token",
45
+ advanced=True,
46
+ info="The session key for your AWS account. "
47
+ "Only needed for temporary credentials. "
48
+ "Usually set in Python code as the environment variable 'AWS_SESSION_TOKEN'.",
49
+ load_from_db=False,
50
+ ),
51
+ SecretStrInput(
52
+ name="credentials_profile_name",
53
+ display_name="Credentials Profile Name",
54
+ advanced=True,
55
+ info="The name of the profile to use from your "
56
+ "~/.aws/credentials file. "
57
+ "If not provided, the default profile will be used.",
58
+ load_from_db=False,
59
+ ),
60
+ DropdownInput(
61
+ name="region_name",
62
+ display_name="Region Name",
63
+ value="us-east-1",
64
+ options=AWS_REGIONS,
65
+ info="The AWS region where your Bedrock resources are located.",
66
+ ),
67
+ MessageTextInput(
68
+ name="endpoint_url",
69
+ display_name="Endpoint URL",
70
+ advanced=True,
71
+ info="The URL of the Bedrock endpoint to use.",
72
+ ),
73
+ # Model-specific parameters for fine control
74
+ FloatInput(
75
+ name="temperature",
76
+ display_name="Temperature",
77
+ value=0.7,
78
+ info="Controls randomness in output. Higher values make output more random.",
79
+ advanced=True,
80
+ ),
81
+ IntInput(
82
+ name="max_tokens",
83
+ display_name="Max Tokens",
84
+ value=4096,
85
+ info="Maximum number of tokens to generate.",
86
+ advanced=True,
87
+ ),
88
+ FloatInput(
89
+ name="top_p",
90
+ display_name="Top P",
91
+ value=0.9,
92
+ info="Nucleus sampling parameter. Controls diversity of output.",
93
+ advanced=True,
94
+ ),
95
+ IntInput(
96
+ name="top_k",
97
+ display_name="Top K",
98
+ value=250,
99
+ info="Limits the number of highest probability vocabulary tokens to consider. "
100
+ "Note: Not all models support top_k. Use 'Additional Model Fields' for manual configuration if needed.",
101
+ advanced=True,
102
+ ),
103
+ BoolInput(
104
+ name="disable_streaming",
105
+ display_name="Disable Streaming",
106
+ value=False,
107
+ info="If True, disables streaming responses. Useful for batch processing.",
108
+ advanced=True,
109
+ ),
110
+ DictInput(
111
+ name="additional_model_fields",
112
+ display_name="Additional Model Fields",
113
+ advanced=True,
114
+ is_list=True,
115
+ info="Additional model-specific parameters for fine-tuning behavior.",
116
+ ),
117
+ ]
118
+
119
+ def build_model(self) -> LanguageModel: # type: ignore[type-var]
120
+ try:
121
+ from langchain_aws.chat_models.bedrock_converse import ChatBedrockConverse
122
+ except ImportError as e:
123
+ msg = "langchain_aws is not installed. Please install it with `pip install langchain_aws`."
124
+ raise ImportError(msg) from e
125
+
126
+ # Prepare initialization parameters
127
+ init_params = {
128
+ "model": self.model_id,
129
+ "region_name": self.region_name,
130
+ }
131
+
132
+ # Add AWS credentials if provided
133
+ if self.aws_access_key_id:
134
+ init_params["aws_access_key_id"] = self.aws_access_key_id
135
+ if self.aws_secret_access_key:
136
+ init_params["aws_secret_access_key"] = self.aws_secret_access_key
137
+ if self.aws_session_token:
138
+ init_params["aws_session_token"] = self.aws_session_token
139
+ if self.credentials_profile_name:
140
+ init_params["credentials_profile_name"] = self.credentials_profile_name
141
+ if self.endpoint_url:
142
+ init_params["endpoint_url"] = self.endpoint_url
143
+
144
+ # Add model parameters directly as supported by ChatBedrockConverse
145
+ if hasattr(self, "temperature") and self.temperature is not None:
146
+ init_params["temperature"] = self.temperature
147
+ if hasattr(self, "max_tokens") and self.max_tokens is not None:
148
+ init_params["max_tokens"] = self.max_tokens
149
+ if hasattr(self, "top_p") and self.top_p is not None:
150
+ init_params["top_p"] = self.top_p
151
+
152
+ # Handle streaming - only disable if explicitly requested
153
+ if hasattr(self, "disable_streaming") and self.disable_streaming:
154
+ init_params["disable_streaming"] = True
155
+
156
+ # Handle additional model request fields carefully
157
+ # Based on the error, inferenceConfig should not be passed as additional fields for some models
158
+ additional_model_request_fields = {}
159
+
160
+ # Only add top_k if user explicitly provided additional fields or if needed for specific models
161
+ if hasattr(self, "additional_model_fields") and self.additional_model_fields:
162
+ for field in self.additional_model_fields:
163
+ if isinstance(field, dict):
164
+ additional_model_request_fields.update(field)
165
+
166
+ # For now, don't automatically add inferenceConfig for top_k to avoid validation errors
167
+ # Users can manually add it via additional_model_fields if their model supports it
168
+
169
+ # Only add if we have actual additional fields
170
+ if additional_model_request_fields:
171
+ init_params["additional_model_request_fields"] = additional_model_request_fields
172
+
173
+ try:
174
+ output = ChatBedrockConverse(**init_params)
175
+ except Exception as e:
176
+ # Provide helpful error message with fallback suggestions
177
+ error_details = str(e)
178
+ if "validation error" in error_details.lower():
179
+ msg = (
180
+ f"ChatBedrockConverse validation error: {error_details}. "
181
+ f"This may be due to incompatible parameters for model '{self.model_id}'. "
182
+ f"Consider adjusting the model parameters or trying the legacy Amazon Bedrock component."
183
+ )
184
+ elif "converse api" in error_details.lower():
185
+ msg = (
186
+ f"Converse API error: {error_details}. "
187
+ f"The model '{self.model_id}' may not support the Converse API. "
188
+ f"Try using the legacy Amazon Bedrock component instead."
189
+ )
190
+ else:
191
+ msg = f"Could not initialize ChatBedrockConverse: {error_details}"
192
+ raise ValueError(msg) from e
193
+
194
+ return output
@@ -0,0 +1,109 @@
1
+ from lfx.base.models.aws_constants import AWS_EMBEDDING_MODEL_IDS, AWS_REGIONS
2
+ from lfx.base.models.model import LCModelComponent
3
+ from lfx.field_typing import Embeddings
4
+ from lfx.inputs.inputs import SecretStrInput
5
+ from lfx.io import DropdownInput, MessageTextInput, Output
6
+
7
+
8
+ class AmazonBedrockEmbeddingsComponent(LCModelComponent):
9
+ display_name: str = "Amazon Bedrock Embeddings"
10
+ description: str = "Generate embeddings using Amazon Bedrock models."
11
+ icon = "Amazon"
12
+ name = "AmazonBedrockEmbeddings"
13
+
14
+ inputs = [
15
+ DropdownInput(
16
+ name="model_id",
17
+ display_name="Model Id",
18
+ options=AWS_EMBEDDING_MODEL_IDS,
19
+ value="amazon.titan-embed-text-v1",
20
+ ),
21
+ SecretStrInput(
22
+ name="aws_access_key_id",
23
+ display_name="AWS Access Key ID",
24
+ info="The access key for your AWS account."
25
+ "Usually set in Python code as the environment variable 'AWS_ACCESS_KEY_ID'.",
26
+ value="AWS_ACCESS_KEY_ID",
27
+ required=True,
28
+ ),
29
+ SecretStrInput(
30
+ name="aws_secret_access_key",
31
+ display_name="AWS Secret Access Key",
32
+ info="The secret key for your AWS account. "
33
+ "Usually set in Python code as the environment variable 'AWS_SECRET_ACCESS_KEY'.",
34
+ value="AWS_SECRET_ACCESS_KEY",
35
+ required=True,
36
+ ),
37
+ SecretStrInput(
38
+ name="aws_session_token",
39
+ display_name="AWS Session Token",
40
+ advanced=False,
41
+ info="The session key for your AWS account. "
42
+ "Only needed for temporary credentials. "
43
+ "Usually set in Python code as the environment variable 'AWS_SESSION_TOKEN'.",
44
+ value="AWS_SESSION_TOKEN",
45
+ ),
46
+ SecretStrInput(
47
+ name="credentials_profile_name",
48
+ display_name="Credentials Profile Name",
49
+ advanced=True,
50
+ info="The name of the profile to use from your "
51
+ "~/.aws/credentials file. "
52
+ "If not provided, the default profile will be used.",
53
+ value="AWS_CREDENTIALS_PROFILE_NAME",
54
+ ),
55
+ DropdownInput(
56
+ name="region_name",
57
+ display_name="Region Name",
58
+ value="us-east-1",
59
+ options=AWS_REGIONS,
60
+ info="The AWS region where your Bedrock resources are located.",
61
+ ),
62
+ MessageTextInput(
63
+ name="endpoint_url",
64
+ display_name="Endpoint URL",
65
+ advanced=True,
66
+ info="The URL of the AWS Bedrock endpoint to use.",
67
+ ),
68
+ ]
69
+
70
+ outputs = [
71
+ Output(display_name="Embeddings", name="embeddings", method="build_embeddings"),
72
+ ]
73
+
74
+ def build_embeddings(self) -> Embeddings:
75
+ try:
76
+ from langchain_aws import BedrockEmbeddings
77
+ except ImportError as e:
78
+ msg = "langchain_aws is not installed. Please install it with `pip install langchain_aws`."
79
+ raise ImportError(msg) from e
80
+ try:
81
+ import boto3
82
+ except ImportError as e:
83
+ msg = "boto3 is not installed. Please install it with `pip install boto3`."
84
+ raise ImportError(msg) from e
85
+ if self.aws_access_key_id or self.aws_secret_access_key:
86
+ session = boto3.Session(
87
+ aws_access_key_id=self.aws_access_key_id,
88
+ aws_secret_access_key=self.aws_secret_access_key,
89
+ aws_session_token=self.aws_session_token,
90
+ )
91
+ elif self.credentials_profile_name:
92
+ session = boto3.Session(profile_name=self.credentials_profile_name)
93
+ else:
94
+ session = boto3.Session()
95
+
96
+ client_params = {}
97
+ if self.endpoint_url:
98
+ client_params["endpoint_url"] = self.endpoint_url
99
+ if self.region_name:
100
+ client_params["region_name"] = self.region_name
101
+
102
+ boto3_client = session.client("bedrock-runtime", **client_params)
103
+ return BedrockEmbeddings(
104
+ credentials_profile_name=self.credentials_profile_name,
105
+ client=boto3_client,
106
+ model_id=self.model_id,
107
+ endpoint_url=self.endpoint_url,
108
+ region_name=self.region_name,
109
+ )
@@ -0,0 +1,130 @@
1
+ from lfx.base.models.aws_constants import AWS_REGIONS, AWS_MODEL_IDs
2
+ from lfx.base.models.model import LCModelComponent
3
+ from lfx.field_typing import LanguageModel
4
+ from lfx.inputs.inputs import MessageTextInput, SecretStrInput
5
+ from lfx.io import DictInput, DropdownInput
6
+
7
+
8
+ class AmazonBedrockComponent(LCModelComponent):
9
+ display_name: str = "Amazon Bedrock"
10
+ description: str = (
11
+ "Generate text using Amazon Bedrock LLMs with the legacy ChatBedrock API. "
12
+ "This component is deprecated. Please use Amazon Bedrock Converse instead "
13
+ "for better compatibility, newer features, and improved conversation handling."
14
+ )
15
+ icon = "Amazon"
16
+ name = "AmazonBedrockModel"
17
+ legacy = True
18
+ replacement = "amazon.AmazonBedrockConverseModel"
19
+
20
+ inputs = [
21
+ *LCModelComponent.get_base_inputs(),
22
+ DropdownInput(
23
+ name="model_id",
24
+ display_name="Model ID",
25
+ options=AWS_MODEL_IDs,
26
+ value="anthropic.claude-3-haiku-20240307-v1:0",
27
+ info="List of available model IDs to choose from.",
28
+ ),
29
+ SecretStrInput(
30
+ name="aws_access_key_id",
31
+ display_name="AWS Access Key ID",
32
+ info="The access key for your AWS account."
33
+ "Usually set in Python code as the environment variable 'AWS_ACCESS_KEY_ID'.",
34
+ value="AWS_ACCESS_KEY_ID",
35
+ required=True,
36
+ ),
37
+ SecretStrInput(
38
+ name="aws_secret_access_key",
39
+ display_name="AWS Secret Access Key",
40
+ info="The secret key for your AWS account. "
41
+ "Usually set in Python code as the environment variable 'AWS_SECRET_ACCESS_KEY'.",
42
+ value="AWS_SECRET_ACCESS_KEY",
43
+ required=True,
44
+ ),
45
+ SecretStrInput(
46
+ name="aws_session_token",
47
+ display_name="AWS Session Token",
48
+ advanced=False,
49
+ info="The session key for your AWS account. "
50
+ "Only needed for temporary credentials. "
51
+ "Usually set in Python code as the environment variable 'AWS_SESSION_TOKEN'.",
52
+ load_from_db=False,
53
+ ),
54
+ SecretStrInput(
55
+ name="credentials_profile_name",
56
+ display_name="Credentials Profile Name",
57
+ advanced=True,
58
+ info="The name of the profile to use from your "
59
+ "~/.aws/credentials file. "
60
+ "If not provided, the default profile will be used.",
61
+ load_from_db=False,
62
+ ),
63
+ DropdownInput(
64
+ name="region_name",
65
+ display_name="Region Name",
66
+ value="us-east-1",
67
+ options=AWS_REGIONS,
68
+ info="The AWS region where your Bedrock resources are located.",
69
+ ),
70
+ DictInput(
71
+ name="model_kwargs",
72
+ display_name="Model Kwargs",
73
+ advanced=True,
74
+ is_list=True,
75
+ info="Additional keyword arguments to pass to the model.",
76
+ ),
77
+ MessageTextInput(
78
+ name="endpoint_url",
79
+ display_name="Endpoint URL",
80
+ advanced=True,
81
+ info="The URL of the Bedrock endpoint to use.",
82
+ ),
83
+ ]
84
+
85
+ def build_model(self) -> LanguageModel: # type: ignore[type-var]
86
+ try:
87
+ from langchain_aws import ChatBedrock
88
+ except ImportError as e:
89
+ msg = "langchain_aws is not installed. Please install it with `pip install langchain_aws`."
90
+ raise ImportError(msg) from e
91
+ try:
92
+ import boto3
93
+ except ImportError as e:
94
+ msg = "boto3 is not installed. Please install it with `pip install boto3`."
95
+ raise ImportError(msg) from e
96
+ if self.aws_access_key_id or self.aws_secret_access_key:
97
+ try:
98
+ session = boto3.Session(
99
+ aws_access_key_id=self.aws_access_key_id,
100
+ aws_secret_access_key=self.aws_secret_access_key,
101
+ aws_session_token=self.aws_session_token,
102
+ )
103
+ except Exception as e:
104
+ msg = "Could not create a boto3 session."
105
+ raise ValueError(msg) from e
106
+ elif self.credentials_profile_name:
107
+ session = boto3.Session(profile_name=self.credentials_profile_name)
108
+ else:
109
+ session = boto3.Session()
110
+
111
+ client_params = {}
112
+ if self.endpoint_url:
113
+ client_params["endpoint_url"] = self.endpoint_url
114
+ if self.region_name:
115
+ client_params["region_name"] = self.region_name
116
+
117
+ boto3_client = session.client("bedrock-runtime", **client_params)
118
+ try:
119
+ output = ChatBedrock(
120
+ client=boto3_client,
121
+ model_id=self.model_id,
122
+ region_name=self.region_name,
123
+ model_kwargs=self.model_kwargs,
124
+ endpoint_url=self.endpoint_url,
125
+ streaming=self.stream,
126
+ )
127
+ except Exception as e:
128
+ msg = "Could not connect to AmazonBedrock API."
129
+ raise ValueError(msg) from e
130
+ return output
@@ -0,0 +1,211 @@
1
+ from pathlib import Path
2
+ from typing import Any
3
+
4
+ from lfx.custom.custom_component.component import Component
5
+ from lfx.io import (
6
+ BoolInput,
7
+ DropdownInput,
8
+ HandleInput,
9
+ Output,
10
+ SecretStrInput,
11
+ StrInput,
12
+ )
13
+
14
+
15
+ class S3BucketUploaderComponent(Component):
16
+ """S3BucketUploaderComponent is a component responsible for uploading files to an S3 bucket.
17
+
18
+ It provides two strategies for file upload: "By Data" and "By File Name". The component
19
+ requires AWS credentials and bucket details as inputs and processes files accordingly.
20
+
21
+ Attributes:
22
+ display_name (str): The display name of the component.
23
+ description (str): A brief description of the components functionality.
24
+ icon (str): The icon representing the component.
25
+ name (str): The internal name of the component.
26
+ inputs (list): A list of input configurations required by the component.
27
+ outputs (list): A list of output configurations provided by the component.
28
+
29
+ Methods:
30
+ process_files() -> None:
31
+ Processes files based on the selected strategy. Calls the appropriate method
32
+ based on the strategy attribute.
33
+ process_files_by_data() -> None:
34
+ Processes and uploads files to an S3 bucket based on the data inputs. Iterates
35
+ over the data inputs, logs the file path and text content, and uploads each file
36
+ to the specified S3 bucket if both file path and text content are available.
37
+ process_files_by_name() -> None:
38
+ Processes and uploads files to an S3 bucket based on their names. Iterates through
39
+ the list of data inputs, retrieves the file path from each data item, and uploads
40
+ the file to the specified S3 bucket if the file path is available. Logs the file
41
+ path being uploaded.
42
+ _s3_client() -> Any:
43
+ Creates and returns an S3 client using the provided AWS access key ID and secret
44
+ access key.
45
+
46
+ Please note that this component requires the boto3 library to be installed. It is designed
47
+ to work with File and Director components as inputs
48
+ """
49
+
50
+ display_name = "S3 Bucket Uploader"
51
+ description = "Uploads files to S3 bucket."
52
+ icon = "Amazon"
53
+ name = "s3bucketuploader"
54
+
55
+ inputs = [
56
+ SecretStrInput(
57
+ name="aws_access_key_id",
58
+ display_name="AWS Access Key ID",
59
+ required=True,
60
+ password=True,
61
+ info="AWS Access key ID.",
62
+ ),
63
+ SecretStrInput(
64
+ name="aws_secret_access_key",
65
+ display_name="AWS Secret Key",
66
+ required=True,
67
+ password=True,
68
+ info="AWS Secret Key.",
69
+ ),
70
+ StrInput(
71
+ name="bucket_name",
72
+ display_name="Bucket Name",
73
+ info="Enter the name of the bucket.",
74
+ advanced=False,
75
+ ),
76
+ DropdownInput(
77
+ name="strategy",
78
+ display_name="Strategy for file upload",
79
+ options=["Store Data", "Store Original File"],
80
+ value="By Data",
81
+ info=(
82
+ "Choose the strategy to upload the file. By Data means that the source file "
83
+ "is parsed and stored as LangFlow data. By File Name means that the source "
84
+ "file is uploaded as is."
85
+ ),
86
+ ),
87
+ HandleInput(
88
+ name="data_inputs",
89
+ display_name="Data Inputs",
90
+ info="The data to split.",
91
+ input_types=["Data", "JSON"],
92
+ is_list=True,
93
+ required=True,
94
+ ),
95
+ StrInput(
96
+ name="s3_prefix",
97
+ display_name="S3 Prefix",
98
+ info="Prefix for all files.",
99
+ advanced=True,
100
+ ),
101
+ BoolInput(
102
+ name="strip_path",
103
+ display_name="Strip Path",
104
+ info="Removes path from file path.",
105
+ required=True,
106
+ advanced=True,
107
+ ),
108
+ ]
109
+
110
+ outputs = [
111
+ Output(display_name="Writes to AWS Bucket", name="data", method="process_files"),
112
+ ]
113
+
114
+ def process_files(self) -> None:
115
+ """Process files based on the selected strategy.
116
+
117
+ This method uses a strategy pattern to process files. The strategy is determined
118
+ by the `self.strategy` attribute, which can be either "By Data" or "By File Name".
119
+ Depending on the strategy, the corresponding method (`process_files_by_data` or
120
+ `process_files_by_name`) is called. If an invalid strategy is provided, an error
121
+ is logged.
122
+
123
+ Returns:
124
+ None
125
+ """
126
+ strategy_methods = {
127
+ "Store Data": self.process_files_by_data,
128
+ "Store Original File": self.process_files_by_name,
129
+ }
130
+ strategy_methods.get(self.strategy, lambda: self.log("Invalid strategy"))()
131
+
132
+ def process_files_by_data(self) -> None:
133
+ """Processes and uploads files to an S3 bucket based on the data inputs.
134
+
135
+ This method iterates over the data inputs, logs the file path and text content,
136
+ and uploads each file to the specified S3 bucket if both file path and text content
137
+ are available.
138
+
139
+ Args:
140
+ None
141
+
142
+ Returns:
143
+ None
144
+ """
145
+ for data_item in self.data_inputs:
146
+ file_path = data_item.data.get("file_path")
147
+ text_content = data_item.data.get("text")
148
+
149
+ if file_path and text_content:
150
+ self._s3_client().put_object(
151
+ Bucket=self.bucket_name, Key=self._normalize_path(file_path), Body=text_content
152
+ )
153
+
154
+ def process_files_by_name(self) -> None:
155
+ """Processes and uploads files to an S3 bucket based on their names.
156
+
157
+ Iterates through the list of data inputs, retrieves the file path from each data item,
158
+ and uploads the file to the specified S3 bucket if the file path is available.
159
+ Logs the file path being uploaded.
160
+
161
+ Returns:
162
+ None
163
+ """
164
+ for data_item in self.data_inputs:
165
+ file_path = data_item.data.get("file_path")
166
+ self.log(f"Uploading file: {file_path}")
167
+ if file_path:
168
+ self._s3_client().upload_file(file_path, Bucket=self.bucket_name, Key=self._normalize_path(file_path))
169
+
170
+ def _s3_client(self) -> Any:
171
+ """Creates and returns an S3 client using the provided AWS access key ID and secret access key.
172
+
173
+ Returns:
174
+ Any: A boto3 S3 client instance.
175
+ """
176
+ try:
177
+ import boto3
178
+ except ImportError as e:
179
+ msg = "boto3 is not installed. Please install it using `uv pip install boto3`."
180
+ raise ImportError(msg) from e
181
+
182
+ return boto3.client(
183
+ "s3",
184
+ aws_access_key_id=self.aws_access_key_id,
185
+ aws_secret_access_key=self.aws_secret_access_key,
186
+ )
187
+
188
+ def _normalize_path(self, file_path) -> str:
189
+ """Process the file path based on the s3_prefix and path_as_prefix.
190
+
191
+ Args:
192
+ file_path (str): The original file path.
193
+ s3_prefix (str): The S3 prefix to use.
194
+ path_as_prefix (bool): Whether to use the file path as the S3 prefix.
195
+
196
+ Returns:
197
+ str: The processed file path.
198
+ """
199
+ prefix = self.s3_prefix
200
+ strip_path = self.strip_path
201
+ processed_path: str = file_path
202
+
203
+ if strip_path:
204
+ # Filename only
205
+ processed_path = Path(file_path).name
206
+
207
+ # Concatenate the s3_prefix if it exists
208
+ if prefix:
209
+ processed_path = str(Path(prefix) / processed_path)
210
+
211
+ return processed_path
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://schemas.langflow.org/extension/v1.json",
3
+ "id": "lfx-amazon",
4
+ "version": "0.1.0",
5
+ "name": "Amazon",
6
+ "description": "Amazon component(s) as a standalone Langflow Extension Bundle.",
7
+ "lfx": {
8
+ "compat": ["1"]
9
+ },
10
+ "bundles": [
11
+ {
12
+ "name": "amazon",
13
+ "path": "components/amazon"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,45 @@
1
+ Metadata-Version: 2.4
2
+ Name: lfx-amazon
3
+ Version: 0.1.0
4
+ Summary: Amazon component(s) as a standalone Langflow Extension Bundle.
5
+ Project-URL: Homepage, https://github.com/langflow-ai/langflow
6
+ Project-URL: Documentation, https://docs.langflow.org/extensions
7
+ Project-URL: Repository, https://github.com/langflow-ai/langflow
8
+ Author-email: Langflow <contact@langflow.org>
9
+ License: MIT
10
+ Keywords: amazon,bundle,extension,langflow,lfx
11
+ Requires-Python: <3.15,>=3.10
12
+ Requires-Dist: boto3<2.0.0,>=1.34.162
13
+ Requires-Dist: langchain-aws~=1.1.0
14
+ Requires-Dist: lfx<2.0.0,>=1.11.0.dev0
15
+ Description-Content-Type: text/markdown
16
+
17
+ # lfx-amazon
18
+
19
+ Amazon component(s) as a standalone Langflow Extension Bundle.
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pip install lfx-amazon
25
+ ```
26
+
27
+ The bundle is registered automatically via the `langflow.extensions`
28
+ entry-point. After install, restart your Langflow server; the bundle's
29
+ components will appear in the palette under the `amazon` group with
30
+ the namespaced IDs `ext:amazon:<Class>@official`.
31
+
32
+ ## Develop
33
+
34
+ ```bash
35
+ cd src/bundles/amazon
36
+ pip install -e .
37
+ lfx extension validate src/lfx_amazon
38
+ ```
39
+
40
+ ## Migration
41
+
42
+ Saved flows referencing the legacy class name(s) or the old import paths
43
+ under `lfx.components.amazon.*` are rewritten to the new namespaced
44
+ IDs by the migration table in
45
+ `src/lfx/src/lfx/extension/migration/migration_table.json`.
@@ -0,0 +1,12 @@
1
+ lfx_amazon/__init__.py,sha256=xCWeEXTDF1DjAw-55rGmLj0MWT_9N4rhWoF_uXBU1QI,786
2
+ lfx_amazon/extension.json,sha256=Ejr9xXXpgIV_Ny6aBihhTgBQt8mW9rCYaq6zh1pie3A,339
3
+ lfx_amazon/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ lfx_amazon/components/amazon/__init__.py,sha256=VcvjM_esVzalJQaJMiZBPmjcajhmGUBJa5WnSr5X51c,1716
5
+ lfx_amazon/components/amazon/amazon_bedrock_converse.py,sha256=ZrlRn09iUwUiWNEzbcKLdje386r4YGj-bC0j7wyi5wM,8179
6
+ lfx_amazon/components/amazon/amazon_bedrock_embedding.py,sha256=cNA5_3nwkegWS3BY75IfjOwpo-g8dpg-EgtQJSgVXfg,4261
7
+ lfx_amazon/components/amazon/amazon_bedrock_model.py,sha256=kiCTqDG2Krbe0i5YBG9UODxwNTB9ePZwLfgNMR91UwQ,5113
8
+ lfx_amazon/components/amazon/s3_bucket_uploader.py,sha256=EZyJtr1AOad5dg5wr-K9TwXyCjCbb6U5NPV41nYJii4,7696
9
+ lfx_amazon-0.1.0.dist-info/METADATA,sha256=g1GcpT4-VoGMcDRDeWmkLKjQClbscD4YI0WoeFXVzsg,1342
10
+ lfx_amazon-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
11
+ lfx_amazon-0.1.0.dist-info/entry_points.txt,sha256=drlpBtwZARzsmLFCgTKDKFj98bTO_O4u2RpGDRrNiCc,46
12
+ lfx_amazon-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [langflow.extensions]
2
+ lfx-amazon = lfx_amazon