Widget work for AWS (#11095)

- Added `to_display_text` for `S3_File` and `Enso_File`.
- Improved widget for `AWS_Credential` allowing use of Enso secrets.
- Adjust `S3.list_objects` to return `S3_File` objects, allowing easier drill down.
- Fix for merging inherited config with direct config in widgets.
- Add missing constant types to Date.Diff widget.

![image](https://github.com/user-attachments/assets/ea125a09-5067-4dee-bef2-3d7c8d551260)
This commit is contained in:
James Dunkerley 2024-09-16 19:56:14 +01:00 committed by GitHub
parent 0b91002933
commit 0e9821519d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 46 additions and 10 deletions

View File

@ -202,7 +202,7 @@ export function functionCallConfiguration(
): FunctionCall {
const parametersMap = new Map(inherited?.parameters)
for (const [name, param] of parameters) {
parametersMap.set(name, param)
parametersMap.set(name, parametersMap.get(name) ?? param)
}
return {
kind: 'FunctionCall',

View File

@ -1,7 +1,10 @@
from Standard.Base import all
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
import Standard.Base.Errors.Common.Missing_Argument
from Standard.Base.Enso_Cloud.Enso_Secret import as_hideable_value
from Standard.Base.Metadata import make_single_choice, Widget
from Standard.Base.Metadata import Display, make_single_choice, Widget
from Standard.Base.Metadata.Choice import Option
from Standard.Base.Widget_Helpers import make_text_secret_selector
import project.AWS_Region.AWS_Region
@ -25,7 +28,9 @@ type AWS_Credential
Arguments:
- access_key_id: AWS access key ID.
- secret_access_key: AWS secret access key.
Key access_key_id:Text|Enso_Secret secret_access_key:Text|Enso_Secret
@access_key_id make_text_secret_selector
@secret_access_key make_text_secret_selector
Key (access_key_id : (Text|Enso_Secret) = (Missing_Argument.throw "access_key_id")) (secret_access_key : (Text|Enso_Secret) = (Missing_Argument.throw "secret_access_key"))
## PRIVATE
Allows to override additional configuration associated with the credential.
@ -35,6 +40,7 @@ type AWS_Credential
Default, Profile, Key.
- default_region: The default region to use for operations that may
require a region but it is not explicitly specified.
@default_region AWS_Region.default_widget
With_Configuration (base_credential : AWS_Credential) (default_region : AWS_Region)
## ICON cloud
@ -106,3 +112,11 @@ type AWS_Credential
## PRIVATE
to_display_text self -> Text = self.to_text.to_display_text
## PRIVATE
default_widget (display : Display = ..When_Modified) -> Widget =
default = Option "Default" "..Default"
profile = Option "Profile" "..Profile" [["profile", make_single_choice AWS_Credential.profile_names]]
key = Option "Key" "..Key" [["access_key_id", make_text_secret_selector], ["secret_access_key", make_text_secret_selector]]
with_config = Option "With_Configuration" "..With_Configuration"
Widget.Single_Choice values=[default, profile, key, with_config] display=display

View File

@ -1,10 +1,12 @@
from Standard.Base import all
import Standard.Base.Errors.Common.Missing_Argument
import Standard.Base.Network.HTTP.Response_Body.Response_Body
import Standard.Base.System.File_Format_Metadata.File_Format_Metadata
import Standard.Base.System.Input_Stream.Input_Stream
from Standard.Base.Network.HTTP.Response import filename_from_content_disposition
import project.AWS_Credential.AWS_Credential
import project.S3.S3_File.S3_File
import project.Errors.AWS_SDK_Error
import project.Errors.More_Records_Available
import project.Errors.S3_Bucket_Not_Found
@ -42,6 +44,7 @@ polyglot java import software.amazon.awssdk.services.s3.S3Client
! Error Conditions
- If the credentials are invalid or access to S3 is denied, then an
`AWS_SDK_Error` will be raised.
@credentials AWS_Credential.default_widget
list_buckets : AWS_Credential -> Vector Text ! S3_Error
list_buckets credentials:AWS_Credential=..Default = handle_s3_errors <|
client = make_client credentials
@ -68,9 +71,11 @@ list_buckets credentials:AWS_Credential=..Default = handle_s3_errors <|
- If the bucket does not exist, an `S3_Bucket_Not_Found` error is thrown.
- If more items are available than the `max_count` parameter, a
`More_Records_Available` warning is attached to the result.
list_objects : Text -> Text -> AWS_Credential -> Integer -> Vector Text ! S3_Error
list_objects bucket prefix="" credentials:AWS_Credential=..Default max_count:Integer=1000 =
read_bucket bucket prefix credentials delimiter="" max_count=max_count . second
@credentials AWS_Credential.default_widget
list_objects : Text -> Text -> AWS_Credential -> Integer -> Vector S3_File ! S3_Error
list_objects (bucket : Text = Missing_Argument.throw "bucket") prefix:Text="" credentials:AWS_Credential=..Default max_count:Integer=1000 =
names = read_bucket bucket prefix credentials delimiter="" max_count=max_count . second
names.map name-> S3_File.new "s3://"+bucket+"/"+name credentials
## PRIVATE
ADVANCED
@ -121,8 +126,9 @@ get_object bucket key credentials:AWS_Credential=AWS_Credential.Default delimite
`AWS_SDK_Error` will be raised.
- If the bucket does not exist, an `S3_Bucket_Not_Found` error is thrown.
- If the object does not exist, an `S3_Key_Not_Found` error is thrown.
@credentials AWS_Credential.default_widget
head : Text -> Text -> AWS_Credential -> Dictionary Text Any ! S3_Error
head bucket key="" credentials:AWS_Credential=AWS_Credential.Default =
head (bucket : Text = Missing_Argument.throw "bucket") key:Text="" credentials:AWS_Credential=AWS_Credential.Default =
response = raw_head bucket key credentials
pairs = response.sdkFields.map f-> [f.memberName, f.getValueOrDefault response]
Dictionary.from_vector pairs

View File

@ -44,6 +44,7 @@ type S3_File
! Error Conditions
- If the URI is not in the correct format, an `Illegal_Argument` error is
thrown.
@credentials AWS_Credential.default_widget
new : Text -> AWS_Credential -> S3_File ! Illegal_Argument
new (uri : Text = S3.uri_prefix) credentials:AWS_Credential=..Default =
S3_File.Value (S3_Path.parse uri) credentials
@ -588,6 +589,16 @@ type S3_File
is_descendant_of : S3_File -> Boolean
is_descendant_of self other = self.s3_path.is_descendant_of other.s3_path
## PRIVATE
Return the absolute path of this S3_File.
to_text : Text
to_text self = self.uri
## PRIVATE
Convert to a display representation of this S3_File.
to_display_text : Text
to_display_text self = "S3_File {" + self.to_text + "}"
## PRIVATE
File_Format_Metadata.from (that : S3_File) = File_Format_Metadata.Value that.uri that.name (that.extension.catch _->Nothing)

View File

@ -191,6 +191,11 @@ type Enso_File
is_descendant_of self (other : Enso_File) -> Boolean =
self.enso_path.is_descendant_of other.enso_path
## PRIVATE
Convert to a display representation of this S3_File.
to_display_text : Text
to_display_text self = "Enso_File {" + self.path + "}"
## PRIVATE
ADVANCED
Creates a new output stream for this file and runs the specified action

View File

@ -246,13 +246,13 @@ type Date_Operation
## PRIVATE
create_widget : Table_Ref -> Display -> Widget
create_widget table:Table_Ref display:Display=Display.Always =
col_names = Widget_Helpers.make_column_ref_by_name_selector table
with_number = Widget_Helpers.make_column_ref_by_name_selector table add_number=True
with_date = Widget_Helpers.make_column_ref_by_name_selector table add_date=True add_date_time=True
options = Vector.build builder->
builder.append (Option "add" "..Add" [["length", with_number]])
builder.append (Option "part" "..Part")
builder.append (Option "diff" "..Diff" [["end", col_names]])
builder.append (Option "diff" "..Diff" [["end", with_date]])
builder.append (Option "truncate" "..Truncate")
builder.append (Option "year" "..Year")
builder.append (Option "month" "..Month")

View File

@ -204,7 +204,7 @@ add_specs suite_builder =
suite_builder.group "S3.list_objects" pending=api_pending group_builder->
group_builder.specify "should be able to list objects" <|
objects = S3.list_objects bucket_name credentials=test_credentials
objects . should_contain object_name
objects . map .name . should_contain object_name
group_builder.specify "should attach a warning if not a complete list" <|
objects = S3.list_objects bucket_name max_count=1 credentials=test_credentials