openai 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/LICENSE.txt +1 -1
- data/README.md +18 -9
- data/Rakefile +5 -1
- data/lib/openai.rb +6 -28
- data/lib/openai/choice.rb +3 -0
- data/lib/openai/client.rb +139 -0
- data/lib/openai/completion.rb +7 -0
- data/lib/openai/engine.rb +3 -0
- data/lib/openai/logprobs.rb +3 -0
- data/lib/openai/search_result.rb +3 -0
- data/lib/openai/version.rb +2 -2
- data/openai.gemspec +12 -12
- metadata +44 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72e52493a36fa127172247c0db2f53153cdbb9ff1f3025d007fe9638e9298a77
|
4
|
+
data.tar.gz: 011f3c8fd9b2704f57a65bd406d7ea62efcfe17637c90a95ce3db97c02cfc3a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a3dcb467a183d8d7c73b0a3cdc1026e26e07f84957044c4dd7d2ba586fefb68af85aacf092f460005f99191e2ec609b545bf987cec3511538423e4fdcbad768
|
7
|
+
data.tar.gz: b71e17545c81c4399bcb485e750f6222d8ca43c1744452e7477aadb988f8eec4dfbfb9aa4b28308d930153f336a77dd4b916add2c4c454c4c78da399cd658848
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2020
|
3
|
+
Copyright (c) 2020 Nilesh Trivedi, Erik Berlin
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# OpenAI API client library to access GPT-3 in Ruby
|
2
2
|
|
3
3
|
This is a wrapper for calling OpenAI and GPT-3's HTTP APIs. API docs are available here: https://beta.openai.com/api-docs
|
4
4
|
|
@@ -20,19 +20,28 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
```
|
24
|
-
require
|
25
|
-
client = Openai::Client.new(pk: "your_public_key", sk: "your_secret_key")
|
26
|
-
completions = client.completions(prompt: "Have you wondered why", max_tokens: 10)
|
27
|
-
```
|
23
|
+
```ruby
|
24
|
+
require "openai"
|
28
25
|
|
29
|
-
|
26
|
+
openai_client = OpenAI::Client.new(api_key: ENV.fetch("OPENAI_API_KEY"), default_engine: "ada")
|
30
27
|
|
31
|
-
|
32
|
-
|
28
|
+
# List Engines
|
29
|
+
openai_client.engines
|
33
30
|
|
31
|
+
# Retrieve Engine
|
32
|
+
openai_client.engine("babbage")
|
33
|
+
|
34
|
+
# Search
|
35
|
+
openai_client.search(documents: ["White House", "hospital", "school"], query: "the president")
|
36
|
+
|
37
|
+
# Create Completion
|
38
|
+
openai_client.completions(prompt: "Once upon a time", max_tokens: 5)
|
34
39
|
```
|
35
40
|
|
41
|
+
## TODO
|
42
|
+
|
43
|
+
* Stream Completion
|
44
|
+
|
36
45
|
## Development
|
37
46
|
|
38
47
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
data/lib/openai.rb
CHANGED
@@ -1,29 +1,7 @@
|
|
1
|
+
require "openai/choice"
|
2
|
+
require "openai/client"
|
3
|
+
require "openai/completion"
|
4
|
+
require "openai/engine"
|
5
|
+
require "openai/logprobs"
|
6
|
+
require "openai/search_result"
|
1
7
|
require "openai/version"
|
2
|
-
require "httparty"
|
3
|
-
|
4
|
-
module Openai
|
5
|
-
class Client
|
6
|
-
BASE_URL = "https://api.openai.com/v1/engines/davinci"
|
7
|
-
|
8
|
-
attr_accessor :pk, :sk
|
9
|
-
|
10
|
-
def initialize(pk:, sk:)
|
11
|
-
@pk, @sk = pk, sk
|
12
|
-
end
|
13
|
-
|
14
|
-
def completions(prompt:, max_tokens: 5)
|
15
|
-
response = HTTParty.post(BASE_URL + "/completions", headers: self.headers, body: {
|
16
|
-
prompt: prompt,
|
17
|
-
max_tokens: max_tokens
|
18
|
-
}.to_json)
|
19
|
-
return JSON.parse(response.body)
|
20
|
-
end
|
21
|
-
|
22
|
-
def headers
|
23
|
-
{
|
24
|
-
"Content-Type" => "application/json",
|
25
|
-
"Authorization" => "Bearer #{@sk}"
|
26
|
-
}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
require "time"
|
4
|
+
require "uri"
|
5
|
+
|
6
|
+
module OpenAI
|
7
|
+
class Client
|
8
|
+
class Error < RuntimeError
|
9
|
+
end
|
10
|
+
|
11
|
+
LastResponse = Struct.new(:date, :organization, :processing_ms, :request_id, :status_code, :status_message, keyword_init: true)
|
12
|
+
|
13
|
+
attr_reader :last_response
|
14
|
+
attr_writer :api_key
|
15
|
+
attr_accessor :default_engine
|
16
|
+
|
17
|
+
def initialize(api_key:, default_engine: "davinci")
|
18
|
+
@api_key = api_key
|
19
|
+
@default_engine = default_engine
|
20
|
+
end
|
21
|
+
|
22
|
+
def engine(id = default_engine)
|
23
|
+
engine = get("/v1/engines/#{id}")
|
24
|
+
Engine.new(**engine)
|
25
|
+
end
|
26
|
+
|
27
|
+
def engines
|
28
|
+
engines = get("/v1/engines")
|
29
|
+
engines[:data].map do |engine|
|
30
|
+
Engine.new(**engine)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def completions(prompt: nil, max_tokens: nil, temperature: nil, top_p: nil, n: nil, logprobs: nil, echo: nil, stop: nil, presence_penalty: nil, frequency_penalty: nil, engine: default_engine)
|
35
|
+
body = {
|
36
|
+
"prompt" => prompt,
|
37
|
+
"max_tokens" => max_tokens,
|
38
|
+
"temperature" => temperature,
|
39
|
+
"top_p" => top_p,
|
40
|
+
"n" => n,
|
41
|
+
"logprobs" => logprobs,
|
42
|
+
"echo" => echo,
|
43
|
+
"stop" => stop,
|
44
|
+
"presence_penalty" => presence_penalty,
|
45
|
+
"frequency_penalty" => frequency_penalty,
|
46
|
+
}.compact
|
47
|
+
|
48
|
+
completion = post("/v1/engines/#{engine}/completions", body: body)
|
49
|
+
|
50
|
+
choices = completion[:choices]&.map do |choice|
|
51
|
+
Choice.new(
|
52
|
+
finish_reason: choice[:finish_reason],
|
53
|
+
index: choice[:index],
|
54
|
+
text: choice[:text],
|
55
|
+
logprobs: choice[:logprobs]&.tap do |logprob|
|
56
|
+
Logprobs.new(
|
57
|
+
text_offset: logprob[:text_offset],
|
58
|
+
token_logprobs: logprob[:token_logprobs],
|
59
|
+
tokens: logprob[:tokens],
|
60
|
+
top_logprobs: logprob[:top_logprobs]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
Completion.new(
|
67
|
+
choices: choices,
|
68
|
+
created: completion[:created],
|
69
|
+
id: completion[:id],
|
70
|
+
model: completion[:model],
|
71
|
+
object: completion[:object]
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def search(documents:, query:, engine: default_engine)
|
76
|
+
body = {
|
77
|
+
"documents" => documents,
|
78
|
+
"query" => query,
|
79
|
+
}.compact
|
80
|
+
|
81
|
+
search_results = post("/v1/engines/#{engine}/search", body: body)
|
82
|
+
search_results[:data].map.with_index do |datum, index|
|
83
|
+
SearchResult.new(**datum).tap do |result|
|
84
|
+
result.text = documents[index]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private def get(path)
|
90
|
+
uri = URI.parse("https://api.openai.com#{path}")
|
91
|
+
req = Net::HTTP::Get.new(uri)
|
92
|
+
headers.each do |name, value|
|
93
|
+
req[name] = value
|
94
|
+
end
|
95
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
96
|
+
http.request(req)
|
97
|
+
end
|
98
|
+
handle_response(response)
|
99
|
+
end
|
100
|
+
|
101
|
+
private def post(path, body: nil)
|
102
|
+
uri = URI.parse("https://api.openai.com#{path}")
|
103
|
+
req = Net::HTTP::Post.new(uri)
|
104
|
+
req.body = body.to_json
|
105
|
+
headers.each do |name, value|
|
106
|
+
req[name] = value
|
107
|
+
end
|
108
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
109
|
+
http.request(req)
|
110
|
+
end
|
111
|
+
handle_response(response)
|
112
|
+
end
|
113
|
+
|
114
|
+
private def handle_response(response)
|
115
|
+
date = Time.httpdate(response["date"]) if response["date"]
|
116
|
+
organization = response["openai-organization"]
|
117
|
+
processing_ms = response["openai-processing-ms"]&.to_i
|
118
|
+
request_id = response["x-request-id"]
|
119
|
+
status_code = response.code&.to_i
|
120
|
+
status_message = response.message
|
121
|
+
@last_response = LastResponse.new(date: date, organization: organization, processing_ms: processing_ms, request_id: request_id, status_code: status_code, status_message: status_message)
|
122
|
+
|
123
|
+
response_body = JSON.parse(response.body, symbolize_names: true)
|
124
|
+
case response
|
125
|
+
when Net::HTTPSuccess
|
126
|
+
response_body
|
127
|
+
else
|
128
|
+
raise Error, response_body[:error][:message].to_s
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private def headers
|
133
|
+
@headers ||= {
|
134
|
+
"Authorization" => "Bearer #{@api_key}",
|
135
|
+
"Content-Type" => "application/json",
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/openai/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "0.
|
1
|
+
module OpenAI
|
2
|
+
VERSION = "0.2.0".freeze
|
3
3
|
end
|
data/openai.gemspec
CHANGED
@@ -1,17 +1,16 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require "openai/version"
|
1
|
+
require_relative "lib/openai/version"
|
4
2
|
|
5
3
|
Gem::Specification.new do |spec|
|
6
4
|
spec.name = "openai"
|
7
|
-
spec.version =
|
8
|
-
spec.authors = ["Nilesh Trivedi"]
|
9
|
-
spec.email = ["git@nileshtrivedi.com"]
|
5
|
+
spec.version = OpenAI::VERSION
|
6
|
+
spec.authors = ["Nilesh Trivedi", "Erik Berlin"]
|
7
|
+
spec.email = ["git@nileshtrivedi.com", "sferik@gmail.com"]
|
10
8
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description
|
9
|
+
spec.summary = "OpenAI API client library to access GPT-3 in Ruby"
|
10
|
+
spec.description = "OpenAI API client library to access GPT-3 in Ruby"
|
13
11
|
spec.homepage = "https://github.com/nileshtrivedi/openai"
|
14
12
|
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
14
|
|
16
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
16
|
spec.metadata["source_code_uri"] = "https://github.com/nileshtrivedi/openai"
|
@@ -19,14 +18,15 @@ Gem::Specification.new do |spec|
|
|
19
18
|
|
20
19
|
# Specify which files should be added to the gem when it is released.
|
21
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
-
spec.files = Dir.chdir(File.expand_path(
|
21
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
23
22
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
23
|
end
|
25
24
|
spec.bindir = "exe"
|
26
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
26
|
spec.require_paths = ["lib"]
|
28
27
|
|
29
|
-
spec.add_development_dependency "bundler", "
|
30
|
-
spec.add_development_dependency "rake", "
|
31
|
-
spec.
|
28
|
+
spec.add_development_dependency "bundler", ">= 2"
|
29
|
+
spec.add_development_dependency "rake", ">= 10"
|
30
|
+
spec.add_development_dependency "rspec", ">= 3.9"
|
31
|
+
spec.add_development_dependency "webmock", ">= 3.8"
|
32
32
|
end
|
metadata
CHANGED
@@ -1,65 +1,82 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nilesh Trivedi
|
8
|
-
|
8
|
+
- Erik Berlin
|
9
|
+
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2020-
|
12
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - "
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2
|
20
|
+
version: '2'
|
20
21
|
type: :development
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - "
|
25
|
+
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2
|
27
|
+
version: '2'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: rake
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- - "
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version: '10
|
34
|
+
version: '10'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- - "
|
39
|
+
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
|
-
version: '10
|
41
|
+
version: '10'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
+
name: rspec
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
46
|
- - ">="
|
46
47
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
48
|
+
version: '3.9'
|
49
|
+
type: :development
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
53
|
- - ">="
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
|
55
|
+
version: '3.9'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: webmock
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.8'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.8'
|
70
|
+
description: OpenAI API client library to access GPT-3 in Ruby
|
56
71
|
email:
|
57
72
|
- git@nileshtrivedi.com
|
73
|
+
- sferik@gmail.com
|
58
74
|
executables: []
|
59
75
|
extensions: []
|
60
76
|
extra_rdoc_files: []
|
61
77
|
files:
|
62
78
|
- ".gitignore"
|
79
|
+
- ".travis.yml"
|
63
80
|
- Gemfile
|
64
81
|
- LICENSE.txt
|
65
82
|
- README.md
|
@@ -67,6 +84,12 @@ files:
|
|
67
84
|
- bin/console
|
68
85
|
- bin/setup
|
69
86
|
- lib/openai.rb
|
87
|
+
- lib/openai/choice.rb
|
88
|
+
- lib/openai/client.rb
|
89
|
+
- lib/openai/completion.rb
|
90
|
+
- lib/openai/engine.rb
|
91
|
+
- lib/openai/logprobs.rb
|
92
|
+
- lib/openai/search_result.rb
|
70
93
|
- lib/openai/version.rb
|
71
94
|
- openai.gemspec
|
72
95
|
homepage: https://github.com/nileshtrivedi/openai
|
@@ -76,7 +99,7 @@ metadata:
|
|
76
99
|
homepage_uri: https://github.com/nileshtrivedi/openai
|
77
100
|
source_code_uri: https://github.com/nileshtrivedi/openai
|
78
101
|
changelog_uri: https://github.com/nileshtrivedi/openai/blob/master/changelog.md
|
79
|
-
post_install_message:
|
102
|
+
post_install_message:
|
80
103
|
rdoc_options: []
|
81
104
|
require_paths:
|
82
105
|
- lib
|
@@ -84,15 +107,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
107
|
requirements:
|
85
108
|
- - ">="
|
86
109
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
110
|
+
version: 2.3.0
|
88
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
112
|
requirements:
|
90
113
|
- - ">="
|
91
114
|
- !ruby/object:Gem::Version
|
92
115
|
version: '0'
|
93
116
|
requirements: []
|
94
|
-
rubygems_version: 3.
|
95
|
-
signing_key:
|
117
|
+
rubygems_version: 3.1.2
|
118
|
+
signing_key:
|
96
119
|
specification_version: 4
|
97
|
-
summary:
|
120
|
+
summary: OpenAI API client library to access GPT-3 in Ruby
|
98
121
|
test_files: []
|