From 2ea7e1ddbf205f6f7cf1d4df1ed67a9d6d3a61de Mon Sep 17 00:00:00 2001 From: Jennifer Hamon Date: Wed, 28 Aug 2024 15:56:57 -0400 Subject: [PATCH] Improve output from list/describe actions on indexes and collections (#387) ## Problem When running in notebooks, output from the `list_indexes` and `list_collections` commands created confusion because the `__repr__` representation for these objects showed an object with a top-level key that implied the response should be interacted with like a dictionary. This expectation contradicts with the way the `__iter__` implementations on these results objects are set up to enable iterating over results without drilling down. The origin of the complexity here is that the backing APIs used to return simple arrays of names that could be easily iterated over, and earlier this year they become more fleshed out responses. Returning more data is useful in some situations, but in trying to smooth out the impact of the API change and maintain a similar way of interacting with the results, we accidentally opened up this inconsistency in the experience. ## Solution - For these actions, migrate from output by `pprint.pformat` to `json.dumps`. For deeply nested objects, this produces a result that is easier to read. - Stop sorting keys alphabetically. The way they are returned from the API makes the most sense (name first). - Remove top-level keys from the printed output, which created wrong expectations about how to interact with the results object. Now list_indexes looks like an array, and you index into it like an array. Ditto for collections. ### Before Screenshot 2024-08-28 at 1 38 27 PM ![Collections output](https://github.com/user-attachments/assets/466d7a75-69c6-41d9-b75c-bbcc797ef315) ### After Screenshot 2024-08-28 at 1 29 00 PM ![Screenshot 2024-08-28 at 1 42 05 PM](https://github.com/user-attachments/assets/fb8eee8e-6b7c-442e-878e-ddaad635d317) ![Screenshot 2024-08-28 at 3 28 44 PM](https://github.com/user-attachments/assets/e33b1858-0718-4e36-8e7d-af41b6457784) ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update - [ ] Infrastructure change (CI configs, etc) - [ ] Non-code change (docs, etc) - [X] None of the above: UX improvement, but should be no functional change --- pinecone/control/__init__.py | 4 ++++ pinecone/control/repr_overrides.py | 17 +++++++++++++++++ pinecone/models/collection_list.py | 3 ++- pinecone/models/index_list.py | 5 +++-- pinecone/models/index_model.py | 6 +++--- 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 pinecone/control/repr_overrides.py diff --git a/pinecone/control/__init__.py b/pinecone/control/__init__.py index 4c739f1a..dc6bf1e2 100644 --- a/pinecone/control/__init__.py +++ b/pinecone/control/__init__.py @@ -1 +1,5 @@ from .pinecone import Pinecone + +from .repr_overrides import install_repr_overrides + +install_repr_overrides() diff --git a/pinecone/control/repr_overrides.py b/pinecone/control/repr_overrides.py new file mode 100644 index 00000000..4cf76c7c --- /dev/null +++ b/pinecone/control/repr_overrides.py @@ -0,0 +1,17 @@ +from pinecone.models.index_model import IndexModel +from pinecone.core.openapi.control.models import CollectionModel + +import json + + +def install_repr_overrides(): + """ + The generator code uses pprint.pformat to format the repr output + which looks really poor when printing a list of large objects + in a notebook setting. We override it here for a few select models + instead of modifying the generator code because the more compact output + from pprint.pformat seems better for data plane objects such as lists of + query results. + """ + for model in [IndexModel, CollectionModel]: + model.__repr__ = lambda self: json.dumps(self.to_dict(), indent=4, sort_keys=False) diff --git a/pinecone/models/collection_list.py b/pinecone/models/collection_list.py index 9b788cee..865a55ac 100644 --- a/pinecone/models/collection_list.py +++ b/pinecone/models/collection_list.py @@ -1,3 +1,4 @@ +import json from pinecone.core.openapi.control.models import ( CollectionList as OpenAPICollectionList, ) @@ -28,7 +29,7 @@ def __str__(self): return str(self.collection_list) def __repr__(self): - return repr(self.collection_list) + return json.dumps([c.to_dict() for c in self.collection_list.collections], indent=4) def __getattr__(self, attr): return getattr(self.collection_list, attr) diff --git a/pinecone/models/index_list.py b/pinecone/models/index_list.py index 6c524489..5240ebe4 100644 --- a/pinecone/models/index_list.py +++ b/pinecone/models/index_list.py @@ -1,3 +1,4 @@ +import json from pinecone.core.openapi.control.models import IndexList as OpenAPIIndexList from .index_model import IndexModel @@ -21,10 +22,10 @@ def __iter__(self): return iter(self.indexes) def __str__(self): - return str(self.index_list) + return str(self.indexes) def __repr__(self): - return repr(self.index_list) + return json.dumps([i.to_dict() for i in self.indexes], indent=4) def __getattr__(self, attr): return getattr(self.index_list, attr) diff --git a/pinecone/models/index_model.py b/pinecone/models/index_model.py index 9d46b0ed..ebf5d238 100644 --- a/pinecone/models/index_model.py +++ b/pinecone/models/index_model.py @@ -9,11 +9,11 @@ def __init__(self, index: OpenAPIIndexModel): def __str__(self): return str(self.index) - def __repr__(self): - return repr(self.index) - def __getattr__(self, attr): return getattr(self.index, attr) def __getitem__(self, key): return self.__getattr__(key) + + def to_dict(self): + return self.index.to_dict()