Your browser is not recommended for EDX, we suggest using the latest version of Google Chrome.

Obtaining Your API Key

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

To obtain your EDX account's API key, log into EDX. Navigate to your users profile and hover over the "Hover to reveal API Key" label and click to copy the API key to your clipboard.

This API key is used to check your access permissions as you attempt to upload files to various locations within EDX. You can only upload files to EDX Drives of workspaces that you are an editor or admin of. You can only upload files to submissions that you have editing rights to (private workspace [editor or admin] or specific drafts).

DOWNLOAD RESOURCE FILES [Public or Private]

API Endpoint: resource_download

NOTE: An API Key is required for ALL downloads as of EDX 3.07 (9/3/2020)

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

Public Resources:

To obtain a public URL needed to download a resource, you can navigate to the public submission (e.g. https://edx.netl.doe.gov/dataset/global-oil-gas-features-database), right click on the blue “Download” button and “Copy Link Address” (wording from Chrome). The copied URL from this example will look as follows (as of 5/28/2019): https://edx.netl.doe.gov/dataset/global-oil-gas-features-database/resource_download/34280f73-526f-497b-a672-9f37313acede

wget --header="EDX-API-Key:<YOUR_EDX_API_KEY>" https://edx.netl.doe.gov/dataset/<submission name or id>/resource_download/<resource id>

Private Resources:

To obtain a private URL needed to download a private resource, there are two scenarios:

  1. Private Submission:
  2. Navigate to the private submission (e.g. https://edx.netl.doe.gov/dataset/databook-node-modules-folder-content), right click on the blue “Download” button and “Copy Link Address” (wording from Chrome). The copied URL from this example will look as follows (5/28/2019): https://edx.netl.doe.gov/dataset/databook-node-modules-folder-content/resource_download/720f64d3-f722-4fbf-be38-3eee0d6d91ca

  3. EDX Drive Resource
  4. Navigate to the EDX Drive of a workspace, right click on a resource and select the “Copy Download Link” option (e.g. https://edx.netl.doe.gov/dataset/444e779f-0c64-4cff-a850-8e1cb10529ef/resource_download/99e03d45-b742-46bb-97ef-0a902159d9fc

Add your EDX API KEY as a header to the download link ... ie:

wget --header="EDX-API-Key:<YOUR_EDX_API_KEY>" https://edx.netl.doe.gov/dataset/<submission name or id>/resource_download/<resource id>

Example #1 (Python 3):

import requests
import urllib3
import re

urllib3.disable_warnings()

# EDX API KEY, can be found at https://edx.netl.doe.gov/user/<your_username>
APIKEY = ""

# Resource download url
# https://edx.netl.doe.gov/dataset/<package_id>/resource_download/<resource_id>
URL = ""

HEADERS = {"EDX-API-Key": APIKEY}

print("Getting resource...")
r = requests.get(URL, headers=HEADERS)

fname = ''
if "Content-Disposition" in r.headers.keys():
    fname = re.findall("filename=(.+)", r.headers["Content-Disposition"])[0]
else:
    fname = URL.split("/")[-1]

if fname.startswith('"'):
    fname = fname[1:]

if fname.endswith('"'):
    fname = fname[:-1]

open('/path/to/downloads/'+fname+'', 'wb').write(r.content)

IMPORTANT NOTE: A submission name is the text that appears in the address bar, it is NOT the plain text title found in the body of the website.

For example,

use global-oil-gas-features-database.

Do NOT use Global Oil & Gas Features Database.

OBTAIN LIST OF RESOURCE FILE(S) AND THEIR METADATA FROM FOLDER ID [Private Workspace Only]

API Endpoint: folder_resource

Obtaining a list of resources files and their associated metadata can be a powerful step in creating complex scripts for bulk downloading files, investigating resource metadata in bulk, identifying subfolders/subdirectories, etc.

NOTE: An API Key is required for ALL private workspace activities.

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

NOTE: Results for this API endpoint are in JSON format.

To obtain the initial/seed folder ID:

Using the EDX web user interface, navigate to the workspace that contains the folder that you wish to upload to, right click the folder, select the "Get Folder ID" option from the menu, and select the "Copy ID to Clipboard" option from the modal pop-up window.

PARAMETER DEFINITIONS:

Parameter Name Description Required Field
workspace_id The name or ID of workspace where the folder resides Required
folder_id The ID of the folder on EDX Drive you wish to explore Required
only_show_type If you wish to only return resources or folders Optional

NOTE: If the only_show_type is not used, then both resources and folders will return in the JSON.

NOTE: If you wish to return items at the root level of the EDX drive, then use the value root for folder_id

In the example below, you will see that you can provide one OR many folder IDs in a single request. If the list of folder IDs provided contain a deleted folder, that deleted folder will not return information in the JSON. Essentially, if a folder is missing in the JSON, either the folder was deleted or the ID provided is incorrect.

Example #1 (Python 3):

import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'test-workspace',
    "folder_id": '7c3e598c-3486-468d-9d5b-9eee6da7637a'
    #"folder_id": ['7c3e598c-3486-468d-9d5b-9eee6da7637a', '4d932b54-57be-404a-b38e-6e9caa6e3b23']  list of folders format
    #"only_show_type": 'folders' # Uncomment this line if you wish to only return folders
    #"only_show_type": 'resources' # Uncomment this line if you wish to only return resources
}

url = 'https://edx.netl.doe.gov/api/3/action/folder_resources'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)

print (r.json())

EXAMPLE #1 RETURNED OUTPUT

{
  'help': 'http://edx.netl.doe.gov/api/3/action/help_show?name=folder_resources',
  'success': True,
  'result': {
    'resources': [
      {
        'id': 'c133dc74-c719-4072-8ee3-69c491223f62',
        'package_id': '78a8dcb1-2736-49f6-a7ca-b4994498e21a',
        'revision_id': '77bd7083-179a-4c58-b649-4ac21b68e122',
        'url': 'http://edx.netl.doe.gov/storage/f/edx/2021/04/2021-04-15T14:53:02.651Z/c133dc74-c719-4072-8ee3-69c491223f62/alligator.jpeg',
        'format': 'JPEG',
        'description': '',
        'hash': 'md5:86b552add383a47a8958a19617652805',
        'position': 0,
        'name': 'alligator.jpeg',
        'resource_type': 'file.upload',
        'mimetype': 'image/jpeg',
        'mimetype_inner': None,
        'size': 5944,
        'created': '2021-04-15T10:53:02.707000',
        'last_modified': '2021-04-15T10:53:02.707000',
        'cache_url': 'storage/f/edx/2021/04/2021-04-15T14:53:02.651Z/c133dc74-c719-4072-8ee3-69c491223f62/alligator.jpeg',
        'cache_last_updated': None,
        'url_type': 'upload',
        'state': 'active',
        'license_type': 'notspecified',
        'folder_id': '2fba33a7-6607-482d-89dd-ec964342e843',
        'owner_org': '2bcc2e6c-8830-4c52-9f77-dca017947723',
        'recycle_removed': False,
        'rating': None,
        'key': '2021-04-15T14:53:02.651Z/c133dc74-c719-4072-8ee3-69c491223f62/alligator.jpeg',
        'owner': 'catherinehines',
        'cache_url_updated': '2021-04-15T10:53:02.707',
        'datastore_active': False,
        'revision_timestamp': 'April 15, 2021, 14:53:02 (EST)',
        'intended_use_auth': False
      },
      {
        'id': '741c4bdb-b04a-457b-8947-42d9a95faf53',
        'package_id': '584a1890-3970-442f-9a96-dea794fff0f1',
        'revision_id': '469e4fc7-ad98-46a4-9c71-88412333e4c2',
        'url': 'http://edx.netl.doe.gov/storage/f/edx/2021/04/2021-04-15T14:51:35.522Z/741c4bdb-b04a-457b-8947-42d9a95faf53/red_panda.jpeg',
        'format': 'JPEG',
        'description': '',
        'hash': 'md5:4a6acf2c516fdaa608f090ccca5b6a7e',
        'position': 0,
        'name': 'red_panda.jpeg',
        'resource_type': 'file.upload',
        'mimetype': 'image/jpeg',
        'mimetype_inner': None,
        'size': 6714,
        'created': '2021-04-15T10:51:35.676000',
        'last_modified': '2021-04-15T10:51:35.676000',
        'cache_url': 'storage/f/edx/2021/04/2021-04-15T14:51:35.522Z/741c4bdb-b04a-457b-8947-42d9a95faf53/red_panda.jpeg',
        'cache_last_updated': None,
        'url_type': 'upload',
        'state': 'active',
        'license_type': 'notspecified',
        'folder_id': '2fba33a7-6607-482d-89dd-ec964342e843',
        'owner_org': '2bcc2e6c-8830-4c52-9f77-dca017947723',
        'recycle_removed': False,
        'rating': None,
        'key': '2021-04-15T14:51:35.522Z/741c4bdb-b04a-457b-8947-42d9a95faf53/red_panda.jpeg',
        'owner': 'catherinehines',
        'cache_url_updated': '2021-04-15T10:51:35.676',
        'datastore_active': False,
        'group': '2bcc2e6c-8830-4c52-9f77-dca017947723',
        'revision_timestamp': 'April 15, 2021, 14:51:35 (EST)',
        'intended_use_auth': False
      }
    ],
    'folders': [
      {
        'id': 'f80b7c26-9017-4538-8989-5cef771093d8',
        'name': 'Subfolder'
      }
    ]
  }
}

UPLOAD RESOURCE FILES

API Endpoint: resource_create_api

There are a variety of ways to upload files to EDX using the API. First, we will cover the initial options, recommendations, and definitions to better understand how to use this specific feature. Further clarification will be made for each bullet point and use case examples will be provided using python 3.8.

UPLOADING SCENARIOS:

  1. Upload file to EDX Drive within a private workspace (root level)
  2. Upload file to EDX Drive within a private workspace (specified folder location)
  3. Upload file to existing private submission within private workspace
  4. Upload file to existing draft submission

UPLOAD SIZE RECOMMENDATIONS & CLARIFICATIONS:

  • Small files- Files being uploaded that are under 2 GB do not require chunking in order to upload to EDX via the API. However, you can use chunking if you would like. If you decide to use the chunk parameter, you must also use the original_size parameter to specify the total size of the file in bytes. It is strongly encouraged to programmatically determine the file size in your script rather than manually entering a value.
  • Large files- Files being uploaded that are 2 GB or larger are strongly recommended to use chunking when uploading to EDX via the API. Chunking large files into small parts will put less stress on your connection and allow for percentage tracking progress of your upload. When using the chunk parameter, you must also use the original_size parameter to specify the total size of the file in bytes. It is strongly encouraged to programmatically determine the file size in your script rather than manually entering a value.

EDX ACCOUNT API KEY MUST BE INCLUDED IN HEADER:

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

To obtain your EDX account's API key, log into EDX. Navigate to your users profile and hover over the "Hover to reveal API Key" label and click to copy the API key to your clipboard.

This API key is used to check your access permissions as you attempt to upload files to various locations within EDX. You can only upload files to EDX Drives of workspaces that you are an editor or admin of. You can only upload files to submissions that you have editing rights to (private workspace [editor or admin] or specific drafts).

PARAMETER DEFINITIONS:

Parameter Name Description Required Field
workspace_id The name or ID of workspace that you wish to upload to Situational Required
package_id The name or ID of the submission that you wish to upload to Situational Required
resource_name The name that you want to give to your uploaded resource.Be sure to include file extension. Required
folder_id The ID of the folder on EDX Drive to place the uploaded resource in Optional
chunk Boolean (True, False) to send file to server in chunks Required
original_size Total size in bytes of file being transferred via API Required if using chunk

"SITUATIONAL" REQUIRED PARAMETERS ARE ONLY REQUIRED IN SPECIFIC USE CASES.

Situational Use Case Specifics:

  • workspace_id is required when you are uploading to an EDX Drive.
  • package_id is required when you are uploading to a private or draft submission.

NOTE: You do not have to provide a workspace_id AND package_id when adding a resource to a private submission, you only need the package_id but there is no harm in including both (as seen in example #2 below).

A package's name is the text that appears in the address bar, it is NOT the plain text title found in the body of the website. This also applies to workspace names.

For example (submission names):

useglobal-oil-gas-features-database.

Do NOT use Global Oil & Gas Features Database.

To Obtain a Folder ID:

Navigate to the workspace that contains the folder that you wish to upload to, right click the folder, select the "Get Folder ID" option from the menu, and select the "Copy ID to Clipboard" option from the modal pop-up window.

EXAMPLE #1: CHUNKED FILE UPLOAD (PYTHON 3.8)

In this example, we are uploading a large file to an existing workspace's private submission.

NOTE 1: The response object will return a parameter called "key"; this parameter is generated by server logic and must be sent after the first returned request. Server logic will require key data in order to determine which file to append additional file data.

NOTE 2: If you chunk size is larger than your file size, then the whole file will be uploaded in one request. It is highly recommended to upload large files in smaller chunks (e.g. 5 GB file - Chunked at chunk_size = 10000000 # 10 MB chunks). Returned output will provide the status of uploading file

import os
import requests

# Path to your file
path = '/home/user/edxprod-aug.zip'

headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'test-workspace',
    "package_id": 'test-submission',
    "resource_name": 'sql_backup.zip',
    "original_size": os.path.getsize(path), # Determine your file size. Server logic uses this to determine when a file is complete.
    "chunk": True # Set to True when sending file in chunks. Server logic uses this to know when to expect additional file data.
}

# Set chunk size. In bytes.
chunk_size = 10000000 # 10 MB chunks

if os.path.exists(path):
    with open(path, "rb") as f:
        url = 'https://edx.netl.doe.gov/api/3/action/resource_create_api'
        while True:
            chunked_stream = f.read(chunk_size)
            if not chunked_stream:
                break # Break out of loop and stop uploading when no more bytes to stream
            r = requests.post(
                url, # URL to API endpoint
                headers=headers, # Headers dictionary
                files={'file': chunked_stream}, # byte stream of chunked data
                data=data, # Dictionary of data params
            )
            r_json = r.json()
            print (r.json())
            # IMPORTANT!!! Add key parameter from response object to request data when chunking. 
            # Server logic will require key data in order to determine which file to append additional file data.  
            data['key'] = r_json['result']['key'] # ex. of response data: u'key': u'2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip'

            print (r.json()['result']['progress']) # Print out current progress of upload.
        print (r.json())

EXAMPLE #1 RETURNED OUTPUT

# An example of return data from the resource_create_api endpoint:
# {
#     u'help': u'https://edx.netl.doe.gov/api/3/action/help_show?name=resource_create_api',
#     u'success': True,
#     u'result': {
#         u'resource_name': u'sql_backup.zip',
#         u'created': u'2020-10-27T14:19:43.670115',
#         u'url': u'https://edx.netl.doe.gov/storage/f/edx/2020/10/2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip',
#         u'last_modified': u'2020-10-27T14:19:43.670131',
#         u'key': u'2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip',
#         u'progress': u'100%',
#         u'id': u'c9a8f82e-4bf0-4563-b931-d97b27a3f2a1'
#     }
# }

EXAMPLE #2: UPLOADING MULTIPLE FILES FROM A LOCAL DIRECTORY (PYTHON 3.8)

In this example, we are uploading a multiple files on a computer's file system to an existing workspace.

NOTE: The response object will return a parameter called "key"; this parameter is generated by server logic and must be sent after the first returned request. Server logic will require key data in order to determine which file to append additional file data.

import os
import requests

# Path to your directory.
path = '/home/user/Documents/project_001'

headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'test-workspace',
    "chunk": True # Set to true when sending file in chunks. Server logic uses this to know when to expect additional file data.
}

# Set chunk size. In bytes.
chunk_size = 10000000

# Set up a loop for each file in a given directory.
for filename in os.listdir(path):
    filepath = os.path.join(path, filename)
    if os.path.isdir(filepath): # Ignore sub directories of given file path, only focuses on files
        continue
    data['resource_name'] = filename 

    # WHEN CHUNKING SET THE ORIGINAL SIZE FOR EACH FILE IN A DIRECTORY DURING ITS ITERATION.
    data['original_size'] = os.path.getsize(filepath) # Determine your file's size. Server logic uses this to determine when a file is complete.

    if os.path.exists(filepath):
        with open(filepath, "rb") as f:
            url = 'https://edx.netl.doe.gov/api/3/action/resource_create_api'
            while True:
                chunked_stream = f.read(chunk_size)
                if not chunked_stream:
                    break # Break out of loop and stop uploading when no more bytes to stream
                r = requests.post(
                    url, # URL to API endpoint
                    headers=headers, # Headers dictionary
                    files={'file': chunked_stream}, # byte stream of chunked data
                    data=data, # Dictionary of data params
                )
                r_json = r.json()

                # Print out response data.
                print (r.json())

                # IMPORTANT!!! Add key parameter from response object to request data when chunking. 
                # Server logic will require key data in order to determine which file to append additional file data.  
                data['key'] = r_json['result']['key'] # ex. of response data: u'key': u'2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip'

                print (r.json()['result']['progress']) # Print out current progress of upload.
            # Print out final response.
            print (r.json())

EXAMPLE #2 RETURNED OUTPUT

# An example of return data from the resource_create_api endpoint:
# {
#     u'help': u'https://edx.netl.doe.gov/api/3/action/help_show?name=resource_create_api',
#     u'success': True,
#     u'result': {
#         u'resource_name': u'sql_backup.zip',
#         u'created': u'2020-10-27T14:19:43.670115',
#         u'url': u'https://edx.netl.doe.gov/storage/f/edx/2020/10/2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip',
#         u'last_modified': u'2020-10-27T14:19:43.670131',
#         u'key': u'2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/sql_backup.zip',
#         u'progress': u'100%',
#         u'id': u'c9a8f82e-4bf0-4563-b931-d97b27a3f2a1'
#     }
# }

UPDATE EXISTING RESOURCE FILE - MAKE REVISION (FILE AND/OR RESOURCE METADATA) [Private Workspace Only]

API Endpoint: resource_update_api

EDX resources have a revision history. An update to the resource's revision history can be a change in the resource's metadata and/or a new file upload that becomes the most recent file at the "top of the revision history stack".

NOTE: Due to EDX review workflow governance policies for approval of public submissions, this feature is only available to EDX workspaces (private side) at this time.

NOTE: HTML resource formats are NOT supported at this time. Uploaded File resources are the ONLY supported format at this time.

NOTE: An API Key is required for ALL private workspace activities.

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

UPDATING REVISION SCENARIOS:

  1. Upload file to resource to become latest revision
  2. Update resource metadata
  3. Upload file to become latest revision and update resource metadata

RESOURCE REVISION UPDATE CLARIFICATIONS:

  • HTML Link Resources - Attempting to upload a file to an existing HTML link resource will result in the API returning a message noting that this action is not allowed.
  • Only Updating Metadata - When only updating resource metadata, you do NOT need to specify a file path or resource_name.
  • Only Updating File - When only updating resource file, you ONLY need to specify a file path, resource_id, and resource_name.

EDX LICENSE PARAMETERS (used when specifying license type):

NOTE: You may use either the exact License Value Name or the exact Description text when defining license in your data dictionary

License Value Name Description
bsd3 BSD-3 Clause
cc-by Creative Commons Attribution
cc-by-sa Creative Commons Attribution Share-Alike
cc-zero Creative Commons CCZero
cc-nc Creative Commons Non-Commercial (Any)
gfdl GNU Free Documentation License
notspecified License Not Specified
non-disclosure-agreement Non-Disclosure Agreement
odc-by Open Data Commons Attribution License
odc-odbl Open Data Commons Open Database License (ODbL)
odc-pddl Open Data Commons Public Domain Dedication and License (PDDL)
other-at Other (Attribution)
other-nc Other (Non-Commercial)
other-closed Other (Not Open)
other-open Other (Open)
other-pd Other (Public Domain)
prop-comm Proprietary (Commercial)
uk-ogl UK Open Government Licence (OGL)
ouo Official Use Only

PARAMETER DEFINITIONS:

Parameter Name Description Required Field
resource_id The ID of resource that you wish to revise Required
resource_name The name that you want to give to your uploaded resource. Be sure to include file extension. Required
description The description of the resource you are revising Optional
name The human readable name of the resource if you wish to not use resource's file name by default Optional
license_type License type for resource (must use EDX license types [see license table]) Optional
chunk Boolean (True, False) to send file to server in chunks Optional
original_size Total size in bytes of file being transferred via API Required if using chunk

EXAMPLE #1: RESOURCE REVISION [FILE ONLY] (PYTHON 3.8)

import os
import requests

headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

# Path to your file
path = '/home/user/test.png'

data = {
    "resource_id": '99f513c5-e309-4e15-8db2-b1a37395c3be',
    "resource_name": 'test.png',
}

if os.path.exists(path):
    with open(path, "rb") as f:
        url = 'https://edx.netl.doe.gov/api/3/action/resource_update_api'

        r = requests.post(
            url, # URL to API endpoint
            headers=headers, # Headers dictionary
            files={'file': f},  # byte stream of chunked data
            data=data, # Dictionary of data params
        )

        print (r.json())

else:
    print('The path does not exist.')

EXAMPLE #1 RETURNED OUTPUT

{
  'help': 'http://edx.netl.doe.gov/api/3/action/help_show?name=resource_update_api',
  'success': True,
  'result': {
    'id': '808460cf-70e1-4f92-8ec8-d60015c34738',
    'package_id': '584a1890-3970-442f-9a96-dea794fff0f1',
    'revision_id': '02545e0d-f610-4dab-a514-ce259eb586de',
    'url': 'http://edx.netl.doe.gov/storage/f/edx/2021/04/2021-04-15T12:34:45.357Z/a532d9aa-a79b-4ce1-80e6-efd81cce0797/dog.jpeg',
    'format': 'jpeg',
    'description': '',
    'hash': 'md5:af29aa85e824dccd18494283b15b350d',
    'position': 0,
    'name': 'dog.jpeg',
    'resource_type': 'file.upload',
    'mimetype': 'image/jpeg',
    'mimetype_inner': None,
    'size': 6567,
    'created': '2021-04-15T12:34:45.453196',
    'last_modified': '2021-04-15T12:34:45.453203',
    'cache_url': 'storage/f/edx/2021/04/2021-04-15T16:34:17.153Z/808460cf-70e1-4f92-8ec8-d60015c34738/chameleon.jpeg',
    'cache_last_updated': None,
    'url_type': 'upload',
    'state': 'active',
    'license_type': 'notspecified',
    'folder_id': 'root',
    'owner_org': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'recycle_removed': False,
    'rating': None,
    'key': '2021-04-15T12:34:45.357Z/a532d9aa-a79b-4ce1-80e6-efd81cce0797/dog.jpeg',
    'owner': 'catherinehines',
    'cache_url_updated': '2021-04-15T12:34:17.251',
    'datastore_active': False,
    'group': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'keys': [
      'package_id',
      'package_name'
    ],
    'progress': '100%'
  }
}

EXAMPLE #2: RESOURCE REVISION [METADATA ONLY] (PYTHON 3.8)

import requests

headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "resource_id": '99f513c5-e309-4e15-8db2-b1a37395c3be', 
    "description": 'This is the description of the resource.', 
    "name": 'Final Report Document from John Smith',
    "license_type": 'Creative Commons CCZero', 
}


url = 'https://edx.netl.doe.gov/api/3/action/resource_update_api'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)

print (r.json())

EXAMPLE #2 RETURNED OUTPUT

{
  'help': 'http://edx.netl.doe.gov/api/3/action/help_show?name=resource_update_api',
  'success': True,
  'result': {
    'id': '808460cf-70e1-4f92-8ec8-d60015c34738',
    'package_id': '584a1890-3970-442f-9a96-dea794fff0f1',
    'revision_id': '0369453b-3866-4cb9-a268-1eb59cfd695b',
    'url': 'http://edx.netl.doe.gov/storage/f/edx/2021/04/2021-04-15T12:34:45.357Z/a532d9aa-a79b-4ce1-80e6-efd81cce0797/dog.jpeg',
    'format': 'jpeg',
    'description': 'This is the description of the resource.',
    'hash': 'md5:af29aa85e824dccd18494283b15b350d',
    'position': 0,
    'name': 'Final Report Document from John Smith',
    'resource_type': 'file.upload',
    'mimetype': 'image/jpeg',
    'mimetype_inner': None,
    'size': 6567,
    'created': '2021-04-15T12:34:45.453196',
    'last_modified': '2021-04-15T12:34:45.453203',
    'cache_url': 'storage/f/edx/2021/04/2021-04-15T16:34:17.153Z/808460cf-70e1-4f92-8ec8-d60015c34738/chameleon.jpeg',
    'cache_last_updated': None,
    'url_type': 'upload',
    'state': 'active',
    'license_type': 'cc-zero',
    'folder_id': 'root',
    'owner_org': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'recycle_removed': False,
    'rating': None,
    'key': '2021-04-15T12:34:45.357Z/a532d9aa-a79b-4ce1-80e6-efd81cce0797/dog.jpeg',
    'owner': 'catherinehines',
    'cache_url_updated': '2021-04-15T12:34:17.251',
    'datastore_active': False,
    'group': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'progress': '100%'
  }
}

EXAMPLE #3: RESOURCE REVISION [FILE UPLOAD & METADATA UPDATE] (PYTHON 3.8)

import os
import requests

headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'
}

# Path to your file
path = '/home/user/test.png'

data = {
    "resource_id": '99f513c5-e309-4e15-8db2-b1a37395c3be',
    "description": 'This is the description of the resource.',
    "resource_name": 'test.png',
    "name": 'resource name',
    "license_type": 'cc-by',
    "chunk": True, # Set to True when sending file in chunks. Server logic uses this to know when to expect additional file data.
    "original_size": os.path.getsize(path), # Determine your file size. Server logic uses this to determine when a file is complete.
}

# Set chunk size. In bytes.
chunk_size = 10000000 # 10 MB chunks

if os.path.exists(path):
    with open(path, "rb") as f:
        url = 'https://edx.netl.doe.gov/api/3/action/resource_update_api'
        while True:
            chunked_stream = f.read(chunk_size)
            if not chunked_stream:
                break # Break out of loop and stop uploading when no more bytes to stream
            r = requests.post(
                url, # URL to API endpoint
                headers=headers, # Headers dictionary
                files={'file': chunked_stream}, # byte stream of chunked data
                data=data, # Dictionary of data params
            )

            r_json = r.json()

            print (r.json())
            # IMPORTANT!!! Add key parameter from response object to request data when chunking.    
            # Server logic will require key data in order to determine which file to append additional file data.  
            data['key'] = r_json['result']['key'] # ex. of response data: u'key': u'2020-10-27T14:18:29.946Z/c9a8f82e-4bf0-4563-b931-d97b27a3f2a1/test.png'

            print (r.json()['result']['progress']) # Print out current progress of upload.
        print(r.json())
else:
    print('The path does not exist.')

EXAMPLE #3 RETURNED OUTPUT

{
  'help': 'http://edx.netl.doe.gov/api/3/action/help_show?name=resource_update_api',
  'success': True,
  'result': {
    'id': '808460cf-70e1-4f92-8ec8-d60015c34738',
    'package_id': '584a1890-3970-442f-9a96-dea794fff0f1',
    'revision_id': '24a4b5c6-cb54-4c95-a9a0-ae65bae0977d',
    'url': 'http://edx.netl.doe.gov/storage/f/edx/2021/04/2021-04-15T12:47:05.113Z/a4b05534-334b-451a-bc20-fa70f5406539/test.png',
    'format': 'png',
    'description': 'This is the description of the resource.',
    'hash': 'md5:af29aa85e824dccd18494283b15b350d',
    'position': 0,
    'name': 'resource name',
    'resource_type': 'file.upload',
    'mimetype': 'image/jpeg',
    'mimetype_inner': None,
    'size': 6567,
    'created': '2021-04-15T12:47:15.193340',
    'last_modified': '2021-04-15T12:47:15.193347',
    'cache_url': 'storage/f/edx/2021/04/2021-04-15T16:34:17.153Z/808460cf-70e1-4f92-8ec8-d60015c34738/chameleon.jpeg',
    'cache_last_updated': None,
    'url_type': 'upload',
    'state': 'active',
    'license_type': 'cc-by',
    'folder_id': 'root',
    'owner_org': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'recycle_removed': False,
    'rating': None,
    'key': '2021-04-15T12:47:05.113Z/a4b05534-334b-451a-bc20-fa70f5406539/test.png',
    'owner': 'catherinehines',
    'cache_url_updated': '2021-04-15T12:34:17.251',
    'datastore_active': False,
    'group': '2bcc2e6c-8830-4c52-9f77-dca017947723',
    'keys': [
      'package_id',
      'package_name'
    ],
    'progress': '100%'
  }
}

CREATE FOLDER ON EDX DRIVE

API Endpoint: create_folder

NOTE: An API Key is required for ALL private workspace activities.

NOTE: The API Key name component can be added to your header using any of the following ways, "X-CKAN-API-Key", "EDX-API-Key", or "Authorization".

NOTE: If you wish to create folder at the root level of the EDX drive, then use the value root for parent_id

Parameter Definitions:

Parameter Name Description Required Field
workspace_id The ID of workspace that you wish to add folder to Required
folder_name The name that you want to give to your folder. Required
parent_id The ID of the parent folder where new folder will live. Optional (if omitted, created folder will exist on root level)
import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'YOUR-WORKSPACE-NAME-OR-ID-HERE',
    "folder_name": 'Test Folder 123',
    "parent_id": 'ID-OF-DESTINATION-FOLDER-HERE'
}

url = 'https://edx.netl.doe.gov/api/3/action/create_folder'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)
print (r.json())
print("End results")

CREATE EXAMPLE RETURNED OUTPUT

{
    'help': 'https://edx.netl.doe.gov/api/3/action/help_show?name=create_folder', 
    'success': True, 
    'result': {
        'folder_id': 'FOLDER-ID-HERE', 
        'name': 'API Test 07-20-2020', 
        'parent_id': 'PARENT-ID-HERE', 
        'workspace_id': 'WORKSPACE-ID-HERE', 
        'workspace_name': 'demo-workspace-test'
    }
}

EXAMPLE 1: MOVE SINGLE ITEM (FOLDER OR RESOURCE) ON EDX DRIVE

API Endpoint: move_folder

NOTE: An API Key is required for ALL private workspace activities.

NOTE: If you wish to move items (resource or folder) to the root level of the EDX drive, then use the value root for parent_id

import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'YOUR-WORKSPACE-NAME-OR-ID-HERE',
    "new_parent_id": 'ID-OF-DESTINATION-FOLDER-HERE',
    "item_id": 'ID-OF-FOLDER-OR-RESOURCE-HERE'
}

url = 'https://edx.netl.doe.gov/api/3/action/move_folder'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)
print (r.json())
print("End results")

EXAMPLE #1: MOVE SINGLE ITEM - RETURNED OUTPUT

NOTE: In the event that a resource is not found an item will be added to the returned output named "items_not_moved".

{
    'help': 'https://edx.netl.doe.gov/api/3/action/help_show?name=move_folder',
    'success': True, 
    'result': {
        'folder_id': 'FOLDER-ID-HERE', 
        'workspace_id': 'WORKSPACE-ID-HERE',
        'workspace_name': 'demo-workspace-test'
        'items_moved': [moved_items]
    }
}

EXAMPLE #2: MOVE MULTIPLE ITEMS (FOLDERS and/or RESOURCES)

API Endpoint: move_folder

NOTE: An API Key is required for ALL private workspace activities.

NOTE: If you wish to move items (resource or folder) to the root level of the EDX drive, then use the value root for parent_id

import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'YOUR-WORKSPACE-NAME-OR-ID-HERE',
    "new_parent_id": 'ID-OF-DESTINATION-FOLDER-HERE',
    "item_id": 'ID-OF-FOLDER-OR-RESOURCE-HERE'
}

url = 'https://edx.netl.doe.gov/api/3/action/move_folder'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)

print (r.json())
print("End results")

EXAMPLE #2: MOVE MULTIPLE ITEMS - RETURNED OUTPUT

NOTE: In the event that a resource is not found an item will be added to the returned output named "items_not_moved".

{
    'help': 'https://edx.netl.doe.gov/api/3/action/help_show?name=move_folder',
    'success': True, 
    'result': {
        'folder_id': 'FOLDER-ID-HERE', 
        'workspace_id': 'WORKSPACE-ID-HERE',
        'workspace_name': 'demo-workspace-test',
        'items_moved': [moved_items]
    }
}

EDIT FOLDER ON EDX DRIVE

API Endpoint: edit_folder

NOTE: An API Key is required for ALL private workspace activities.

import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'YOUR-WORKSPACE-NAME-OR-ID-HERE',
    "folder_id": 'YOUR-FOLDER-ID-HERE',
    "new_folder_name": 'My New Name For My Folder'
}

url = 'https://edx.netl.doe.gov/api/3/action/edit_folder'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)
print (r.json())
print("End results")

EXAMPLE RETURNED OUTPUT

{
    'help': 'https://edx.netl.doe.gov/api/3/action/help_show?name=edit_folder', 
    'success': True, 
    'result': {
        'workspace_id': 'WORKSPACE-ID-HERE', 
        'folder_id': 'FOLDER-ID-HERE', 
        'name': 'API Test Update 07-20-2020'
    }
}

DELETE FOLDER ON EDX DRIVE

API Endpoint: delete_folder

NOTE: An API Key is required for ALL private workspace activities.

import requests
headers = {
    "EDX-API-Key": 'YOUR-API-KEY-HERE'   
}

data = {
    "workspace_id": 'YOUR-WORKSPACE-NAME-OR-ID-HERE',
    "folder_id": 'YOUR-FOLDER-ID-HERE'
}

url = 'https://edx.netl.doe.gov/api/3/action/delete_folder'

r = requests.post(
    url, # URL to API endpoint
    headers=headers, # Headers dictionary
    data=data, # Dictionary of data params
)
print (r.json())
print("End results")

EXAMPLE RETURNED OUTPUT

{
    'help': 'https://edx.netl.doe.gov/api/3/action/help_show?name=delete_folder', 
    'success': True, 
    'result': {
        'folder_id': 'FOLDER-ID-HERE', 
        'workspace_id': 'WORKSPACE-ID-HERE', 
        'workspace_name': 'demo-workspace-test'
    }
}