Skip to content
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

Swift: S3 update #6890

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@

// snippet-start:[s3.swift.deleteobjects.example]
// snippet-start:[s3.swift.deleteobjects.main.imports]
import ArgumentParser
import Foundation
import ServiceHandler
import ArgumentParser

// snippet-end:[s3.swift.deleteobjects.main.imports]

/// The command-line arguments and options available for this
/// example command.
// snippet-start:[s3.swift.deleteobjects.command]
struct ExampleCommand: ParsableCommand {
@Option(help: "AWS Region the bucket where the bucket is")
var region = "us-east-1"
var region: String?

@Argument(help: "Name of the S3 bucket to delete objects in")
var bucketName: String
Expand All @@ -37,17 +38,17 @@ struct ExampleCommand: ParsableCommand {
/// example.
// snippet-start:[s3.swift.deleteobjects.command.runasync]
func runAsync() async throws {
let serviceHandler = await ServiceHandler(region: region)

do {
try await serviceHandler.deleteObjects(bucket: bucketName,
keys: fileNames)
let serviceHandler = try await ServiceHandler(region: region)
try await serviceHandler.deleteObjects(bucket: bucketName,
keys: fileNames)
} catch {
print("*** Error. Unable to complete deleting the objects.")
}
}
// snippet-end:[s3.swift.deleteobjects.command.runasync]
}

// snippet-end:[s3.swift.deleteobjects.command]

//
Expand All @@ -65,7 +66,8 @@ struct Main {
} catch {
ExampleCommand.exit(withError: error)
}
}
}
}

// snippet-end:[s3.swift.deleteobjects.main]
// snippet-end:[s3.swift.deleteobjects.example]
// snippet-end:[s3.swift.deleteobjects.example]
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,52 @@
// SPDX-License-Identifier: Apache-2.0

/*
A class containing functions that interact with AWS services.
*/
A class containing functions that interact with AWS services.
*/

// snippet-start:[s3.swift.deleteobjects.handler]
// snippet-start:[s3.swift.deleteobjects.handler.imports]
import Foundation
import AWSS3
import ClientRuntime
import Foundation

// snippet-end:[s3.swift.deleteobjects.handler.imports]

/// Errors returned by `ServiceHandler` functions.
// snippet-start:[s3.swift.deleteobjects.enum.service-error]
public enum ServiceHandlerError: Error {
case deleteObjectsError
}

// snippet-end:[s3.swift.deleteobjects.enum.service-error]

/// A class containing all the code that interacts with the AWS SDK for Swift.
public class ServiceHandler {
public let client: S3Client
public var region: S3ClientTypes.BucketLocationConstraint?


/// Initialize and return a new ``ServiceHandler`` object, which is used
/// to drive the AWS calls
/// used for the example.
///
///
/// - Parameters:
/// - region: The AWS Region to access.
/// - region: The optional AWS Region to access.
///
/// - Returns: A new ``ServiceHandler`` object, ready to be called to
/// execute AWS operations.
// snippet-start:[s3.swift.deleteobjects.handler.init]
public init(region: String = "us-east-2") async {
self.region = S3ClientTypes.BucketLocationConstraint(rawValue: region)
public init(region: String? = nil) async throws {
do {
client = try S3Client(region: region)
let config = try await S3Client.S3ClientConfiguration()
if let region = region {
config.region = region
}
client = S3Client(config: config)
} catch {
print("ERROR: ", dump(error, name: "Initializing Amazon S3 client"))
exit(1)
throw error
}
}

// snippet-end:[s3.swift.deleteobjects.handler.init]

/// Deletes the specified objects from Amazon S3.
Expand All @@ -56,30 +61,19 @@ public class ServiceHandler {
let input = DeleteObjectsInput(
bucket: bucket,
delete: S3ClientTypes.Delete(
objects: keys.map({ S3ClientTypes.ObjectIdentifier(key: $0) }),
objects: keys.map { S3ClientTypes.ObjectIdentifier(key: $0) },
quiet: true
)
)

do {
let output = try await client.deleteObjects(input: input)

// As of the last update to this example, any errors are returned
// in the `output` object's `errors` property. If there are any
// errors in this array, throw an exception. Once the error
// handling is finalized in later updates to the AWS SDK for
// Swift, this example will be updated to handle errors better.

guard let errors = output.errors else {
return // No errors.
}
if errors.count != 0 {
throw ServiceHandlerError.deleteObjectsError
}
_ = try await client.deleteObjects(input: input)
} catch {
print("ERROR: deleteObjects:", dump(error))
throw error
}
}
// snippet-end:[s3.swift.deleteobjects.handler.DeleteObjects]
}

// snippet-end:[s3.swift.deleteobjects.handler]
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class DeleteObjectsTests: XCTestCase {
super.setUp()

Task() {
DeleteObjectsTests.serviceHandler = await ServiceHandler()
DeleteObjectsTests.serviceHandler = try await ServiceHandler()
DeleteObjectsTests.demoCleanup = await S3DemoCleanup()
tdSem.signal()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class S3DemoCleanup {

init() async {
do {
self.client = try S3Client(region: "us-east-2")
self.client = try await S3Client()
} catch {
print("Error initializing S3 client for tracking and deleting Amazon S3 buckets and files created by the example:")
dump(error)
Expand Down Expand Up @@ -237,4 +237,4 @@ public class S3DemoCleanup {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ public extension ServiceHandler {
/// - name: Name of the bucket to create.
/// Throws an exception if an error occurs.
func createBucket(name: String) async throws {
let config = S3ClientTypes.CreateBucketConfiguration(
locationConstraint: self.region
)
let input = CreateBucketInput(
bucket: name,
createBucketConfiguration: config
bucket: name
)
_ = try await client.createBucket(input: input)
}
Expand Down Expand Up @@ -100,4 +96,4 @@ public extension ServiceHandler {
}

return names
}}
}}
60 changes: 39 additions & 21 deletions swift/example_code/s3/ListBuckets-Simple/Sources/entry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,56 @@
/// Amazon Simple Storage Service (Amazon S3) function `ListBuckets`.

// snippet-start:[s3.swift.intro.imports]
import Foundation
import AWSS3
import AWSClientRuntime
import AWSS3
import Foundation

// snippet-end:[s3.swift.intro.imports]

// snippet-start:[s3.swift.intro.getbucketnames]
// Return an array containing the names of all available buckets.
//
// - Returns: An array of strings listing the buckets.
func getBucketNames() async throws -> [String] {
// Get an S3Client with which to access Amazon S3.
// snippet-start:[s3.swift.intro.client-init]
let client = try S3Client(region: "us-east-1")
// snippet-end:[s3.swift.intro.client-init]
do {
// Get an S3Client with which to access Amazon S3.
// snippet-start:[s3.swift.intro.client-init]
let configuration = try await S3Client.S3ClientConfiguration()
// configuration.region = "us-east-2" // Uncomment this to set the region programmatically.
let client = S3Client(config: configuration)
// snippet-end:[s3.swift.intro.client-init]

// snippet-start:[s3.swift.intro.listbuckets]
let output = try await client.listBuckets(
input: ListBucketsInput()
)
// snippet-end:[s3.swift.intro.listbuckets]

// Get the bucket names.
var bucketNames: [String] = []
// snippet-start:[s3.swift.intro.listbuckets]
// Use "Paginated" to get all the buckets.
// This lets the SDK handle the 'continuationToken' in "ListBucketsOutput".
let pages = client.listBucketsPaginated(
input: ListBucketsInput( maxBuckets: 10)
)
// snippet-end:[s3.swift.intro.listbuckets]

guard let buckets = output.buckets else {
return bucketNames
}
for bucket in buckets {
bucketNames.append(bucket.name ?? "<unknown>")
}
// Get the bucket names.
var bucketNames: [String] = []

do {
for try await page in pages {
guard let buckets = page.buckets else {
print("Error: no buckets returned.")
continue
}

for bucket in buckets {
bucketNames.append(bucket.name ?? "<unknown>")
}
}

return bucketNames
return bucketNames
} catch {
print("ERROR: listBuckets:", dump(error))
throw error
}
}
}

// snippet-end:[s3.swift.intro.getbucketnames]

// snippet-start:[s3.swift.intro.main]
Expand All @@ -61,4 +78,5 @@ struct Main {
}
}
}

// snippet-end:[s3.swift.intro.main]
Loading
Loading