@@ -17,21 +17,20 @@ import AppKit.NSImage
1717#endif
1818
1919@available ( iOS 15 . 0 , macOS 12 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
20- public final class OpenAIDefaultLoader : IOpenAILoader {
20+ public final class OpenAIDefaultLoader : IOpenAILoader {
2121
2222 /// HTTP async client to handle requests
23- private let client : Http . Proxy < JsonReader , JsonWriter > ?
23+ private let client : Http . Proxy < JsonReader , JsonWriter > ?
2424
2525 /// Endpoint parameters required for making requests
26- private let endpoint : IOpenAIImageEndpoint
26+ private let endpoint : IOpenAIImageEndpoint
2727
2828 /// Initializes the loader with endpoint parameters
2929 /// - Parameter endpoint: Set of parameters for making requests
30- public init ( endpoint : IOpenAIImageEndpoint ) {
31-
30+ public init ( endpoint: IOpenAIImageEndpoint ) {
3231 self . endpoint = endpoint
3332
34- guard let url = URL ( string: endpoint. urlString) else {
33+ guard let url = URL ( string: endpoint. urlString) else {
3534 client = nil
3635 return
3736 }
@@ -45,33 +44,52 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
4544 /// - size: The size of the generated image
4645 /// - Returns: OpenAI Image
4746 public func load(
48- _ prompt : String ,
49- with size : OpenAIImageSize
50- ) async throws -> Image {
51-
52- // Prepare the request body with the prompt and size
53- let body = Input ( prompt: prompt, size: size, response_format: . b64, n: 1 )
54-
55- // Set the request headers, including authorization
56- let headers = [ " Content-Type " : " application/json " , " Authorization " : " Bearer \( endpoint. apiKey) " ]
57- let path = endpoint. path
47+ _ prompt: String ,
48+ with size: OpenAIImageSize
49+ ) async throws -> Image {
5850
59- guard let client = client else {
51+ guard let client = client else {
6052 throw AsyncImageErrors . clientIsNotDefined
6153 }
6254
63- // Send the request and get the response
64- let result : Http . Response < Output > = try await client. post ( path: path, body: body, headers: headers)
55+ do {
56+ let ( path, body, headers) = prepareRequest ( prompt: prompt, size: size)
57+ let result : Http . Response < Output > = try await client. post ( path: path, body: body, headers: headers)
58+ return try imageBase64 ( from: result. value)
59+
60+ } catch {
61+ try handleRequestError ( error)
62+ }
63+ }
64+
65+ /// Prepares the request with the necessary parameters
66+ /// - Parameters:
67+ /// - prompt: The text prompt describing the desired image
68+ /// - size: The size of the generated image
69+ /// - Returns: A tuple containing the path, body, and headers for the request
70+ private func prepareRequest( prompt: String , size: OpenAIImageSize ) -> ( String , Input , [ String : String ] ) {
71+ let body = Input ( prompt: prompt, size: size, response_format: . b64, n: 1 )
72+ let headers = [ " Content-Type " : " application/json " , " Authorization " : " Bearer \( endpoint. apiKey) " ]
73+ let path = endpoint. path
74+ return ( path, body, headers)
75+ }
76+
77+ /// Handles errors that occur during the request
78+ /// - Parameter error: The error that occurred
79+ private func handleRequestError( _ error: Error ) throws -> Never {
80+ if case let Http . Errors . status( _, _, data) = error, let responseData = data {
81+ let data = String ( data: responseData, encoding: . utf8) ?? " Unable to decode data "
82+ throw AsyncImageErrors . httpStatus ( data)
83+ }
6584
66- // Convert the response to an image
67- return try imageBase64 ( from: result. value)
85+ throw error
6886 }
6987
7088 /// Decodes base64 encoded string to Data
7189 /// - Parameter output: The output received from the endpoint
7290 /// - Returns: Decoded Data
73- private func decodeBase64( from output: Output ) throws -> Data ? {
74- guard let base64 = output. firstImage else {
91+ private func decodeBase64( from output: Output ) throws -> Data ? {
92+ guard let base64 = output. firstImage else {
7593 throw AsyncImageErrors . returnedNoImages
7694 }
7795
@@ -83,10 +101,9 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
83101 /// - Parameter output: OpenAI response type
84102 /// - Returns: UIImage
85103 private func imageBase64( from output: Output ) throws -> Image {
86-
87104 let data = try decodeBase64 ( from: output)
88105
89- if let data, let image = UIImage ( data: data) {
106+ if let data, let image = UIImage ( data: data) {
90107 return Image ( uiImage: image)
91108 }
92109
@@ -99,10 +116,9 @@ public final class OpenAIDefaultLoader : IOpenAILoader{
99116 /// - Parameter output: OpenAI response type
100117 /// - Returns: NSImage
101118 private func imageBase64( from output: Output ) throws -> Image {
102-
103119 let data = try decodeBase64 ( from: output)
104120
105- if let data, let image = NSImage ( data: data) {
121+ if let data, let image = NSImage ( data: data) {
106122 return Image ( nsImage: image)
107123 }
108124
0 commit comments