main.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 NIOSSL
  23. /// Prepare an SSL context for a general SSL client that supports HTTP/2.
  24. func makeClientTLS() throws -> NIOSSLContext {
  25. let configuration = TLSConfiguration.forClient(applicationProtocols: ["h2"])
  26. return try NIOSSLContext(configuration: configuration)
  27. }
  28. /// Create a client and return a future to provide its value.
  29. func makeServiceClient(host: String,
  30. port: Int,
  31. eventLoopGroup: MultiThreadedEventLoopGroup)
  32. -> EventLoopFuture<Google_Cloud_Language_V1_LanguageServiceServiceClient> {
  33. let promise = eventLoopGroup.next().makePromise(of: Google_Cloud_Language_V1_LanguageServiceServiceClient.self)
  34. do {
  35. let configuration = GRPCClientConnection.Configuration(
  36. target: .hostAndPort(host, port),
  37. eventLoopGroup: eventLoopGroup,
  38. tlsConfiguration: .init(sslContext: try makeClientTLS())
  39. try GRPCClientConnection.start(configuration)
  40. .map { client in
  41. Google_Cloud_Language_V1_LanguageServiceServiceClient(connection: client)
  42. }.cascade(to: promise)
  43. } catch {
  44. promise.fail(error)
  45. }
  46. return promise.futureResult
  47. }
  48. enum AuthError: Error {
  49. case noTokenProvider
  50. case tokenProviderFailed
  51. }
  52. /// Get an auth token and return a future to provide its value.
  53. func getAuthToken(scopes: [String],
  54. eventLoop: EventLoop)
  55. -> EventLoopFuture<String> {
  56. let promise = eventLoop.makePromise(of: String.self)
  57. guard let provider = DefaultTokenProvider(scopes: scopes) else {
  58. promise.fail(AuthError.noTokenProvider)
  59. return promise.futureResult
  60. }
  61. do {
  62. try provider.withToken { (token, error) in
  63. if let token = token,
  64. let accessToken = token.AccessToken {
  65. promise.succeed(accessToken)
  66. } else if let error = error {
  67. promise.fail(error)
  68. } else {
  69. promise.fail(AuthError.tokenProviderFailed)
  70. }
  71. }
  72. } catch {
  73. promise.fail(error)
  74. }
  75. return promise.futureResult
  76. }
  77. /// Main program. Make a sample API request.
  78. do {
  79. let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  80. // Get an auth token.
  81. let scopes = ["https://www.googleapis.com/auth/cloud-language"]
  82. let authToken = try getAuthToken(
  83. scopes: scopes,
  84. eventLoop: eventLoopGroup.next()).wait()
  85. // Create a service client.
  86. let service = try makeServiceClient(
  87. host: "language.googleapis.com",
  88. port: 443,
  89. eventLoopGroup: eventLoopGroup).wait()
  90. // Use CallOptions to send the auth token (necessary) and set a custom timeout (optional).
  91. let headers = HTTPHeaders([("authorization", "Bearer " + authToken)])
  92. let timeout = try! GRPCTimeout.seconds(30)
  93. let callOptions = CallOptions(customMetadata: headers, timeout: timeout)
  94. print("CALL OPTIONS\n\(callOptions)\n")
  95. // Construct the API request.
  96. var document = Google_Cloud_Language_V1_Document()
  97. document.type = .plainText
  98. document.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."
  99. var features = Google_Cloud_Language_V1_AnnotateTextRequest.Features()
  100. features.extractSyntax = true
  101. features.extractEntities = true
  102. features.extractDocumentSentiment = true
  103. features.extractEntitySentiment = true
  104. features.classifyText = true
  105. var request = Google_Cloud_Language_V1_AnnotateTextRequest()
  106. request.document = document
  107. request.features = features
  108. print("REQUEST MESSAGE\n\(request)")
  109. // Create/start the API call.
  110. let call = service.annotateText(request, callOptions: callOptions)
  111. call.response.whenSuccess { response in
  112. print("CALL SUCCEEDED WITH RESPONSE\n\(response)")
  113. }
  114. call.response.whenFailure { error in
  115. print("CALL FAILED WITH ERROR\n\(error)")
  116. }
  117. // wait() on the status to stop the program from exiting.
  118. let status = try call.status.wait()
  119. print("CALL STATUS\n\(status)")
  120. } catch {
  121. print("EXAMPLE FAILED WITH ERROR\n\(error)")
  122. }