-
Notifications
You must be signed in to change notification settings - Fork 13
Add new CreateServerlessIndex method #94
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
Conversation
14c2bc2
to
53da9c9
Compare
// Serverless currently has limited availability in specific regions, hard-code us-west-2 for now | ||
private static final String serverlessRegion = "us-west-2"; | ||
private static final Pinecone controlPlaneClient = new Pinecone.Builder(System.getenv("PINECONE_API_KEY")).build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a lint; ignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I like the direct/action oriented/semantics.
Couple comments throughout, LMK if you have questions!
public <E extends Enum<E>> boolean validateEnums(String stringToValidate, List<E> validEnums) { | ||
return validEnums.stream() | ||
.anyMatch(validEnum -> Objects.equals(stringToValidate, validEnum.toString())); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there is a method in these enums called fromValue
to convert a string into its equivalent enum, and I see you using that below post-validation. Is there a reason you can't use it here?
IndexMetric metric = IndexMetric.fromValue("cosine");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yes, thank you so much! Removing validation method now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
List<IndexMetric> indexMetricEnums = Arrays.asList(IndexMetric.values()); | ||
if (!validateEnums(metric, indexMetricEnums)) { | ||
throw new PineconeValidationException(String.format("Metric must be one of %s", IndexMetric.values())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this will stringify the contents of the array properly. You might need to use Arrays.toString
:
......... String.format("Metric must be one of %s", Arrays.toString(IndexMetric.values())) ...........
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wow, incredible catch, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -35,6 +40,64 @@ public IndexModel createIndex(CreateIndexRequest createIndexRequest) throws Pine | |||
return indexModel; | |||
} | |||
|
|||
public <E extends Enum<E>> boolean validateEnums(String stringToValidate, List<E> validEnums) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method doesn't need to be public, I don't think? Also, I'd suggest moving it down towards the bottom of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually had it w/o any access modifier previously, but my tests wouldn't run because my IDE said it had to be public.
Is there something special I need to do? I'm using IntelliJ and I've marked the dir as a 'test source root'...
if (dimension < 1) { | ||
throw new PineconeValidationException("Dimension must be greater than 0"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an upper bound on dimension? I am not sure what we have in our other SDKs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically the limit is 4.2B haha (for dense vectors). I don't see in the Python or Node SDKs, at least any upper limit enacted through code.
I'll add a link to our limits section, though. That'll be helpful for users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (cloud == null || cloud.isEmpty()) { | ||
throw new PineconeValidationException("Cloud cannot be null or empty."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be helpful to include the possible values, like in the error message below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
public IndexModel createServerlessIndex(String indexName, String metric, int dimension, String cloud, | ||
String region) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like these as simple string types for simplicity. Can we add javadoc to this method? I bet copilot will write most of it for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might leave this to @rohanshah18 since I think he's been working on that for this SDK in general, but I'll confirm in Slack :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good callout though, yeah we need to add javadoc comments all over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, looks great. 🚢
public IndexModel createServerlessIndex(String indexName, String metric, int dimension, String cloud, | ||
String region) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good callout though, yeah we need to add javadoc comments all over.
} | ||
|
||
if (region == null || region.isEmpty()) { | ||
throw new PineconeValidationException("Region cannot be null or empty."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really small nit I'm sorry - let's drop the period since we don't use one for any of the other thrown errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha! Don't be sorry at all. I love grammatical consistency :)
OkHttpClient mockClient = mock(OkHttpClient.class); | ||
when(mockClient.newCall(any(Request.class))).thenReturn(mockCall); | ||
|
||
Pinecone client = new Pinecone.Builder("testAPiKey").withOkHttpClient(mockClient).build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for covering all these test cases!
Merging this w/the integration test failure b/c the failure is a known flake, as documented here https://www.notion.so/Integration-Tests-Error-Log-a422cf031ca44271a76d899324ed385d?pvs=4 |
## Problem It's currently cumbersome to make the user create a bunch of objects from our generated code, e.g. `CreateIndexRequest`, etc. just to create an index. ## Solution Piggybacking off of [my last PR](#94), this PR creates a new method called `CreatePodsIndex`. Together with `CreateServerlessIndex`, we can now deprecate `createIndex` altogether (in a forthcoming PR). The overloaded method signatures for the `createPodsIndex` methods are as follows. (Please lmk if you having feelings about these options. It was a bit of a crapshoot figuring out which I thought would be most useful to users.) - The minimal required parameters (note: `podType` is required by the backend, not our OpenAPI spec, FWIW): - String indexName - Integer dimension - String environment - String podType - Minimal + metric: - String indexName - Integer dimension - String environment - String podType - String metric - Minimal + metric + metadata: - String indexName - Integer dimension - String environment - String podType - String metric - PodSpecMetadataConfig metadataConfig - Minimal + metric + source collection - String indexName - Integer dimension - String environment - String podType - String metric - String sourceCollection - Minimal + pods - String indexName - Integer dimension - String environment - String podType - Integer pods - Minimal + pods + metadata: - String indexName - Integer dimension - String environment - String podType - Integer pods - PodSpecMetadataConfig metadataConfig - Minimal + replicas and shards - String indexName - Integer dimension - String environment - String podType - Integer replicas - Integer shards - Minimal + replicas, shards + metadata: - String indexName - Integer dimension - String environment - String podType - Integer replicas - Integer shards - PodSpecMetadataConfig metadataConfig - Max: - String indexName - Integer dimension - String environment - String podType - String metric - Integer replicas - Integer shards - Integer pods - PodSpecMetadataConfig metadataConfig - String sourceCollection ## Callouts: - When a user provides `pods`, they should not provide `shards` or `replicas`, and vice versa (unless in the "max" method) - If `replicas * shards` do not equal `pods`, an error is thrown - Like with `createServerlessIndex` and `cloud`, the user passes `metric` as a string, and it's internally validated against the `IndexMetric.Enum` types - Besides checking for nulls and empties, there are no checks for the actual values in `environment`, `podType`, or `sourceCollection`. ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] This change requires a documentation update - [ ] Infrastructure change (CI configs, etc) - [ ] Non-code change (docs, etc) - [ ] None of the above: (explain here) ## Test Plan Unit and integration tests included. Note: in the next PR I will deprecate `createIndex` altogether. Within this PR, I will update the `TestIndexResourcesManager` singleton to work with the new methods. I will also update the README, as per this [ticket](https://app.asana.com/0/1203260648987893/1206994598304493/f).
Problem
It's currently cumbersome to force users to create
CreateIndexRequest
object, aServerlessSpec
object, and the requiredenum
s (IndexMetric
andCloudEnum
.Solution
This PR is a start on the road towards removing the
createIndex
method.In this PR, you will find a new method called
CreateServerlessIndex
. This is what users will use to create a serverless index. All they have to do is pass strings/ints forindexName
,metric
,dimension
,cloud
, andregion
. All validation of the inputs, transforms intoenum
objects, and construction of theRequest
objects takes place within the function itself.Note:
enum
s (necessary formetric
andcloud
), rather than pass in strings, since constructingenum
s directly is more type-safe and self-documenting. However, I think ease-of-use trumps those concerns, since we are building these SDKs primarily to increase developer experience.LMK if you agree in the comments!
Asana ticket: https://app.asana.com/0/1203260648987893/1206510790411726/f
Follow-ups
CreatePodsIndex
method (ticket)CreateIndex
from the client altogether, updating unit tests and integration tests as necessary.Type of Change
Test Plan
Unit test & integration tests included in PR.