pythonrestweb-servicesmoodle-api

Duplicating courses in Moodle by using REST webservice with Python


I'm really struggling to get my code for duplicating moodle courses via REST to work, just couldn't figure out the reason:

import requests
import json

token = 'mytoken123'
domainname = 'https://example.com'

functionname = 'core_course_duplicate_course'

# Course ID of the course to be duplicated
courseid = 61  # Replace with your course ID

# New course details
newcoursedata = {
    'fullname': 'New Course Full Name',
    'shortname': 'NewCourseShortName',
    'categoryid': 10,
    'visible': 1,
}

restformat = 'json'  # Also possible to use 'xml'

data = {
    'courseid': courseid,
    'options': newcoursedata,
}

headers = {
    'Content-Type': 'application/json',
}

# REST CALL
serverurl = f'{domainname}/webservice/rest/server.php?wstoken={token}&wsfunction={functionname}&moodlewsrestformat={restformat}'
response = requests.post(serverurl, headers=headers, data=json.dumps(data))

# Print response
print(json.dumps(response.json(), indent=4))

The error message is:

{
    "exception": "invalid_parameter_exception",
    "errorcode": "invalidparameter",
    "message": "invalid parameter value (Missing required key in single structure: courseid)",
    "debuginfo": "Missing required key in single structure: courseid"
}

What I'm missing here? Any help much appreciated!


Solution

  • It was due to the format of the options data array. This code works:

    import requests
    from urllib.parse import urlencode
    
    api = 'https://example.com/webservice/rest/server.php'
    courseid = 61
    categoryid = 10
    token = '1234567890'
    
    fullname = 'New Course Full Name'
    shortname = 'NewCourseShortName'
    
    params = {
        'wstoken': token,
        'wsfunction': 'core_course_duplicate_course',
        'courseid': courseid,
        'fullname': fullname,
        'shortname': shortname,
        'categoryid': categoryid,
        'options[0][name]': 'users',
        'options[0][value]': '0',
        'moodlewsrestformat': 'json'
    }
    
    # Encode the parameters
    encoded_params = urlencode(params)
    
    # Construct the URL
    url = f"{api}?{encoded_params}"
    
    # REST CALL
    response = requests.post(url)
    
    # Print response
    print(response.json())