|
6 | 6 | [martian.core :as martian]
|
7 | 7 | [martian.hato :as martian-http]
|
8 | 8 | [wkok.openai-clojure.interceptors :as openai-interceptors]
|
9 |
| - [wkok.openai-clojure.sse :as sse])) |
| 9 | + [wkok.openai-clojure.sse :as sse] |
| 10 | + [martian.interceptors :as interceptors] |
| 11 | + [martian.encoders :as encoders])) |
10 | 12 |
|
11 | 13 | (def add-authentication-header
|
12 | 14 | {:name ::add-authentication-header
|
|
26 | 28 | idx (s/index-of url "/openai")]
|
27 | 29 | (str endpoint (subs url idx))))))})
|
28 | 30 |
|
29 |
| -(defn- ->patched-handler |
30 |
| - [m from to] |
31 |
| - (-> (martian/handler-for m :completions-create) |
32 |
| - (assoc :route-name :create-completion))) |
33 |
| - |
34 | 31 | (def route-mappings
|
35 | 32 | {:completions-create :create-completion
|
36 | 33 | :chat-completions-create :create-chat-completion
|
|
51 | 48 | (defn load-openai-spec []
|
52 | 49 | (json/decode (slurp (io/resource "azure_openai.json")) keyword))
|
53 | 50 |
|
| 51 | +(defn- multipart-form-data? |
| 52 | + [handler] |
| 53 | + (-> handler :openapi-definition :requestBody :content :multipart/form-data)) |
| 54 | + |
| 55 | +(defn- param->multipart-entry |
| 56 | + [[param content]] |
| 57 | + {:name (name param) |
| 58 | + :content (if (or (instance? java.io.File content) |
| 59 | + (instance? java.io.InputStream content) |
| 60 | + (bytes? content)) |
| 61 | + content |
| 62 | + (str content))}) |
| 63 | + |
| 64 | +(def multipart-form-data |
| 65 | + {:name ::multipart-form-data |
| 66 | + :enter (fn [{:keys [handler params] :as ctx}] |
| 67 | + (let [params' (:martian.core/body params)] |
| 68 | + (if (multipart-form-data? handler) |
| 69 | + (-> (assoc-in ctx [:request :multipart] |
| 70 | + (map param->multipart-entry params')) |
| 71 | + (update-in [:request :headers] dissoc "Content-Type") |
| 72 | + (update :request dissoc :body)) |
| 73 | + ctx)))}) |
| 74 | + |
| 75 | +(defn update-file-schema |
| 76 | + [m operation-id field-name] |
| 77 | + (martian/update-handler m operation-id assoc-in [:body-schema :body field-name] java.io.File)) |
| 78 | + |
| 79 | +(defn update-file-schemas |
| 80 | + [m] |
| 81 | + (-> m |
| 82 | + (update-file-schema :transcriptions-create :file) |
| 83 | + (update-file-schema :translations-create :file))) |
| 84 | + |
| 85 | + |
| 86 | +(defn bootstrap-openapi |
| 87 | + "Bootstrap the martian from a local copy of the openai swagger spec" |
| 88 | + [] |
| 89 | + (let [definition (load-openai-spec) |
| 90 | + base-url "/openai" |
| 91 | + encoders (assoc (encoders/default-encoders) |
| 92 | + "multipart/form-data" nil |
| 93 | + "application/octet-stream" nil) |
| 94 | + opts (update martian-http/default-opts |
| 95 | + :interceptors (fn [interceptors] |
| 96 | + (-> interceptors |
| 97 | + (interceptors/inject |
| 98 | + add-authentication-header |
| 99 | + :after |
| 100 | + :martian.interceptors/header-params) |
| 101 | + (interceptors/inject |
| 102 | + multipart-form-data |
| 103 | + :after |
| 104 | + ::add-authentication-header) |
| 105 | + (interceptors/inject |
| 106 | + openai-interceptors/set-request-options |
| 107 | + :before |
| 108 | + :martian.hato/perform-request) |
| 109 | + (interceptors/inject |
| 110 | + override-api-endpoint |
| 111 | + :before |
| 112 | + :martian.hato/perform-request) |
| 113 | + (interceptors/inject |
| 114 | + sse/perform-sse-capable-request |
| 115 | + :replace |
| 116 | + :martian.hato/perform-request) |
| 117 | + (interceptors/inject |
| 118 | + (interceptors/encode-body encoders) |
| 119 | + :replace |
| 120 | + :martian.interceptors/encode-body) |
| 121 | + (interceptors/inject |
| 122 | + (interceptors/coerce-response encoders) |
| 123 | + :replace |
| 124 | + :martian.interceptors/coerce-response))))] |
| 125 | + |
| 126 | + (-> (martian/bootstrap-openapi base-url definition opts) |
| 127 | + update-file-schemas))) |
| 128 | + |
54 | 129 | (def m
|
55 | 130 | (delay
|
56 | 131 | (patch-handler
|
57 |
| - (martian/bootstrap-openapi "/openai" |
58 |
| - (load-openai-spec) |
59 |
| - (update |
60 |
| - martian-http/default-opts |
61 |
| - :interceptors |
62 |
| - #(-> (remove (comp #{martian-http/perform-request}) %) |
63 |
| - (concat [add-authentication-header |
64 |
| - openai-interceptors/set-request-options |
65 |
| - override-api-endpoint |
66 |
| - sse/perform-sse-capable-request]))))))) |
| 132 | + (bootstrap-openapi)))) |
67 | 133 |
|
68 | 134 | (defn patch-params [params]
|
69 |
| - {:api-version "2024-06-01" |
70 |
| - :deployment-id (:model params) |
| 135 | + {:api-version "2024-06-01" |
| 136 | + :deployment-id (:model params) |
71 | 137 | :martian.core/body (dissoc params :model)})
|
72 | 138 |
|
73 | 139 |
|
|
0 commit comments