Repository: opensearch-project/opensearch-py
Pull request #191 (2022-08-19 09:58:02)

Fix point in time rest api
Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>

### Description
Changes for point in time API

### Related issue
https://github.com/opensearch-project/OpenSearch/issues/3959
#227 

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check [here](https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin).


Arpit-Bandejiya: > Is there a way we could add tests for the same?

Have added the tests. Thanks @Bukhtawar 
Arpit-Bandejiya: @VachaShah @axeoman please have a look
Arpit-Bandejiya: @dblock  please have a look. Thanks!

Arpit-Bandejiya: @dblock please take a look. Thanks!
dblock: @Arpit-Bandejiya Needs a CHANGELOG entry as well, thx
Arpit-Bandejiya: Please merge the PR @opensearch-project/clients 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ab8246d..7c12dddb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,8 +3,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 
 ## [Unreleased]
 ### Added
+- Added Point in time API rest API([#191](https://github.com/opensearch-project/opensearch-py/pull/191))
 - Github workflow for changelog verification ([#218](https://github.com/opensearch-project/opensearch-py/pull/218))
-
 ### Changed
 
 ### Deprecated
diff --git a/README.md b/README.md
index 8c4b4279..3fd2432c 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
 OpenSearch Python Client
 
 - [Welcome!](https://github.com/opensearch-project/opensearch-py#welcome)
-- [Getting Started](https://github.com/opensearch-project/opensearch-py#getting-started)
+- [User guide](https://github.com/opensearch-project/opensearch-py#user-guide)
 - [API Doc](https://opensearch-project.github.io/opensearch-py/)
 - [Compatibility with OpenSearch](https://github.com/opensearch-project/opensearch-py#compatibility-with-opensearch)
 - [Project Resources](https://github.com/opensearch-project/opensearch-py#project-resources)
diff --git a/GETTING_STARTED.md b/USER_GUIDE.md
similarity index 89%
rename from GETTING_STARTED.md
rename to USER_GUIDE.md
index 53e50dc7..1b4a7df7 100644
--- a/GETTING_STARTED.md
+++ b/USER_GUIDE.md
@@ -9,6 +9,8 @@
     - [Searching for a document](#searching-for-a-document)
     - [Deleting a document](#deleting-a-document)
     - [Deleting an index](#deleting-an-index)
+  - [Making API Calls](#making-api-calls)
+    - [Point in Time API](#point-in-time-api-calls)
   - [Using plugins](#using-plugins)
     - [Alerting plugin](#alerting-plugin)
       - [**Searching for monitors**](#searching-for-monitors)
@@ -20,7 +22,7 @@
   - [Using IAM credentials for authentication](#using-iam-credentials-for-authentication)
       - [Pre-requisites to use `AWSV4SignerAuth`](#pre-requisites-to-use-awsv4signerauth)
 
-# Getting Started with the OpenSearch Python Client
+# User guide of OpenSearch Python Client
 
 ## Setup
 
@@ -39,7 +41,9 @@ from opensearchpy import OpenSearch
 If you prefer to add the client manually or just want to examine the source code, see [opensearch-py on GitHub](https://github.com/opensearch-project/opensearch-py).
 
 
-## Sample code
+## Example
+In the example given below, we create a client, an index with non-default settings, insert a 
+document in the index, search for the document, delete the document and finally delete the index.
 
 ### Creating a client
 
@@ -68,7 +72,6 @@ client = OpenSearch(
     ssl_show_warn = False,
     ca_certs = ca_certs_path
 )
-
 ```
 
 ### Creating an index
@@ -183,6 +186,37 @@ response = client.indices.delete(
 print('\nDeleting index:')
 print(response)
 ```
+## Making API Calls
+
+### Point in Time API
+
+```python
+# create a point in time on a index
+index_name = "test-index"
+response = client.create_point_in_time(index=index_name,
+                                       keep_alive="1m")
+
+pit_id = response.get("pit_id")
+print('\n Point in time ID:')
+print(pit_id)
+
+# To list all point in time which are alive in the cluster
+response = client.list_all_point_in_time()
+print('\n List of all Point in Time:')
+print(response)
+
+# To delete point in time
+pit_body = {
+    "pit_id": [pit_id]
+}
+
+# To delete all point in time 
+# client.delete_point_in_time(body=None, all=True)
+response = client.delete_point_in_time(body=pit_body)
+
+print('\n The deleted point in time:')
+print(response)
+```
 
 ## Using plugins
 
diff --git a/noxfile.py b/noxfile.py
index 895b4fa2..cb385fa7 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -49,7 +49,7 @@ def format(session):
     session.install("black", "isort")
 
     session.run("isort", "--profile=black", *SOURCE_FILES)
-    session.run("black", "--target-version=py27", *SOURCE_FILES)
+    session.run("black", "--target-version=py33", *SOURCE_FILES)
     session.run("python", "utils/license-headers.py", "fix", *SOURCE_FILES)
 
     lint(session)
diff --git a/opensearchpy/_async/client/__init__.py b/opensearchpy/_async/client/__init__.py
index 8346b236..a8b0db45 100644
--- a/opensearchpy/_async/client/__init__.py
+++ b/opensearchpy/_async/client/__init__.py
@@ -1950,26 +1950,46 @@ class AsyncOpenSearch(object):
         )
 
     @query_params()
-    async def close_point_in_time(self, body=None, params=None, headers=None):
+    async def list_all_point_in_time(self, params=None, headers=None):
         """
-        Close a point in time
+        Returns the list of point in times which are alive
+        """
+        return await self.transport.perform_request(
+            "GET",
+            _make_path("_search", "point_in_time", "_all"),
+            params=params,
+            headers=headers,
+        )
+
+    @query_params()
+    async def delete_point_in_time(
+        self, body=None, all=False, params=None, headers=None
+    ):
+        """
+        Delete a point in time
 
 
-        :arg body: a point-in-time id to close
+        :arg body: a point-in-time id to delete
+        :arg all: set it to `True` to delete all alive point in time.
         """
+        path = (
+            _make_path("_search", "point_in_time", "_all")
+            if all
+            else _make_path("_search", "point_in_time")
+        )
         return await self.transport.perform_request(
-            "DELETE", "/_pit", params=params, headers=headers, body=body
+            "DELETE", path, params=params, headers=headers, body=body
         )
 
     @query_params(
         "expand_wildcards", "ignore_unavailable", "keep_alive", "preference", "routing"
     )
-    async def open_point_in_time(self, index=None, params=None, headers=None):
+    async def create_point_in_time(self, index=None, params=None, headers=None):
         """
-        Open a point in time that can be used in subsequent searches
+        Create a point in time that can be used in subsequent searches
 
 
-        :arg index: A comma-separated list of index names to open point
+        :arg index: A comma-separated list of index names to create point
             in time; use `_all` or empty string to perform the operation on all
             indices
         :arg expand_wildcards: Whether to expand wildcard expression to
@@ -1983,7 +2003,10 @@ class AsyncOpenSearch(object):
         :arg routing: Specific routing value
         """
         return await self.transport.perform_request(
-            "POST", _make_path(index, "_pit"), params=params, headers=headers
+            "POST",
+            _make_path(index, "_search", "point_in_time"),
+            params=params,
+            headers=headers,
         )
 
     @query_params()
diff --git a/opensearchpy/client/__init__.py b/opensearchpy/client/__init__.py
index d517a505..36e2bc63 100644
--- a/opensearchpy/client/__init__.py
+++ b/opensearchpy/client/__init__.py
@@ -1951,23 +1951,42 @@ class OpenSearch(object):
         )
 
     @query_params()
-    def close_point_in_time(self, body=None, params=None, headers=None):
+    def list_all_point_in_time(self, params=None, headers=None):
         """
-        Close a point in time
+        Returns the list of active point in times searches
+        """
+        return self.transport.perform_request(
+            "GET",
+            _make_path("_search", "point_in_time", "_all"),
+            params=params,
+            headers=headers,
+        )
 
+    @query_params()
+    def delete_point_in_time(self, body=None, all=False, params=None, headers=None):
+        """
+        Delete a point in time
 
-        :arg body: a point-in-time id to close
+
+        :arg body: a point-in-time id to delete
+        :arg all: set it to `True` to delete all alive point in time.
         """
+
+        path = (
+            _make_path("_search", "point_in_time", "_all")
+            if all
+            else _make_path("_search", "point_in_time")
+        )
         return self.transport.perform_request(
-            "DELETE", "/_pit", params=params, headers=headers, body=body
+            "DELETE", path, params=params, headers=headers, body=body
         )
 
     @query_params(
         "expand_wildcards", "ignore_unavailable", "keep_alive", "preference", "routing"
     )
-    def open_point_in_time(self, index=None, params=None, headers=None):
+    def create_point_in_time(self, index=None, params=None, headers=None):
         """
-        Open a point in time that can be used in subsequent searches
+        Create a point in time that can be used in subsequent searches
 
 
         :arg index: A comma-separated list of index names to open point
@@ -1984,7 +2003,10 @@ class OpenSearch(object):
         :arg routing: Specific routing value
         """
         return self.transport.perform_request(
-            "POST", _make_path(index, "_pit"), params=params, headers=headers
+            "POST",
+            _make_path(index, "_search", "point_in_time"),
+            params=params,
+            headers=headers,
         )
 
     @query_params()


Test patch:
diff --git a/test_opensearchpy/test_client/test_point_in_time.py b/test_opensearchpy/test_client/test_point_in_time.py
new file mode 100644
index 00000000..53742dbe
--- /dev/null
+++ b/test_opensearchpy/test_client/test_point_in_time.py
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: Apache-2.0
+#
+# The OpenSearch Contributors require contributions made to
+# this file be licensed under the Apache-2.0 license or a
+# compatible open source license.
+#
+# Modifications Copyright OpenSearch Contributors. See
+# GitHub history for details.
+
+from test_opensearchpy.test_cases import OpenSearchTestCase
+
+
+class TestPointInTime(OpenSearchTestCase):
+    def test_create_one_point_in_time(self):
+        index_name = "test-index"
+        self.client.create_point_in_time(index=index_name)
+        self.assert_url_called("POST", "/test-index/_search/point_in_time")
+
+    def test_delete_one_point_in_time(self):
+        self.client.delete_point_in_time(body={"pit_id": ["Sample-PIT-ID"]})
+        self.assert_url_called("DELETE", "/_search/point_in_time")
+
+    def test_delete_all_point_in_time(self):
+        self.client.delete_point_in_time(all=True)
+        self.assert_url_called("DELETE", "/_search/point_in_time/_all")
+
+    def test_list_all_point_in_time(self):
+        self.client.list_all_point_in_time()
+        self.assert_url_called("GET", "/_search/point_in_time/_all")