Skip to content

Commit

Permalink
chore: add additional pinecone requests
Browse files Browse the repository at this point in the history
  • Loading branch information
thiskevinwang committed Oct 5, 2023
1 parent 8739eb0 commit 4e95920
Show file tree
Hide file tree
Showing 2 changed files with 219 additions and 19 deletions.
6 changes: 5 additions & 1 deletion internal/resources/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ func (r *indexResource) Create(ctx context.Context, req resource.CreateRequest,
metric := plan.Metric.ValueString()

// Create new index
response, err := r.client.CreateIndex(name, dimension, metric)
response, err := r.client.CreateIndex(services.CreateIndexBodyParams{
Name: name,
Dimension: dimension,
Metric: metric,
})
if err != nil {
resp.Diagnostics.AddError(
"Failed to create index",
Expand Down
232 changes: 214 additions & 18 deletions internal/services/pinecone.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,218 @@ type Pinecone struct {
Environment string
}

const (
baseUrl = "https://controller.%s.pinecone.io"
)

// list_collections
// GET
// https://controller.{environment}.pinecone.io/collections
// This operation returns a list of your Pinecone collections.
//
// 200 Array of String - This operation returns a list of all the collections in your current project.

type CreateCollectionBodyParams struct {
// The name of the collection to be created.
Name string `json:"name"`
// The name of the source index to be used as the source for the collection.
Source string `json:"source"`
}

// create_collection
// POST
// https://controller.{environment}.pinecone.io/collections
// This operation creates a Pinecone collection. Not supported by projects on the gcp-starter environment.
//
// 201 String - The collection has been successfully created.
// 400 String - Bad request. Request exceeds quota or collection name is invalid.
// 409 String - A collection with the name provided already exists.
// 500 String - Internal error. Can be caused by invalid parameters.
func (p *Pinecone) CreateCollection(bodyParams CreateCollectionBodyParams) (*string, error) {
url := fmt.Sprintf(baseUrl+"/collections", p.Environment)

// convert struct to byte[]
payloadBytes, err := json.Marshal(bodyParams)
if err != nil {
return nil, err
}

// convert byte[] to io.Reader
payload := bytes.NewReader(payloadBytes)

// initialize a request
req, err := http.NewRequest("POST", url, payload)
if err != nil {
return nil, err
}

req.Header.Add("accept", "text/plain")
req.Header.Add("content-type", "application/json")
req.Header.Add("Api-Key", p.ApiKey)

// fire off the request
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

fmt.Println(string(body))
bodyString := string(body)

switch {
case res.StatusCode < 300: // 2xx
return &bodyString, nil
default: // non-2xx
return nil, fmt.Errorf("CreateCollection failed with status code %d and message %q", res.StatusCode, bodyString)
}
}

type DescribeCollectionResponse struct {
Name string `json:"name"`
// values: Ready,
Status string `json:"status"`
Size int64 `json:"size"`
// The dimension of the vectors stored in the collection.
Dimension int64 `json:"dimension"`
VecotrCount int64 `json:"vector_count"`
}

// describe_collection
// GET
// https://controller.{environment}.pinecone.io/collections/{collectionName}
// Get a description of a collection.
//
// 200 JSON - Configuration information and deployment status of the index
// 404 String - Index not found.
// 500 String - Internal error. Can be caused by invalid parameters.
func (p *Pinecone) DescribeCollection(name string) (*DescribeCollectionResponse, error) {
url := fmt.Sprintf(baseUrl+"/collections/%s", p.Environment, name)

// initialize a request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}

req.Header.Add("accept", "application/json")
req.Header.Add("Api-Key", p.ApiKey)

// fire off the request
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

bodyString := string(body)

switch {
case res.StatusCode < 300: // 2xx
// unmarshal json to struct
descCollectionResponse := &DescribeCollectionResponse{}
err := json.Unmarshal(body, descCollectionResponse)
if err != nil {
return nil, err
}
return descCollectionResponse, nil
default: // non-2xx
return nil, fmt.Errorf("DescribeCollection failed with status code %d and message %q", res.StatusCode, bodyString)
}
}

// delete_collection
// DELETE
// https://controller.{environment}.pinecone.io/collections/{collectionName}
// This operation deletes an existing collection.
//
// 202 String - The index has been successfully deleted.
// 404 String - Collection not found.
// 500 String - Internal error. Can be caused by invalid parameters.
func (p *Pinecone) DeleteCollection(name string) (*string, error) {
url := fmt.Sprintf(baseUrl+"/collections/%s", p.Environment, name)

// initialize a request
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}

req.Header.Add("accept", "application/json")
req.Header.Add("Api-Key", p.ApiKey)

res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

bodyString := string(body)

switch {
case res.StatusCode < 300: // 2xx
return &bodyString, nil
default: // non-2xx
return nil, fmt.Errorf("DeleteCollection failed with status code %d and message %q", res.StatusCode, bodyString)
}
}

type CreateIndexBodyParams struct {
// The name of the index to be created. The maximum length is 45 characters.
Name string `json:"name"`
// The dimensions of the vectors to be inserted in the index
Dimension int64 `json:"dimension"`
// The distance metric to be used for similarity search. You can use 'euclidean', 'cosine', or 'dotproduct'.
Metric string `json:"metric"`
// The number of pods for the index to use,including replicas.
Pods int64 `json:"pods"`
// The number of replicas. Replicas duplicate your index. They provide higher availability and throughput.
Replicas int64 `json:"replicas"`
// The type of pod to use. One of s1, p1, or p2 appended with . and one of x1, x2, x4, or x8.
PodType string `json:"pod_type"`
// Configuration for the behavior of Pinecone's internal metadata index. By default, all metadata is indexed; when metadata_config is present, only specified metadata fields are indexed. To specify metadata fields to index, provide a JSON object of the following form:
MetadataConfig *map[string]interface{} `json:"metadata_config"`
// The name of the collection to create an index from
SourceCollection string `json:"source_collection"`
}

// create_index
// POST
// https://controller.us-west4-gcp-free.pinecone.io/databases
// https://controller.{environment}.pinecone.io/databases
// This operation creates a Pinecone index. You can use it to specify the measure of similarity, the dimension of vectors to be stored in the index, the numbers of replicas to use, and more.
func (p *Pinecone) CreateIndex(name string, dimension int64, metric string) (*string, error) {
url := fmt.Sprintf("https://controller.%s.pinecone.io/databases", p.Environment)

// payload := strings.NewReader("{\"metric\":\"cosine\",\"pods\":1,\"replicas\":1,\"pod_type\":\"p1.x1\",\"name\":\"test\",\"dimension\":1536}")
data := map[string]interface{}{
"metric": metric,
"name": name,
"dimension": dimension,
"pods": 1,
"replicas": 1,
"pod_type": "p1.x1",
func (p *Pinecone) CreateIndex(data CreateIndexBodyParams) (*string, error) {
url := fmt.Sprintf(baseUrl+"/databases", p.Environment)

// set default values
if data.Metric == "" {
data.Metric = "cosine"
}
if data.Pods == 0 {
data.Pods = 1
}
if data.Replicas == 0 {
data.Replicas = 1
}
if data.PodType == "" {
data.PodType = "p1.x1"
}

// convert struct to byte[]
payloadBytes, err := json.Marshal(data)
if err != nil {
return nil, err
Expand Down Expand Up @@ -92,10 +288,10 @@ type DescribeIndexResponse struct {

// describe_index
// GET
// https://controller.us-west4-gcp-free.pinecone.io/databases/{indexName}
// https://controller.{environment}.pinecone.io/databases/{indexName}
// Get a description of an index.
func (p *Pinecone) DescribeIndex(name string) (*DescribeIndexResponse, error) {
url := fmt.Sprintf("https://controller.%s.pinecone.io/databases/%s", p.Environment, name)
url := fmt.Sprintf(baseUrl+"/databases/%s", p.Environment, name)

// initialize a request
req, err := http.NewRequest("GET", url, nil)
Expand Down Expand Up @@ -143,7 +339,7 @@ type ConfigureIndexRequest struct {

// configure_index
// PATCH
// https://controller.us-west4-gcp-free.pinecone.io/databases/{indexName}
// https://controller.{environment}.pinecone.io/databases/{indexName}
// This operation specifies the pod type and number of replicas for an index. Not supported by projects on the gcp-starter environment.
// (Not supported for free tier)
//
Expand All @@ -152,7 +348,7 @@ type ConfigureIndexRequest struct {
// 404 String - Index not found.
// 500 String - Internal error. Can be caused by invalid parameters.
func (p *Pinecone) ConfigureIndex(name string, data *ConfigureIndexRequest) (*string, error) {
url := fmt.Sprintf("https://controller.%s.pinecone.io/databases/%s", p.Environment, name)
url := fmt.Sprintf(baseUrl+"/databases/%s", p.Environment, name)

payloadBytes, err := json.Marshal(data)
if err != nil {
Expand Down Expand Up @@ -196,14 +392,14 @@ func (p *Pinecone) ConfigureIndex(name string, data *ConfigureIndexRequest) (*st

// delete_index
// DELETE
// https://controller.us-west4-gcp-free.pinecone.io/databases/{indexName}
// https://controller.{environment}.pinecone.io/databases/{indexName}
// This operation deletes an existing index.
//
// 202 String - The index has been successfully deleted
// 404 String - Index not found.
// 500 String - Internal error. Can be caused by invalid parameters.
func (p *Pinecone) DeleteIndex(name string) (*string, error) {
url := fmt.Sprintf("https://controller.%s.pinecone.io/databases/%s", p.Environment, name)
url := fmt.Sprintf(baseUrl+"/databases/%s", p.Environment, name)

// initialize a request
req, err := http.NewRequest("DELETE", url, nil)
Expand Down

0 comments on commit 4e95920

Please sign in to comment.