Timer Management

These examples demonstrate how to create, list, and delete timers with the SDK.

Create a timer

This script creates a new timer, on source and destination collections provided via the command-line. It syncs an input file or directory between the two.

The script assumes that the path being synced is the same on the source and destination for simplicity.

Note

This example does not handle data_access scope requirements. See the later example to handle this.

create_timer.py [download]
#!/usr/bin/env python

import argparse
import datetime

import globus_sdk
from globus_sdk.experimental.globus_app import UserApp

# Tutorial Client ID - <replace this with your own client>
NATIVE_CLIENT_ID = "61338d24-54d5-408f-a10d-66c06b59f6d2"
USER_APP = UserApp("manage-timers-example", client_id=NATIVE_CLIENT_ID)


def main():
    parser = argparse.ArgumentParser()
    # the source, destination, and path to a file or dir to sync
    parser.add_argument("SOURCE_COLLECTION")
    parser.add_argument("DESTINATION_COLLECTION")
    parser.add_argument("PATH")
    parser.add_argument(
        "--interval-seconds",
        help="How frequently the timer runs, in seconds (default: 1 hour)",
        default=3600,
        type=int,
    )
    parser.add_argument(
        "--days",
        help="How many days to run the timer (default: 2)",
        default=2,
        type=int,
    )
    args = parser.parse_args()

    client = globus_sdk.TimersClient(app=USER_APP)

    body = globus_sdk.TransferData(
        source_endpoint=args.SOURCE_COLLECTION,
        destination_endpoint=args.DESTINATION_COLLECTION,
    )
    body.add_item(args.PATH, args.PATH)

    # the timer will run until the end date, on whatever interval was requested
    schedule = globus_sdk.RecurringTimerSchedule(
        interval_seconds=args.interval_seconds,
        end={
            "condition": "time",
            "datetime": datetime.datetime.now() + datetime.timedelta(days=args.days),
        },
    )

    timer = client.create_timer(
        timer=globus_sdk.TransferTimer(
            name=(
                "create-timer-example "
                f"[created at {datetime.datetime.now().isoformat()}]"
            ),
            body=body,
            schedule=schedule,
        )
    )
    print("Finished submitting timer.")
    print(f"timer_id: {timer['timer']['job_id']}")


if __name__ == "__main__":
    main()

List timers

This script lists your current timers.

list_timers.py [download]
#!/usr/bin/env python

import globus_sdk
from globus_sdk.experimental.globus_app import UserApp

# Tutorial Client ID - <replace this with your own client>
NATIVE_CLIENT_ID = "61338d24-54d5-408f-a10d-66c06b59f6d2"
USER_APP = UserApp("manage-timers-example", client_id=NATIVE_CLIENT_ID)


def main():
    client = globus_sdk.TimersClient(app=USER_APP)

    first = True
    for record in client.list_jobs(query_params={"filter_active": True})["jobs"]:
        if not first:
            print("---")
        first = False
        print("name:", record["name"])
        print("id:", record["job_id"])


if __name__ == "__main__":
    main()

Delete a timer

This script deletes a timer by ID.

delete_timer.py [download]
#!/usr/bin/env python

import argparse

import globus_sdk
from globus_sdk.experimental.globus_app import UserApp

# Tutorial Client ID - <replace this with your own client>
NATIVE_CLIENT_ID = "61338d24-54d5-408f-a10d-66c06b59f6d2"
USER_APP = UserApp("manage-timers-example", client_id=NATIVE_CLIENT_ID)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("TIMER_ID")
    args = parser.parse_args()

    client = globus_sdk.TimersClient(app=USER_APP)

    client.delete_job(args.TIMER_ID)
    print("Finished deleting timer.")


if __name__ == "__main__":
    main()

Create a timer with data_access

This script is similar to the create_timer.py example above. However, it also handles data_access scope requirements for the source and destination collections.

Discovering data_access requirements requires the use of a TransferClient to look up the collections.

As in the simpler example, this script creates a new timer, on source and destination collections provided via the command-line. It syncs an input file or directory between the two, and assumes that the path is the same on the source and destination.

create_timer_data_access.py [download]
#!/usr/bin/env python

import argparse
import datetime

import globus_sdk
from globus_sdk.experimental.globus_app import UserApp

# Tutorial Client ID - <replace this with your own client>
NATIVE_CLIENT_ID = "61338d24-54d5-408f-a10d-66c06b59f6d2"
USER_APP = UserApp("manage-timers-example", client_id=NATIVE_CLIENT_ID)


def uses_data_access(transfer_client, collection_id):
    doc = transfer_client.get_endpoint(collection_id)
    if doc["entity_type"] != "GCSv5_mapped_collection":
        return False
    if doc["high_assurance"]:
        return False
    return True


def main():
    parser = argparse.ArgumentParser()
    # the source, destination, and path to a file or dir to sync
    parser.add_argument("SOURCE_COLLECTION")
    parser.add_argument("DESTINATION_COLLECTION")
    parser.add_argument("PATH")
    parser.add_argument(
        "--interval-seconds",
        help="How frequently the timer runs, in seconds (default: 1 hour)",
        default=3600,
        type=int,
    )
    parser.add_argument(
        "--days",
        help="How many days to run the timer (default: 2)",
        default=2,
        type=int,
    )
    args = parser.parse_args()

    timers_client = globus_sdk.TimersClient(app=USER_APP)
    transfer_client = globus_sdk.TransferClient(app=USER_APP)

    # check if the source or destination use 'data_access' scopes
    # if so, register these requirements with the app
    if uses_data_access(transfer_client, args.SOURCE_COLLECTION):
        timers_client.add_app_transfer_data_access_scope(args.SOURCE_COLLECTION)
    if uses_data_access(transfer_client, args.DESTINATION_COLLECTION):
        timers_client.add_app_transfer_data_access_scope(args.DESTINATION_COLLECTION)

    # from this point onwards, the example is the same as the basic create_timer.py
    # script -- we've handled the nuance of data_access
    #
    # when the timer submission runs, you *may* be prompted to login again, if
    # 'data_access' requirements were detected

    body = globus_sdk.TransferData(
        source_endpoint=args.SOURCE_COLLECTION,
        destination_endpoint=args.DESTINATION_COLLECTION,
    )
    body.add_item(args.PATH, args.PATH)

    # the timer will run until the end date, on whatever interval was requested
    schedule = globus_sdk.RecurringTimerSchedule(
        interval_seconds=args.interval_seconds,
        end={
            "condition": "time",
            "datetime": datetime.datetime.now() + datetime.timedelta(days=args.days),
        },
    )

    timer = timers_client.create_timer(
        timer=globus_sdk.TransferTimer(
            name=(
                "create-timer-example "
                f"[created at {datetime.datetime.now().isoformat()}]"
            ),
            body=body,
            schedule=schedule,
        )
    )
    print("Finished submitting timer.")
    print(f"timer_id: {timer['timer']['job_id']}")


if __name__ == "__main__":
    main()