Skip to content

Commit

Permalink
Merge pull request #6 from monofuel/api-key-locks
Browse files Browse the repository at this point in the history
Api key locks
  • Loading branch information
monofuel authored Oct 29, 2024
2 parents 224aa52 + 2fcc37e commit b02672b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
2 changes: 1 addition & 1 deletion openai_leap.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "2.0.7"
version = "2.0.8"
author = "Andrew Brower"
description = "OpenAI API for Nim"
license = "MIT"
Expand Down
48 changes: 34 additions & 14 deletions src/openai_leap.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import
std/[os, osproc, json, options, strutils, strformat, tables],
std/[os, locks, osproc, json, options, strutils, strformat, tables],
curly, jsony, webby

## OpenAI Api Reference: https://platform.openai.com/docs/api-reference/introduction
Expand All @@ -11,6 +11,7 @@ import
type
OpenAiApiObj* = object
curly: Curly
lock: Lock # lock for modifying the openai api object
baseUrl: string
curlTimeout: int
apiKey: string
Expand Down Expand Up @@ -271,11 +272,24 @@ proc newOpenAiApi*(

result = cast[OpenAiApi](allocShared0(sizeof(OpenAiApiObj)))
result.curly = newCurly(maxInFlight)
initLock(result.lock)
result.baseUrl = baseUrl
result.curlTimeout = curlTimeout
result.apiKey = apiKeyVar
result.organization = organization

template sync*(a: Lock, body: untyped) =
acquire(a)
try:
body
finally:
release(a)

proc updateApiKey*(api: OpenAiApi, apiKey: string) =
## Update the API key for the OpenAI API client.
api.lock.sync:
api.apiKey = apiKey

proc close*(api: OpenAiApi) =
## Clean up the OpenAPI API client.
api.curly.close()
Expand All @@ -285,22 +299,24 @@ proc get(api: OpenAiApi, path: string): Response =
## Make a GET request to the OpenAI API.
var headers: curly.HttpHeaders
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Bearer " & api.apiKey
api.lock.sync:
headers["Authorization"] = "Bearer " & api.apiKey
if api.organization != "":
headers["Organization"] = api.organization
let resp = api.curly.get(api.baseUrl & path, headers, api.curlTimeout)
if resp.code != 200:
raise newException(
OpenAiError,
&"OpenAi call {path} failed: {resp.code} {resp.body}"
&"API call {path} failed: {resp.code} {resp.body}"
)
result = resp

proc post(api: OpenAiApi, path: string, body: string): Response =
## Make a POST request to the OpenAI API.
var headers: curly.HttpHeaders
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Bearer " & api.apiKey
api.lock.sync:
headers["Authorization"] = "Bearer " & api.apiKey
if api.organization != "":
headers["Organization"] = api.organization
let resp = api.curly.post(
Expand All @@ -312,15 +328,16 @@ proc post(api: OpenAiApi, path: string, body: string): Response =
if resp.code != 200:
raise newException(
OpenAiError,
&"OpenAi call {path} failed: {resp.code} {resp.body}"
&"API call {path} failed: {resp.code} {resp.body}"
)
result = resp

proc postStream(api: OpenAiApi, path: string, body: string): ResponseStream =
## Make a streaming POST request to the OpenAI API.
var headers: curly.HttpHeaders
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Bearer " & api.apiKey
api.lock.sync:
headers["Authorization"] = "Bearer " & api.apiKey
if api.organization != "":
headers["Organization"] = api.organization

Expand All @@ -333,7 +350,7 @@ proc postStream(api: OpenAiApi, path: string, body: string): ResponseStream =
if resp.code != 200:
raise newException(
OpenAiError,
&"OpenAi call {path} failed: {resp.code}"
&"API call {path} failed: {resp.code}"
)
result = resp

Expand All @@ -344,7 +361,8 @@ proc post(
): Response =
## Make a POST request to the OpenAI API.
var headers: curly.HttpHeaders
headers["Authorization"] = "Bearer " & api.apiKey
api.lock.sync:
headers["Authorization"] = "Bearer " & api.apiKey
if api.organization != "":
headers["Organization"] = api.organization
let (contentType, body) = encodeMultipart(entries)
Expand All @@ -358,22 +376,23 @@ proc post(
if resp.code != 200:
raise newException(
OpenAiError,
&"OpenAi call {path} failed: {resp.code} {resp.body}"
&"API call {path} failed: {resp.code} {resp.body}"
)
result = resp

proc delete(api: OpenAiApi, path: string): Response =
## Make a DELETE request to the OpenAI API.
var headers: curly.HttpHeaders
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Bearer " & api.apiKey
api.lock.sync:
headers["Authorization"] = "Bearer " & api.apiKey
if api.organization != "":
headers["Organization"] = api.organization
let resp = api.curly.delete(api.baseUrl & path, headers, api.curlTimeout)
if resp.code != 200:
raise newException(
OpenAiError,
&"OpenAi call {path} failed: {resp.code} {resp.body}"
&"API call {path} failed: {resp.code} {resp.body}"
)
result = resp

Expand Down Expand Up @@ -534,14 +553,15 @@ proc createFineTuneDataset*(api: OpenAiApi, filepath: string): OpenAIFile =

if not fileExists(filepath):
raise newException(OpenAiError, "File does not exist: " & filepath)

let auth = "Bearer " & api.apiKey
var authToken: string
api.lock.sync:
authToken = "Bearer " & api.apiKey
var orgLine = ""
if api.organization != "":
orgLine = "-H \"Organization: " & api.organization & "\""
let curlUploadCmd = &"""
curl -s https://api.openai.com/v1/files \
-H "Authorization: {auth}" \
-H "Authorization: {authToken}" \
{orgLine} \
-F purpose="fine-tune" \
-F file="@{filepath}"
Expand Down

0 comments on commit b02672b

Please sign in to comment.