Repository: ansys/pyhps-data-transfer
Pull request #200: Readme: update basic usage and add more Doc for examples
Author: login: saimanikant
Labels: name: maintenance
description: Package and maintenance related
Created: 2025-03-27T11:34:12Z | Merged: 2025-05-13T16:06:39Z

# Pull Request Template

## Description
addressing https://github.com/ansys/pyhps-data-transfer/issues/192
## Checklist
Please complete the following checklist before submitting your pull request:
- [x] I have tested these changes locally and verified that they work as intended.
- [x] I have updated any documentation as needed to reflect these changes (if appropriate)
- [x] I have verified that these changes to the best of my knowledge do not introduce any security vulnerabilities.
- [x] Unit tests have been added (if appropriate)
- [x] Test-cases have been added (if appropriate)
- [x] Testing instructions have been added (if appropriate)



Diff:
diff --git a/README.rst b/README.rst
index 0c883ba7..6d82349d 100644
--- a/README.rst
+++ b/README.rst
@@ -42,7 +42,6 @@ Installation
 ^^^^^^^^^^^^
 
 You can use `pip <https://pypi.org/project/pip/>`_ to install PyHPS Data Transfer.
-Note: This will be available only after released. For now, please install from git
 
 .. code:: bash
 
@@ -61,14 +60,40 @@ For more information, see `Getting Started`_.
 Basic usage
 ^^^^^^^^^^^
 
-This code shows how to import PyHPS Data Transfer and use some basic capabilities:
+The following sections show how to import PyHPS Data Transfer and use some basic capabilities.
+
+Request access token
+~~~~~~~~~~~~~~~~~~~~
+
+The client library requires an access token to connect to the HPS Data Transfer service.
+
+.. code:: python
+
+    from ansys.hps.data_transfer.client.authenticate import authenticate
+
+    auth_url = "https://localhost:8443/hps/auth/realms/rep"
+
+    token = authenticate(username="repadmin", password="repadmin", verify=False, url=auth_url)
+    token = token.get("access_token", None)
+
+Connect to data transfer service client
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After obtaining the access token, you can connect to the data transfer service client:
 
 .. code:: python
 
     from ansys.hps.data_transfer.client import Client    # Import the Client class
+    dt_url = f"https://localhost:8443/hps/dt/api/v1"
     client = Client()   # Create a client object
+    client.binary_config.update(verbosity=3, debug=True, insecure=True, token=token, data_transfer_url=dt_url, log=True)
+    client.start()
+
+    api = DataTransferApi(client)
+    api.status(wait=True)
+
 
-For comprehensive usage information, see `Examples`_ in the `PyHPS Data Transfer documentation`_.
+For comprehensive usage information, see `Examples`_.
 
 Documentation and issues
 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,6 +112,6 @@ To reach the project support team, email `pyansys.core@ansys.com <mailto:pyansys
 
 
 .. LINKS AND REFERENCES
-.. _Getting Started: https://hps.docs.pyansys.com/version/stable/getting_started/index.html
-.. _Examples: https://hps.docs.pyansys.com/version/stable/examples.html
-.. _PyHPS Data Transfer documentation: https://hps.docs.pyansys.com/version/stable/index.html
+.. _Getting Started: https://data-transfer.hps.docs.pyansys.com/version/stable/getting_started/index.html
+.. _Examples: https://data-transfer.hps.docs.pyansys.com/version/stable/examples/index.html
+.. _PyHPS Data Transfer documentation: https://data-transfer.hps.docs.pyansys.com/
diff --git a/examples/basic/async_data_transfer_client.py b/examples/basic/async_data_transfer_client.py
index 2647fae0..04e965c2 100644
--- a/examples/basic/async_data_transfer_client.py
+++ b/examples/basic/async_data_transfer_client.py
@@ -68,7 +68,10 @@ async def main(
     token = token.get("access_token", None)
     assert token is not None
 
-    log.info("Connecting to the data transfer service client..")
+########################################
+# Create an ``AsyncClient`` instance
+# ==================================
+
     client = AsyncClient(clean=True)
 
     client.binary_config.update(
@@ -80,19 +83,25 @@ async def main(
     )
     await client.start()
 
-    ########################################
-    # Create a AsyncDataTransferApi instance
-    # ======================================
+########################################
+# Create an ``AsyncDataTransferApi`` instance
+# ===========================================
+
 
     api = AsyncDataTransferApi(client)
     await api.status(wait=True)
 
-    log.info("Query storages ...")
+########################################
+# Get available storages
+# ======================
     storages = await api.storages()
     storage_names = [f"{storage['name']}({storage['type']})" for storage in storages]
     log.info(f"Available storages: {storage_names}")
 
-    log.info("Creating a directory ...")
+#################
+# Perform file operations
+# =======================
+
     base_dir = "basic-example"
     mkdir_op = await api.mkdir([StoragePath(path=f"{base_dir}")])
     await api.wait_for([mkdir_op.id])
diff --git a/examples/basic/file_operations_client.py b/examples/basic/file_operations_client.py
index 7f7499a4..792b21c1 100644
--- a/examples/basic/file_operations_client.py
+++ b/examples/basic/file_operations_client.py
@@ -49,8 +49,10 @@
 
 log = logging.getLogger(__name__)
 
-
-def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
+####################################
+# Perform file operations
+# ========================
+def file_operations(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
     if not remote_path:
         remote_path = Path(local_path).parent.name
 
@@ -73,10 +75,6 @@ def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None
     op = api.wait_for([op.id])
     log.info(f"Operation {op[0].state}")
 
-    ####################################
-    # Listing files and getting metadata
-    # ==================================
-
     log.info("Listing files ...")
     op = api.list([StoragePath(path=base_dir)])
     op = api.wait_for([op.id])
@@ -94,15 +92,17 @@ def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None
     op = api.wait_for([op.id])
     log.info(f"Operation {op[0].state}")
 
-
+####################################
+# Define the main function
+# ========================
 def main(
-    local_path: Annotated[str, typer.Option(help="Path to the files or directory to transfer. Supports wildcards")],
-    remote_path: Annotated[str, typer.Option(help="Optional path to the remote directory to transfer files to")] = None,
-    debug: Annotated[bool, typer.Option(help="Enable debug logging")] = False,
-    url: Annotated[str, typer.Option(help="HPS URL to connect to")] = "https://localhost:8443/hps",
-    username: Annotated[str, typer.Option(help="Username to authenticate with")] = "repadmin",
+    local_path: Annotated[str, typer.Option(help="Path to the files or directory to transfer. Supports wildcards.")],
+    remote_path: Annotated[str, typer.Option(help="Optional path to the remote directory to transfer files to.")] = None,
+    debug: Annotated[bool, typer.Option(help="Enable debug logging.")] = False,
+    url: Annotated[str, typer.Option(help="HPS URL to connect to.")] = "https://localhost:8443/hps",
+    username: Annotated[str, typer.Option(help="Username to authenticate with.")] = "repadmin",
     password: Annotated[
-        str, typer.Option(prompt=True, hide_input=True, help="Password to authenticate with")
+        str, typer.Option(prompt=True, hide_input=True, help="Password to authenticate with.")
     ] = "repadmin",
 ):
 
@@ -134,7 +134,7 @@ def main(
     storage_names = [f"{s['name']}({s['type']})" for s in api.storages()]
     log.info(f"Available storages: {storage_names}")
 
-    run(api=api, local_path=local_path, remote_path=remote_path)
+    file_operations(api=api, local_path=local_path, remote_path=remote_path)
 
     client.stop()
 
diff --git a/examples/permissions/set_permissions_example.py b/examples/permissions/set_permissions_example.py
index b2473cfc..f26251ac 100644
--- a/examples/permissions/set_permissions_example.py
+++ b/examples/permissions/set_permissions_example.py
@@ -64,8 +64,11 @@
 log.addHandler(stream_handler)
 log.setLevel(logging.DEBUG)
 
-
+######################################################################
+# Define a method to get the user ID of `'repuser`' from Keycloak
+# ===============================================================
 def get_user_id_from_keycloak(keycloak_url):
+    """Get the user id of 'repuser' from Keycloak."""
     admin = KeycloakAdmin(
         server_url=keycloak_url + "/",
         username="keycloak",
@@ -78,7 +81,11 @@ def get_user_id_from_keycloak(keycloak_url):
     return user_id
 
 
+##################################################################################
+# Define a method to set and query permissions on files and directories
+# =====================================================================
 def permissions(api: DataTransferApi, url: str):
+    """Set and query permissions on files and directories."""
     keycloak_url = f"{url}/auth"
     auth_url = f"{keycloak_url}/realms/rep"
     dt_url = f"{url}/dt/api/v1"
@@ -95,6 +102,9 @@ def permissions(api: DataTransferApi, url: str):
     for file in files:
         log.info(f"- {file}")
 
+##############################################################
+# Copy files as ``repuser``
+# =======================
     log.info("### Trying to copy files as 'repuser'...")
     target_dir = "permissions_demo"
     src_dst = [
@@ -122,6 +132,9 @@ def permissions(api: DataTransferApi, url: str):
     admin_token = authenticate(username="repadmin", password="repadmin", verify=False, url=auth_url)
     admin_token = admin_token.get("access_token", None)
 
+##############################################################
+# Create a data transfer client for ``repadmin``
+# ==============================================
     log.info("### Preparing data transfer client for 'repadmin' ...")
     admin_client = Client()
     admin_client.binary_config.update(
@@ -133,13 +146,12 @@ def permissions(api: DataTransferApi, url: str):
     )
     admin_client.start()
 
-    ###################################
-    # Create a DataTransferApi instance
-    # =================================
-
     admin = DataTransferApi(admin_client)
     admin.status(wait=True)
 
+##############################################################
+# Grant ``repuser`` the necessary permissions
+# ===========================================
     log.info("### Granting 'repuser' the necessary permissions ...")
     user_id = get_user_id_from_keycloak(keycloak_url)
 
@@ -156,6 +168,9 @@ def permissions(api: DataTransferApi, url: str):
     except Exception as ex:
         log.info(ex)
 
+##############################################################
+# Verify permissions for ``repuser``
+# ==================================
     try:
         log.info("### Verifying permissions for 'repuser' ...")
         resp = admin.check_permissions(
@@ -175,11 +190,17 @@ def permissions(api: DataTransferApi, url: str):
         op = api.wait_for([resp.id], timeout=None)[0]
         log.info(f"### Copy operation state: {op.state}")
 
+##############################################################
+# List files in the target directory as ``repadmin``
+# ==================================================
         log.info("### Listing files in the target directory as 'repadmin' ...")
         resp = admin.list([StoragePath(path=target_dir, remote="any")])
         op = admin.wait_for([resp.id], timeout=10)[0]
         log.info(f"### Result: {op.result}")
 
+##############################################################
+# Download files to ``downloaded`` directory
+# ==========================================
         target_dir = os.path.join(os.path.dirname(__file__), "downloaded")
         log.info(f"### Downloading files to {target_dir}...")
         src_dst = [
@@ -207,11 +228,11 @@ def permissions(api: DataTransferApi, url: str):
             ]
         )
 
-    log.info("And that's all folks!")
-
     admin_client.stop()
 
-
+###################################################
+# Define the main function
+# ========================
 def main(
     debug: Annotated[bool, typer.Option(help="Enable debug logging")] = False,
     url: Annotated[str, typer.Option(help="HPS URL to connect to")] = "https://localhost:8443/hps",
diff --git a/examples/startup/data_transfer_runner.py b/examples/startup/data_transfer_runner.py
index f62a1334..36fea093 100644
--- a/examples/startup/data_transfer_runner.py
+++ b/examples/startup/data_transfer_runner.py
@@ -61,10 +61,6 @@ def main(
     user_token = user_token.get("access_token", None)
     assert user_token is not None
 
-    ##########################
-    # Create a Client instance
-    # ========================
-
     client = Client()
     client.binary_config.update(
         verbosity=3,
diff --git a/examples/transfer_files/transfer_files.py b/examples/transfer_files/transfer_files.py
index 5832f331..27f6598f 100644
--- a/examples/transfer_files/transfer_files.py
+++ b/examples/transfer_files/transfer_files.py
@@ -36,6 +36,9 @@
 
 """
 
+###################################################
+# Perform necessary imports
+# =========================
 import filecmp
 import glob
 import logging
@@ -48,17 +51,15 @@
 import typer
 from typing_extensions import Annotated
 
-###################################################
-# Necessary imports
-# =================
-
 from ansys.hps.data_transfer.client import Client, DataTransferApi
 from ansys.hps.data_transfer.client.authenticate import authenticate
 from ansys.hps.data_transfer.client.models.msg import SrcDst, StoragePath
 
 log = logging.getLogger(__name__)
 
-
+########################################################################
+# Define a method to transfer files using the data transfer service
+# =================================================================
 def transfer_files(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
     """Transfer files to remote backends and back using new data transfer service."""
     if not remote_path:
@@ -145,7 +146,9 @@ def transfer_files(api: DataTransferApi, local_path: str, remote_path: Optional[
         log.info(f"- {fname}: {'Success' if success else 'Failed'}")
         assert success, f"File {fname} comparison failed!"
 
-
+###################################################
+# Define the main function
+# ========================
 def main(
     local_path: Annotated[str, typer.Option(help="Path to the files or directory to transfer. Supports wildcards")],
     remote_path: Annotated[str, typer.Option(help="Optional path to the remote directory to transfer files to")] = None,
@@ -167,10 +170,9 @@ def main(
     token = token.get("access_token", None)
     assert token is not None
 
-    log.info("Connecting to the data transfer service client..")
-    ##############################
-    # Create a ``client`` instance
-    # ============================
+###################################################
+# Create a ``client`` instance
+# ============================
     client = Client(clean=True)
 
     client.binary_config.update(
@@ -181,9 +183,14 @@ def main(
         data_transfer_url=dt_url,
     )
     client.start()
-
+###################################################
+# Create a ``DataTransferApi`` instance
+# =====================================
     api = DataTransferApi(client)
     api.status(wait=True)
+###################################################
+# Get available storages
+# ======================
     storage_names = [f"{s['name']}({s['type']})" for s in api.storages()]
     log.info(f"Available storages: {storage_names}")
 


Reviews:
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:49:52Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:50:26Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:51:15Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:52:18Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:52:41Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:54:17Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:56:01Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:56:32Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:58:06Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:58:39Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:59:13Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T14:59:39Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:00:23Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:00:39Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:00:56Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:01:13Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:01:50Z
user: login: PipKat
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-13T15:09:24Z
user: login: PipKat
body: One new suggested edit. This is for doc string approval only. You likely still need to obtain the approval of a technical reviewer.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-13T15:10:43Z
user: login: FedericoNegri
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-13T16:06:06Z

Review comments:
diff_hunk: @@ -61,14 +60,40 @@ For more information, see `Getting Started`_.
 Basic usage
 ^^^^^^^^^^^
 
-This code shows how to import PyHPS Data Transfer and use some basic capabilities:
+The following sections show how to import PyHPS Data Transfer and use some basic capabilities:
path: README.rst
user: login: PipKat
body: ```suggestion
The following sections show how to import PyHPS Data Transfer and use some basic capabilities.
```
Use period as a colon implies that a list follows.
created_at: 2025-05-12T14:49:52Z
author_association: MEMBER
diff_hunk: @@ -61,14 +60,40 @@ For more information, see `Getting Started`_.
 Basic usage
 ^^^^^^^^^^^
 
-This code shows how to import PyHPS Data Transfer and use some basic capabilities:
+The following sections show how to import PyHPS Data Transfer and use some basic capabilities:
+
+Requesting access token
+~~~~~~~~~~~~~~~~~~~~~~~
path: README.rst
user: login: PipKat
body: ```suggestion
Request access token
~~~~~~~~~~~~~~~~~~~~
```
Use simple verb form in titles of example sections.
created_at: 2025-05-12T14:50:26Z
author_association: MEMBER
diff_hunk: @@ -61,14 +60,40 @@ For more information, see `Getting Started`_.
 Basic usage
 ^^^^^^^^^^^
 
-This code shows how to import PyHPS Data Transfer and use some basic capabilities:
+The following sections show how to import PyHPS Data Transfer and use some basic capabilities:
+
+Requesting access token
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The client library requires an access token to connect to the HPS Data Transfer service.
+
+.. code:: python
+
+    from ansys.hps.data_transfer.client.authenticate import authenticate
+
+    auth_url = "https://localhost:8443/hps/auth/realms/rep"
+
+    token = authenticate(username="repadmin", password="repadmin", verify=False, url=auth_url)
+    token = token.get("access_token", None)
+
+Connect to data transfer service
path: README.rst
user: login: PipKat
body: Should client be part of the sentence tile as it is used in the first sentence? We want to use terms consistently.
created_at: 2025-05-12T14:51:15Z
author_association: MEMBER
diff_hunk: @@ -68,7 +68,9 @@ async def main(
     token = token.get("access_token", None)
     assert token is not None
 
-    log.info("Connecting to the data transfer service client..")
+########################################
+# Create a AsyncClient instance
+# =============================
path: examples/basic/async_data_transfer_client.py
user: login: PipKat
body: ```suggestion
# Create an ``AsyncClient`` instance
# ==================================

```
created_at: 2025-05-12T14:52:18Z
author_association: MEMBER
diff_hunk: @@ -80,19 +82,23 @@ async def main(
     )
     await client.start()
 
-    ########################################
-    # Create a AsyncDataTransferApi instance
-    # ======================================
+########################################
+# Create a AsyncDataTransferApi instance
+# ======================================
path: examples/basic/async_data_transfer_client.py
user: login: PipKat
body: ```suggestion
# Create an ``AsyncDataTransferApi`` instance
# ===========================================

```
created_at: 2025-05-12T14:52:41Z
author_association: MEMBER
diff_hunk: @@ -80,19 +82,23 @@ async def main(
     )
     await client.start()
 
-    ########################################
-    # Create a AsyncDataTransferApi instance
-    # ======================================
+########################################
+# Create a AsyncDataTransferApi instance
+# ======================================
 
     api = AsyncDataTransferApi(client)
     await api.status(wait=True)
 
-    log.info("Query storages ...")
+########################################
+# Get available storages
+# ======================
     storages = await api.storages()
     storage_names = [f"{storage['name']}({storage['type']})" for storage in storages]
     log.info(f"Available storages: {storage_names}")
 
-    log.info("Creating a directory ...")
+########################################################################
+# Create a directory, copy files, list files, get metadata, remove files
path: examples/basic/async_data_transfer_client.py
user: login: PipKat
body: Can the section title be shortened to something like "Set up project"? The current title is quite long!
created_at: 2025-05-12T14:54:17Z
author_association: MEMBER
diff_hunk: @@ -49,8 +49,10 @@
 
 log = logging.getLogger(__name__)
 
-
-def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
+####################################
+# File operations function
path: examples/basic/file_operations_client.py
user: login: PipKat
body: This title should start with a simple verb. Perhaps "Perform file operations"?
created_at: 2025-05-12T14:56:01Z
author_association: MEMBER
diff_hunk: @@ -94,7 +92,9 @@ def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None
     op = api.wait_for([op.id])
     log.info(f"Operation {op[0].state}")
 
-
+####################################
+# Main function
path: examples/basic/file_operations_client.py
user: login: PipKat
body: Again the title should start with a simple verb. 
created_at: 2025-05-12T14:56:32Z
author_association: MEMBER
diff_hunk: @@ -94,7 +92,9 @@ def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None
     op = api.wait_for([op.id])
     log.info(f"Operation {op[0].state}")
 
-
+####################################
+# Main function
+# =============
 def main(
path: examples/basic/file_operations_client.py
user: login: PipKat
body: Is the "help" information coming from elsewhere? If this is the actual source for the help documentation, we should add concluding punctuation.
created_at: 2025-05-12T14:58:06Z
author_association: MEMBER
diff_hunk: @@ -64,8 +64,11 @@
 log.addHandler(stream_handler)
 log.setLevel(logging.DEBUG)
 
-
+######################################################################
+# Define a method to get the user id of 'repuser' from Keycloak
+# =============================================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Define a method to get the user ID of `'repuser`' from Keycloak
# ===============================================================
```
created_at: 2025-05-12T14:58:39Z
author_association: MEMBER
diff_hunk: @@ -95,6 +102,9 @@ def permissions(api: DataTransferApi, url: str):
     for file in files:
         log.info(f"- {file}")
 
+##############################################################
+# Copy files as 'repuser'
+# =======================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Copy files as ``repuser``
# =======================
```
Code entities must be in double backticks. Otherwise, the word is simply rendered in italic in the generated doc.
created_at: 2025-05-12T14:59:13Z
author_association: MEMBER
diff_hunk: @@ -122,6 +132,9 @@ def permissions(api: DataTransferApi, url: str):
     admin_token = authenticate(username="repadmin", password="repadmin", verify=False, url=auth_url)
     admin_token = admin_token.get("access_token", None)
 
+##############################################################
+# Create a data transfer client for 'repadmin'
+# ============================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Create a data transfer client for ``repadmin``
# ==============================================
```
created_at: 2025-05-12T14:59:39Z
author_association: MEMBER
diff_hunk: @@ -133,13 +146,12 @@ def permissions(api: DataTransferApi, url: str):
     )
     admin_client.start()
 
-    ###################################
-    # Create a DataTransferApi instance
-    # =================================
-
     admin = DataTransferApi(admin_client)
     admin.status(wait=True)
 
+##############################################################
+# Grant 'repuser' the necessary permissions
+# =========================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Grant ``repuser`` the necessary permissions
# ===========================================
```
created_at: 2025-05-12T15:00:22Z
author_association: MEMBER
diff_hunk: @@ -156,6 +168,9 @@ def permissions(api: DataTransferApi, url: str):
     except Exception as ex:
         log.info(ex)
 
+##############################################################
+# Verify permissions for 'repuser'
+# ================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Verify permissions for ``repuser``
# ==================================
```
created_at: 2025-05-12T15:00:39Z
author_association: MEMBER
diff_hunk: @@ -175,11 +190,17 @@ def permissions(api: DataTransferApi, url: str):
         op = api.wait_for([resp.id], timeout=None)[0]
         log.info(f"### Copy operation state: {op.state}")
 
+##############################################################
+# List files in the target directory as 'repadmin'
+# ================================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# List files in the target directory as ``repadmin``
# ==================================================
```
created_at: 2025-05-12T15:00:56Z
author_association: MEMBER
diff_hunk: @@ -175,11 +190,17 @@ def permissions(api: DataTransferApi, url: str):
         op = api.wait_for([resp.id], timeout=None)[0]
         log.info(f"### Copy operation state: {op.state}")
 
+##############################################################
+# List files in the target directory as 'repadmin'
+# ================================================
         log.info("### Listing files in the target directory as 'repadmin' ...")
         resp = admin.list([StoragePath(path=target_dir, remote="any")])
         op = admin.wait_for([resp.id], timeout=10)[0]
         log.info(f"### Result: {op.result}")
 
+##############################################################
+# Download files to 'downloaded' directory
+# ========================================
path: examples/permissions/set_permissions_example.py
user: login: PipKat
body: ```suggestion
# Download files to ``downloaded`` directory
# ==========================================
```
created_at: 2025-05-12T15:01:13Z
author_association: MEMBER
diff_hunk: @@ -36,6 +36,9 @@
 
 """
 
+###################################################
+# Necessary imports
+# =================
path: examples/transfer_files/transfer_files.py
user: login: PipKat
body: ```suggestion
# Perform necessary imports
# =========================
```
created_at: 2025-05-12T15:01:50Z
author_association: MEMBER
diff_hunk: @@ -80,19 +83,24 @@ async def main(
     )
     await client.start()
 
-    ########################################
-    # Create a AsyncDataTransferApi instance
-    # ======================================
+########################################
+# Create an ``AsyncDataTransferApi`` instance
+# ===========================================
+
 
     api = AsyncDataTransferApi(client)
     await api.status(wait=True)
 
-    log.info("Query storages ...")
+########################################
+# Get available storages
+# ======================
     storages = await api.storages()
     storage_names = [f"{storage['name']}({storage['type']})" for storage in storages]
     log.info(f"Available storages: {storage_names}")
 
-    log.info("Creating a directory ...")
+#################
+# File operations
+# ===============
path: examples/basic/async_data_transfer_client.py
user: login: PipKat
body: ```suggestion
# Perform file operations
# =======================

```
created_at: 2025-05-13T15:09:24Z
author_association: MEMBER

PR comments:
user: login: codecov-commenter
created_at: 2025-05-12T16:53:15Z
body: ## [Codecov](https://app.codecov.io/gh/ansys/pyhps-data-transfer/pull/200?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ansys) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 82.98%. Comparing base [(`6323797`)](https://app.codecov.io/gh/ansys/pyhps-data-transfer/commit/632379718f6420e8e1b767832ef7d0a181a72065?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ansys) to head [(`bbd365b`)](https://app.codecov.io/gh/ansys/pyhps-data-transfer/commit/bbd365b1052fb5454e8facb2213a75946a1c9279?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ansys).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #200      +/-   ##
==========================================
- Coverage   84.99%   82.98%   -2.02%     
==========================================
  Files          19       19              
  Lines        1193     1193              
==========================================
- Hits         1014      990      -24     
- Misses        179      203      +24     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/ansys/pyhps-data-transfer/pull/200?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ansys).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ansys).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: saimanikant
created_at: 2025-05-12T17:06:26Z
body: @PipKat Thanks for the review. Comments are addressed in the latest commit
author_association: COLLABORATOR