main.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 2019, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Dispatch
  17. import Foundation
  18. import GRPC
  19. import OAuth2
  20. import NIO
  21. import NIOHTTP1
  22. import NIOHPACK
  23. import NIOSSL
  24. /// Create a client and return a future to provide its value.
  25. func makeServiceClient(
  26. host: String,
  27. port: Int,
  28. eventLoopGroup: MultiThreadedEventLoopGroup
  29. ) -> Google_Cloud_Language_V1_LanguageServiceServiceClient {
  30. let configuration = ClientConnection.Configuration(
  31. target: .hostAndPort(host, port),
  32. eventLoopGroup: eventLoopGroup,
  33. tls: .init()
  34. )
  35. let connection = ClientConnection(configuration: configuration)
  36. return Google_Cloud_Language_V1_LanguageServiceServiceClient(connection: connection)
  37. }
  38. enum AuthError: Error {
  39. case noTokenProvider
  40. case tokenProviderFailed
  41. }
  42. /// Get an auth token and return a future to provide its value.
  43. func getAuthToken(
  44. scopes: [String],
  45. eventLoop: EventLoop
  46. ) -> EventLoopFuture<String> {
  47. let promise = eventLoop.makePromise(of: String.self)
  48. guard let provider = DefaultTokenProvider(scopes: scopes) else {
  49. promise.fail(AuthError.noTokenProvider)
  50. return promise.futureResult
  51. }
  52. do {
  53. try provider.withToken { (token, error) in
  54. if let token = token,
  55. let accessToken = token.AccessToken {
  56. promise.succeed(accessToken)
  57. } else if let error = error {
  58. promise.fail(error)
  59. } else {
  60. promise.fail(AuthError.tokenProviderFailed)
  61. }
  62. }
  63. } catch {
  64. promise.fail(error)
  65. }
  66. return promise.futureResult
  67. }
  68. /// Main program. Make a sample API request.
  69. do {
  70. let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  71. // Get an auth token.
  72. let scopes = ["https://www.googleapis.com/auth/cloud-language"]
  73. let authToken = try getAuthToken(
  74. scopes: scopes,
  75. eventLoop: eventLoopGroup.next()
  76. ).wait()
  77. // Create a service client.
  78. let service = makeServiceClient(
  79. host: "language.googleapis.com",
  80. port: 443,
  81. eventLoopGroup: eventLoopGroup
  82. )
  83. // Use CallOptions to send the auth token (necessary) and set a custom timeout (optional).
  84. let headers: HPACKHeaders = ["authorization": "Bearer \(authToken)"]
  85. let callOptions = CallOptions(customMetadata: headers, timeout: .seconds(rounding: 30))
  86. print("CALL OPTIONS\n\(callOptions)\n")
  87. // Construct the API request.
  88. let request = Google_Cloud_Language_V1_AnnotateTextRequest.with {
  89. $0.document = .with {
  90. $0.type = .plainText
  91. $0.content = "The Caterpillar and Alice looked at each other for some time in silence: at last the Caterpillar took the hookah out of its mouth, and addressed her in a languid, sleepy voice. `Who are you?' said the Caterpillar."
  92. }
  93. $0.features = .with {
  94. $0.extractSyntax = true
  95. $0.extractEntities = true
  96. $0.extractDocumentSentiment = true
  97. $0.extractEntitySentiment = true
  98. $0.classifyText = true
  99. }
  100. }
  101. print("REQUEST MESSAGE\n\(request)")
  102. // Create/start the API call.
  103. let call = service.annotateText(request, callOptions: callOptions)
  104. call.response.whenSuccess { response in
  105. print("CALL SUCCEEDED WITH RESPONSE\n\(response)")
  106. }
  107. call.response.whenFailure { error in
  108. print("CALL FAILED WITH ERROR\n\(error)")
  109. }
  110. // wait() on the status to stop the program from exiting.
  111. let status = try call.status.wait()
  112. print("CALL STATUS\n\(status)")
  113. } catch {
  114. print("EXAMPLE FAILED WITH ERROR\n\(error)")
  115. }