diff --git a/README.md b/README.md index 99cafa6..6c6de63 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [x] [ChatGPT](https://github.com/D7EAD/liboai/tree/main/documentation/chat) - [X] [Audio](https://github.com/D7EAD/liboai/tree/main/documentation/audio) +- [X] [Azure](https://github.com/D7EAD/liboai/tree/main/documentation/azure) - [x] [Image DALLĀ·E](https://github.com/D7EAD/liboai/tree/main/documentation/images) - [x] [Models](https://github.com/D7EAD/liboai/tree/main/documentation/models) - [x] [Completions](https://github.com/D7EAD/liboai/tree/main/documentation/completions) diff --git a/documentation/authorization/README.md b/documentation/authorization/README.md index 3d5ee90..2729df7 100644 --- a/documentation/authorization/README.md +++ b/documentation/authorization/README.md @@ -21,6 +21,20 @@ static Authorization& Authorizer() noexcept; bool SetKey(std::string_view key) noexcept; ``` +

Set Azure API Key

+

Sets the Azure API key to use in subsequent component calls.

+ +```cpp +bool SetAzureKey(std::string_view key) noexcept; +``` + +

Set Active Directory Azure API Key

+

Sets the Active Directory Azure API key to use in subsequent component calls.

+ +```cpp +bool SetAzureKeyAD(std::string_view key) noexcept; +``` +

Set API Key (File)

Sets the API key to use in subsequent component calls from data found in file at path.

@@ -28,12 +42,40 @@ bool SetKey(std::string_view key) noexcept; bool SetKeyFile(const std::filesystem::path& path) noexcept; ``` +

Set Azure API Key (File)

+

Sets the Azure API key to use in subsequent component calls from data found in file at path.

+ +```cpp +bool SetAzureKeyFile(const std::filesystem::path& path) noexcept; +``` + +

Set Active Directory zure API Key (File)

+

Sets the Active Directory Azure API key to use in subsequent component calls from data found in file at path.

+ +```cpp +bool SetAzureKeyFileAD(const std::filesystem::path& path) noexcept; +``` +

Set API Key (Environment Variable)

Sets the API key to use in subsequent component calls from an environment variable.

```cpp bool SetKeyEnv(std::string_view var) noexcept; ``` + +

Set Azure API Key (Environment Variable)

+

Sets the Azure API key to use in subsequent component calls from an environment variable.

+ +```cpp +bool SetAzureKeyEnv(std::string_view var) noexcept; +``` + +

Set Active Directory Azure API Key (Environment Variable)

+

Sets the Active Directory Azure API key to use in subsequent component calls from an environment variable.

+ +```cpp +bool SetAzureKeyEnvAD(std::string_view var) noexcept; +```

Set Organization ID

Sets the organization ID to send in subsequent component calls.

@@ -123,6 +165,13 @@ netimpl::components::Timeout GetMaxTimeout() const noexcept; constexpr const netimpl::components::Header& GetAuthorizationHeaders() const noexcept; ``` +

Get Azure Authorization Headers

+

Returns the currently set Azure authorization headers based on set information.

+ +```cpp +constexpr const netimpl::components::Header& GetAzureAuthorizationHeaders() const noexcept; +``` +

Example Usage

For example usage of the above function(s), please refer to the examples folder. diff --git a/documentation/authorization/examples/set_azure_key.cpp b/documentation/authorization/examples/set_azure_key.cpp new file mode 100644 index 0000000..5d777ff --- /dev/null +++ b/documentation/authorization/examples/set_azure_key.cpp @@ -0,0 +1,10 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + if (oai.auth.SetAzureKey("hard-coded-key")) { // NOT recommended + ... + } +} diff --git a/documentation/authorization/examples/set_azure_key_env.cpp b/documentation/authorization/examples/set_azure_key_env.cpp new file mode 100644 index 0000000..42ae506 --- /dev/null +++ b/documentation/authorization/examples/set_azure_key_env.cpp @@ -0,0 +1,10 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + ... + } +} diff --git a/documentation/authorization/examples/set_azure_key_file.cpp b/documentation/authorization/examples/set_azure_key_file.cpp new file mode 100644 index 0000000..b84f490 --- /dev/null +++ b/documentation/authorization/examples/set_azure_key_file.cpp @@ -0,0 +1,10 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + if (oai.auth.SetAzureKeyFile("C:/some/folder/key.dat")) { + ... + } +} diff --git a/documentation/azure/README.md b/documentation/azure/README.md new file mode 100644 index 0000000..d979761 --- /dev/null +++ b/documentation/azure/README.md @@ -0,0 +1,204 @@ +

Azure

+

The Azure class is defined in azure.h at liboai::Azure, and its interface can ideally be accessed through a liboai::OpenAI object. + +This class and its associated liboai::OpenAI interface allow access to the Azure OpenAI API components. + +
+

Methods

+

This document covers the method(s) located in azure.h. You can find their function signature(s) below.

+ +

Create a Completion

+

Given a prompt, the model will return one or more predicted completions. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response create_completion( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + std::optional prompt = std::nullopt, + std::optional suffix = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional temperature = std::nullopt, + std::optional top_p = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional logprobs = std::nullopt, + std::optional echo = std::nullopt, + std::optional> stop = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional best_of = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Create a Completion (async)

+

Given a prompt, the model will asynchronously return one or more predicted completions. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse create_completion_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + std::optional prompt = std::nullopt, + std::optional suffix = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional temperature = std::nullopt, + std::optional top_p = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional logprobs = std::nullopt, + std::optional echo = std::nullopt, + std::optional> stop = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional best_of = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Create an Embedding

+

Creates an embedding vector representing the input text. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response create_embedding( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const std::string& input, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Create an Embedding (async)

+

Asynchronously creates an embedding vector representing the input text. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse create_embedding_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const std::string& input, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Create a Chat Completion

+

Creates a completion for the chat message. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response create_chat_completion( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const Conversation& conversation, + std::optional temperature = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional> stop = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Create a Chat Completion (async)

+

Asynchronously creates a completion for the chat message. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse create_chat_completion_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const Conversation& conversation, + std::optional temperature = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional> stop = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt +) const & noexcept(false); +``` + +

Request an Image Generation

+

Generate a batch of images from a text caption. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response request_image_generation( + const std::string& resource_name, + const std::string& api_version, + const std::string& prompt, + std::optional n = std::nullopt, + std::optional size = std::nullopt +) const & noexcept(false); +``` + +

Request an Image Generation (async)

+

Asynchronously generate a batch of images from a text caption. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse request_image_generation_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& prompt, + std::optional n = std::nullopt, + std::optional size = std::nullopt +) const & noexcept(false); +``` + +

Get a Previously Generated Image

+

Retrieve the results (URL) of a previously called image generation operation. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response get_generated_image( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id +) const & noexcept(false); +``` + +

Get a Previously Generated Image (async)

+

Asynchronously retrieve the results (URL) of a previously called image generation operation. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse get_generated_image_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id +) const & noexcept(false); +``` + +

Delete a Previously Generated Image

+

Deletes the corresponding image from the Azure server. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response delete_generated_image( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id +) const & noexcept(false); +``` + +

Delete a Previously Generated Image (async)

+

Asynchronously deletes the corresponding image from the Azure server. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse delete_generated_image_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id +) const & noexcept(false); +``` + +

All function parameters marked optional are not required and are resolved on OpenAI's end if not supplied.

+ +
+

Example Usage

+

For example usage of the above function(s), please refer to the examples folder. diff --git a/documentation/azure/examples/create_chat_completion.cpp b/documentation/azure/examples/create_chat_completion.cpp new file mode 100644 index 0000000..d9b1c87 --- /dev/null +++ b/documentation/azure/examples/create_chat_completion.cpp @@ -0,0 +1,28 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + Conversation convo; + convo.AddUserData("Hi, how are you?"); + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->create_chat_completion( + "resource", "deploymentID", "api_version", + convo + ); + + // update the conversation with the response + convo.Update(res); + + // print the response from the API + std::cout << convo.GetLastResponse() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/create_chat_completion_async.cpp b/documentation/azure/examples/create_chat_completion_async.cpp new file mode 100644 index 0000000..06d64c0 --- /dev/null +++ b/documentation/azure/examples/create_chat_completion_async.cpp @@ -0,0 +1,37 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + Conversation convo; + convo.AddUserData("Hi, how are you?"); + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + // call async method; returns a future + auto fut = oai.Azure->create_chat_completion_async( + "resource", "deploymentID", "api_version", + convo + ); + + // do other work... + + // check if the future is ready + fut.wait(); + + // get the contained response + auto res = fut.get(); + + // update the conversation with the response + convo.Update(res); + + // print the response from the API + std::cout << convo.GetLastResponse() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/create_completion.cpp b/documentation/azure/examples/create_completion.cpp new file mode 100644 index 0000000..0f14f28 --- /dev/null +++ b/documentation/azure/examples/create_completion.cpp @@ -0,0 +1,21 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->create_completion( + "resource", "deploymentID", "api_version", + "Write a short poem about a snowman." + ); + + std::cout << res["choices"][0]["text"].get() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/create_completion_async.cpp b/documentation/azure/examples/create_completion_async.cpp new file mode 100644 index 0000000..a94bc00 --- /dev/null +++ b/documentation/azure/examples/create_completion_async.cpp @@ -0,0 +1,29 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + auto fut = oai.Azure->create_completion_async( + "resource", "deploymentID", "api_version", + "Write a short poem about a snowman." + ); + + // do other stuff + + // wait for the future to be ready + fut.wait(); + + // get the result + auto res = fut.get(); + + std::cout << res["choices"][0]["text"].get() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/create_embedding.cpp b/documentation/azure/examples/create_embedding.cpp new file mode 100644 index 0000000..61070f8 --- /dev/null +++ b/documentation/azure/examples/create_embedding.cpp @@ -0,0 +1,21 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->create_embedding( + "resource", "deploymentID", "api_version", + "String to get embedding for" + ); + + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/create_embedding_async.cpp b/documentation/azure/examples/create_embedding_async.cpp new file mode 100644 index 0000000..8734cad --- /dev/null +++ b/documentation/azure/examples/create_embedding_async.cpp @@ -0,0 +1,27 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + auto fut = oai.Azure->create_embedding_async( + "resource", "deploymentID", "api_version", + "String to get embedding for" + ); + + // do other work + + // wait for the future to complete + auto res = fut.get(); + + // output the response + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/delete_generated_image.cpp b/documentation/azure/examples/delete_generated_image.cpp new file mode 100644 index 0000000..e261e65 --- /dev/null +++ b/documentation/azure/examples/delete_generated_image.cpp @@ -0,0 +1,22 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->delete_generated_image( + "resource", "api_version", + "f508bcf2-e651-4b4b-85a7-58ad77981ffa" + ); + + // output the response + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/delete_generated_image_async.cpp b/documentation/azure/examples/delete_generated_image_async.cpp new file mode 100644 index 0000000..714442f --- /dev/null +++ b/documentation/azure/examples/delete_generated_image_async.cpp @@ -0,0 +1,30 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + auto fut = oai.Azure->delete_generated_image_async( + "resource", "api_version", + "f508bcf2-e651-4b4b-85a7-58ad77981ffa" + ); + + // do other work + + // wait for the future to complete + fut.wait(); + + // get the result + auto res = fut.get(); + + // output the response + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/get_generated_image.cpp b/documentation/azure/examples/get_generated_image.cpp new file mode 100644 index 0000000..8b189df --- /dev/null +++ b/documentation/azure/examples/get_generated_image.cpp @@ -0,0 +1,22 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->get_generated_image( + "resource", "api_version", + "f508bcf2-e651-4b4b-85a7-58ad77981ffa" + ); + + // output the response + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/get_generated_image_async.cpp b/documentation/azure/examples/get_generated_image_async.cpp new file mode 100644 index 0000000..08ce9b7 --- /dev/null +++ b/documentation/azure/examples/get_generated_image_async.cpp @@ -0,0 +1,30 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + auto fut = oai.Azure->get_generated_image_async( + "resource", "api_version", + "f508bcf2-e651-4b4b-85a7-58ad77981ffa" + ); + + // do other work + + // wait for the future to complete + fut.wait(); + + // get the result + auto res = fut.get(); + + // output the response + std::cout << res << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/request_image_generation.cpp b/documentation/azure/examples/request_image_generation.cpp new file mode 100644 index 0000000..c869472 --- /dev/null +++ b/documentation/azure/examples/request_image_generation.cpp @@ -0,0 +1,24 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + Response res = oai.Azure->request_image_generation( + "resource", "api_version", + "A snake in the grass!", + 1, + "512x512" + ); + + // output the response + std::cout << res["data"][0]["url"].get() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/azure/examples/request_image_generation_async.cpp b/documentation/azure/examples/request_image_generation_async.cpp new file mode 100644 index 0000000..06c6a09 --- /dev/null +++ b/documentation/azure/examples/request_image_generation_async.cpp @@ -0,0 +1,29 @@ +#include "liboai.h" + +using namespace liboai; + +int main() { + OpenAI oai; + + if (oai.auth.SetAzureKeyEnv("AZURE_API_KEY")) { + try { + auto fut = oai.Azure->request_image_generation_async( + "resource", "api_version", + "A snake in the grass!", + 1, + "512x512" + ); + + // do other work + + // wait for the future to complete + auto res = fut.get(); + + // output the response + std::cout << res["data"][0]["url"].get() << std::endl; + } + catch (std::exception& e) { + std::cout << e.what() << std::endl; + } + } +} diff --git a/documentation/fine-tunes/README.md b/documentation/fine-tunes/README.md index 1c695af..73facf1 100644 --- a/documentation/fine-tunes/README.md +++ b/documentation/fine-tunes/README.md @@ -119,6 +119,24 @@ liboai::FutureResponse list_events_async( ) const & noexcept(false); ``` +

Delete Fine-Tune Model

+

Delete a fine-tuned model. You must have the Owner role in your organization. Returns a liboai::Response containing response data.

+ +```cpp +liboai::Response remove( + const std::string& model +) const & noexcept(false); +``` + +

Delete Fine-Tune Model (async)

+

Asynchronously delete a fine-tuned model. You must have the Owner role in your organization. Returns a liboai::FutureResponse containing future response data.

+ +```cpp +liboai::FutureResponse remove_async( + const std::string& model +) const & noexcept(false); +``` +

All function parameters marked optional are not required and are resolved on OpenAI's end if not supplied.


diff --git a/documentation/fine-tunes/examples/delete_fine_tune_model.cpp b/documentation/fine-tunes/examples/delete_fine_tune_model.cpp index 0a7df6f..a7ba4e7 100644 --- a/documentation/fine-tunes/examples/delete_fine_tune_model.cpp +++ b/documentation/fine-tunes/examples/delete_fine_tune_model.cpp @@ -6,7 +6,7 @@ int main() { OpenAI oai; if (oai.auth.SetKeyEnv("OPENAI_API_KEY")) { try { - Response response = oai.Model->remove( + Response response = oai.FineTune->remove( "curie:ft-acmeco-2021-03-03-21-44-20" ); std::cout << response["deleted"].get() << std::endl; diff --git a/documentation/fine-tunes/examples/delete_fine_tune_model_async.cpp b/documentation/fine-tunes/examples/delete_fine_tune_model_async.cpp index 9b2bffb..40fad9f 100644 --- a/documentation/fine-tunes/examples/delete_fine_tune_model_async.cpp +++ b/documentation/fine-tunes/examples/delete_fine_tune_model_async.cpp @@ -7,7 +7,7 @@ int main() { if (oai.auth.SetKeyEnv("OPENAI_API_KEY")) { try { // call async method; returns a future - auto fut = oai.Model->remove_async( + auto fut = oai.FineTune->remove_async( "curie:ft-acmeco-2021-03-03-21-44-20" ); diff --git a/documentation/models/README.md b/documentation/models/README.md index 7302ea5..fd5d0f1 100644 --- a/documentation/models/README.md +++ b/documentation/models/README.md @@ -40,24 +40,6 @@ liboai::FutureResponse retrieve_async( ) const & noexcept(false); ``` -

Delete Fine-Tune Model

-

Delete a fine-tuned model. You must have the Owner role in your organization. Returns a liboai::Response containing response data.

- -```cpp -liboai::Response remove( - const std::string& model -) const & noexcept(false); -``` - -

Delete Fine-Tune Model (async)

-

Asynchronously delete a fine-tuned model. You must have the Owner role in your organization. Returns a liboai::FutureResponse containing future response data.

- -```cpp -liboai::FutureResponse remove_async( - const std::string& model -) const & noexcept(false); -``` -

Example Usage

For example usage of the above function(s), please refer to the examples folder. diff --git a/liboai/components/audio.cpp b/liboai/components/audio.cpp index a732a1c..aa738c5 100644 --- a/liboai/components/audio.cpp +++ b/liboai/components/audio.cpp @@ -21,7 +21,7 @@ liboai::Response liboai::Audio::transcribe(const std::filesystem::path& file, co Response res; res = this->Request( - Method::HTTP_POST, "/audio/transcriptions", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/audio/transcriptions", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -50,11 +50,11 @@ liboai::FutureResponse liboai::Audio::transcribe_async(const std::filesystem::pa if (response_format) { form.parts.push_back({ "response_format", response_format.value() }); } if (temperature) { form.parts.push_back({ "temperature", std::to_string(temperature.value()) }); } if (language) { form.parts.push_back({ "language", language.value() }); } - + return std::async( std::launch::async, [&, form]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/audio/transcriptions", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/audio/transcriptions", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -85,7 +85,7 @@ liboai::Response liboai::Audio::translate(const std::filesystem::path& file, con Response res; res = this->Request( - Method::HTTP_POST, "/audio/translations", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/audio/translations", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -117,7 +117,7 @@ liboai::FutureResponse liboai::Audio::translate_async(const std::filesystem::pat return std::async( std::launch::async, [&, form]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/audio/translations", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/audio/translations", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), diff --git a/liboai/components/azure.cpp b/liboai/components/azure.cpp new file mode 100644 index 0000000..d0e7c58 --- /dev/null +++ b/liboai/components/azure.cpp @@ -0,0 +1,321 @@ +#include "../include/components/azure.h" + +liboai::Response liboai::Azure::create_completion(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, std::optional prompt, std::optional suffix, std::optional max_tokens, std::optional temperature, std::optional top_p, std::optional n, std::optional> stream, std::optional logprobs, std::optional echo, std::optional> stop, std::optional presence_penalty, std::optional frequency_penalty, std::optional best_of, std::optional> logit_bias, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("prompt", std::move(prompt)); + jcon.push_back("suffix", std::move(suffix)); + jcon.push_back("max_tokens", std::move(max_tokens)); + jcon.push_back("temperature", std::move(temperature)); + jcon.push_back("top_p", std::move(top_p)); + jcon.push_back("n", std::move(n)); + jcon.push_back("stream", stream); + jcon.push_back("logprobs", std::move(logprobs)); + jcon.push_back("echo", std::move(echo)); + jcon.push_back("stop", std::move(stop)); + jcon.push_back("presence_penalty", std::move(presence_penalty)); + jcon.push_back("frequency_penalty", std::move(frequency_penalty)); + jcon.push_back("best_of", std::move(best_of)); + jcon.push_back("logit_bias", std::move(logit_bias)); + jcon.push_back("user", std::move(user)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/completions", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::create_completion_async(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, std::optional prompt, std::optional suffix, std::optional max_tokens, std::optional temperature, std::optional top_p, std::optional n, std::optional> stream, std::optional logprobs, std::optional echo, std::optional> stop, std::optional presence_penalty, std::optional frequency_penalty, std::optional best_of, std::optional> logit_bias, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("prompt", std::move(prompt)); + jcon.push_back("suffix", std::move(suffix)); + jcon.push_back("max_tokens", std::move(max_tokens)); + jcon.push_back("temperature", std::move(temperature)); + jcon.push_back("top_p", std::move(top_p)); + jcon.push_back("n", std::move(n)); + jcon.push_back("stream", stream); + jcon.push_back("logprobs", std::move(logprobs)); + jcon.push_back("echo", std::move(echo)); + jcon.push_back("stop", std::move(stop)); + jcon.push_back("presence_penalty", std::move(presence_penalty)); + jcon.push_back("frequency_penalty", std::move(frequency_penalty)); + jcon.push_back("best_of", std::move(best_of)); + jcon.push_back("logit_bias", std::move(logit_bias)); + jcon.push_back("user", std::move(user)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, jcon, params, stream]() -> liboai::Response { + return this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/completions", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} + +liboai::Response liboai::Azure::create_embedding(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, const std::string& input, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("input", input); + jcon.push_back("user", std::move(user)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/embeddings", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::create_embedding_async(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, const std::string& input, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("input", input); + jcon.push_back("user", std::move(user)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, jcon, params]() -> liboai::Response { + return this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/embeddings", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} + +liboai::Response liboai::Azure::create_chat_completion(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, const Conversation& conversation, std::optional temperature, std::optional n, std::optional> stream, std::optional> stop, std::optional max_tokens, std::optional presence_penalty, std::optional frequency_penalty, std::optional> logit_bias, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("temperature", std::move(temperature)); + jcon.push_back("n", std::move(n)); + jcon.push_back("stream", stream); + jcon.push_back("stop", std::move(stop)); + jcon.push_back("max_tokens", std::move(max_tokens)); + jcon.push_back("presence_penalty", std::move(presence_penalty)); + jcon.push_back("frequency_penalty", std::move(frequency_penalty)); + jcon.push_back("logit_bias", std::move(logit_bias)); + jcon.push_back("user", std::move(user)); + + if (conversation.GetJSON().contains("messages")) { + jcon.push_back("messages", conversation.GetJSON()["messages"]); + } + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/chat/completions", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::create_chat_completion_async(const std::string& resource_name, const std::string& deployment_id, const std::string& api_version, const Conversation& conversation, std::optional temperature, std::optional n, std::optional> stream, std::optional> stop, std::optional max_tokens, std::optional presence_penalty, std::optional frequency_penalty, std::optional> logit_bias, std::optional user) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("temperature", std::move(temperature)); + jcon.push_back("n", std::move(n)); + jcon.push_back("stream", stream); + jcon.push_back("stop", std::move(stop)); + jcon.push_back("max_tokens", std::move(max_tokens)); + jcon.push_back("presence_penalty", std::move(presence_penalty)); + jcon.push_back("frequency_penalty", std::move(frequency_penalty)); + jcon.push_back("logit_bias", std::move(logit_bias)); + jcon.push_back("user", std::move(user)); + + if (conversation.GetJSON().contains("messages")) { + jcon.push_back("messages", conversation.GetJSON()["messages"]); + } + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, jcon, params, stream]() -> liboai::Response { + return this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_ + "/deployments/" + deployment_id), "/chat/completions", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} + +liboai::Response liboai::Azure::request_image_generation(const std::string& resource_name, const std::string& api_version, const std::string& prompt, std::optional n, std::optional size) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("prompt", prompt); + jcon.push_back("n", std::move(n)); + jcon.push_back("size", std::move(size)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_), "/images/generations:submit", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::request_image_generation_async(const std::string& resource_name, const std::string& api_version, const std::string& prompt, std::optional n, std::optional size) const & noexcept(false) { + liboai::JsonConstructor jcon; + jcon.push_back("prompt", prompt); + jcon.push_back("n", std::move(n)); + jcon.push_back("size", std::move(size)); + + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, jcon, params]() -> liboai::Response { + return this->Request( + Method::HTTP_POST, ("https://" + resource_name + this->azure_root_), "/images/generations:submit", "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + netimpl::components::Body { + jcon.dump() + }, + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} + +liboai::Response liboai::Azure::get_generated_image(const std::string& resource_name, const std::string& api_version, const std::string& operation_id) const & noexcept(false) { + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_GET, ("https://" + resource_name + this->azure_root_), "/operations/images/" + operation_id, "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::get_generated_image_async(const std::string& resource_name, const std::string& api_version, const std::string& operation_id) const & noexcept(false) { + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, params]() -> liboai::Response { + return this->Request( + Method::HTTP_GET, ("https://" + resource_name + this->azure_root_), "/operations/images/" + operation_id, "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} + +liboai::Response liboai::Azure::delete_generated_image(const std::string& resource_name, const std::string& api_version, const std::string& operation_id) const & noexcept(false) { + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + Response res; + res = this->Request( + Method::HTTP_DELETE, ("https://" + resource_name + this->azure_root_), "/operations/images/" + operation_id, "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::Azure::delete_generated_image_async(const std::string& resource_name, const std::string& api_version, const std::string& operation_id) const & noexcept(false) { + netimpl::components::Parameters params; + params.Add({ "api-version", api_version }); + + return std::async( + std::launch::async, [&, params]() -> liboai::Response { + return this->Request( + Method::HTTP_DELETE, ("https://" + resource_name + this->azure_root_), "/operations/images/" + operation_id, "application/json", + this->auth_.GetAzureAuthorizationHeaders(), + std::move(params), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); +} \ No newline at end of file diff --git a/liboai/components/chat.cpp b/liboai/components/chat.cpp index f4f3a14..fdaa52c 100644 --- a/liboai/components/chat.cpp +++ b/liboai/components/chat.cpp @@ -220,7 +220,7 @@ liboai::Response liboai::ChatCompletion::create(const std::string& model, const Response res; res = this->Request( - Method::HTTP_POST, "/chat/completions", "application/json", + Method::HTTP_POST, this->openai_root_, "/chat/completions", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -253,9 +253,9 @@ liboai::FutureResponse liboai::ChatCompletion::create_async(const std::string& m } return std::async( - std::launch::async, [&, jcon]() -> liboai::Response { + std::launch::async, [&, jcon, stream]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/chat/completions", "application/json", + Method::HTTP_POST, this->openai_root_, "/chat/completions", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() diff --git a/liboai/components/completions.cpp b/liboai/components/completions.cpp index ee1ce0b..b4c4137 100644 --- a/liboai/components/completions.cpp +++ b/liboai/components/completions.cpp @@ -21,7 +21,7 @@ liboai::Response liboai::Completions::create(const std::string& model_id, std::o Response res; res = this->Request( - Method::HTTP_POST, "/completions", "application/json", + Method::HTTP_POST, this->openai_root_, "/completions", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -55,9 +55,9 @@ liboai::FutureResponse liboai::Completions::create_async(const std::string& mode jcon.push_back("user", std::move(user)); return std::async( - std::launch::async, [&, jcon]() -> liboai::Response { + std::launch::async, [&, jcon, stream]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/completions", "application/json", + Method::HTTP_POST, this->openai_root_, "/completions", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() diff --git a/liboai/components/edits.cpp b/liboai/components/edits.cpp index f8acf04..904c8ee 100644 --- a/liboai/components/edits.cpp +++ b/liboai/components/edits.cpp @@ -11,7 +11,7 @@ liboai::Response liboai::Edits::create(const std::string& model_id, std::optiona Response res; res = this->Request( - Method::HTTP_POST, "/edits", "application/json", + Method::HTTP_POST, this->openai_root_, "/edits", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -36,7 +36,7 @@ liboai::FutureResponse liboai::Edits::create_async(const std::string& model_id, return std::async( std::launch::async, [&, jcon]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/edits", "application/json", + Method::HTTP_POST, this->openai_root_, "/edits", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() diff --git a/liboai/components/embeddings.cpp b/liboai/components/embeddings.cpp index 7dd3e17..5755fa2 100644 --- a/liboai/components/embeddings.cpp +++ b/liboai/components/embeddings.cpp @@ -8,7 +8,7 @@ liboai::Response liboai::Embeddings::create(const std::string& model_id, std::op Response res; res = this->Request( - Method::HTTP_POST, "/embeddings", "application/json", + Method::HTTP_POST, this->openai_root_, "/embeddings", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -30,7 +30,7 @@ liboai::FutureResponse liboai::Embeddings::create_async(const std::string& model return std::async( std::launch::async, [&, jcon]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/embeddings", "application/json", + Method::HTTP_POST, this->openai_root_, "/embeddings", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() diff --git a/liboai/components/files.cpp b/liboai/components/files.cpp index a99e29a..e4e1ef2 100644 --- a/liboai/components/files.cpp +++ b/liboai/components/files.cpp @@ -3,7 +3,7 @@ liboai::Response liboai::Files::list() const & noexcept(false) { Response res; res = this->Request( - Method::HTTP_GET, "/files", "application/json", + Method::HTTP_GET, this->openai_root_, "/files", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -17,7 +17,7 @@ liboai::FutureResponse liboai::Files::list_async() const & noexcept(false) { return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/files", "application/json", + Method::HTTP_GET, this->openai_root_, "/files", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -43,7 +43,7 @@ liboai::Response liboai::Files::create(const std::filesystem::path& file, const Response res; res = this->Request( - Method::HTTP_POST, "/files", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/files", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -71,7 +71,7 @@ liboai::FutureResponse liboai::Files::create_async(const std::filesystem::path& return std::async( std::launch::async, [&, form]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/files", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/files", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -85,7 +85,7 @@ liboai::FutureResponse liboai::Files::create_async(const std::filesystem::path& liboai::Response liboai::Files::remove(const std::string& file_id) const & noexcept(false) { Response res; res = this->Request( - Method::HTTP_DELETE, "/files/" + file_id, "application/json", + Method::HTTP_DELETE, this->openai_root_, "/files/" + file_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -99,7 +99,7 @@ liboai::FutureResponse liboai::Files::remove_async(const std::string& file_id) c return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_DELETE, "/files/" + file_id, "application/json", + Method::HTTP_DELETE, this->openai_root_, "/files/" + file_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -112,7 +112,7 @@ liboai::FutureResponse liboai::Files::remove_async(const std::string& file_id) c liboai::Response liboai::Files::retrieve(const std::string& file_id) const & { Response res; res = this->Request( - Method::HTTP_GET, "/files/" + file_id, "application/json", + Method::HTTP_GET, this->openai_root_, "/files/" + file_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -126,7 +126,7 @@ liboai::FutureResponse liboai::Files::retrieve_async(const std::string& file_id) return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/files/" + file_id, "application/json", + Method::HTTP_GET, this->openai_root_, "/files/" + file_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), diff --git a/liboai/components/fine_tunes.cpp b/liboai/components/fine_tunes.cpp index 4e88231..b92bbbc 100644 --- a/liboai/components/fine_tunes.cpp +++ b/liboai/components/fine_tunes.cpp @@ -17,7 +17,7 @@ liboai::Response liboai::FineTunes::create(const std::string& training_file, std Response res; res = this->Request( - Method::HTTP_POST, "/fine-tunes", "application/json", + Method::HTTP_POST, this->openai_root_, "/fine-tunes", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -48,7 +48,7 @@ liboai::FutureResponse liboai::FineTunes::create_async(const std::string& traini return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/fine-tunes", "application/json", + Method::HTTP_POST, this->openai_root_, "/fine-tunes", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -64,7 +64,7 @@ liboai::FutureResponse liboai::FineTunes::create_async(const std::string& traini liboai::Response liboai::FineTunes::list() const& { Response res; res = this->Request( - Method::HTTP_GET, "/fine-tunes", "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -78,7 +78,7 @@ liboai::FutureResponse liboai::FineTunes::list_async() const & noexcept(false) { return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/fine-tunes", "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -91,7 +91,7 @@ liboai::FutureResponse liboai::FineTunes::list_async() const & noexcept(false) { liboai::Response liboai::FineTunes::retrieve(const std::string& fine_tune_id) const& { Response res; res = this->Request( - Method::HTTP_GET, "/fine-tunes/" + fine_tune_id, "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes/" + fine_tune_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -105,7 +105,7 @@ liboai::FutureResponse liboai::FineTunes::retrieve_async(const std::string& fine return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/fine-tunes/" + fine_tune_id, "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes/" + fine_tune_id, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -118,7 +118,7 @@ liboai::FutureResponse liboai::FineTunes::retrieve_async(const std::string& fine liboai::Response liboai::FineTunes::cancel(const std::string& fine_tune_id) const& { Response res; res = this->Request( - Method::HTTP_POST, "/fine-tunes/" + fine_tune_id + "/cancel", "application/json", + Method::HTTP_POST, this->openai_root_, "/fine-tunes/" + fine_tune_id + "/cancel", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -132,7 +132,7 @@ liboai::FutureResponse liboai::FineTunes::cancel_async(const std::string& fine_t return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/fine-tunes/" + fine_tune_id + "/cancel", "application/json", + Method::HTTP_POST, this->openai_root_, "/fine-tunes/" + fine_tune_id + "/cancel", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -148,7 +148,7 @@ liboai::Response liboai::FineTunes::list_events(const std::string& fine_tune_id, Response res; res = this->Request( - Method::HTTP_GET, "/fine-tunes/" + fine_tune_id + "/events", "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes/" + fine_tune_id + "/events", "application/json", this->auth_.GetAuthorizationHeaders(), std::move(params), stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, @@ -165,9 +165,9 @@ liboai::FutureResponse liboai::FineTunes::list_events_async(const std::string& f stream ? params.Add({ "stream", "true"}) : void(); return std::async( - std::launch::async, [&, params]() -> liboai::Response { + std::launch::async, [&, params, stream]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/fine-tunes/" + fine_tune_id + "/events", "application/json", + Method::HTTP_GET, this->openai_root_, "/fine-tunes/" + fine_tune_id + "/events", "application/json", this->auth_.GetAuthorizationHeaders(), std::move(params), stream ? netimpl::components::WriteCallback{std::move(stream.value())} : netimpl::components::WriteCallback{}, @@ -177,4 +177,31 @@ liboai::FutureResponse liboai::FineTunes::list_events_async(const std::string& f ); } ); +} + +liboai::Response liboai::FineTunes::remove(const std::string& model) const& noexcept(false) { + Response res; + res = this->Request( + Method::HTTP_DELETE, this->openai_root_, "/models/" + model, "application/json", + this->auth_.GetAuthorizationHeaders(), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + + return res; +} + +liboai::FutureResponse liboai::FineTunes::remove_async(const std::string& model) const & noexcept(false) { + return std::async( + std::launch::async, [&]() -> liboai::Response { + return this->Request( + Method::HTTP_DELETE, this->openai_root_, "/models/" + model, "application/json", + this->auth_.GetAuthorizationHeaders(), + this->auth_.GetProxies(), + this->auth_.GetProxyAuth(), + this->auth_.GetMaxTimeout() + ); + } + ); } \ No newline at end of file diff --git a/liboai/components/images.cpp b/liboai/components/images.cpp index 00980ad..e0a3ba7 100644 --- a/liboai/components/images.cpp +++ b/liboai/components/images.cpp @@ -10,7 +10,7 @@ liboai::Response liboai::Images::create(const std::string& prompt, std::optional Response res; res = this->Request( - Method::HTTP_POST, "/images/generations", "application/json", + Method::HTTP_POST, this->openai_root_, "/images/generations", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -34,7 +34,7 @@ liboai::FutureResponse liboai::Images::create_async(const std::string& prompt, s return std::async( std::launch::async, [&, jcon]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/images/generations", "application/json", + Method::HTTP_POST, this->openai_root_, "/images/generations", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -78,7 +78,7 @@ liboai::Response liboai::Images::create_edit(const std::filesystem::path& image, Response res; res = this->Request( - Method::HTTP_POST, "/images/edits", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/images/edits", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -121,7 +121,7 @@ liboai::FutureResponse liboai::Images::create_edit_async(const std::filesystem:: return std::async( std::launch::async, [&, form]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/images/edits", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/images/edits", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -152,7 +152,7 @@ liboai::Response liboai::Images::create_variation(const std::filesystem::path& i Response res; res = this->Request( - Method::HTTP_POST, "/images/variations", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/images/variations", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), @@ -184,7 +184,7 @@ liboai::FutureResponse liboai::Images::create_variation_async(const std::filesys return std::async( std::launch::async, [&, form]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/images/variations", "multipart/form-data", + Method::HTTP_POST, this->openai_root_, "/images/variations", "multipart/form-data", this->auth_.GetAuthorizationHeaders(), std::move(form), this->auth_.GetProxies(), diff --git a/liboai/components/models.cpp b/liboai/components/models.cpp index eecc413..e37894e 100644 --- a/liboai/components/models.cpp +++ b/liboai/components/models.cpp @@ -3,7 +3,7 @@ liboai::Response liboai::Models::list() const & noexcept(false) { Response res; res = this->Request( - Method::HTTP_GET, "/models", "application/json", + Method::HTTP_GET, this->openai_root_, "/models", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -17,7 +17,7 @@ liboai::FutureResponse liboai::Models::list_async() const & noexcept(false) { return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/models", "application/json", + Method::HTTP_GET, this->openai_root_, "/models", "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -30,7 +30,7 @@ liboai::FutureResponse liboai::Models::list_async() const & noexcept(false) { liboai::Response liboai::Models::retrieve(const std::string& model) const & noexcept(false) { Response res; res = this->Request( - Method::HTTP_GET, "/models/" + model, "application/json", + Method::HTTP_GET, this->openai_root_, "/models/" + model, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), @@ -44,34 +44,7 @@ liboai::FutureResponse liboai::Models::retrieve_async(const std::string& model) return std::async( std::launch::async, [&]() -> liboai::Response { return this->Request( - Method::HTTP_GET, "/models/" + model, "application/json", - this->auth_.GetAuthorizationHeaders(), - this->auth_.GetProxies(), - this->auth_.GetProxyAuth(), - this->auth_.GetMaxTimeout() - ); - } - ); -} - -liboai::Response liboai::Models::remove(const std::string& model) const & noexcept(false) { - Response res; - res = this->Request( - Method::HTTP_DELETE, "/models/" + model, "application/json", - this->auth_.GetAuthorizationHeaders(), - this->auth_.GetProxies(), - this->auth_.GetProxyAuth(), - this->auth_.GetMaxTimeout() - ); - - return res; -} - -liboai::FutureResponse liboai::Models::remove_async(const std::string& model) const & noexcept(false) { - return std::async( - std::launch::async, [&]() -> liboai::Response { - return this->Request( - Method::HTTP_DELETE, "/models/" + model, "application/json", + Method::HTTP_GET, this->openai_root_, "/models/" + model, "application/json", this->auth_.GetAuthorizationHeaders(), this->auth_.GetProxies(), this->auth_.GetProxyAuth(), diff --git a/liboai/components/moderations.cpp b/liboai/components/moderations.cpp index e46c61b..aee4fa6 100644 --- a/liboai/components/moderations.cpp +++ b/liboai/components/moderations.cpp @@ -7,7 +7,7 @@ liboai::Response liboai::Moderations::create(const std::string& input, std::opti Response res; res = this->Request( - Method::HTTP_POST, "/moderations", "application/json", + Method::HTTP_POST, this->openai_root_, "/moderations", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() @@ -28,7 +28,7 @@ liboai::FutureResponse liboai::Moderations::create_async(const std::string& inpu return std::async( std::launch::async, [&, jcon]() -> liboai::Response { return this->Request( - Method::HTTP_POST, "/moderations", "application/json", + Method::HTTP_POST, this->openai_root_, "/moderations", "application/json", this->auth_.GetAuthorizationHeaders(), netimpl::components::Body { jcon.dump() diff --git a/liboai/core/authorization.cpp b/liboai/core/authorization.cpp index 82bb41a..0a234ce 100644 --- a/liboai/core/authorization.cpp +++ b/liboai/core/authorization.cpp @@ -3,10 +3,34 @@ bool liboai::Authorization::SetKey(std::string_view key) noexcept { if (!key.empty()) { this->key_ = key; - if (this->auth_headers_.count("Authorization") > 0) { - this->auth_headers_.erase("Authorization"); + if (this->openai_auth_headers_.count("Authorization") > 0) { + this->openai_auth_headers_.erase("Authorization"); } - this->auth_headers_["Authorization"] = ("Bearer " + this->key_); + this->openai_auth_headers_["Authorization"] = ("Bearer " + this->key_); + return true; + } + return false; +} + +bool liboai::Authorization::SetAzureKey(std::string_view key) noexcept { + if (!key.empty()) { + this->key_ = key; + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); + } + this->azure_auth_headers_["api-key"] = this->key_; + return true; + } + return false; +} + +bool liboai::Authorization::SetAzureKeyAD(std::string_view key) noexcept { + if (!key.empty()) { + this->key_ = key; + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); + } + this->azure_auth_headers_["Authorization"] = ("Bearer " + this->key_); return true; } return false; @@ -17,10 +41,40 @@ bool liboai::Authorization::SetKeyFile(const std::filesystem::path& path) noexce std::ifstream file(path); if (file.is_open()) { std::getline(file, this->key_); - if (this->auth_headers_.count("Authorization") > 0) { - this->auth_headers_.erase("Authorization"); + if (this->openai_auth_headers_.count("Authorization") > 0) { + this->openai_auth_headers_.erase("Authorization"); + } + this->openai_auth_headers_["Authorization"] = ("Bearer " + this->key_); + return true; + } + } + return false; +} + +bool liboai::Authorization::SetAzureKeyFile(const std::filesystem::path& path) noexcept { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path) && std::filesystem::file_size(path) > 0) { + std::ifstream file(path); + if (file.is_open()) { + std::getline(file, this->key_); + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); + } + this->azure_auth_headers_["api-key"] = this->key_; + return true; + } + } + return false; +} + +bool liboai::Authorization::SetAzureKeyFileAD(const std::filesystem::path& path) noexcept { + if (std::filesystem::exists(path) && std::filesystem::is_regular_file(path) && std::filesystem::file_size(path) > 0) { + std::ifstream file(path); + if (file.is_open()) { + std::getline(file, this->key_); + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); } - this->auth_headers_["Authorization"] = ("Bearer " + this->key_); + this->azure_auth_headers_["Authorization"] = ("Bearer " + this->key_); return true; } } @@ -32,10 +86,42 @@ bool liboai::Authorization::SetKeyEnv(std::string_view var) noexcept { const char* key = std::getenv(var.data()); if (key != nullptr) { this->key_ = key; - if (this->auth_headers_.count("Authorization") > 0) { - this->auth_headers_.erase("Authorization"); + if (this->openai_auth_headers_.count("Authorization") > 0) { + this->openai_auth_headers_.erase("Authorization"); + } + this->openai_auth_headers_["Authorization"] = ("Bearer " + this->key_); + return true; + } + return false; + } + return false; +} + +bool liboai::Authorization::SetAzureKeyEnv(std::string_view var) noexcept { + if (!var.empty()) { + const char* key = std::getenv(var.data()); + if (key != nullptr) { + this->key_ = key; + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); + } + this->azure_auth_headers_["api-key"] = this->key_; + return true; + } + return false; + } + return false; +} + +bool liboai::Authorization::SetAzureKeyEnvAD(std::string_view var) noexcept { + if (!var.empty()) { + const char* key = std::getenv(var.data()); + if (key != nullptr) { + this->key_ = key; + if (this->azure_auth_headers_.size() > 0) { + this->azure_auth_headers_.clear(); } - this->auth_headers_["Authorization"] = ("Bearer " + this->key_); + this->azure_auth_headers_["Authorization"] = ("Bearer " + this->key_); return true; } return false; @@ -46,10 +132,10 @@ bool liboai::Authorization::SetKeyEnv(std::string_view var) noexcept { bool liboai::Authorization::SetOrganization(std::string_view org) noexcept { if (!org.empty()) { this->org_ = std::move(org); - if (this->auth_headers_.count("OpenAI-Organization") > 0) { - this->auth_headers_.erase("OpenAI-Organization"); + if (this->openai_auth_headers_.count("OpenAI-Organization") > 0) { + this->openai_auth_headers_.erase("OpenAI-Organization"); } - this->auth_headers_["OpenAI-Organization"] = this->org_; + this->openai_auth_headers_["OpenAI-Organization"] = this->org_; return true; } return false; @@ -60,10 +146,10 @@ bool liboai::Authorization::SetOrganizationFile(const std::filesystem::path& pat std::ifstream file(path); if (file.is_open()) { std::getline(file, this->key_); - if (this->auth_headers_.count("OpenAI-Organization") > 0) { - this->auth_headers_.erase("OpenAI-Organization"); + if (this->openai_auth_headers_.count("OpenAI-Organization") > 0) { + this->openai_auth_headers_.erase("OpenAI-Organization"); } - this->auth_headers_["OpenAI-Organization"] = this->org_; + this->openai_auth_headers_["OpenAI-Organization"] = this->org_; return true; } } @@ -75,10 +161,10 @@ bool liboai::Authorization::SetOrganizationEnv(std::string_view var) noexcept { const char* org = std::getenv(var.data()); if (org != nullptr) { this->org_ = org; - if (this->auth_headers_.count("OpenAI-Organization") > 0) { - this->auth_headers_.erase("OpenAI-Organization"); + if (this->openai_auth_headers_.count("OpenAI-Organization") > 0) { + this->openai_auth_headers_.erase("OpenAI-Organization"); } - this->auth_headers_["OpenAI-Organization"] = this->org_; + this->openai_auth_headers_["OpenAI-Organization"] = this->org_; return true; } return false; diff --git a/liboai/core/netimpl.cpp b/liboai/core/netimpl.cpp index 1a1a371..ed1c4ed 100644 --- a/liboai/core/netimpl.cpp +++ b/liboai/core/netimpl.cpp @@ -17,6 +17,13 @@ liboai::netimpl::CurlHolder::CurlHolder() { else { // flag set to true to avoid future checks if SSL present _flag = true; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] SSL is enabled; check flag set.\n", + __func__ + ); + #endif } } @@ -28,12 +35,23 @@ liboai::netimpl::CurlHolder::CurlHolder() { "liboai::netimpl::CurlHolder::CurlHolder()" ); } + + #if defined(LIBOAI_DEBUG) + curl_easy_setopt(this->curl_, CURLOPT_VERBOSE, 1L); + #endif } liboai::netimpl::CurlHolder::~CurlHolder() { if (this->curl_) { curl_easy_cleanup(this->curl_); this->curl_ = nullptr; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] curl_easy_cleanup() called.\n", + __func__ + ); + #endif } } @@ -41,12 +59,26 @@ liboai::netimpl::Session::~Session() { if (this->headers) { curl_slist_free_all(this->headers); this->headers = nullptr; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] curl_slist_free_all() called.\n", + __func__ + ); + #endif } #if LIBCURL_VERSION_MAJOR < 7 || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR < 56) if (this->form) { curl_formfree(this->form); this->form = nullptr; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] curl_formfree() called.\n", + __func__ + ); + #endif } #endif @@ -54,6 +86,13 @@ liboai::netimpl::Session::~Session() { if (this->mime) { curl_mime_free(this->mime); this->mime = nullptr; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] curl_mime_free() called.\n", + __func__ + ); + #endif } #endif } @@ -69,16 +108,38 @@ void liboai::netimpl::Session::Prepare() { this->url_ += this->parameter_string_; } this->url_str = this->url_; - - e[0] = curl_easy_setopt(this->curl_, CURLOPT_URL, this->url_.c_str()); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set URL for Session (0x%p) to %s.\n", + __func__, this, this->url_str.c_str() + ); + #endif + + e[0] = curl_easy_setopt(this->curl_, CURLOPT_URL, this->url_.c_str()); + // set proxy if available const std::string protocol = url_.substr(0, url_.find(':')); if (proxies_.has(protocol)) { e[1] = curl_easy_setopt(this->curl_, CURLOPT_PROXY, proxies_[protocol].c_str()); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_PROXY for Session (0x%p) to %s.\n", + __func__, this, proxies_[protocol].c_str() + ); + #endif + if (proxyAuth_.has(protocol)) { e[2] = curl_easy_setopt(this->curl_, CURLOPT_PROXYUSERNAME, proxyAuth_.GetUsername(protocol)); e[3] = curl_easy_setopt(this->curl_, CURLOPT_PROXYPASSWORD, proxyAuth_.GetPassword(protocol)); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD for Session (0x%p) to %s and %s.\n", + __func__, this, proxyAuth_.GetUsername(protocol), proxyAuth_.GetPassword(protocol) + ); + #endif } } @@ -87,18 +148,39 @@ void liboai::netimpl::Session::Prepare() { #if LIBCURL_VERSION_MAJOR > 7 || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 71) e[5] = curl_easy_setopt(this->curl_, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_SSL_OPTIONS for Session (0x%p) to CURLSSLOPT_NATIVE_CA.\n", + __func__, this + ); + #endif #endif // set string the response will be sent to if (!this->write_.callback) { e[6] = curl_easy_setopt(this->curl_, CURLOPT_WRITEFUNCTION, liboai::netimpl::components::writeFunction); e[7] = curl_easy_setopt(this->curl_, CURLOPT_WRITEDATA, &this->response_string_); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] No user supplied WriteCallback. Set CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA for Session (0x%p) to 0x%p and 0x%p.\n", + __func__, this, liboai::netimpl::components::writeFunction, &this->response_string_ + ); + #endif } // set string the raw headers will be sent to e[8] = curl_easy_setopt(this->curl_, CURLOPT_HEADERFUNCTION, liboai::netimpl::components::writeFunction); e[9] = curl_easy_setopt(this->curl_, CURLOPT_HEADERDATA, &this->header_string_); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_HEADERFUNCTION and CURLOPT_HEADERDATA for Session (0x%p) to 0x%p and 0x%p.\n", + __func__, this, liboai::netimpl::components::writeFunction, &this->header_string_ + ); + #endif + ErrorCheck(e, 10, "liboai::netimpl::Session::Prepare()"); } @@ -113,25 +195,61 @@ void liboai::netimpl::Session::PrepareDownloadInternal() { } this->url_str = this->url_; + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set URL for Session (0x%p) to %s.\n", + __func__, this, this->url_str.c_str() + ); + #endif + e[0] = curl_easy_setopt(this->curl_, CURLOPT_URL, this->url_.c_str()); const std::string protocol = url_.substr(0, url_.find(':')); if (proxies_.has(protocol)) { e[1] = curl_easy_setopt(this->curl_, CURLOPT_PROXY, proxies_[protocol].c_str()); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_PROXY for Session (0x%p) to %s.\n", + __func__, this, proxies_[protocol].c_str() + ); + #endif + if (proxyAuth_.has(protocol)) { e[2] = curl_easy_setopt(this->curl_, CURLOPT_PROXYUSERNAME, proxyAuth_.GetUsername(protocol)); e[3] = curl_easy_setopt(this->curl_, CURLOPT_PROXYPASSWORD, proxyAuth_.GetPassword(protocol)); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD for Session (0x%p) to %s and %s.\n", + __func__, this, proxyAuth_.GetUsername(protocol), proxyAuth_.GetPassword(protocol) + ); + #endif } } e[4] = curl_easy_setopt(this->curl_, CURLOPT_HEADERFUNCTION, liboai::netimpl::components::writeFunction); e[5] = curl_easy_setopt(this->curl_, CURLOPT_HEADERDATA, &this->header_string_); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_HEADERFUNCTION and CURLOPT_HEADERDATA for Session (0x%p) to 0x%p and 0x%p.\n", + __func__, this, liboai::netimpl::components::writeFunction, &this->header_string_ + ); + #endif + ErrorCheck(e, 6, "liboai::netimpl::Session::PrepareDownloadInternal()"); } CURLcode liboai::netimpl::Session::Perform() { - CURLcode e = curl_easy_perform(this->curl_); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called curl_easy_perform() for Session (0x%p).\n", + __func__, this + ); + #endif + + CURLcode e = curl_easy_perform(this->curl_); ErrorCheck(e, "liboai::netimpl::Session::Perform()"); return e; } @@ -141,15 +259,43 @@ liboai::Response liboai::netimpl::Session::BuildResponseObject() { // when checking unset values CURLcode e[3]; memset(e, CURLcode::CURLE_OK, sizeof(e)); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called ParseResponseHeader() for Session (0x%p).\n", + __func__, this + ); + #endif + // fill status line and reason this->ParseResponseHeader(this->header_string_, &this->status_line, &this->reason); - + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called curl_easy_getinfo() for Session (0x%p) to get status code.\n", + __func__, this + ); + #endif + // get status code e[0] = curl_easy_getinfo(this->curl_, CURLINFO_RESPONSE_CODE, &this->status_code); - + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called curl_easy_getinfo() for Session (0x%p) to get elapsed time.\n", + __func__, this + ); + #endif + // get elapsed time e[1] = curl_easy_getinfo(this->curl_, CURLINFO_TOTAL_TIME, &this->elapsed); - + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called curl_easy_getinfo() for Session (0x%p) to get effective url.\n", + __func__, this + ); + #endif + // get url char* effective_url = nullptr; e[2] = curl_easy_getinfo(this->curl_, CURLINFO_EFFECTIVE_URL, &effective_url); @@ -160,6 +306,13 @@ liboai::Response liboai::netimpl::Session::BuildResponseObject() { // fill content this->content = this->response_string_; + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Constructed response object.\n", + __func__ + ); + #endif + return liboai::Response { std::move(this->url_str), std::move(this->content), @@ -172,6 +325,14 @@ liboai::Response liboai::netimpl::Session::BuildResponseObject() { liboai::Response liboai::netimpl::Session::Complete() { this->hasBody = false; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called BuildResponseObject().\n", + __func__ + ); + #endif + return this->BuildResponseObject(); } @@ -186,6 +347,14 @@ liboai::Response liboai::netimpl::Session::CompleteDownload() { ErrorCheck(e, 2, "liboai::netimpl::Session::CompleteDownload()"); this->hasBody = false; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called BuildResponseObject().\n", + __func__ + ); + #endif + return this->BuildResponseObject(); } @@ -197,21 +366,65 @@ void liboai::netimpl::Session::PrepareGet() { if (this->hasBody) { e[0] = curl_easy_setopt(this->curl_, CURLOPT_NOBODY, 0L); e[1] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, "GET"); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_NOBODY and CURLOPT_CUSTOMREQUEST for Session (0x%p) to 0L and \"GET\".\n", + __func__, this + ); + #endif } else { e[2] = curl_easy_setopt(this->curl_, CURLOPT_NOBODY, 0L); e[3] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, nullptr); e[4] = curl_easy_setopt(this->curl_, CURLOPT_HTTPGET, 1L); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_NOBODY, CURLOPT_CUSTOMREQUEST and CURLOPT_HTTPGET for Session (0x%p) to 0L, nullptr and 1L.\n", + __func__, this + ); + #endif } ErrorCheck(e, 5, "liboai::netimpl::Session::PrepareGet()"); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Prepare().\n", + __func__ + ); + #endif + this->Prepare(); } liboai::Response liboai::netimpl::Session::Get() { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called PrepareGet().\n", + __func__ + ); + #endif + this->PrepareGet(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Perform().\n", + __func__ + ); + #endif + this->Perform(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Complete().\n", + __func__ + ); + #endif + return Complete(); } @@ -223,20 +436,64 @@ void liboai::netimpl::Session::PreparePost() { e[0] = curl_easy_setopt(this->curl_, CURLOPT_NOBODY, 0L); if (this->hasBody) { e[1] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, nullptr); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_NOBODY and CURLOPT_CUSTOMREQUEST for Session (0x%p) to 0L and nullptr.\n", + __func__, this + ); + #endif } else { e[2] = curl_easy_setopt(this->curl_, CURLOPT_POSTFIELDS, ""); e[3] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, "POST"); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_NOBODY, CURLOPT_POSTFIELDS and CURLOPT_CUSTOMREQUEST for Session (0x%p) to 0L, \"\" and \"POST\".\n", + __func__, this + ); + #endif } ErrorCheck(e, 4, "liboai::netimpl::Session::PreparePost()"); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Prepare().\n", + __func__ + ); + #endif + this->Prepare(); } liboai::Response liboai::netimpl::Session::Post() { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called PreparePost().\n", + __func__ + ); + #endif + this->PreparePost(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Perform().\n", + __func__ + ); + #endif + Perform(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Complete().\n", + __func__ + ); + #endif + return Complete(); } @@ -249,14 +506,51 @@ void liboai::netimpl::Session::PrepareDelete() { e[1] = curl_easy_setopt(this->curl_, CURLOPT_NOBODY, 0L); e[2] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, "DELETE"); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_HTTPGET, CURLOPT_NOBODY and CURLOPT_CUSTOMREQUEST for Session (0x%p) to 0L, 0L and \"DELETE\".\n", + __func__, this + ); + #endif + ErrorCheck(e, 3, "liboai::netimpl::Session::PrepareDelete()"); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Prepare().\n", + __func__ + ); + #endif + this->Prepare(); } liboai::Response liboai::netimpl::Session::Delete() { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called PrepareDelete().\n", + __func__ + ); + #endif + this->PrepareDelete(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Perform().\n", + __func__ + ); + #endif + Perform(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Complete().\n", + __func__ + ); + #endif + return Complete(); } @@ -270,15 +564,52 @@ void liboai::netimpl::Session::PrepareDownload(std::ofstream& file) { e[2] = curl_easy_setopt(this->curl_, CURLOPT_WRITEFUNCTION, liboai::netimpl::components::writeFileFunction); e[3] = curl_easy_setopt(this->curl_, CURLOPT_WRITEDATA, &file); e[4] = curl_easy_setopt(this->curl_, CURLOPT_CUSTOMREQUEST, nullptr); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_NOBODY, CURLOPT_HTTPGET, CURLOPT_WRITEFUNCTION, CURLOPT_WRITEDATA and CURLOPT_CUSTOMREQUEST for Session (0x%p) to 0L, 1L, liboai::netimpl::components::writeFileFunction, &file and nullptr.\n", + __func__, this + ); + #endif ErrorCheck(e, 5, "liboai::netimpl::Session::PrepareDownload()"); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called PrepareDownloadInternal().\n", + __func__ + ); + #endif + this->PrepareDownloadInternal(); } liboai::Response liboai::netimpl::Session::Download(std::ofstream& file) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called PrepareDownload().\n", + __func__ + ); + #endif + this->PrepareDownload(file); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called Perform().\n", + __func__ + ); + #endif + this->Perform(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called CompleteDownload().\n", + __func__ + ); + #endif + return CompleteDownload(); } @@ -325,6 +656,13 @@ void liboai::netimpl::Session::ParseResponseHeader(const std::string& headers, s } } } + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Parsed response header.\n", + __func__ + ); + #endif } void liboai::netimpl::Session::SetOption(const components::Url& url) { @@ -333,6 +671,13 @@ void liboai::netimpl::Session::SetOption(const components::Url& url) { void liboai::netimpl::Session::SetUrl(const components::Url& url) { this->url_ = url.str(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set base URL for Session (0x%p) to \"%s\".\n", + __func__, this, this->url_.c_str() + ); + #endif } void liboai::netimpl::Session::SetOption(const components::Body& body) { @@ -348,6 +693,13 @@ void liboai::netimpl::Session::SetBody(const components::Body& body) { e[0] = curl_easy_setopt(this->curl_, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(body.str().length())); e[1] = curl_easy_setopt(this->curl_, CURLOPT_POSTFIELDS, body.c_str()); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_POSTFIELDSIZE_LARGE and CURLOPT_POSTFIELDS for Session (0x%p) to %lld and \"%s\".\n", + __func__, this, static_cast(body.str().length()), body.c_str() + ); + #endif + ErrorCheck(e, 2, "liboai::netimpl::Session::SetBody()"); } @@ -364,6 +716,13 @@ void liboai::netimpl::Session::SetBody(components::Body&& body) { e[0] = curl_easy_setopt(this->curl_, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(body.str().length())); e[1] = curl_easy_setopt(this->curl_, CURLOPT_COPYPOSTFIELDS, body.c_str()); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set CURLOPT_POSTFIELDSIZE_LARGE and CURLOPT_COPYPOSTFIELDS for Session (0x%p) to %lld and \"%s\".\n", + __func__, this, static_cast(body.str().length()), body.c_str() + ); + #endif + ErrorCheck(e, 2, "liboai::netimpl::Session::SetBody()"); } @@ -409,6 +768,13 @@ void liboai::netimpl::Session::SetMultipart(const components::Multipart& multipa } } e = curl_easy_setopt(this->curl_, CURLOPT_HTTPPOST, this->form); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set multipart for Session (0x%p) using curl_formadd() and CURLOPT_HTTPPOST.\n", + __func__, this + ); + #endif ErrorCheck(fe, 2, "liboai::netimpl::Session::SetMultipart()"); ErrorCheck(e, "liboai::netimpl::Session::SetMultipart()"); @@ -461,6 +827,13 @@ void liboai::netimpl::Session::SetMultipart(const components::Multipart& multipa } e[5] = curl_easy_setopt(this->curl_, CURLOPT_MIMEPOST, this->mime); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set multipart for Session (0x%p) using curl_mime_addpart() and CURLOPT_MIMEPOST.\n", + __func__, this + ); + #endif + ErrorCheck(e, 6, "liboai::netimpl::Session::SetMultipart()"); this->hasBody = true; @@ -512,6 +885,13 @@ void liboai::netimpl::Session::SetMultipart(components::Multipart&& multipart) { } e = curl_easy_setopt(this->curl_, CURLOPT_HTTPPOST, this->form); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set multipart for Session (0x%p) using curl_formadd() and CURLOPT_HTTPPOST.\n", + __func__, this + ); + #endif + ErrorCheck(fe, 2, "liboai::netimpl::Session::SetMultipart()"); ErrorCheck(e, "liboai::netimpl::Session::SetMultipart()"); @@ -564,6 +944,13 @@ void liboai::netimpl::Session::SetMultipart(components::Multipart&& multipart) { } e[5] = curl_easy_setopt(this->curl_, CURLOPT_MIMEPOST, this->mime); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set multipart for Session (0x%p) using curl_mime_addpart() and CURLOPT_MIMEPOST.\n", + __func__, this + ); + #endif + ErrorCheck(e, 6, "liboai::netimpl::Session::SetMultipart()"); this->hasBody = true; @@ -571,6 +958,13 @@ void liboai::netimpl::Session::SetMultipart(components::Multipart&& multipart) { } std::string liboai::netimpl::CurlHolder::urlEncode(const std::string& s) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] URL-encode string \"%s\".\n", + __func__, s.c_str() + ); + #endif + char* output = curl_easy_escape(this->curl_, s.c_str(), static_cast(s.length())); if (output) { std::string result = output; @@ -581,6 +975,13 @@ std::string liboai::netimpl::CurlHolder::urlEncode(const std::string& s) { } std::string liboai::netimpl::CurlHolder::urlDecode(const std::string& s) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] URL-decode string \"%s\".\n", + __func__, s.c_str() + ); + #endif + char* output = curl_easy_unescape(this->curl_, s.c_str(), static_cast(s.length()), nullptr); if (output) { std::string result = output; @@ -601,17 +1002,38 @@ std::string liboai::netimpl::components::urlDecodeHelper(const std::string& s) { } size_t liboai::netimpl::components::writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called with %zu bytes.\n", + __func__, size * nmemb + ); + #endif + size *= nmemb; return (*write)({ ptr, size }) ? size : 0; } size_t liboai::netimpl::components::writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called with %zu bytes.\n", + __func__, size * nmemb + ); + #endif + size *= nmemb; data->append(ptr, size); return size; } size_t liboai::netimpl::components::writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* file) { + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Called with %zu bytes.\n", + __func__, size * nmemb + ); + #endif + size *= nmemb; file->write(ptr, static_cast(size)); return size; @@ -677,11 +1099,25 @@ liboai::netimpl::components::Parameters::Parameters(const std::initializer_list< void liboai::netimpl::components::Parameters::Add(const std::initializer_list& parameters) { for (const auto& parameter : parameters) { this->parameters_.emplace_back(parameter.key, parameter.value); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Added parameter \"%s\" with value \"%s\".\n", + __func__, parameter.key.c_str(), parameter.value.c_str() + ); + #endif } } void liboai::netimpl::components::Parameters::Add(const Parameter& parameter) { this->parameters_.emplace_back(parameter.key, parameter.value); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Added parameter \"%s\" with value \"%s\".\n", + __func__, parameter.key.c_str(), parameter.value.c_str() + ); + #endif } bool liboai::netimpl::components::Parameters::Empty() const { @@ -701,6 +1137,13 @@ std::string liboai::netimpl::components::Parameters::BuildParameterString() cons parameter_string.pop_back(); } + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Built parameter string \"%s\".\n", + __func__, parameter_string.c_str() + ); + #endif + return parameter_string; } @@ -738,6 +1181,13 @@ void liboai::netimpl::Session::SetHeader(const components::Header& header) { e = curl_easy_setopt(this->curl_, CURLOPT_HTTPHEADER, this->headers); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set headers.\n", + __func__ + ); + #endif + ErrorCheck(e, "liboai::netimpl::Session::SetHeader()"); } @@ -748,6 +1198,13 @@ void liboai::netimpl::Session::SetOption(const components::Parameters& parameter void liboai::netimpl::Session::SetParameters(const components::Parameters& parameters) { if (!parameters.Empty()) { this->parameter_string_ = parameters.BuildParameterString(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set parameters.\n", + __func__ + ); + #endif } } @@ -758,6 +1215,13 @@ void liboai::netimpl::Session::SetOption(components::Parameters&& parameters) { void liboai::netimpl::Session::SetParameters(components::Parameters&& parameters) { if (!parameters.Empty()) { this->parameter_string_ = parameters.BuildParameterString(); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set parameters.\n", + __func__ + ); + #endif } } @@ -767,6 +1231,14 @@ void liboai::netimpl::Session::SetOption(const components::Timeout& timeout) { void liboai::netimpl::Session::SetTimeout(const components::Timeout& timeout) { CURLcode e = curl_easy_setopt(this->curl_, CURLOPT_TIMEOUT_MS, timeout.Milliseconds()); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set timeout to %ld milliseconds\n", + __func__, timeout.Milliseconds() + ); + #endif + ErrorCheck(e, "liboai::netimpl::Session::SetTimeout()"); } @@ -776,6 +1248,13 @@ void liboai::netimpl::Session::SetOption(const components::Proxies& proxies) { void liboai::netimpl::Session::SetProxies(const components::Proxies& proxies) { this->proxies_ = proxies; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set proxies.\n", + __func__ + ); + #endif } void liboai::netimpl::Session::SetOption(components::Proxies&& proxies) { @@ -784,6 +1263,13 @@ void liboai::netimpl::Session::SetOption(components::Proxies&& proxies) { void liboai::netimpl::Session::SetProxies(components::Proxies&& proxies) { this->proxies_ = std::move(proxies); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set proxies.\n", + __func__ + ); + #endif } void liboai::netimpl::Session::SetOption(const components::ProxyAuthentication& proxy_auth) { @@ -792,6 +1278,13 @@ void liboai::netimpl::Session::SetOption(const components::ProxyAuthentication& void liboai::netimpl::Session::SetProxyAuthentication(const components::ProxyAuthentication& proxy_auth) { this->proxyAuth_ = proxy_auth; + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set proxy authentication.\n", + __func__ + ); + #endif } void liboai::netimpl::Session::SetOption(components::ProxyAuthentication&& proxy_auth) { @@ -800,6 +1293,13 @@ void liboai::netimpl::Session::SetOption(components::ProxyAuthentication&& proxy void liboai::netimpl::Session::SetProxyAuthentication(components::ProxyAuthentication&& proxy_auth) { this->proxyAuth_ = std::move(proxy_auth); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set proxy authentication.\n", + __func__ + ); + #endif } void liboai::netimpl::Session::SetOption(const components::WriteCallback& write) { @@ -814,6 +1314,36 @@ void liboai::netimpl::Session::SetWriteCallback(const components::WriteCallback& this->write_ = write; e[1] = curl_easy_setopt(this->curl_, CURLOPT_WRITEDATA, &this->write_); + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set user supplied write callback.\n", + __func__ + ); + #endif + + ErrorCheck(e, 2, "liboai::netimpl::Session::SetWriteCallback()"); + } +} + +void liboai::netimpl::Session::SetOption(components::WriteCallback&& write) { + this->SetWriteCallback(std::move(write)); +} + +void liboai::netimpl::Session::SetWriteCallback(components::WriteCallback&& write) { + if (write.callback) { + CURLcode e[2]; memset(e, CURLcode::CURLE_OK, sizeof(e)); + + e[0] = curl_easy_setopt(this->curl_, CURLOPT_WRITEFUNCTION, components::writeUserFunction); + this->write_ = std::move(write); + e[1] = curl_easy_setopt(this->curl_, CURLOPT_WRITEDATA, &this->write_); + + #if defined(LIBOAI_DEBUG) + _liboai_dbg( + "[dbg] [@%s] Set user supplied write callback.\n", + __func__ + ); + #endif + ErrorCheck(e, 2, "liboai::netimpl::Session::SetWriteCallback()"); } } @@ -945,4 +1475,4 @@ void liboai::netimpl::ErrorCheck(CURLcode ecode, std::string_view where) { ); } } -#endif +#endif \ No newline at end of file diff --git a/liboai/include/components/azure.h b/liboai/include/components/azure.h new file mode 100644 index 0000000..792364a --- /dev/null +++ b/liboai/include/components/azure.h @@ -0,0 +1,301 @@ +#pragma once + +/* + azure.h : Azure component class for OpenAI. + Azure provides their own API for access to the OpenAI API. + This class provides methods that, provided that the proper + Azure authentication information has been set, allows users + to access the OpenAI API through Azure. +*/ + +#include "../core/authorization.h" +#include "../core/response.h" +#include "chat.h" + +namespace liboai { + class Azure final : private Network { + public: + Azure() = default; + ~Azure() = default; + Azure(const Azure&) = delete; + Azure(Azure&&) = delete; + + Azure& operator=(const Azure&) = delete; + Azure& operator=(Azure&&) = delete; + + /* + @brief Given a prompt, the model will return one or more + predicted completions, and can also return the + probabilities of alternative tokens at each position. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param Refer to liboai::Completions::create for more information on the remaining parameters. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response create_completion( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + std::optional prompt = std::nullopt, + std::optional suffix = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional temperature = std::nullopt, + std::optional top_p = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional logprobs = std::nullopt, + std::optional echo = std::nullopt, + std::optional> stop = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional best_of = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Given a prompt, the model will asynchronously return + one or more predicted completions, and can also return the + probabilities of alternative tokens at each position. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param Refer to liboai::Completions::create for more information on the remaining parameters. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse create_completion_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + std::optional prompt = std::nullopt, + std::optional suffix = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional temperature = std::nullopt, + std::optional top_p = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional logprobs = std::nullopt, + std::optional echo = std::nullopt, + std::optional> stop = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional best_of = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Creates an embedding vector representing the input text. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *input Input text to get embeddings for, encoded as a string. The number of input tokens + varies depending on what model you are using. + @param Refer to liboai::Embeddings::create for more information on the remaining parameters. + + @return A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response create_embedding( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const std::string& input, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Asynchronously creates an embedding vector representing the input text. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *input Input text to get embeddings for, encoded as a string. The number of input tokens + varies depending on what model you are using. + @param Refer to liboai::Embeddings::create for more information on the remaining parameters. + + @return A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse create_embedding_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const std::string& input, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Creates a completion for the chat message. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *conversation A Conversation object containing the conversation data. + @param Refer to liboai::Chat::create for more information on the remaining parameters. + + @returns A liboai::Response object containing the + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response create_chat_completion( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const Conversation& conversation, + std::optional temperature = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional> stop = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Asynchronously creates a completion for the chat message. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *deployment_id The deployment name you chose when you deployed the model. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *conversation A Conversation object containing the conversation data. + @param Refer to liboai::Chat::create for more information on the remaining parameters. + + @returns A liboai::Response object containing the + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse create_chat_completion_async( + const std::string& resource_name, + const std::string& deployment_id, + const std::string& api_version, + const Conversation& conversation, + std::optional temperature = std::nullopt, + std::optional n = std::nullopt, + std::optional> stream = std::nullopt, + std::optional> stop = std::nullopt, + std::optional max_tokens = std::nullopt, + std::optional presence_penalty = std::nullopt, + std::optional frequency_penalty = std::nullopt, + std::optional> logit_bias = std::nullopt, + std::optional user = std::nullopt + ) const & noexcept(false); + + /* + @brief Generate a batch of images from a text caption. + Image generation is currently only available with api-version=2023-06-01-preview. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *prompt The text to create an image from. + @param n The number of images to create. + @param size The size of the image to create. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response request_image_generation( + const std::string& resource_name, + const std::string& api_version, + const std::string& prompt, + std::optional n = std::nullopt, + std::optional size = std::nullopt + ) const & noexcept(false); + + /* + @brief Asynchronously generate a batch of images from a text caption. + Image generation is currently only available with api-version=2023-06-01-preview. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *prompt The text to create an image from. + @param n The number of images to create. + @param size The size of the image to create. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse request_image_generation_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& prompt, + std::optional n = std::nullopt, + std::optional size = std::nullopt + ) const & noexcept(false); + + /* + @brief Retrieve the results (URL) of a previously called image generation operation. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *operation_id The GUID that identifies the original image generation request. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response get_generated_image( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id + ) const & noexcept(false); + + /* + @brief Asynchronously retrieve the results (URL) of a previously called image generation operation. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *operation_id The GUID that identifies the original image generation request. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse get_generated_image_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id + ) const & noexcept(false); + + /* + @brief Deletes the corresponding image from the Azure server. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *operation_id The GUID that identifies the original image generation request. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response delete_generated_image( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id + ) const & noexcept(false); + + /* + @brief Asynchronously deletes the corresponding image from the Azure server. + + @param *resource_name The name of your Azure OpenAI Resource. + @param *api_version The API version to use for this operation. This follows the YYYY-MM-DD format. + @param *operation_id The GUID that identifies the original image generation request. + + @returns A liboai::Response object containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse delete_generated_image_async( + const std::string& resource_name, + const std::string& api_version, + const std::string& operation_id + ) const & noexcept(false); + + private: + Authorization& auth_ = Authorization::Authorizer(); + }; +} \ No newline at end of file diff --git a/liboai/include/components/fine_tunes.h b/liboai/include/components/fine_tunes.h index 9947739..e18f8a4 100644 --- a/liboai/include/components/fine_tunes.h +++ b/liboai/include/components/fine_tunes.h @@ -203,6 +203,30 @@ namespace liboai { std::optional> stream = std::nullopt ) const & noexcept(false); + /* + @brief Delete a fine-tuned model. You must have the Owner role in your organization. + + @param *model The model to delete + + @return A liboai::Response future containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::Response remove( + const std::string& model + ) const & noexcept(false); + + /* + @brief Asynchronously deletes a fine-tuned model. You must have the Owner role in your organization. + + @param *model The model to delete + + @return A liboai::Response future containing the image(s) + data in JSON format. + */ + LIBOAI_EXPORT liboai::FutureResponse remove_async( + const std::string& model + ) const & noexcept(false); + private: Authorization& auth_ = Authorization::Authorizer(); }; diff --git a/liboai/include/components/models.h b/liboai/include/components/models.h index 3af6d99..0ecc026 100644 --- a/liboai/include/components/models.h +++ b/liboai/include/components/models.h @@ -64,30 +64,6 @@ namespace liboai { LIBOAI_EXPORT liboai::FutureResponse retrieve_async( const std::string& model ) const & noexcept(false); - - /* - @brief Delete a fine-tuned model. - - #param *model The model to delete. - - @returns A liboai::Response object containing the image(s) - data in JSON format. - */ - LIBOAI_EXPORT liboai::Response remove( - const std::string& model - ) const & noexcept(false); - - /* - @brief Asynchronously delete a fine-tuned model. - - #param *model The model to delete. - - @returns A liboai::Response future containing the image(s) - data in JSON format. - */ - LIBOAI_EXPORT liboai::FutureResponse remove_async( - const std::string& model - ) const & noexcept(false); private: Authorization& auth_ = Authorization::Authorizer(); diff --git a/liboai/include/core/authorization.h b/liboai/include/core/authorization.h index 243d322..cccff55 100644 --- a/liboai/include/core/authorization.h +++ b/liboai/include/core/authorization.h @@ -52,6 +52,24 @@ namespace liboai { [[nodiscard]] LIBOAI_EXPORT bool SetKey(std::string_view key) noexcept; + /* + @brief Sets the authorization key for the Azure OpenAI API + as the passed string. + @param key : The authorization key to use in Azure component calls. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKey(std::string_view key) noexcept; + + /* + @brief Sets the Active Directory authorization token for the Azure OpenAI API + as the passed string. + @param key : The authorization key to use in Azure component calls. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKeyAD(std::string_view key) noexcept; + /* @brief Sets the authorization key for the OpenAI API as the first line present in the file at the passed path. @@ -61,6 +79,24 @@ namespace liboai { [[nodiscard]] LIBOAI_EXPORT bool SetKeyFile(const std::filesystem::path& path) noexcept; + /* + @brief Sets the authorization key for the Azure OpenAI API + as the first line present in the file at the passed path. + @param key : The path to the file containing the authorization key. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKeyFile(const std::filesystem::path& path) noexcept; + + /* + @brief Sets the Active Directory authorization token for the Azure OpenAI API + as the first line present in the file at the passed path. + @param key : The path to the file containing the authorization key. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKeyFileAD(const std::filesystem::path& path) noexcept; + /* @brief Sets the authorization key for the OpenAI API as the value stored in the environment variable with @@ -71,6 +107,28 @@ namespace liboai { */ [[nodiscard]] LIBOAI_EXPORT bool SetKeyEnv(std::string_view var) noexcept; + + /* + @brief Sets the authorization key for the Azure OpenAI API + as the value stored in the environment variable with + the passed name. + @param var : The name of the environment variable to + retrieve the authorization key from. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKeyEnv(std::string_view var) noexcept; + + /* + @brief Sets the Active Directory authorization token for the Azure OpenAI API + as the value stored in the environment variable with + the passed name. + @param var : The name of the environment variable to + retrieve the authorization key from. + @returns True if the key was set successfully, false otherwise. + */ + [[nodiscard]] + LIBOAI_EXPORT bool SetAzureKeyEnvAD(std::string_view var) noexcept; /* @brief Sets the organization identifier as the passed @@ -175,11 +233,18 @@ namespace liboai { currently set authorization information for use in component calls. */ - constexpr const netimpl::components::Header& GetAuthorizationHeaders() const noexcept { return this->auth_headers_; } + constexpr const netimpl::components::Header& GetAuthorizationHeaders() const noexcept { return this->openai_auth_headers_; } + + /* + @returns An authorization header with the + currently set Azure authorization information for use + in Azure component calls. + */ + constexpr const netimpl::components::Header& GetAzureAuthorizationHeaders() const noexcept { return this->azure_auth_headers_; } private: // member variables std::string key_, org_; - netimpl::components::Header auth_headers_; + netimpl::components::Header openai_auth_headers_, azure_auth_headers_; netimpl::components::Proxies proxies_; netimpl::components::ProxyAuthentication proxyAuth_; netimpl::components::Timeout timeout_ = { 30000 }; diff --git a/liboai/include/core/exception.h b/liboai/include/core/exception.h index 69a0e7f..3a149d7 100644 --- a/liboai/include/core/exception.h +++ b/liboai/include/core/exception.h @@ -11,6 +11,10 @@ #include #include +#if defined(LIBOAI_DEBUG) + #define _liboai_dbg(fmt, ...) printf(fmt, __VA_ARGS__); +#endif + namespace liboai { namespace exception { enum class EType : uint8_t { diff --git a/liboai/include/core/netimpl.h b/liboai/include/core/netimpl.h index b11e2b8..94d9b1a 100644 --- a/liboai/include/core/netimpl.h +++ b/liboai/include/core/netimpl.h @@ -172,8 +172,8 @@ namespace liboai { struct File final { explicit File(std::string p_filepath, const std::string& p_overrided_filename = {}) : filepath(std::move(p_filepath)), overrided_filename(p_overrided_filename) {} - const std::string filepath; - const std::string overrided_filename; + std::string filepath; + std::string overrided_filename; bool hasOverridedFilename() const noexcept { return !overrided_filename.empty(); @@ -228,6 +228,8 @@ namespace liboai { class Body final : public StringHolder { public: Body() = default; + Body(const Body& other) { this->str_ = other.str_; } + Body(Body&& old) noexcept { this->str_ = std::move(old.str_); } Body(std::string body) : StringHolder(std::move(body)) {} Body(std::string_view body) : StringHolder(body) {} Body(const char* body) : StringHolder(body) {} @@ -247,12 +249,16 @@ namespace liboai { is.read(buffer.data(), length); str_ = std::move(buffer); } - Body(const Body& other) = default; - Body(Body&& old) noexcept = default; ~Body() override = default; - Body& operator=(Body&& old) noexcept = default; - Body& operator=(const Body& other) = default; + Body& operator=(Body&& old) noexcept { + this->str_ = std::move(old.str_); + return *this; + } + Body& operator=(const Body& other) { + this->str_ = other.str_; + return *this; + } }; struct Buffer final { @@ -293,6 +299,23 @@ namespace liboai { class Multipart final { public: + Multipart() = default; + Multipart(const Multipart& other) { + this->parts = other.parts; + } + Multipart(Multipart&& old) noexcept { + this->parts = std::move(old.parts); + } + + Multipart& operator=(const Multipart& other) { + this->parts = other.parts; + return *this; + } + Multipart& operator=(Multipart&& old) noexcept { + this->parts = std::move(old.parts); + return *this; + } + Multipart(const std::initializer_list& parts); std::vector parts; @@ -308,8 +331,28 @@ namespace liboai { using Header = std::map; struct Parameter final { + Parameter() = default; + Parameter(const Parameter& other) { + this->key = other.key; + this->value = other.value; + } + Parameter(Parameter&& old) noexcept { + this->key = std::move(old.key); + this->value = std::move(old.value); + } Parameter(std::string p_key, std::string p_value) : key{ std::move(p_key) }, value{ std::move(p_value) } {} + Parameter& operator=(const Parameter& other) { + this->key = other.key; + this->value = other.value; + return *this; + } + Parameter& operator=(Parameter&& old) noexcept { + this->key = std::move(old.key); + this->value = std::move(old.value); + return *this; + } + std::string key; std::string value; }; @@ -317,8 +360,23 @@ namespace liboai { class Parameters final { public: Parameters() = default; + Parameters(const Parameters& other) { + this->parameters_ = other.parameters_; + } + Parameters(Parameters&& old) noexcept { + this->parameters_ = std::move(old.parameters_); + } Parameters(const std::initializer_list& parameters); + Parameters& operator=(const Parameters& other) { + this->parameters_ = other.parameters_; + return *this; + } + Parameters& operator=(Parameters&& old) noexcept { + this->parameters_ = std::move(old.parameters_); + return *this; + } + void Add(const std::initializer_list& parameters); void Add(const Parameter& parameter); bool Empty() const; @@ -342,9 +400,24 @@ namespace liboai { class Proxies final { public: Proxies() = default; + Proxies(const Proxies& other) { + this->hosts_ = other.hosts_; + } + Proxies(Proxies&& old) noexcept { + this->hosts_ = std::move(old.hosts_); + } Proxies(const std::initializer_list>& hosts); Proxies(const std::map& hosts); + Proxies& operator=(const Proxies& other) { + this->hosts_ = other.hosts_; + return *this; + } + Proxies& operator=(Proxies&& old) noexcept { + this->hosts_ = std::move(old.hosts_); + return *this; + } + bool has(const std::string& protocol) const; const std::string& operator[](const std::string& protocol); @@ -361,13 +434,27 @@ namespace liboai { public: EncodedAuthentication() = default; + EncodedAuthentication(const EncodedAuthentication& other) { + this->username = other.username; + this->password = other.password; + } + EncodedAuthentication(EncodedAuthentication&& old) noexcept { + this->username = std::move(old.username); + this->password = std::move(old.password); + } EncodedAuthentication(const std::string& p_username, const std::string& p_password) : username(urlEncodeHelper(p_username)), password(urlEncodeHelper(p_password)) {} - EncodedAuthentication(const EncodedAuthentication& other) = default; - EncodedAuthentication(EncodedAuthentication&& old) noexcept = default; virtual ~EncodedAuthentication() noexcept; - EncodedAuthentication& operator=(EncodedAuthentication&& old) noexcept = default; - EncodedAuthentication& operator=(const EncodedAuthentication& other) = default; + EncodedAuthentication& operator=(EncodedAuthentication&& old) noexcept { + this->username = std::move(old.username); + this->password = std::move(old.password); + return *this; + } + EncodedAuthentication& operator=(const EncodedAuthentication& other) { + this->username = other.username; + this->password = other.password; + return *this; + } [[nodiscard]] const std::string& GetUsername() const; [[nodiscard]] const std::string& GetPassword() const; @@ -382,9 +469,24 @@ namespace liboai { class ProxyAuthentication final { public: ProxyAuthentication() = default; + ProxyAuthentication(const ProxyAuthentication& other) { + this->proxyAuth_ = other.proxyAuth_; + } + ProxyAuthentication(ProxyAuthentication&& old) noexcept { + this->proxyAuth_ = std::move(old.proxyAuth_); + } ProxyAuthentication(const std::initializer_list>& auths) : proxyAuth_{auths} {} explicit ProxyAuthentication(const std::map& auths) : proxyAuth_{auths} {} + ProxyAuthentication& operator=(const ProxyAuthentication& other) { + this->proxyAuth_ = other.proxyAuth_; + return *this; + } + ProxyAuthentication& operator=(ProxyAuthentication&& old) noexcept { + this->proxyAuth_ = std::move(old.proxyAuth_); + return *this; + } + [[nodiscard]] bool has(const std::string& protocol) const; const char* GetUsername(const std::string& protocol); const char* GetPassword(const std::string& protocol); @@ -396,10 +498,23 @@ namespace liboai { class WriteCallback final { public: WriteCallback() = default; + WriteCallback(const WriteCallback& other) : callback(other.callback), userdata(other.userdata) {} + WriteCallback(WriteCallback&& old) noexcept : callback(std::move(old.callback)), userdata(std::move(old.userdata)) {} WriteCallback(std::function p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {} - bool operator()(std::string data) const { + WriteCallback& operator=(const WriteCallback& other) { + this->callback = other.callback; + this->userdata = other.userdata; + return *this; + } + WriteCallback& operator=(WriteCallback&& old) noexcept { + this->callback = std::move(old.callback); + this->userdata = std::move(old.userdata); + return *this; + } + + [[nodiscard]] bool operator()(std::string data) const { return callback(std::move(data), userdata); } @@ -486,6 +601,8 @@ namespace liboai { void SetOption(const components::WriteCallback& write); void SetWriteCallback(const components::WriteCallback& write); + void SetOption(components::WriteCallback&& write); + void SetWriteCallback(components::WriteCallback&& write); long status_code = 0; double elapsed = 0.0; std::string status_line{}, content{}, url_str{}, reason{}; @@ -541,4 +658,4 @@ namespace liboai { (session.SetOption(std::forward<_Options>(opts)), ...); } } -} +} \ No newline at end of file diff --git a/liboai/include/core/network.h b/liboai/include/core/network.h index 87ceb5a..b82a3bd 100644 --- a/liboai/include/core/network.h +++ b/liboai/include/core/network.h @@ -74,8 +74,8 @@ namespace liboai { return res.status_code == 200; } ); - } - + } + protected: enum class Method : uint8_t { HTTP_GET, // GET @@ -87,6 +87,7 @@ namespace liboai { std::enable_if_t>...>, int> = 0> inline Response Request( const Method& http_method, + const std::string& root, const std::string& endpoint, const std::string& content_type, std::optional headers = std::nullopt, @@ -104,14 +105,14 @@ namespace liboai { Response res; if constexpr (sizeof...(parameters) > 0) { res = Network::MethodSchema::_method[static_cast(http_method)]( - netimpl::components::Url { this->root_ + endpoint }, + netimpl::components::Url { root + endpoint }, std::move(_headers), std::forward<_Params>(parameters)... ); } else { res = Network::MethodSchema::_method[static_cast(http_method)]( - netimpl::components::Url { this->root_ + endpoint }, + netimpl::components::Url { root + endpoint }, std::move(_headers) ); } @@ -132,6 +133,9 @@ namespace liboai { } return false; } + + const std::string openai_root_ = "https://api.openai.com/v1"; + const std::string azure_root_ = ".openai.azure.com/openai"; private: template struct MethodSchema { @@ -141,6 +145,5 @@ namespace liboai { netimpl::Delete }; }; - const std::string root_ = "https://api.openai.com/v1"; }; } \ No newline at end of file diff --git a/liboai/include/liboai.h b/liboai/include/liboai.h index 1f5eccd..8fb628d 100644 --- a/liboai/include/liboai.h +++ b/liboai/include/liboai.h @@ -29,6 +29,7 @@ */ #include "components/audio.h" +#include "components/azure.h" #include "components/chat.h" #include "components/completions.h" #include "components/edits.h" @@ -55,6 +56,12 @@ namespace liboai { */ std::unique_ptr Audio = std::make_unique(); + /* + @brief A pointer to the Azure component class that + provides access to its API endpoints. + */ + std::unique_ptr Azure = std::make_unique(); + /* @brief A pointer to the Chat component class that provides access to its OpenAI API endpoints. @@ -109,7 +116,7 @@ namespace liboai { */ std::unique_ptr Moderation = std::make_unique(); - public: + public: /* @brief Convenience reference to the Authorization class singleton used to set authorization information.