1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! REST API client module for OpenAI interface
//!
//! This module provides the core HTTP functionality for making requests to OpenAI-compatible APIs.
//! It includes traits and implementations for both streaming and non-streaming API calls.
//!
//! # Overview
//!
//! The `rest` module contains:
//! - [`post`]: HTTP POST request functionality with streaming and non-streaming support
//! - [`get`]: HTTP GET request functionality with various parameter handling options
//! - [`delete`]: HTTP DELETE request functionality
//! - [`default_client`]: A `reqwest::Client` constructor shared by all request traits
//! - [`check_status`]: Shared non-2xx response handling which parses the error body
//!
//! # Usage
//!
//! The module is designed to be used through the higher-level API modules (`chat`, `completions`,
//! etc.). However, you can use the traits directly if needed:
//!
//! ## POST Requests
//!
//! ```rust
//! use openai_interface::rest::post::{Post, PostNoStream};
//! use openai_interface::errors::OapiError;
//! use serde::{Serialize, Deserialize};
//!
//! use std::str::FromStr;
//!
//! #[derive(Serialize)]
//! struct MyRequest {
//! prompt: String,
//! stream: bool,
//! }
//!
//! #[derive(Deserialize)]
//! struct MyResponse {
//! // Define the fields of your response here
//! id: String,
//! }
//!
//! impl FromStr for MyResponse {
//! type Err = OapiError;
//!
//! fn from_str(content: &str) -> Result<Self, Self::Err> {
//! let parse_result: Result<Self, _> = serde_json::from_str(content)
//! .map_err(|e| OapiError::DeserializationError(e.to_string()));
//! parse_result
//! }
//! }
//!
//! impl Post for MyRequest {
//! fn is_streaming(&self) -> bool {
//! self.stream
//! }
//! fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
//! Ok(format!("{}/service", base_url))
//! }
//! }
//!
//! impl PostNoStream for MyRequest {
//! type Response = MyResponse;
//! }
//!
//! // Send it with a client:
//! // let client = openai_interface::rest::default_client();
//! // let response: MyResponse = request
//! // .get_response(&client, "https://api.openai.com/v1/chat/completions", "API_KEY")
//! // .await?;
//! ```
//!
//! ## GET Requests
//!
//! ```rust
//! use openai_interface::rest::get::Get;
//! use openai_interface::errors::OapiError;
//!
//! // GET request with URL building
//! struct ComplexRequest {
//! resource_id: String,
//! limit: Option<u32>,
//! }
//!
//! impl Get for ComplexRequest {
//! fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
//! let mut url = format!("{}/{}", base_url, self.resource_id);
//! if let Some(limit) = self.limit {
//! url.push_str(&format!("?limit={}", limit));
//! }
//! Ok(url)
//! }
//! }
//! ```
//!
//! # Client configuration
//!
//! Every request method takes the client as its first argument, so callers
//! control proxies, timeouts and connection pooling. Use
//! [`default_client`] for a sensible default, or build your own, e.g. with a
//! proxy:
//!
//! ```rust
//! let client = reqwest::Client::builder()
//! .proxy(reqwest::Proxy::http("http://127.0.0.1:10808")?)
//! .timeout(std::time::Duration::from_secs(60))
//! .build()?;
//! # Ok::<(), reqwest::Error>(())
//! ```
use crate;
/// Builds a [`reqwest::Client`] with library defaults.
///
/// The client has a 300-second total timeout and a 60-second connect
/// timeout. Pass your own client to any request method if you need a
/// different configuration (proxy, timeout, pooling, ...).
///
/// # Panics
///
/// Panics if the underlying TLS backend fails to initialize. This mirrors
/// the panic behavior of [`reqwest::Client::new`].
/// Checks a response status, turning a non-2xx response into an
/// [`OapiError::ApiError`] that carries the parsed error body.
///
/// For a non-2xx status, this consumes the response and attempts to parse
/// the body as an [`ApiError`]. If the body cannot be parsed, the raw text
/// is kept as the error message. The response is returned unchanged when
/// the status is a success.
pub async
/// Parses a response body as text, applying [`check_status`] first.
pub async
/// Parses a response body as raw bytes, applying [`check_status`] first.
pub async