Search code examples
python-3.xpython-requestsredmineredmine-api

Redmine API claims missing 'hours' field and returns 422 on POST to time_entry.json


I am trying to create time entries in a Redmine 3.3.0.stable installation via the REST API, using the Requests library in the client software. I am using the following code:

    urlSuffix='/time_entries.json'

    time_entry = {
        'hours':       0.25,
        'project_id':  1,
        'comments':    'test',
        'activity_id': 1,
    }

    params = {
        'key': session.APIKey,
    }

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

    requestURL = "%s%s" % (session.redmineBaseUrl, urlSuffix)
    response = requests.post(requestURL, json=time_entry, params=params)

response.status_code is always 422, and the response contains the following localized message:

{"errors":["Stunden muss ausgefüllt werden"]}

which translates to

hours must be provided

However, the field 'hours' was given correctly, as you can see. Furthermore, the log file indicates that the parameter reaches Redmine correctly:

Started POST "/PROJECTNAMEHERE/time_entries.json?key=APIKEYHERE" for 62.178.175.81 at 2016-11-15 00:19:47 +0100
Processing by TimelogController#create as JSON
  Parameters: {"project_id"=>"1", "spent_on"=>"2016-11-15T00:19:24.513001", "comments"=>"lkj", "activity_id"=>"1", "hours"=>0.25, "key"=>"a009fdb7d15f174b31860cfa9d56fd648737d862"}
  Current user: MichaelJaros (id=5)
  Rendered common/error_messages.api.rsb (0.2ms)
Completed 422 Unprocessable Entity in 22ms (Views: 0.7ms | ActiveRecord: 5.1ms)

I have tried with the same outcome:

  • all combinations of localized decimal point (, instead of .)
  • passing the hours as an integer, float or string
  • switching to XML as suggested by this similar issue found in the Redmine boards (this makes Redmine complain about missing and invalid project id as well)
  • using the data= parameter instead of json= in the post() method (this makes the hours value a string like "1.0" instead of 1.0 in the log file)

My last resort would be trying one of the Python Redmine libraries, but I can't see what they should do different in this case.

  • Am I doing anything wrong?
  • What exactly do they mean by:

time_entry (required): a hash of the time entry attributes, including: [...]

in the time entries documentation? When the request is in XML format, I would expect the API to require XML data for the time_entry as well, not "a hash". But maybe that part was just written inaccurately?


Solution

  • I did a pip install python-redmine and the following code works perfectly:

    from redmine import Redmine
    redmine = Redmine (redmineBaseUrl, version='3.3.0', key=APIKey)
    [...]
    redmine.time_entry.create(project_id=self.projectId, activity_id=self.activityId, hours=self.getHoursRounded(), spent_on=self.startDateTime.date(), comments=self.comment)
    

    I should have done it this way before messing around with this for hours yesterday.