Uploading files through API with Python gives HTTP 500

314 views
Skip to first unread message

Jacob Aleksandrovich

unread,
Nov 25, 2021, 10:53:47 AM11/25/21
to ResourceSpace
Hi all,

I am trying to upload files into ResourceSpace through Python. I am able to create a resource (create_resource), I can update simple metadata like the title (update_field), I can query my resource (get_resource_field_data), but I am not able to upload a file.

I have tried both 'upload_file' and 'upload_file_by_url' but both give me a HTTP 500 error.

I am running ResourceSpace SVN 9.5, in a docker container, for testing purposes. Any help would be more than welcome.

Thanks,
Jacob

Jacob Aleksandrovich

unread,
Nov 25, 2021, 11:03:13 AM11/25/21
to ResourceSpace
Just looking in the Apache log, I can see the following error:

[Thu Nov 25 16:00:24.447072 2021] [php7:error] [pid 16] [client 172.23.0.1:55172] PHP Fatal error:  Uncaught ReflectionException: Internal error: Failed to retrieve the default value in /var/www/html/include/api_functions.php:111\nStack trace:\n#0 /var/www/html/include/api_functions.php(111): ReflectionParameter->getDefaultValue()\n#1 /var/www/html/api/index.php(73): execute_api_call()\n#2 {main}\n  thrown in /var/www/html/include/api_functions.php on line 111

I think I'll just try upgrading to the latest...

Jacob Aleksandrovich

unread,
Nov 25, 2021, 11:51:03 AM11/25/21
to ResourceSpace
All right, now running on SVN /releases/9.7 9.7 r18742.
First, it kept throwing me a status 500. BUT, after I enabled php-apcu (supposedly for better file uploads), I made some strides, and I'm now thrown an HTTP Status 401. We're making progress...

Jacob Aleksandrovich

unread,
Nov 25, 2021, 1:42:39 PM11/25/21
to ResourceSpace
401 was caused by invalid API key (due to full restart of docker container). So, back to square one: Status 500! Apache log still shows the same 'Reflection' error. Anybody?

David Janzen

unread,
Nov 25, 2021, 7:28:03 PM11/25/21
to ResourceSpace
Do you want to post your Python script, and I'll try to recreate the problem on my SVN 9.7 and 9.4 instances?

I'm also having problems with my Python "create_resource" script (on SVN 9.5+); although I think I'm one step behind you, as I'm still getting 401/Invalid Signature errors.

I have a working script that uses "create_resource" to upload files to an SVN 9.4 instance; although it's pulling the files from a path on the same box.

reidb...@gmail.com

unread,
Nov 27, 2021, 10:51:53 AM11/27/21
to ResourceSpace
Do you have the patch from RS 18716 applied? This is in the trunk branch, not the 9.7 release branch. That patch fixes issues with create_resource API calls in 9.7.

Jacob Aleksandrovich

unread,
Nov 29, 2021, 5:12:58 AM11/29/21
to ResourceSpace
Hi all,

thanks for your replies thus far.

@David, I am actually working on a PythonResourcespace API and aiming to put it on Github and into pypi. Currently, it's in a very basic and unstable state, but I hope to be able to at least update it onto github today or tomorrow, with a couple of examples how it should work. Stay tuned!

About my specific problem: I 'forgot' that I could actually upload a picture from a URL using the 'create_resource' function.. So, I just did that today, and: IT WORKS! The file gets uploaded and attached to my resource.
The problem that I am still encountering is that I cannot attach an image afterwards. Both 'upload_file' and 'upload_file_by_url' will return an HTTP 500 error.

@reidb, I would say that I probably have that patch included, as 9.7 is on r18742 and since I am able to upload a resourcefile with 'create_resource'.

Fred

unread,
Dec 3, 2021, 2:05:07 PM12/3/21
to ResourceSpace
Hi Jakobalek

Great idea. A plugin would be great!

Is it progressing!? Meanwhile, would u mind to share your script?

David Janzen

unread,
Dec 3, 2021, 11:34:06 PM12/3/21
to ResourceSpace
I'll share this slightly dated create_resource script (currently setup for audio files) if it helps anyone, in the interim, until Jakob is able to publish his version.

It works with ResourceSpace 9.4, but gets HTTP 401 errors in 9.5+ (likely because the API started to require an 'authmode' parameter).

If anyone has any suggestions on how to format and pass the authmode='userkey' parameter (in the 'query_url' variable), I'll test it with 9.7 and publish an updated version of the script.


import hashlib
import urllib.request
import urllib.response

metadata_date = "2021/12/03"                            # Sample metadata (date field) to be created for the new resource
metadata_description = "Test description"               # Sample metadata (description field) to be created for the new resource
metadata_media_url = "/home/ubuntu/testfile.mp3"        # Local path for the media file to be uploaded to the new resource

rs_user = "insert your username"
rs_private_key = "insert your user's private key"
rs_site_ip = "yourservername.domain.com"

def upload_files_to_rs(metadata_date, metadata_description, metadata_media_url, rs_user, rs_private_key, rs_site_ip):
    try:
        # Formats JSON text for query; uses the ResourceSpace system reference numbers for each metadata field
        url_json_text = '{"12":"' + metadata_date + '","8":"' + metadata_description + '"}'
        # Encodes string as a URL
        url_json_text = urllib.parse.quote(url_json_text, safe='')
        # Builds list of parameters to pass in query
        meta1 = "4"                                                 # File type 1=photo, 4=audio, etc.
        meta2 = "0"                                                 # Resource active and avaiable to users = 0
        meta3 = metadata_media_url                                  # Path where ResourceSpace can find the media file to upload
        meta4 = ""                                                  # See $no_exif in ResourceSpace API docs
        meta5 = ""                                                  # Not used
        meta6 = ""                                                  # See $autorotate in ResourceSpace API docs
        meta7 = url_json_text                                       # Formatted JSON text for resource metadata
        parameters = "param1=%s&param2=%s&param3=%s&param4=%s&param5=%s&param6=%s&param7=%s" % (meta1, meta2, meta3, meta4, meta5, meta6, meta7)
        # Sends create_resource request to ResourceSpace API     
        resource_id = query(rs_user, "create_resource", parameters, rs_private_key, rs_site_ip)
        return resource_id
    except:
        print('Error')

def query(rs_user, function_to_query, parameters, rs_private_key, rs_site_ip):
    # Formats, signs, and sends query for ResourceSpace API request
    query = "user=%s&function=%s&%s" % (rs_user, function_to_query, parameters)
    sign = hashlib.sha256(rs_private_key.encode('utf-8')+query.encode('utf-8')).hexdigest()
    query_url = "https://%s/api/index.php?%s&sign=%s" % (rs_site_ip, query, sign)
    try:
        result = urllib.request.urlopen(query_url).read()
        return result
    except:
        print('Error')

if __name__=="__main__":
    status = upload_files_to_rs(metadata_date, metadata_description, metadata_media_url, rs_user, rs_private_key, rs_site_ip)
    # If create_resource API call successful, prints new resource ID; otherwise, prints 'false' if resource could not be created
    print('Result: {}'.format(status))

Adam

unread,
May 4, 2022, 6:15:33 PM5/4/22
to ResourceSpace

I just ran into this issue.  Was uploading using the param names.  according to the docs, param1 should be called "resource", but if you enable debugging, the code is looking for a param called "ref".  changing the param name from "resource" to "ref" fixed it for me.  Should probably be updated in the upload_file documentation
Reply all
Reply to author
Forward
0 new messages