Skip to content

Readme: update basic usage and add more Doc fro examples #200

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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
^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -87,6 +112,6 @@ To reach the project support team, email `[email protected] <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/
18 changes: 12 additions & 6 deletions examples/basic/async_data_transfer_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
# =============================
client = AsyncClient(clean=True)

client.binary_config.update(
Expand All @@ -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
# ======================================================================
base_dir = "basic-example"
mkdir_op = await api.mkdir([StoragePath(path=f"{base_dir}")])
await api.wait_for([mkdir_op.id])
Expand Down
16 changes: 8 additions & 8 deletions examples/basic/file_operations_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@

log = logging.getLogger(__name__)


def run(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
####################################
# File operations function
# ========================
def file_operations(api: DataTransferApi, local_path: str, remote_path: Optional[str] = None):
if not remote_path:
remote_path = Path(local_path).parent.name

Expand All @@ -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])
Expand All @@ -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(
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,
Expand Down Expand Up @@ -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()

Expand Down
37 changes: 29 additions & 8 deletions examples/permissions/set_permissions_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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"
Expand All @@ -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 = [
Expand Down Expand Up @@ -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(
Expand All @@ -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)

Expand All @@ -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(
Expand All @@ -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 = [
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 0 additions & 4 deletions examples/startup/data_transfer_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
29 changes: 18 additions & 11 deletions examples/transfer_files/transfer_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@

"""

###################################################
# Necessary imports
# =================
import filecmp
import glob
import logging
Expand All @@ -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:
Expand Down Expand Up @@ -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,
Expand All @@ -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(
Expand All @@ -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}")

Expand Down
Loading