rusty_openai/openai_api/projects.rs
1use crate::{error_handling::OpenAIResult, openai::OpenAI};
2use serde::Serialize;
3use serde_json::Value;
4
5/// [`ProjectsApi`] struct to interact with the projects endpoints of the API.
6#[allow(dead_code)]
7pub struct ProjectsApi<'a>(pub(crate) &'a OpenAI<'a>);
8
9#[allow(dead_code)]
10#[derive(Serialize)]
11struct CreateProjectRequest<'a> {
12 /// The friendly name of the project
13 name: &'a str,
14
15 /// Optional description of the business, project, or use case
16 #[serde(skip_serializing_if = "Option::is_none")]
17 app_use_case: Option<&'a str>,
18
19 /// Optional business URL or social media link
20 #[serde(skip_serializing_if = "Option::is_none")]
21 business_website: Option<&'a str>,
22}
23
24#[allow(dead_code)]
25#[derive(Serialize)]
26struct CreateProjectUserRequest<'a> {
27 /// The ID of the user
28 user_id: &'a str,
29
30 /// The role of the user (owner or member)
31 role: &'a str,
32}
33
34impl<'a> ProjectsApi<'a> {
35 /// List projects within an organization.
36 ///
37 /// # Arguments
38 ///
39 /// * `limit` - Optional limit on the number of objects to return (1-100, default 20).
40 /// * `after` - Optional cursor for pagination.
41 /// * `include_archived` - Optional flag to include archived projects.
42 ///
43 /// # Returns
44 ///
45 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
46 pub async fn list_projects(
47 &self,
48 limit: Option<u8>,
49 after: Option<&str>,
50 include_archived: Option<bool>,
51 ) -> OpenAIResult<Value> {
52 let mut url = "/organization/projects".to_string();
53 let mut query_params = Vec::new();
54
55 if let Some(limit) = limit {
56 query_params.push(format!("limit={}", limit));
57 }
58 if let Some(after) = after {
59 query_params.push(format!("after={}", after));
60 }
61 if let Some(include_archived) = include_archived {
62 query_params.push(format!("include_archived={}", include_archived));
63 }
64
65 if !query_params.is_empty() {
66 url.push('?');
67 url.push_str(&query_params.join("&"));
68 }
69
70 self.0.get(&url).await
71 }
72
73 /// Create a new project in the organization.
74 ///
75 /// # Arguments
76 ///
77 /// * `name` - The friendly name of the project.
78 /// * `app_use_case` - Optional description of the business, project, or use case.
79 /// * `business_website` - Optional business URL or social media link.
80 ///
81 /// # Returns
82 ///
83 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
84 pub async fn create_project(
85 &self,
86 name: &str,
87 app_use_case: Option<&str>,
88 business_website: Option<&str>,
89 ) -> OpenAIResult<Value> {
90 let body = CreateProjectRequest {
91 name,
92 app_use_case,
93 business_website,
94 };
95
96 self.0.post_json("/organization/projects", &body).await
97 }
98
99 /// Retrieve information about a specific project.
100 ///
101 /// # Arguments
102 ///
103 /// * `project_id` - The ID of the project to retrieve.
104 ///
105 /// # Returns
106 ///
107 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
108 pub async fn retrieve_project(&self, project_id: &str) -> OpenAIResult<Value> {
109 let url = format!("/organization/projects/{}", project_id);
110 self.0.get(&url).await
111 }
112
113 /// Modify an existing project in the organization.
114 ///
115 /// # Arguments
116 ///
117 /// * `project_id` - The ID of the project to modify.
118 /// * `name` - The updated name of the project.
119 /// * `app_use_case` - Optional updated description of the business, project, or use case.
120 /// * `business_website` - Optional updated business URL or social media link.
121 ///
122 /// # Returns
123 ///
124 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
125 pub async fn modify_project(
126 &self,
127 project_id: &str,
128 name: &str,
129 app_use_case: Option<&str>,
130 business_website: Option<&str>,
131 ) -> OpenAIResult<Value> {
132 let body = CreateProjectRequest {
133 name,
134 app_use_case,
135 business_website,
136 };
137
138 let url = format!("/organization/projects/{}", project_id);
139 self.0.post_json(&url, &body).await
140 }
141
142 /// Archive a project in the organization.
143 ///
144 /// # Arguments
145 ///
146 /// * `project_id` - The ID of the project to archive.
147 ///
148 /// # Returns
149 ///
150 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
151 pub async fn archive_project(&self, project_id: &str) -> OpenAIResult<Value> {
152 let url = format!("/organization/projects/{}/archive", project_id);
153 self.0.post_json(&url, &serde_json::json!({})).await
154 }
155
156 /// List users in a project.
157 ///
158 /// # Arguments
159 ///
160 /// * `project_id` - The ID of the project.
161 /// * `limit` - Optional limit on the number of objects to return (1-100, default 20).
162 /// * `after` - Optional cursor for pagination.
163 ///
164 /// # Returns
165 ///
166 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
167 pub async fn list_project_users(
168 &self,
169 project_id: &str,
170 limit: Option<u8>,
171 after: Option<&str>,
172 ) -> OpenAIResult<Value> {
173 let mut url = format!("/organization/projects/{}/users", project_id);
174 let mut query_params = Vec::new();
175
176 if let Some(limit) = limit {
177 query_params.push(format!("limit={}", limit));
178 }
179 if let Some(after) = after {
180 query_params.push(format!("after={}", after));
181 }
182
183 if !query_params.is_empty() {
184 url.push('?');
185 url.push_str(&query_params.join("&"));
186 }
187
188 self.0.get(&url).await
189 }
190
191 /// Add a user to a project.
192 ///
193 /// # Arguments
194 ///
195 /// * `project_id` - The ID of the project.
196 /// * `user_id` - The ID of the user to add.
197 /// * `role` - The role of the user (owner or member).
198 ///
199 /// # Returns
200 ///
201 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
202 pub async fn create_project_user(
203 &self,
204 project_id: &str,
205 user_id: &str,
206 role: &str,
207 ) -> OpenAIResult<Value> {
208 let body = CreateProjectUserRequest { user_id, role };
209 let url = format!("/organization/projects/{}/users", project_id);
210 self.0.post_json(&url, &body).await
211 }
212
213 /// Retrieve information about a specific user in a project.
214 ///
215 /// # Arguments
216 ///
217 /// * `project_id` - The ID of the project.
218 /// * `user_id` - The ID of the user.
219 ///
220 /// # Returns
221 ///
222 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
223 pub async fn retrieve_project_user(
224 &self,
225 project_id: &str,
226 user_id: &str,
227 ) -> OpenAIResult<Value> {
228 let url = format!("/organization/projects/{}/users/{}", project_id, user_id);
229 self.0.get(&url).await
230 }
231
232 /// Modify a user's role in a project.
233 ///
234 /// # Arguments
235 ///
236 /// * `project_id` - The ID of the project.
237 /// * `user_id` - The ID of the user.
238 /// * `role` - The new role of the user (owner or member).
239 ///
240 /// # Returns
241 ///
242 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
243 pub async fn modify_project_user(
244 &self,
245 project_id: &str,
246 user_id: &str,
247 role: &str,
248 ) -> OpenAIResult<Value> {
249 let body = serde_json::json!({ "role": role });
250 let url = format!("/organization/projects/{}/users/{}", project_id, user_id);
251 self.0.post_json(&url, &body).await
252 }
253
254 /// Delete a user from a project.
255 ///
256 /// # Arguments
257 ///
258 /// * `project_id` - The ID of the project.
259 /// * `user_id` - The ID of the user to delete.
260 ///
261 /// # Returns
262 ///
263 /// A Result containing the JSON response as [`serde_json::Value`] on success, or an [`OpenAIError`][crate::error_handling::OpenAIError] on failure.
264 pub async fn delete_project_user(
265 &self,
266 project_id: &str,
267 user_id: &str,
268 ) -> OpenAIResult<Value> {
269 let url = format!("/organization/projects/{}/users/{}", project_id, user_id);
270 self.0.delete(&url).await
271 }
272}