Skip to content

Commit dfdfe97

Browse files
authored
Merge pull request #30 from vapor-community/translate
Added support for Cloud translate.
2 parents 2b8315d + 49423f2 commit dfdfe97

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed

Package.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ let package = Package(
2020
.library(
2121
name: "CloudSecretManager",
2222
targets: ["CloudSecretManager"]),
23+
.library(
24+
name: "CloudTranslation",
25+
targets: ["CloudTranslation"]),
2326
],
2427
dependencies: [
2528
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
@@ -54,5 +57,12 @@ let package = Package(
5457
.product(name: "GoogleCloudSecretManager", package: "google-cloud-kit"),
5558
.target(name: "GoogleCloud")
5659
]),
60+
.target(
61+
name: "CloudTranslation",
62+
dependencies: [
63+
.product(name: "Vapor", package: "vapor"),
64+
.product(name: "GoogleCloudTranslation", package: "google-cloud-kit"),
65+
.target(name: "GoogleCloud")
66+
]),
5767
]
5868
)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ You can check each supported API's README for a getting started guide.
2424

2525
[x] [CloudSecretManager](/Sources/CloudSecretManager/README.md)
2626

27+
[x] [CloudTranslation](/Sources/CloudTranslation/README.md)
28+
2729
### A More detailed guide can be found [here](https://github.com/vapor-community/google-cloud-kit).
2830

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//
2+
// GoogleCloudTranslationAPI.swift
3+
//
4+
//
5+
// Created by Andrew Edwards on 5/4/21.
6+
//
7+
8+
import Vapor
9+
@_exported import Translation
10+
@_exported import GoogleCloud
11+
12+
extension Application.GoogleCloudPlatform {
13+
14+
private struct CloudTranslationAPIKey: StorageKey {
15+
typealias Value = GoogleCloudTranslationAPI
16+
}
17+
18+
private struct CloudSecretManagerConfigurationKey: StorageKey {
19+
typealias Value = GoogleCloudTranslationConfiguration
20+
}
21+
22+
private struct CloudTranslationHTTPClientKey: StorageKey, LockKey {
23+
typealias Value = HTTPClient
24+
}
25+
26+
public var translation: GoogleCloudTranslationAPI {
27+
get {
28+
if let existing = self.application.storage[CloudTranslationAPIKey.self] {
29+
return existing
30+
} else {
31+
return .init(application: self.application, eventLoop: self.application.eventLoopGroup.next())
32+
}
33+
}
34+
35+
nonmutating set {
36+
self.application.storage[CloudTranslationAPIKey.self] = newValue
37+
}
38+
}
39+
40+
public struct GoogleCloudTranslationAPI {
41+
public let application: Application
42+
public let eventLoop: EventLoop
43+
44+
/// A client used to interact with the `GoogleCloudTranslation` API.
45+
public var client: GoogleCloudTranslationClient {
46+
do {
47+
let new = try GoogleCloudTranslationClient(credentials: self.application.googleCloud.credentials,
48+
config: self.configuration,
49+
httpClient: self.http,
50+
eventLoop: self.eventLoop)
51+
return new
52+
} catch {
53+
fatalError("\(error.localizedDescription)")
54+
}
55+
}
56+
57+
/// The configuration for using `GoogleCloudTranslation` APIs.
58+
public var configuration: GoogleCloudTranslationConfiguration {
59+
get {
60+
if let configuration = application.storage[CloudSecretManagerConfigurationKey.self] {
61+
return configuration
62+
} else {
63+
fatalError("Cloud Translation configuration has not been set. Use app.googleCloud.translation.configuration = ...")
64+
}
65+
}
66+
set {
67+
if application.storage[CloudSecretManagerConfigurationKey.self] == nil {
68+
application.storage[CloudSecretManagerConfigurationKey.self] = newValue
69+
} else {
70+
fatalError("Attempting to override credentials configuration after being set is not allowed.")
71+
}
72+
}
73+
}
74+
75+
/// Custom `HTTPClient` that ignores unclean SSL shutdown.
76+
public var http: HTTPClient {
77+
if let existing = application.storage[CloudTranslationHTTPClientKey.self] {
78+
return existing
79+
} else {
80+
let lock = application.locks.lock(for: CloudTranslationHTTPClientKey.self)
81+
lock.lock()
82+
defer { lock.unlock() }
83+
if let existing = application.storage[CloudTranslationHTTPClientKey.self] {
84+
return existing
85+
}
86+
let new = HTTPClient(
87+
eventLoopGroupProvider: .shared(application.eventLoopGroup),
88+
configuration: HTTPClient.Configuration(ignoreUncleanSSLShutdown: true)
89+
)
90+
application.storage.set(CloudTranslationHTTPClientKey.self, to: new) {
91+
try $0.syncShutdown()
92+
}
93+
return new
94+
}
95+
}
96+
}
97+
}
98+
99+
extension Request {
100+
private struct GoogleCloudTranslationKey: StorageKey {
101+
typealias Value = GoogleCloudTranslationClient
102+
}
103+
104+
/// A client used to interact with the `GoogleCloudTranslation` API
105+
public var gcTranslation: GoogleCloudTranslationClient {
106+
if let existing = application.storage[GoogleCloudTranslationKey.self] {
107+
return existing.hopped(to: self.eventLoop)
108+
} else {
109+
let new = Application.GoogleCloudPlatform.GoogleCloudTranslationAPI(application: self.application, eventLoop: self.eventLoop).client
110+
application.storage[GoogleCloudTranslationKey.self] = new
111+
return new
112+
}
113+
}
114+
}

Sources/CloudTranslation/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# GoogleCloudTranslationAPI
2+
3+
## Getting Started
4+
If you only need to use the [Google Cloud Translation API](https://cloud.google.com/translate), then this guide will help you get started.
5+
6+
In your `Package.swift` file, make sure you have the following dependencies and targets
7+
8+
```swift
9+
dependencies: [
10+
//...
11+
.package(url: "https://github.com/vapor-community/google-cloud.git", from: "1.0.0"),
12+
],
13+
targets: [
14+
.target(name: "MyAppName", dependencies: [
15+
//...
16+
.product(name: "CloudTranslation", package: "google-cloud"),
17+
]),
18+
]
19+
```
20+
21+
Now you can setup the configuration for any GCP API globally via `Application`.
22+
23+
In `configure.swift`
24+
25+
```swift
26+
import CloudTranslation
27+
28+
app.googleCloud.credentials = try GoogleCloudCredentialsConfiguration(projectId: "myprojectid-12345",
29+
credentialsFile: "~/path/to/service-account.json")
30+
```
31+
Next we setup the CloudTranslation API configuration (specific to this API).
32+
33+
```swift
34+
app.googleCloud.translation.configuration = .default()
35+
```
36+
37+
Now we can start using the GoogleCloudTranslation API
38+
There's a handy extension on `Request` that you can use to get access to a translation client via a property named `gcTranslation`.
39+
40+
```swift
41+
func translateText(_ req: Request) throws -> EventLoopFuture<String> {
42+
req.gcTranslation.translate(text: "Hello World", source: "en", target: "es")
43+
.map { $0.data.translations.first!.translatedText! // returns the spanish translation }
44+
}
45+
```

0 commit comments

Comments
 (0)