Stupidity is doing the same thing over and over and expecting different results.
Save money 💸; stop burning 🔥 tokens during dev/test.
Save time ⏰; avoid Heisenbugs 🥸 and flaky tests 🤞 deterministic API stub 🎯.
The package can be installed by adding stubidity
to your list of dependencies
in mix.exs
:
def deps do
[
{:stubidity, "~> 0.4.0"}
]
end
It can then be mounted in another Plug.Router
, for example:
defmodule ExampleWeb.Router do
use Plug.Router
plug :match
plug :dispatch
forward("/stub", Stubidity)
end
To use in your project, set your OpenAI base url to the path where Stubidity is running.
You are welcome to use a public instance of Stubidity at https://fmops.ai/api/v1/stub/openai/v1
. For example:
import openai
openai.api_base = "https://fmops.ai/api/v1/stub/openai/v1"
Stubidity aims to provide a faithful API stub, so request headers and bodies must conform to the expected schemas. One notable exception is the API key, where any non-empty value is considered valid.
To create a ChatGPT completion with curl
:
curl \
-H "content-type: application/json" \
-H "authorization: bearer foo" \
-X POST \
https://fmops.ai/api/v1/stub/openai/v1/chat/completions \
-d '{"model": "gpt-3.5-turbo","messages": [{"role": "system", "message": "tell me a joke"}]}'
{"choices":[{"finish_reason":null,"index":0,"message":{"content":"Why don't scientists trust atoms? Because they make up everything.","role":"assistant"}}],"created":1682447196,"id":"chatcmpl-abc123","model":"gpt-3.5-turbo-0301","object":"chat.completion","usage":{"completion_tokens":13,"prompt_tokens":3,"total_tokens":16}}
Streaming is also supported:
curl \
-H "content-type: application/json" \
-H "authorization: bearer foo" \
-X POST \
https://fmops.ai/api/v1/stub/openai/v1/chat/completions \
-d '{"model": "gpt-3.5-turbo","messages": [{"role": "system", "message": "tell me a joke"}]}'
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"role":"assistant"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"Why"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" was"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" the"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" math"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" book"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" sad"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"?\n\n"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"Because"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" it"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" had"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" too"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" many"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" problems"},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"."},"index":0,"finish_reason":null}]}
data: {"id":"chatcmpl-6zwEy96ojYcDRcdNX8f4L9fu95CaJ","object":"chat.completion.chunk","created":1680219904,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{},"index":0,"finish_reason":"stop"}]}
data: [DONE]
- OpenAI
/chat/completions
buffered and streaming
- OpenAI
/completions
buffered and streaming
- HuggingFace
- gpt2 buffered
- bloomz buffered and streaming
Copyright (c) 2023, Feynman Liang.
Stubidity source code is licensed under the Apache 2.0 License.