首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Swift SOTO中使用AWS Rekognition

在Swift SOTO中使用AWS Rekognition
EN

Stack Overflow用户
提问于 2021-02-28 14:53:39
回答 1查看 88关注 0票数 0

我使用了

devhr python lambda函数

作为我的Swift Lambda函数的模型,使用

AWS的Soto

..。Lambda函数将在图像上传到S3并使用AWS Rekognition服务向DynamoDB数据库添加标签(图像中对象的描述)时由S3事件触发。我在获取

rekFunction

功能正确,我希望有人能建议如何让它工作。

到目前为止,我编写的Swift代码如下:

代码语言:javascript
复制
import AWSLambdaRuntime
import AWSLambdaEvents
import NIO
import Foundation
import SotoS3
import SotoRekognition
import SotoDynamoDB

struct Bucket: Decodable {
    let name: String
}

struct Object: Decodable {
    let key: String
}

struct MyS3: Decodable {
    let bucket: Bucket
    let object: Object
}

struct Record: Decodable {
    let s3: MyS3
}

struct Input: Decodable {
    let records: [Record]
}

struct Output: Encodable {
    let result: String
}

struct MyHandler: EventLoopLambdaHandler {
    typealias In = APIGateway.V2.Request
    typealias Out = APIGateway.V2.Response
    
    let minConfidence: Float = 50

    let awsClient: AWSClient
    
    init(context: Lambda.InitializationContext) {
        self.awsClient = AWSClient(httpClientProvider: .createNewWithEventLoopGroup(context.eventLoop))
    }
    
    func shutdown(context: Lambda.ShutdownContext) -> EventLoopFuture {
        let promise = context.eventLoop.makePromise(of: Void.self)
        awsClient.shutdown { error in
            if let error = error {
                promise.fail(error)
            } else {
                promise.succeed(())
            }
        }
        return context.eventLoop.makeSucceededFuture(())
    }

    func handle(context: Lambda.Context, event: In) -> EventLoopFuture {
        guard let input: Input = try? event.bodyObject() else {
            return context.eventLoop.makeSucceededFuture(APIGateway.V2.Response(with: APIError.requestError, statusCode: .badRequest))
        }

        for record in input.records {
            let ourBucket = record.s3.bucket.name
            let ourKey = record.s3.object.key
            
            // For each message (photo) get the bucket name and key
            rekFunction(bucket: ourBucket, key: ourKey)
        }
        let output = Output(result: "Finished!")
        let apigatewayOutput = APIGateway.V2.Response(with: output, statusCode: .ok)
        return context.eventLoop.makeSucceededFuture(apigatewayOutput)
    }
        
    func rekFunction(bucket: String, key: String) {
        let safeKey = key.replacingOccurrences(of: "%3A", with: ":")
        print("Currently processing the following image")
        print("Bucket:", bucket, " key name:", safeKey)
        var objectsDetected: [String] = []
        var imageLabels = [ "image": safeKey ]
        let s3Client = S3(client: awsClient, region: .euwest1)

        let s3Object = Rekognition.S3Object(bucket: bucket, name: safeKey)
        let image = Rekognition.Image(s3Object: s3Object)
        let rekognitionClient = Rekognition(client: awsClient)
        let detectLabelsRequest = Rekognition.DetectLabelsRequest(image: image, maxLabels: 10, minConfidence: minConfidence)
        rekognitionClient.detectLabels(detectLabelsRequest)
            .flatMap { detectLabelsResponse -> EventLoopFuture in
                if let labels = detectLabelsResponse.labels {
                    // Add all of our labels into imageLabels by iterating over response['Labels']
                    for label in labels {
                        if let name = label.name {
                            objectsDetected.append(name)
                            let itemAtt = "object\(objectsDetected.count)"
                            
                            // We now have our shiny new item ready to put into DynamoDB
                            imageLabels[itemAtt] = name
                            
                            // Instantiate a table resource object of our environment variable
                            let imageLabelsTable = // Environment("TABLE") How can I read env vars?
                            let table = SotoDynamoDB.getTable(imageLabelsTable) // python: table = dynamodb.Table(imageLabelsTable)
                            // python: table.put_item(Item=imageLabels)
                        }
                    }
                }
                return ???
            }
        
    }
    
}
Lambda.run { MyHandler(context: $0) }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-28 18:00:24

这里有许多问题需要讨论。

因为您是从S3事件触发的。The The The

typealias应为

考虑到没有任何东西在等待结果

应该是

..。

可以使用以下命令提取环境变量

..。

至于写入DynamoDB表,最好的方法可能是使用Soto的DynamoDB可编码支持。在下面的示例中,我将假设您使用s3存储桶和密钥的组合作为密钥。

代码语言:javascript
复制
struct RekEntry: Codable {
    let key: String
    let labels: [String]
}
let entry = RekEntry(
    key: "\(bucket)/\(key)"
    labels: labels
)
let putRequest = DynamoDB.PutItemCodableInput(
    item: entry,
    tableName: Lambda.env("TABLE")
)
return dynamoDB.putItem(putRequest)

最后,从你的flatMap返回什么。首先是你的函数

需要返回一个

因为这是您从Lambda处理程序返回的内容。因此,您将映射

在前一点要作废。

代码语言:javascript
复制
func rekFunction(bucket: String, key: String) -> EventLoopFuture {
    ...
    return rekognitionClient.detectLabels(detectLabelsRequest)
        .flatMap {
            ...
            return dynamoDB.putItem(putRequest)
        }
        .map { _ in }
}

我希望这包括了所有的内容。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66406570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档