Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create serverless index functionality #3

Merged
merged 32 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e6d9537
added source tag cleaning
ericapywang Jun 4, 2024
7d4ea0e
added get_user_string function
ericapywang Jun 5, 2024
bbf12b9
added create_serverless_index function
ericapywang Jun 6, 2024
0bc7db9
added some notes for future
ericapywang Jun 6, 2024
11530db
Merge remote-tracking branch 'origin/main' into ericapywang/create-index
ericapywang Jun 7, 2024
35fbed4
fixed more merge conflicts and tests
ericapywang Jun 7, 2024
d0689b0
started error checking
ericapywang Jun 7, 2024
c48956b
Add error handling to create_index
emily-emily Jun 7, 2024
0b177db
combined create_index for serverless and pods into one function, crea…
ericapywang Jun 7, 2024
cd0dfcb
add builder pattern for CreateIndexParams
ericapywang Jun 10, 2024
901f0d5
added some error checking + more tests
ericapywang Jun 10, 2024
1bc27f1
added builder and more tests for Pinecone
ericapywang Jun 10, 2024
91c885c
added some comments
ericapywang Jun 10, 2024
099b0d9
Update params builder required arg validation
emily-emily Jun 10, 2024
c608955
merge with main
ericapywang Jun 11, 2024
a84154c
remove builder for CreateIndexParams
ericapywang Jun 11, 2024
8c289ea
change builder function names
ericapywang Jun 11, 2024
3c62d01
fixed test cases
ericapywang Jun 11, 2024
a9e2ebd
Merge branch 'main' into ericapywang/create-index
ericapywang Jun 12, 2024
7b64788
Implement Into trait to convert to openapi types
emily-emily Jun 12, 2024
9b620d4
Merge branch 'main' into ericapywang/create-index
emily-emily Jun 12, 2024
ef7870f
Add missing documentation
emily-emily Jun 12, 2024
a40712f
changed Pinecone to PineconeClient
ericapywang Jun 13, 2024
357ea5a
flattened PineconeClient fields, removed builder
ericapywang Jun 13, 2024
d5bf06e
removed parameter struct
ericapywang Jun 13, 2024
e3ecb04
Use Option for cloud and use defaults
emily-emily Jun 13, 2024
2035017
remove redundant test
ericapywang Jun 13, 2024
34871af
remove Option for Cloud and Metric
ericapywang Jun 13, 2024
cadf7b2
Condense control code
emily-emily Jun 13, 2024
24619e6
pass api key to config
ericapywang Jun 13, 2024
90e3254
changed api_key_opt to api_key_str
ericapywang Jun 13, 2024
e0accd4
fixed config construction in PineconeClient
ericapywang Jun 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
273 changes: 273 additions & 0 deletions pinecone_sdk/src/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
use crate::pinecone::PineconeClient;
use crate::utils::errors::PineconeError;
use openapi::apis::manage_indexes_api;
use openapi::apis::manage_indexes_api::ListIndexesError;
use openapi::apis::Error;
use openapi::models;
use openapi::models::{CreateIndexRequest, CreateIndexRequestSpec, IndexModel, ServerlessSpec};

pub use openapi::models::create_index_request::Metric;
pub use openapi::models::serverless_spec::Cloud;

impl PineconeClient {
/// Creates serverless index
pub async fn create_serverless_index(
&self,
name: &str,
dimension: u32,
metric: Metric,
cloud: Cloud,
region: &str,
) -> Result<IndexModel, PineconeError> {
// create request specs
let create_index_request_spec = CreateIndexRequestSpec {
serverless: Some(Box::new(ServerlessSpec {
cloud,
region: region.to_string(),
})),
pod: None,
};

let create_index_request = CreateIndexRequest {
name: name.to_string(),
dimension: dimension.try_into().unwrap(),
metric: Some(metric),
spec: Some(Box::new(create_index_request_spec)),
};

match openapi::apis::manage_indexes_api::create_index(
&self.openapi_config(),
create_index_request,
)
.await
{
Ok(index) => Ok(index),
Err(e) => Err(PineconeError::CreateIndexError { openapi_error: e }),
}
}
/// Lists all indexes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job on the docstring. 👍

///
/// The results include a description of all indexes in your project, including the
/// index name, dimension, metric, status, and spec.
///
/// :return: Returns an `IndexList` object, which is iterable and contains a
/// list of `IndexDescription` objects. It also has a convenience method `names()`
/// which returns a list of index names.
///
/// ### Example
///
/// ```
/// # use pinecone_sdk::pinecone::PineconeClient;
/// # use pinecone_sdk::utils::errors::PineconeError;
/// # #[tokio::main]
/// # async fn main() -> Result<(), PineconeError>{
/// # // Create a Pinecone client with the API key and controller host.
/// # let pinecone = PineconeClient::new(None, None, None, None).unwrap();
/// #
/// // List all indexes in the project.
/// let index_list = pinecone.list_indexes();
/// # Ok(())
/// # }
/// ```

pub async fn list_indexes(&self) -> Result<models::IndexList, Error<ListIndexesError>> {
let response = manage_indexes_api::list_indexes(&self.openapi_config()).await?;
println!("{:?}", response);
Ok(response)
}
}

#[cfg(test)]
mod tests {
use super::*;
use mockito::mock;
use models::IndexList;
use tokio;

#[tokio::test]
async fn test_create_serverless_index() {
let _m = mock("POST", "/indexes")
.with_status(201)
.with_header("content-type", "application/json")
.with_body(
r#"
{
"name": "index_name",
"dimension": 10,
"metric": "euclidean",
"host": "host1",
"spec": {
"serverless": {
"cloud": "aws",
"region": "us-east-1"
}
},
"status": {
"ready": true,
"state": "Initializing"
}
}
"#,
)
.create();

let pinecone = PineconeClient::new(
Some("api_key".to_string()),
Some(mockito::server_url()),
None,
None,
);

let create_index_request = pinecone
.unwrap()
.create_serverless_index("index_name", 10, Metric::Cosine, Cloud::Aws, "us-east-1")
.await;
assert!(create_index_request.is_ok());

let create_index_req = create_index_request.unwrap();
assert_eq!(create_index_req.name, "index_name");
assert_eq!(create_index_req.dimension, 10);
assert_eq!(
create_index_req.metric,
openapi::models::index_model::Metric::Euclidean
);

let spec = create_index_req.spec.serverless.unwrap();
assert_eq!(spec.cloud, openapi::models::serverless_spec::Cloud::Aws);
assert_eq!(spec.region, "us-east-1");
}

#[tokio::test]
async fn test_create_serverless_index_defaults() {
let _m = mock("POST", "/indexes")
.with_status(201)
.with_header("content-type", "application/json")
.with_body(
r#"
{
"name": "index_name",
"dimension": 10,
"metric": "cosine",
"host": "host1",
"spec": {
"serverless": {
"cloud": "gcp",
"region": "us-east-1"
}
},
"status": {
"ready": true,
"state": "Initializing"
}
}
"#,
)
.create();

let pinecone = PineconeClient::new(
Some("api_key".to_string()),
Some(mockito::server_url()),
None,
None,
);

let create_index_request = pinecone
.unwrap()
.create_serverless_index(
"index_name",
10,
Default::default(),
Default::default(),
"us-east-1",
)
.await;
assert!(create_index_request.is_ok());

let create_index_req = create_index_request.unwrap();
assert_eq!(create_index_req.name, "index_name");
assert_eq!(create_index_req.dimension, 10);
assert_eq!(
create_index_req.metric,
openapi::models::index_model::Metric::Cosine
);

let spec = create_index_req.spec.serverless.unwrap();
assert_eq!(spec.cloud, openapi::models::serverless_spec::Cloud::Gcp);
assert_eq!(spec.region, "us-east-1");
}

#[tokio::test]
async fn test_list_indexes() -> Result<(), PineconeError> {
// Create a mock server
let _m = mock("GET", "/indexes")
.with_status(200)
.with_header("content-type", "application/json")
.with_body(
r#"
{
"indexes": [
{
"name": "index1",
"dimension": 1536,
"metric": "cosine",
"host": "host1",
"spec": {},
"status": {
"ready": false,
"state": "Initializing"
}
},
{
"name": "index2",
"dimension": 1536,
"metric": "cosine",
"host": "host2",
"spec": {},
"status": {
"ready": false,
"state": "Initializing"
}
}
]
}
"#,
)
.create();

// Construct Pinecone instance with the mock server URL
let api_key = "test_api_key".to_string();
let pinecone = PineconeClient::new(Some(api_key), Some(mockito::server_url()), None, None)
.expect("Failed to create Pinecone instance");

// Call list_indexes and verify the result
let index_list = pinecone
.list_indexes()
.await
.expect("Failed to list indexes");

let expected = IndexList {
// name: String, dimension: i32, metric: Metric, host: String, spec: models::IndexModelSpec, status: models::IndexModelStatus)
indexes: Some(vec![
IndexModel::new(
"index1".to_string(),
1536,
openapi::models::index_model::Metric::Cosine,
"host1".to_string(),
models::IndexModelSpec::default(),
models::IndexModelStatus::default(),
),
IndexModel::new(
"index2".to_string(),
1536,
openapi::models::index_model::Metric::Cosine,
"host2".to_string(),
models::IndexModelSpec::default(),
models::IndexModelStatus::default(),
),
]),
};
assert_eq!(index_list, expected);

Ok(())
}
}
124 changes: 0 additions & 124 deletions pinecone_sdk/src/control/list_indexes.rs

This file was deleted.

Loading