ExOpenAI.Codegen (ex_openai.ex v0.3.0) View Source
Codegeneration helpers for parsing the OpenAI openapi documentation and converting it into something easy to work with
Link to this section Summary
Functions
Modules provided by this package that are not in the openapi docs provided by OpenAI So instead of generating those, we just provide a fallback
Parses the given schema recursively into a normalize representation such as %{description: "", example: "", name: "", type: ""}
.
Parses a given "path". A path is what is mapped under the "paths" key of the OpenAI openapi docs, and represents an API endpoint (GET, POST, DELETE, PUT)
Parses the given component type, returns a flattened representation of that type
Link to this section Functions
Specs
Modules provided by this package that are not in the openapi docs provided by OpenAI So instead of generating those, we just provide a fallback
Parses the given schema recursively into a normalize representation such as %{description: "", example: "", name: "", type: ""}
.
A "component schema" is what is defined in the original OpenAI openapi document under the path /components/schema and could look like this:
ChatCompletionRequestMessage:
type: object
properties:
content:
type: string
description: The contents of the message
name:
type: string
description: The name of the user in a multi-user chat
required:
- name
required_props
will consist of all properties that were listed under the "required" listoptional_props
will be all others
"Type" will get normalized into a internal representation consiting of all it's nested children that can be unfolded easily later on:
- "string" -> "string"
- "integer" -> "integer"
- "object" -> {:object, %{nestedobject...}}
"array" -> {:array, "string" | "integer" | etc}
Parses a given "path". A path is what is mapped under the "paths" key of the OpenAI openapi docs, and represents an API endpoint (GET, POST, DELETE, PUT)
The result is a normalized Map representation of the parsed path, including arguments, body and return values
response_type
will be the type value (:string, :integer). Components are represented as {:component, %{"a" => "string"}}request_body
on the other hand will not reference the request component but instead inline it. This decision was made to have all type information available as is for the signature, whereas it is not as important for the response
Example parsed construct:
%{
arguments: [
%{example: "davinci", in: "path", name: "engine_id", required?: true, type: "string"}
],
deprecated?: true,
endpoint: "/foo/${engine_id}",
group: "engines",
method: :post,
name: "retrieve_engine",
response_type: :number,
summary: "summary",
request_body: %{
content_type: :"application/json",
request_schema: %{"properties" => %{"foo" => %{"type" => "string"}}, "type" => "object"},
required?: true
}
}
Example from the API docs:
/engines:
get:
operationId: listEngines
deprecated: true
tags:
- OpenAI
summary: Lists the currently available (non-finetuned) models, and provides basic information about each one such as the owner and availability.
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/ListEnginesResponse'
x-oaiMeta:
name: List engines
group: engines
path: list
Parses the given component type, returns a flattened representation of that type
See tests for some examples:
assert ExOpenAI.Codegen.parse_type(%{
"type" => "object",
"properties" => %{
"foo" => %{
"type" => "array",
"items" => %{
"type" => "string"
}
},
"bar" => %{
"type" => "number"
}
}
}) == {:object, %{"foo" => {:array, "string"}, "bar" => "number"}}