Dspace 5.5 API 在脚本中使用 Python 3 个请求时响应 500,在浏览器和 Python 控制台中测试时 returns 200

Dspace 5.5 API response 500 when using Python 3 requests in script, returns 200 when testing in browser and Python Console

我正在尝试向 DSpace 5.5 发送获取请求 API 以检查 DSpace 中是否存在具有给定句柄的项目。

当我在浏览器中测试它时,它工作正常(return 代码 200,我有关于搜索项目的数据)。

然后我开始在 Python 控制台中使用 Python 3 个请求模块测试发送请求。同样,DSpace API return 在响应中编辑了正确的响应代码 (200) 和 json 数据。

所以,我在我的脚本中实现了经过测试的功能,突然 DSpace API 开始出现 return 错误代码 500。在 DSpace 日志中,我遇到了这个错误消息:

org.dspace.rest.RestIndex @ REST Login Success for user: jakub.rihak@ruk.cuni.cz
2017-01-03 15:38:34,326 ERROR org.dspace.rest.Resource @ Something get wrong. Aborting context in finally statement.
2017-01-03 15:38:34,474 ERROR org.dspace.rest.Resource @ Something get wrong. Aborting context in finally statement.

2017-01-03 15:38:34,598 ERROR org.dspace.rest.Resource @ 出错了。终止 finally 语句中的上下文。

根据 DSpace 文档,请求应该是这样的:

GET /handle/{handle-prefix}/{handle-suffix}

它指向处理我们 DSpace 服务器上的 API 端点,因此整个请求应该发送到 https://dspace.cuni.cz/rest/handle/123456789/937(我想你可以自己测试)。

在浏览器中我得到以下响应:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <item>
  <expand>metadata</expand
  <expand>parentCollection</expand>
  <expand>parentCollectionList</expand>
  <expand>parentCommunityList</expand>
  <expand>bitstreams</expand>
  <expand>all</expand>
  <handle>123456789/937</handle>
  <id>1423</id>
  <name>Komparace vývoje české a slovenské pravicové politiky od roku 1989 do současnosti</name>
  <type>item</type>
  <archived>true</archived>
  <lastModified>2016-12-20 17:52:30.641</lastModified
  <withdrawn>false</withdrawn>
 </item>

在 Python 控制台中测试时,我的代码如下所示:

from urllib.parse import urljoin
import requests

def document_in_dspace(handle):
    url = 'https://dspace.cuni.cz/rest/handle/'
    r_url = urljoin(url, handle)
    print(r_url)
    r = requests.get(r_url)

    if r.status_code == requests.codes.ok:
        print(r.text)
        print(r.reason)
        return True
    else:
        print(r.reason)
        print(r.text)
        return False

在 Python 控制台中使用 document_in_dspace('123456789/937') 调用此函数后,响应是这样的:

https://dspace.cuni.cz/rest/handle/123456789/937
{"id":1423,"name":"Komparace vývoje české a slovenské pravicové politiky od roku 1989 do současnosti","handle":"123456789/937","type":"item","link":"/rest/items/1423","expand":["metadata","parentCollection","parentCollectionList","parentCommunityList","bitstreams","all"],"lastModified":"2016-12-20 17:52:30.641","parentCollection":null,"parentCollectionList":null,"parentCommunityList":null,"bitstreams":null,"archived":"true","withdrawn":"false"}
OK
True

所以我决定在我的脚本中实现这个函数(没有任何更改),但是现在 DSpace API returns 响应代码 500 调用函数时。

实施细节如下:

def get_workflow_process(document):
    if document.document_in_dspace(handle=document.handle) is True:
        return 'delete'
    else:
        return None

wf_process = get_workflow_process(document)
    log.msg("Document:", document.doc_id, "Workflow process:", wf_process)

输出为:

2017-01-04 11:08:45+0100 [-] DSPACE API response code: 500
2017-01-04 11:08:45+0100 [-] Internal Server Error
2017-01-04 11:08:45+0100 [-] 
2017-01-04 11:08:45+0100 [-] False
2017-01-04 11:08:45+0100 [-] Document: 28243 Workflow process: None

能否请您向我提供任何可能导致此问题的建议以及如何解决此问题?我很惊讶这在 Python 控制台中有效,但在实际脚本中却无效,而且我自己似乎无法弄清楚。谢谢!

我想我明白了。问题可能出在 document_in_dspace 函数的 handle 参数中的一些尾随换行符。更新后的函数如下所示:

def document_in_dspace(handle):
    url = 'https://dspace.cuni.cz/rest/handle/' # TODO: Move to config

    hdl = handle.rstrip()
    prefix, suffix = str(hdl).split(sep='/')

    r_url = url + prefix + '/' + suffix
    log.msg("DSpace API request url is:", r_url)

    r = requests.get(r_url, timeout=1)

    if r.status_code == requests.codes.ok:
        log.msg("DSPACE API response code:", r.status_code)
        log.msg("Document with handle", handle, "found in DSpace!")
        log.msg("Document handle:", handle)
        log.msg("Request:\n", r.request.headers)
        log.msg("\n")
        log.msg(r.reason)
        return True
    else:
        log.msg("DSPACE API response code:", r.status_code)
        log.msg("Document with handle", handle, "not found in DSpace!")
        log.msg("Document handle:", handle)
        log.msg("Request:\n", r.request.headers)
        log.msg("\n")
        log.msg(r.reason)
        return False

基本上,我所做的是在句柄字符串上调用 .rstrip() 以去除所有不需要的尾随字符,然后我将句柄的 prefixsuffix 部分分开(只是为了确定)并通过将所有部分连接在一起来构造请求 url (r_url)。

以后我会让这个功能更漂亮,但至少现在可以按预期工作了。

输出如下:

2017-01-04 15:06:16+0100 [-] Checking if document with handle 123456789/937
 is in DSpace...
2017-01-04 15:06:16+0100 [-] DSpace API request url is: https://dspace.cuni.cz/rest/handle/123456789/937
2017-01-04 15:06:16+0100 [-] DSPACE API response code: 200
2017-01-04 15:06:16+0100 [-] Document with handle 123456789/937
 found in DSpace!
2017-01-04 15:06:16+0100 [-] Document handle: 123456789/937

2017-01-04 15:06:16+0100 [-] Request:
 {'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'python-requests/2.11.1', 'Connection': 'keep-alive', 'Accept': '*/*'}
2017-01-04 15:06:16+0100 [-] 
2017-01-04 15:06:16+0100 [-] OK

然而,当存储库中不存在具有给定句柄的项目时,DSpace API 似乎 return 响应代码 500,而不是响应代码 404。