+h3(#sharing-link). Create a collection sharing link
+
+You can create a sharing link for a collection by creating a new API token that is only allowed to read that collection; then constructing a link to your Keep web server that includes the collection UUID and the new token.
+
+{% codeblock as python %}
+import urllib.parse
+
+# The UUID of the collection you want to share
+collection_uuid = 'zzzzz-4zz18-12345abcde67890'
+
+sharing_token_scopes = [
+ 'GET /arvados/v1/keep_services/accessible',
+ f'GET /arvados/v1/collections/{collection_uuid}',
+ f'GET /arvados/v1/collections/{collection_uuid}/',
+]
+sharing_token = arv_client.api_client_authorizations().create(
+ body={
+ 'api_client_authorization': {
+ 'scopes': sharing_token_scopes,
+ },
+ },
+).execute()
+
+sharing_url_parts = (
+ # The scheme your Keep web server uses. Change this to 'http' if necessary.
+ 'https',
+ # The hostname, and optionally port, your Keep web server uses
+ 'collections.zzzzz.example.com',
+ # You shouldn't need to change any other items
+ f'/c={collection_uuid}/t={sharing_token["api_token"]}/_/',
+ None,
+ None,
+)
+sharing_url = urllib.parse.urlunsplit(sharing_url_parts)
+print(sharing_url)
+{% endcodeblock %}
+
+h2(#working-with-containers). Working with containers
+
+If you haven't already, start by reading the "Computing with Crunch":{{ site.baseurl }}/api/execution.html guide. It provides a high-level overview of how users submit work to Arvados as container requests; how Arvados dispatches that work to containers; and how Arvados records the association and results back on the original container request record.
+
+If you have experience running CWL workflows on Workbench 2, it runs through this same API. When you start that workflow run, Workbench 2 creates a small container request to run a "CWL runner" tool with the specific inputs you gave it. Once Crunch dispatches a container for it, the CWL runner creates additional container requests to run each step of the workflow, and oversees the process until the workflow runs to completion. The UUID of this container is recorded in the @container_uuid@ field of the container request you submitted.
+
+The UUID of the CWL runner container is recorded in the @requesting_container_uuid@ field of each container request it creates. You can list container requests with a filter on this field to inspect each step of the workflow individually, as shown below.
+
+The next few sections include two examples: a high-level example that describes how to work with any container request, and a more specific example that provides more detail about how to work with CWL workflow runs.
+
+h3(#get-input-of-a-cwl-workflow). Get input of a container or CWL workflow run
+
+A container request's most varied inputs are recorded in the @mounts@ field, which can include data from Keep, specific collections, Git checkouts, and static files. You might also be interested in the @environment@, @command@, @container_image@, and @secret_mounts@ fields. Refer to the "container requests API documentation":{{ site.baseurl }}/api/methods/container_requests.html for details.
+
+{% codeblock as python %}
+container_request = arv_client.container_requests().get(
+ uuid='zzzzz-xvhdp-12345abcde67890',
+).execute()
+# From here, you can process any of the container request's input fields.
+# Below is an example of listing all the mounts.
+import pprint
+for mount_name, mount_source in container_request['mounts'].items():
+ mount_summary = []
+ # These are the fields that define different types of mounts.
+ # Try to collect them all. Just skip any that aren't set.
+ for key in ['kind', 'uuid', 'portable_data_hash', 'commit', 'path']:
+ try:
+ mount_summary.append(mount_source[key])
+ except KeyError:
+ pass
+ print(f"{mount_name}: {' '.join(mount_summary)}")
+ if mount_source.get('kind') == 'json':
+ pprint.pprint(mount_source.get('content'))
+{% endcodeblock %}
+
+When you run a CWL workflow, the CWL inputs are stored in a JSON mount named @/var/lib/cwl/cwl.input.json@.
+
+{% codeblock as python %}
+container_request = arv_client.container_requests().get(
+ uuid='zzzzz-xvhdp-12345abcde67890',
+).execute()
+cwl_input = container_request['mounts']['/var/lib/cwl/cwl.input.json']['content']
+... # Work with the cwl_input dictionary
+{% endcodeblock %}
+
+h3(#get-output-of-a-cwl-workflow). Get output of a container or CWL workflow run
+
+A container's output files are saved in a collection. The UUID of that collection is recorded in the @output_uuid@ of the container request, which you can load as you like.
+
+{% codeblock as python %}
+import arvados.collection
+container_request = arv_client.container_requests().get(
+ uuid='zzzzz-xvhdp-12345abcde67890',
+).execute()
+container_output = arvados.collection.Collection(
+ container_request.get('output_uuid'),
+)
+... # Work with the container_output collection object
+{% endcodeblock %}
+
+When you run a CWL workflow, the output collection includes a file named @cwl.output.json@ that provides additional information about other files in the output.