python-redmine(1)

PYTHON-REDMINE(1) Python-Redmine PYTHON-REDMINE(1)

NAME

python-redmine - Python-Redmine

Python-Redmine is a library for communicating with a Redmine project management application. Redmine exposes some data via REST API for which Python-Redmine provides a simple but powerful Pythonic API inspired by a well-known Django ORM:

>>> from redminelib import Redmine
>>> redmine = Redmine('http://demo.redmine.org', username='foo', password='bar')
>>> project = redmine.project.get('vacation')
>>> project.id
30404
>>> project.identifier
'vacation'
>>> project.created_on
datetime.datetime(2013, 12, 31, 13, 27, 47)
>>> project.issues
<redminelib.resultsets.ResourceSet object with Issue resources>
>>> project.issues[0]
<redminelib.resources.Issue #34441 "Vacation">
>>> dir(project.issues[0])
['assigned_to', 'author', 'created_on', 'description', 'done_ratio',
'due_date', 'estimated_hours', 'id', 'priority', 'project', 'relations',
'start_date', 'status', 'subject', 'time_entries', 'tracker', 'updated_on']
>>> project.issues[0].subject
'Vacation'
>>> project.issues[0].time_entries
<redminelib.resultsets.ResourceSet object with TimeEntry resources>


FEATURES

  • Supports 100% of Redmine API
  • Supports external Redmine plugins API
  • Supports Python 3.7 - 3.12 and PyPy3
  • Supports different request engines
  • Extendable via custom resources and custom request engines
  • Extensively documented
  • Provides ORM-style Pythonic API
  • And many more…

CONTACTS AND SUPPORT

Support for Standard Edition is provided via GitHub only, while support for Pro Edition is provided both via GitHub and support@python-redmine.com. Be sure to write from email that was specified during the purchase procedure.

COPYRIGHT AND LICENSE

Python-Redmine Standard Edition is licensed under Apache 2.0 license. Python-Redmine Pro Edition is licensed under the Python-Redmine Pro Edition 1.0 license. Check the License for details.

TABLE OF CONTENTS

Editions

Standard Edition

Absolutely free, distributed via PyPI and supports all vanilla Redmine features. Licensed under Apache 2.0 license. Check the License for details.

Pro Edition

Supports additional features like async requests to Redmine, additional Redmine plugins and so on. Licensed under Python-Redmine Pro Edition License Version 1.0. License can be bought here for 24.99$ (additional taxes and/or charges may apply (will be shown before the purchase) depending on the country of purchase and payment method used), doesn’t expire and is valid for the current major Python-Redmine version, e.g. if at the time of purchase current Python-Redmine version is 2.0.1 then license will be valid for all 2.x.x versions. Below you can find a feature matrix which shows all the differences between these editions:

Installation

Dependencies

Python-Redmine relies heavily on great Requests library by Kenneth Reitz for all the http(s) calls.

Standard Edition

PyPI

The recommended way to install is from Python Package Index (PyPI) with pip:

$ pip install python-redmine


GitHub

Python-Redmine is actively developed on GitHub. If you want to get latest development sources you have to clone the repository:

$ git clone git://github.com/maxtepkeev/python-redmine.git


Once you have the sources, you can install it into your site-packages:

$ python setup.py install


You can also install latest stable development version via pip:

$ pip install git+https://github.com/maxtepkeev/python-redmine.git@master


Pro Edition

License for a Pro Edition can be bought here. You will receive an email with all the details regarding Pro Edition installation process. In case of any problems support is provided via support@python-redmine.com. Please be sure to write from email that was specified during the purchase procedure.

Configuration

Redmine

To start making requests to Redmine you have to check the box Enable REST API in Administration -> Settings -> Authentication and click the Save button.

HINT:

Some operations in Redmine require a user to have the needed permissions to perform them, that is why sometimes it is a good idea to create a special user with admin rights in Redmine which will be used only for the calls to Redmine REST API.


Parameters

Configuring Python-Redmine is extremely easy, the first thing you need to do is to import the Redmine object, which will represent the connection to the Redmine server:

from redminelib import Redmine


Location

Now you need to configure the Redmine object and pass it a few parameters. The only required parameter is the Redmine location (without the forward slash in the end):

redmine = Redmine('https://redmine.url')


Version

There are a lot of different Redmine versions out there and different versions support different resources and features. To be sure that everything will work as expected you need to tell Python-Redmine what version of Redmine you’re using. You can find the Redmine version by visiting the following address https://redmine.url/admin/info and taking the first 3 numbers, i.e. if you have a version of 5.0.4.stable.21982, Python-Redmine needs only the 5.0.4:

redmine = Redmine('https://redmine.url', version='5.0.4')


Authentication

Most of the time the API requires authentication. It can be done in 2 different ways:

using user’s regular login and password:

redmine = Redmine('https://redmine.url', username='foo', password='bar')


using user’s API key which is a handy way to avoid putting a password in a script:

redmine = Redmine('https://redmine.url', key='b244397884889a29137643be79c83f1d470c1e2fac')


The API key can be found on users account page when logged in, on the right-hand pane of the default layout.

Impersonation

As of Redmine 2.2.0, you can impersonate user through the REST API. It must be set to a user login, e.g. jsmith. This only works when using the API with an administrator account, this will be ignored when using the API with a regular user account.

redmine = Redmine('https://redmine.url', impersonate='jsmith')


If the login specified does not exist or is not active, you will get an exception.

DateTime Formats

Python-Redmine automatically converts Redmine’s date/datetime strings to Python’s date/datetime objects:

'2013-12-31'           -> datetime.date(2013, 12, 31)
'2013-12-31T13:27:47Z' -> datetime.datetime(2013, 12, 31, 13, 27, 47)


The conversion also works backwards, i.e. you can use Python’s date/datetime objects when setting resource attributes or in ResourceManager methods, e.g. filter():

datetime.date(2013, 12, 31)                 -> '2013-12-31'
datetime.datetime(2013, 12, 31, 13, 27, 47) -> '2013-12-31T13:27:47Z'


If the conversion doesn’t work for you and you receive strings instead of objects, you have a different datetime formatting than default. To make the conversion work you have to tell Redmine object what datetime formatting you’re using, e.g. if the string returned is 31.12.2013T13:27:47Z:

redmine = Redmine('https://redmine.url', date_format='%d.%m.%Y', datetime_format='%d.%m.%YT%H:%M:%SZ')


Timezone

Added in version 2.4.0.

Redmine REST API expects and returns all datetime attributes in UTC. As described in the previous section, by default Python-Redmine tries to convert datetime text representation to Python’s naive datetime object during attribute access and vice versa from Python’s datetime object to the text representation ignoring timezone information even if one exists. Since 2.4.0 a support for timezone aware datetime objects has been added via a timezone argument which accepts either a string in a form of ±HHMM which is a time offset from UTC in hours and minutes:

redmine = Redmine('https://redmine.url', timezone='-0930')


or any Python object which is a subclass of datetime.tzinfo:

from datetime import timezone
redmine = Redmine('https://redmine.url', timezone=timezone.utc)


Main difference between the two is that ±HHMM string doesn’t take DST into account, but requires no extra packages to work, while a proper Python object which is a subclass of datetime.tzinfo does, but may require you to install additional packages. If you’re on Python 3.9+, there is a built-in zoneinfo module which is a recommended way of specifying a timezone:

from zoneinfo import ZoneInfo
redmine = Redmine('https://redmine.url', timezone=ZoneInfo('America/Los_Angeles'))


If you’re on Python <3.9, there are several 3rd party packages that provide you with timezone databases and classes that can be used as a value for Python-Redmine’s timezone argument.

After setting a timezone attribute to the desired timezone, Python-Redmine will automatically convert Redmine’s datetime strings to Python’s aware datetime objects:

'2013-12-31T13:27:47Z' -> datetime.datetime(2013, 12, 31, 5, 27, 47, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))


The conversion will also work backwards, i.e. you can use Python’s aware datetime objects when setting resource attributes or in ResourceManager methods, e.g. filter():

datetime.datetime(2013, 12, 31, 5, 27, 47, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles')) -> '2013-12-31T13:27:47Z'


Exception Control

If a requested attribute on a resource object doesn’t exist, Python-Redmine will raise an exception by default. Sometimes this may not be the desired behaviour. Python-Redmine provides a way to control this type of exception.

You can completely turn it OFF for all resources:

redmine = Redmine('https://redmine.url', raise_attr_exception=False)


Or you can turn it ON only for some resources via a list or tuple of resource class names:

redmine = Redmine('https://redmine.url', raise_attr_exception=('Project', 'Issue', 'WikiPage'))


Connection Options

Python-Redmine uses Requests library for all the http(s) calls to Redmine server. Requests provides sensible default connection options, but sometimes you may have a need to change them. For example if your Redmine server uses SSL but the certificate is invalid you need to set a Requests’s verify option to False:

redmine = Redmine('https://redmine.url', requests={'verify': False})


Full list of available connection options can be found in the Requests documentation.

HINT:

Storing settings right in the code is a bad habit. Instead store them in some configuration file and then import them, for example if you use Django, you can create settings for Python-Redmine in project’s settings.py file and then import them in the code, e.g.:

# settings.py
REDMINE_URL = 'https://redmine.url'
REDMINE_KEY = 'b244397884889a29137643be79c83f1d470c1e2fac'
# somewhere in the code
from django.conf import settings
from redminelib import Redmine
redmine = Redmine(settings.REDMINE_URL, key=settings.REDMINE_KEY)




Request Engines

See Request Engines for details.

Custom Resources

See Custom Resources for details.

Introduction

Now when you have configured your Redmine object, you can start making requests to Redmine. This document contains an introduction to the most important information about concepts and objects used in Python-Redmine, so it is recommended to read it carefully to understand how everything works.

Operations

Redmine has a concept of resources, i.e. a resource is an entity to which one can apply CRUD operations. Not all resources support every operation, if a resource doesn’t support the requested operation an exception will be thrown. All CRUD operations that you can execute on a resource are provided by a ResourceManager object. This type of object is created automatically for each resource when you request it, e.g:

>>> redmine.project
<redminelib.managers.ResourceManager object for Project resource>
>>> redmine.issue
<redminelib.managers.ResourceManager object for Issue resource>
>>> redmine.user
<redminelib.managers.ResourceManager object for User resource>


TIP:

It is recommended to create a ResourceManager object every time on the fly:

# this is good
>>> p1 = redmine.project.get(1)
>>> p2 = redmine.project.get(2)
# this is not so good
>>> project = redmine.project
>>> p1 = project.get(1)
>>> p2 = project.get(2)




create

There are 2 create operations available: create() and new().

create

Creates a new resource with given fields, saves it to the Redmine and returns a newly created Resource object.

>>> project = redmine.project.create(
...     name='Vacation',
...     identifier='vacation',
...     description='foo',
...     homepage='http://foo.bar',
...     is_public=True,
...     parent_id=345,
...     inherit_members=True,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> project
<redminelib.resources.Project #123 "Vacation">


new

Constructs an entirely new Resource object but doesn’t save it to the Redmine until you call save() method manually:

>>> project = redmine.project.new()
>>> project.name = 'Vacation'
>>> project.identifier = 'vacation'
>>> project.description = 'foo'
>>> project.homepage = 'http://foo.bar'
>>> project.is_public = True
>>> project.parent_id = 345
>>> project.inherit_members = True
>>> project.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> project.save()
True


There’s a big difference between creating a resource via create() and new() methods of a ResourceManager. A create() method is the most simple way to create a resource, it just creates a resource with the provided fields, returns a newly created Resource object and that’s it. A new() method doesn’t create a resource immediately, it just constructs an empty Resource object so you can use its attributes to set their values as needed, also when you call a save() method on the resource, at first its pre_create() method will be executed to run pre create tasks if any, then a request to Redmine will be made to actually save the resource and finally a post_create() method will be executed to run post create tasks if any. You can use any method you like, though it is recommended to use a new() method as the most advanced one.

HINT:

If there’s no need to process response, one can use a redmine.session with either a return_response=False which doesn’t return any response in a form of Resource object, but still validates it in case there were any errors and raises an exception if needed or a ignore_response=True which totally ignores response even if there were any errors. These attributes can save quite some processing time and if a response isn’t needed one is highly encouraged to use on of them:

with redmine.session(return_response=False):

redmine.issue.create(project_id=123, subject='Vacation') with redmine.session(return_response=False):
issue = redmine.issue.new()
issue.project_id = 123
issue.subject = 'Vacation'
issue.save()




read

There are 3 read operations available: get(), all() and filter(). Each of these methods support different keyword arguments depending on the resource used and method called. You can read more about it in each resource’s documentation.

get

Returns a single Resource object either by integer id or by string identifier:

>>> project = redmine.project.get('vacation')
>>> project
<redminelib.resources.Project #123 "Vacation">


all

Returns a ResourceSet object that contains all the requested Resource objects:

>>> projects = redmine.project.all()
>>> projects
<redminelib.resultsets.ResourceSet object with Project resources>


filter

Returns a ResourceSet object that contains Resource objects filtered by some condition(s):

>>> issues = redmine.issue.filter(project_id='vacation')
>>> issues
<redminelib.resultsets.ResourceSet object with Issue resources>


update

Updates a resource with given fields and saves it to the Redmine.

>>> redmine.project.update(123, name='Work', description='Work tasks')
True


delete

Deletes a resource from Redmine.

>>> redmine.project.delete(1)
True


WARNING:

Deleted resources can’t be restored. Use this method carefully.


Added in version 2.0.0.

Starting from Redmine >= 3.3 it is now possible to search for resources using the new Search API. There are two ways to search for resources in Python-Redmine, one is to use the search() method of a ResourceManager object and another is to use the search() method of a configured redmine object. The difference between two methods is that a method of a ResourceManager object searches only for a specific resource type and a method of a redmine object searches for all supported resource types. For example if we want to search for all issues which have the text “rom” either in title or somewhere in text:

>>> issues = redmine.issue.search('rom')
<redminelib.resultsets.ResourceSet object with Issue resources>


And if we want to do the same but for all resources:

>>> resources = redmine.search('rom')
{'news': <redminelib.resultsets.ResourceSet object with News resources>,

'issues': <redminelib.resultsets.ResourceSet object with Issue resources>}


There can also be a unknown key which contains unknown resource types, for example it is possible to search for messages using this functionality, but because messages don’t have any API endpoints they are considered unknown resource types to Python-Redmine, can’t be converted to a ResourceSet object and thus will be available as dictionaries under unknown key.

Both methods also support some options that can be combined together:

  • titles_only. True to search only in title/names and ignore everything else.
  • open_issues. True to search open issues only.
  • attachments. True to also search attachments, only to search attachments only.
  • scope. Search scope condition. Accepted values:
  • all. Search all projects.
  • my_projects. Search only in user’s projects.
  • subprojects. Include subprojects when my_projects specified.

resources. Only search for these types of resources, makes sense only when applied to search() method on redmine object, available values are: issues, news, documents, changesets, wiki_pages, messages, projects and more if additional plugins that support this API are installed.

All of these options are limiting, i.e. by default we try to find everything, so they should be used only if there is a need to somehow limit search results. To revert the effect of any option set it to None or remove entirely.

>>> list(redmine.issue.search('rom', titles_only=True, open_issues=True))
[<redminelib.resources.Issue "#123 (New): Romul">,

<redminelib.resources.Issue "#456 (In Progress): From Russia with Love">] >>> redmine.search('rom', resources=['issues', 'projects']) {'issues': <redminelib.resultsets.ResourceSet object with Issue resources>,
'projects': <redminelib.resultsets.ResourceSet object with Project resources>}


Resource

A Resource object is the most important part of Python-Redmine. Every such object represents a single resource and can be accessed in several ways, for example you can retrieve a resource via get() method of a ResourceManager as discussed earlier:

>>> project = redmine.project.get('vacation')
>>> project.id
123
>>> project.name
'Vacation'


Or create a new resource via create() method of a ResourceManager:

>>> project = redmine.project.create(
...     name='Vacation',
...     identifier='vacation',
...     description='foo',
...     homepage='http://foo.bar',
...     is_public=True,
...     parent_id=345,
...     inherit_members=True,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> project
<redminelib.resources.Project #123 "Vacation">


Or you can construct an entirely new Resource object using new() method of a ResourceManager:

>>> project = redmine.project.new()
>>> project.name = 'Vacation'
>>> project.identifier = 'vacation'
>>> project.description = 'foo'
>>> project.homepage = 'http://foo.bar'
>>> project.is_public = True
>>> project.parent_id = 345
>>> project.inherit_members = True
>>> project.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> project.save()
True


Introspection

Different resources can have different attributes even when they are of the same type. Attributes are constructed dynamically by Python-Redmine when it receives the resource’s data from Redmine. That means that we need to introspect a resource somehow to see what’s inside before we can use it. Fortunately a Resource object provides several ways to introspect itself:

dir(). Returns all the attributes resource has as a list.

>>> dir(redmine.project.get('vacation'))
['created_on',

'description',
'enabled_modules',
'id',
'identifier',
'issue_categories',
'issues',
'memberships',
'name',
'news',
'status',
'time_entries',
'trackers',
'updated_on',
'versions',
'wiki_pages']


list(). Returns all the attributes with their values, which resource has, as a list of tuples.

>>> list(redmine.project.get('vacation'))
[('created_on', '2015-11-23T08:18:39Z'),

('time_entries', None),
('trackers', None),
('wiki_pages', None),
('status', 1),
('description', 'foo'),
('news', None),
('versions', None),
('identifier', 'vacation'),
('name', 'Vacation'),
('enabled_modules', None),
('issues', None),
('issue_categories', None),
('memberships', None),
('id', 123),
('updated_on', '2015-11-23T08:20:31Z')]


repr(). Returns string representation of a resource.

>>> repr(redmine.project.get('vacation'))
'<redminelib.resources.Project #123 "Vacation">'



HINT:

Python has a very handy getattr() function which you can use to access attributes that are not always available, for example Issue resource has is_private attribute which is set to True if issue is private, otherwise this attribute doesn’t exist:

>>> issue = redmine.issue.get(1)
>>> getattr(issue, 'is_private', False)  # prints True if issue is private, False otherwise
False




Export

Added in version 2.0.0.

A Resource object can be exported in one of the formats supported by Redmine using the export() method. A format can be one of the atom, csv, txt, pdf, html etc. You can read more about the supported formats of each resource in its documentation.

>>> issue = redmine.issue.get(123)
>>> issue.export('pdf', savepath='/home/jsmith')
'/home/jsmith/123.pdf'


You can also get access to export url if needed via export_url() method:

>>> issue = redmine.issue.get(123)
>>> issue.export_url('pdf')
'http://demo.redmine.org/issues/123.pdf'


Refresh

In some cases Redmine’s REST API doesn’t provide us with full resource data, fortunately there is a refresh() method for that:

>>> issue = redmine.issue.get(123)
>>> list(issue.project)
[('name', 'FooBar'),

('id', 456)] >>> issue.project.refresh() >>> list(issue.project) [('created_on', '2015-12-07T09:19:27Z'),
('status', 1),
('description', 'A superb project'),
('identifier', 'foobar'),
('name', 'FooBar'),
('homepage', ''),
('parent', {'id': 789, 'name': 'Yada'}),
('id', 456),
('updated_on', '2015-12-07T09:19:27Z')]


Url

Resource object also provides a convenient url attribute which can be used if there is a need to know its url:

>>> issue = redmine.issue.get(123)
>>> issue.url
'http://demo.redmine.org/issues/123'


ResourceSet

A ResourceSet object is another important object type that is used in Python-Redmine. This type of object is constructed automatically by all() or filter() methods of a ResourceManager and is just a collection of Resource objects with a few convenient features. ResourceSet object is lazy, i.e. it doesn’t make any requests to Redmine when it is created and is evaluated only when some of these conditions are met:

Iteration. A ResourceSet is iterable and is evaluated when you iterate over it.

for project in redmine.project.all():

print(project.name)


len(). A ResourceSet is evaluated during the len() call and returns the length of itself.

len(redmine.project.all())


list(). Force evaluation of a ResourceSet by calling list() on it.

list(redmine.project.all())


Index. A ResourceSet is evaluated when some of its resources are requested by index.

redmine.project.all()[0]  # Returns the first Resource in the ResourceSet



Limit/Offset

ResourceSet object supports limit and offset, i.e. if you need to get only some portion of Resource objects, as [offset:limit] or as keyword arguments:

redmine.project.all()[:135]  # Returns only first 135 projects
redmine.project.all(limit=135)  # Returns only first 135 projects
redmine.issue.filter(project_id='vacation')[10:3]  # Returns only 3 issues starting from 10th
redmine.issue.filter(project_id='vacation', offset=10, limit=3)  # Returns only 3 issues starting from 10th


Please note, that keyword arguments have a higher priority, e.g.:

redmine.project.all(limit=10)[:20]  # Returns 10 projects and not 20


Export

Added in version 2.0.0.

A ResourceSet object can be exported in one of the formats supported by Redmine using the export() method. A format can be one of the atom, csv, txt, pdf, html etc. You can read more about the supported formats of each resource in its documentation.

>>> issues = redmine.issue.filter(project_id='vacation', status_id='*')
>>> issues.export('csv', savepath='/home/jsmith', columns='all')
'/home/jsmith/issues.csv'


Methods

ResourceSet object provides several helper methods:

get()

Returns a single resource from the ResourceSet by resource id:

redmine.project.all().get(30404, None)  # Returns None if a Resource is not found


filter()

Changed in version 2.1.0.

Returns a ResourceSet object filtered on a requested Resource object’s attributes values:

redmine.project.all().filter(is_public=True, status=1)


It is also possible to follow resource relationships using a double underscore __:

redmine.issue.all().filter(author__id=1, status__name='New')


Finally it is possible to apply lookups to an attribute using a double underscore __:

redmine.issue.all().filter(status__name__in=('New', 'Closed'))


If a lookup isn’t defined an exact lookup will be used. The following lookups are available:

  • exact (exact match)
  • in (in a given iterable)

Due to the fact that Redmine may return resources with different attributes, for example some resources may and some may not have a version attribute defined, one should be very careful with correctly applying filters. For example in a case of typo in one of the attribute names an empty ResourceSet will be returned as there is no way for Python-Redmine to know whether it was a typo or there was just really no resources that could satisfy the filtering conditions.

Also keep in mind that filtering a ResourceSet is implemented in Python-Redmine and not in the Redmine itself. It is advised to apply all possible filters on the Redmine side first, i.e. using a filter() method of a ResourceManager and then filter everything else using a filter() method of a ResourceSet object. This strategy will ensure that filtering is done in the fastest and most optimized way.

update()

Updates fields of all resources in a resource set with given values and returns an updated ResourceSet object, e.g., the following assigns issues of a project vacation with ids of 30404 and 30405 to the user with id of 547:

redmine.project.get('vacation').issues.filter((30404, 30405)).update(assigned_to_id=547)


NOTE:

This method will also call pre_update() and post_update() methods for each Resource object in a ResourceSet.


delete()

Deletes all resources in a ResourceSet, e.g. the following deletes all issues from the vacation project:

redmine.project.get('vacation').issues.delete()


NOTE:

This method will also call pre_delete() and post_delete() methods for each Resource object in a ResourceSet.


values()

Returns an iterable of dictionaries rather than resource-instance objects. Each of those dictionaries represents a resource with the keys corresponding to the attribute names of resource objects. This example compares the dictionaries of values() with the normal resource objects:

>>> list(redmine.issue_status.all(limit=1))
[<redminelib.resources.IssueStatus #1 "New">]
>>> list(redmine.issue_status.all(limit=1).values())
[{'id': 1, 'is_default': True, 'name': 'New'}]


The values() method takes optional positional arguments, *fields, which specify field names to which resource fields should be limited. If you specify fields, each dictionary will contain only the field keys/values for the fields you specify. If you don’t specify the fields, each dictionary will contain a key and value for every field in the resource:

>>> list(redmine.issue_status.all(limit=1).values())
[{'id': 1, 'is_default': True, 'name': 'New'}]
>>> list(redmine.issue_status.all(limit=1).values('id', 'name'))
[{'id': 1, 'name': 'New'}]


values_list()

Added in version 2.0.0.

Returns an iterable of tuples rather than resource-instance objects. Each of those tuples represents a resource without keys but with ordered values. This example compares the tuples of values_list() with the normal resource objects:

>>> list(redmine.issue_status.all(limit=2))
[<redminelib.resources.IssueStatus #1 "New">, <redminelib.resources.IssueStatus #2 "In Progress">]
>>> list(redmine.issue_status.all(limit=2).values_list())
[('New', 2), ('In Progress', 3)]


The values_list() method takes optional positional arguments, *fields, which specify field names to which resource fields should be limited. If you specify fields, each tuple will contain only the field values for the fields you specify. If you don’t specify the fields, each tuple will contain a value for every field in the resource:

>>> list(redmine.issue_status.all(limit=2).values_list())
[('New', 2), ('In Progress', 3)]
>>> list(redmine.issue_status.all(limit=2).values_list('id'))
[(2,), (3,)]


You can also flatten the iterable in case you are interested only in one field:

>>> list(redmine.issue_status.all(limit=2).values_list('id', flat=True))
[2, 3]



Attributes

ResourceSet object also provides some attributes:

limit. What limit value was used to retrieve this resource set:

>>> projects = redmine.project.all()[100:255]
>>> projects.limit
255


offset. What offset value was used to retrieve this resource set:

>>> projects = redmine.project.all()[100:255]
>>> projects.offset
100


total_count. How much resources of current resource type there are available in Redmine:

>>> projects = redmine.project.all()[100:255]
>>> projects.total_count
968



Resources

Redmine

Issue

Supported by Redmine starting from version 1.0

Manager

All operations on the Issue resource are provided by its manager. To get access to it you have to call redmine.issue where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Issue resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of issue’s project.
  • subject (string) – (required). Issue subject.
  • tracker_id (int) – (optional). Issue tracker id.
  • description (string) – (optional). Issue description.
  • status_id (int) – (optional). Issue status id.
  • priority_id (int) – (optional). Issue priority id.
  • category_id (int) – (optional). Issue category id.
  • fixed_version_id (int) – (optional). Issue version id.
  • is_private (bool) – (optional). Whether issue is private.
  • assigned_to_id (int) – (optional). Issue will be assigned to this user id.
  • watcher_user_ids (list) – (optional). User ids watching this issue.
  • parent_issue_id (int) – (optional). Parent issue id.
  • start_date (string or date object) – (optional). Issue start date.
  • due_date (string or date object) – (optional). Issue end date.
  • estimated_hours (int) – (optional). Issue estimated hours.
  • done_ratio (int) – (optional). Issue done ratio.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object



>>> from io import BytesIO
>>> issue = redmine.issue.create(
...     project_id='vacation',
...     subject='Vacation',
...     tracker_id=8,
...     description='foo',
...     status_id=3,
...     priority_id=7,
...     assigned_to_id=123,
...     watcher_user_ids=[123],
...     parent_issue_id=345,
...     start_date=datetime.date(2014, 1, 1),
...     due_date=datetime.date(2014, 2, 1),
...     estimated_hours=4,
...     done_ratio=40,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> issue
<redminelib.resources.Issue #123 "Vacation">


new

redminelib.managers.ResourceManager.new()
Creates new empty Issue resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> issue = redmine.issue.new()
>>> issue.project_id = 'vacation'
>>> issue.subject = 'Vacation'
>>> issue.tracker_id = 8
>>> issue.description = 'foo'
>>> issue.status_id = 3
>>> issue.priority_id = 7
>>> issue.assigned_to_id = 123
>>> issue.watcher_user_ids = [123]
>>> issue.parent_issue_id = 345
>>> issue.start_date = datetime.date(2014, 1, 1)
>>> issue.due_date = datetime.date(2014, 2, 1)
>>> issue.estimated_hours = 4
>>> issue.done_ratio = 40
>>> issue.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> issue.uploads = [{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
>>> issue.save()
<redminelib.resources.Issue #123 "Vacation">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Issue resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). Id of the issue.
  • include (list) – .INDENT 2.0
  • children
  • attachments
  • relations
  • changesets
  • journals
  • watchers (requires Redmine >= 2.3.0)
  • allowed_statuses (requires Redmine >= 5.0.0)


Returns
Resource object



>>> issue = redmine.issue.get(34441, include=['children', 'journals', 'watchers'])
>>> issue
<redminelib.resources.Issue #34441 "Vacation">


HINT:

Issue resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with an Issue resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Issue resource object are the same as in the get() method above:

>>> issue = redmine.issue.get(34441)
>>> issue.journals
<redminelib.resultsets.ResourceSet object with IssueJournal resources>




HINT:

Issue resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to an Issue resource object. The relations provided by the Issue resource object are:
  • relations
  • time_entries
  • checklists (requires Pro Edition and Checklists plugin)

>>> issue = redmine.issue.get(34441)
>>> issue.time_entries
<redminelib.resultsets.ResourceSet object with TimeEntry resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Issue resources (both open and closed) from Redmine, to return issues with specific status from Redmine use filter() method below.
Parameters
  • sort (string) – (optional). Column to sort. Append :desc to invert the order.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.
  • include (list) – .INDENT 2.0
  • relations
  • attachments (requires Redmine >= 3.4.0)


Returns
ResourceSet object



>>> issues = redmine.issue.all(sort='category:desc', include=['relations', 'attachments'])
>>> issues
<redminelib.resultsets.ResourceSet object with Issue resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Issue resources that match the given lookup parameters.
Parameters
  • issue_id (int or string) – (optional). Find issue or issues by id (separated by ,)
  • parent_id (int) – (optional). Get issues whose parent issue is given id.
  • project_id (int or string) – (optional). Id or identifier of issue’s project.
  • subproject_id (int or string) – (optional). Get issues from the subproject with the given id. You can use project_id=X, subproject_id=!* to get only the issues of a given project and none of its subprojects.
  • tracker_id (int) – (optional). Get issues from the tracker with given id.
  • query_id (int) – (optional). Get issues for the given query id if the project_id is given.
  • status_id (int or string) – .INDENT 2.0
  • open - open issues
  • closed - closed issues
  • * - all issues
  • id - status id

  • author_id (int) – (optional). Get issues which are authored by the given user id.
  • assigned_to_id (int) – (optional). Get issues which are assigned to the given user id. To get the issues assigned to the user whose credentials were used to access the API pass me as a string.
  • cf_x (string) – (optional). Get issues with given value for custom field with an ID of x. The ~ sign can be used before the value to find issues containing a string in a custom field.
  • sort (string) – (optional). Column to sort. Append :desc to invert the order.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.
  • include (list) – .INDENT 2.0
  • relations
  • attachments (requires Redmine >= 3.4.0)


Returns
ResourceSet object




>>> issues = redmine.issue.filter(
...     project_id='vacation',
...     subproject_id='!*',
...     created_on='><2012-03-01|2012-03-07',
...     cf_22='~foo',
...     sort='category:desc'
... )
>>> issues
<redminelib.resultsets.ResourceSet object with Issue resources>


>>> issues = redmine.issue.filter(
...     project_id='vacation',
...     query_id=326
... )
>>> issues
<redminelib.resultsets.ResourceSet object with Issue resources>


HINT:

You can also get issues from a Project, Tracker, IssueStatus or User resource objects directly using issues relation:

>>> project = redmine.project.get('vacation')
>>> project.issues
<redminelib.resultsets.ResourceSet object with Issue resources>


Added in version 2.5.0.

Apart from issues relation a User resource object provides issues_assigned which is an alias to issues relation and issues_authored relation which returns Issue objects authored by a user:

>>> user = redmine.user.get(9)
>>> user.issues
<redminelib.resultsets.ResourceSet object with Issue resources>
>>> user.issues_assigned
<redminelib.resultsets.ResourceSet object with Issue resources>
>>> user.issues_authored
<redminelib.resultsets.ResourceSet object with Issue resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an Issue resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Issue id.
  • project_id (int) – (optional). Issue project id.
  • subject (string) – (optional). Issue subject.
  • tracker_id (int) – (optional). Issue tracker id.
  • description (string) – (optional). Issue description.
  • notes (string) – (optional). Issue journal note.
  • private_notes (bool) – (optional). Whether notes are private.
  • status_id (int) – (optional). Issue status id.
  • priority_id (int) – (optional). Issue priority id.
  • category_id (int) – (optional). Issue category id.
  • fixed_version_id (int) – (optional). Issue version id.
  • is_private (bool) – (optional). Whether issue is private.
  • assigned_to_id (int) – (optional). Issue will be assigned to this user id.
  • parent_issue_id (int) – (optional). Parent issue id.
  • start_date (string or date object) – (optional). Issue start date.
  • due_date (string or date object) – (optional). Issue end date.
  • estimated_hours (int) – (optional). Issue estimated hours.
  • done_ratio (int) – (optional). Issue done ratio.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True



>>> from io import BytesIO
>>> redmine.issue.update(
...     1,
...     project_id=1,
...     subject='Vacation',
...     tracker_id=8,
...     description='foo',
...     notes='A journal note',
...     private_notes=True,
...     status_id=3,
...     priority_id=7,
...     assigned_to_id=123,
...     parent_issue_id=345,
...     start_date=datetime.date(2014, 1, 1),
...     due_date=datetime.date(2014, 2, 1),
...     estimated_hours=4,
...     done_ratio=40,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Issue.save(**attrs)
Saves the current state of an Issue resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> issue = redmine.issue.get(1)
>>> issue.project_id = 1
>>> issue.subject = 'Vacation'
>>> issue.tracker_id = 8
>>> issue.description = 'foo'
>>> issue.notes = 'A journal note'
>>> issue.private_notes = True
>>> issue.status_id = 3
>>> issue.priority_id = 7
>>> issue.assigned_to_id = 123
>>> issue.parent_issue_id = 345
>>> issue.start_date = datetime.date(2014, 1, 1)
>>> issue.due_date = datetime.date(2014, 2, 1)
>>> issue.estimated_hours = 4
>>> issue.done_ratio = 40
>>> issue.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> issue.uploads = [{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
>>> issue.save()
<redminelib.resources.Issue #1 "Vacation">


Added in version 2.1.0: Alternative syntax was introduced.

>>> issue = redmine.issue.get(1).save(
...     project_id=1,
...     subject='Vacation',
...     tracker_id=8,
...     description='foo',
...     notes='A journal note',
...     private_notes=True,
...     status_id=3,
...     priority_id=7,
...     assigned_to_id=123,
...     parent_issue_id=345,
...     start_date=datetime.date(2014, 1, 1),
...     due_date=datetime.date(2014, 2, 1),
...     estimated_hours=4,
...     done_ratio=40,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
... )
>>> issue
<redminelib.resources.Issue #1 "Vacation">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Issue resource from Redmine by its id.
Parameters
resource_id (int) – (required). Issue id.
Returns
True


>>> redmine.issue.delete(1)
True


redminelib.resources.Issue.delete()
Deletes current Issue resource object from Redmine.
Returns
True


>>> issue = redmine.issue.get(1)
>>> issue.delete()
True


Copying

Added in version 2.5.0.

redminelib.managers.IssueManager.copy(resource_id, project_id=None, link_original=True, include=('subtasks', 'attachments'), **fields)
Copies single Issue resource by its id using the same API as Redmine’s GUI copying which means copying is done the most efficient way possible. By default links original to a copy via relations and copies both subtasks and attachments.
Parameters
  • resource_id (int) – (required). Issue id.
  • project_id (int or string) – (required). Id or identifier of issue’s project.
  • link_original (bool) – (optional). Whether to link the original issue to a copy via relations.
  • include (list) – .INDENT 2.0
  • subtasks
  • attachments

fields (dict) – (optional). Accepts the same fields as Issue’s create() method to add or modify original values.

Returns
Resource object



>>> copy = redmine.issue.copy(1, project_id='vacation', link_original=False, include=['attachments'])
>>> copy
<redminelib.resources.Issue #124 "Vacation">


Copies current Issue resource object.
Returns
Resource object


>>> issue = redmine.issue.get(123)
>>> copy = issue.copy(subject='this is a copy')
>>> copy
<redminelib.resources.Issue #124 "this is a copy">


Export

Added in version 2.0.0.

redminelib.resources.Issue.export(fmt, savepath=None, filename=None)
Exports Issue resource in one of the following formats: atom, pdf
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> issue = redmine.issue.get(123)
>>> issue.export('pdf', savepath='/home/jsmith')
'/home/jsmith/123.pdf'


redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None, columns=None, encoding='UTF-8')
Exports a resource set of Issue resources in one of the following formats: atom, pdf, csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.
  • columns (iterable or string) – (optional). Iterable of column names or “all” string for all available columns or “all_gui” string for GUI like behaviour or iterable of elements with “all_gui” string and additional columns to export.
  • encoding – (optional). Encoding that will be used for the result file.

Returns
String or Object


>>> issues = redmine.issue.all()
>>> issues.export('csv', savepath='/home/jsmith', filename='issues.csv', columns='all')
'/home/jsmith/issues.csv'


Journals

The history of an issue is represented as a ResourceSet of IssueJournal resources. Currently the following operations are possible:

create

To create a new record in issue history, i.e. new journal:

redmine.issue.update(1, notes='new note')
True


read

Recommended way to access issue journals is through associated data includes:

>>> issue = redmine.issue.get(1, include=['journals'])
>>> issue.journals
<redminelib.resultsets.ResourceSet object with IssueJournal resources>


But they can also be accessed through on demand includes:

>>> issue = redmine.issue.get(1)
>>> issue.journals
<redminelib.resultsets.ResourceSet object with IssueJournal resources>


After that they can be used as usual:

>>> for journal in issue.journals:
...     print(journal.id, journal.notes)
...
1 foobar
2 lalala
3 hohoho


update

Added in version 2.4.0.

To update notes attribute (the only attribute that can be updated) of a journal:

>>> issue = redmine.issue.get(1, include=['journals'])
>>> for journal in issue.journals:
...     journal.save(notes='setting notes to a new value')
...


Or if you know the id beforehand:

>>> redmine.issue_journal.update(1, notes='setting notes to a new value')
True


delete

Added in version 2.4.0.

To delete a journal set its notes attribute to empty string:

>>> issue = redmine.issue.get(1, include=['journals'])
>>> for journal in issue.journals:
...     journal.save(notes='')
...


Or if you know the id beforehand:

>>> redmine.issue_journal.update(1, notes='')
True


NOTE:

You can only delete a journal that doesn’t have the associated details attribute.


Watchers

Python-Redmine provides 2 methods to work with issue watchers:

add

redminelib.resources.Issue.Watcher.add(user_id)
Adds a user to issue watchers list by its id.
Parameters
user_id (int) – (required). User id.
Returns
True


>>> issue = redmine.issue.get(1)
>>> issue.watcher.add(1)
True


remove

redminelib.resources.Issue.Watcher.remove(user_id)
Removes a user from issue watchers list by its id.
Parameters
user_id (int) – (required). User id.
Returns
True


>>> issue = redmine.issue.get(1)
>>> issue.watcher.remove(1)
True


Project

Supported by Redmine starting from version 1.0

Manager

All operations on the Project resource are provided by its manager. To get access to it you have to call redmine.project where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Project resource with given fields and saves it to the Redmine.
Parameters
  • name (string) – (required). Project name.
  • identifier (string) – (required). Project identifier.
  • description (string) – (optional). Project description.
  • homepage (string) – (optional). Project homepage url.
  • is_public (bool) – (optional). Whether project is public.
  • parent_id (int) – (optional). Project’s parent project id.
  • inherit_members (bool) – (optional). Whether to inherit parent project’s members.
  • tracker_ids (list) – (optional). The ids of trackers for this project.
  • issue_custom_field_ids (list) – (optional). The ids of issue custom fields for this project.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • enabled_module_names (list) – (optional). The names of enabled modules for this project (requires Redmine >= 2.6.0).

Returns
Resource object


>>> project = redmine.project.create(
...     name='Vacation',
...     identifier='vacation',
...     description='foo',
...     homepage='http://foo.bar',
...     is_public=True,
...     parent_id=345,
...     inherit_members=True,
...     tracker_ids=[1, 2],
...     issue_custom_field_ids=[1, 2],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     enabled_module_names=['calendar', 'documents', 'files', 'gantt']
... )
>>> project
<redminelib.resources.Project #123 "Vacation">


new

redminelib.managers.ResourceManager.new()
Creates new empty Project resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> project = redmine.project.new()
>>> project.name = 'Vacation'
>>> project.identifier = 'vacation'
>>> project.description = 'foo'
>>> project.homepage = 'http://foo.bar'
>>> project.is_public = True
>>> project.parent_id = 345
>>> project.inherit_members = True
>>> project.tracker_ids = [1, 2]
>>> project.issue_custom_field_ids = [1, 2]
>>> project.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> project.enabled_module_names = ['calendar', 'documents', 'files', 'gantt']
>>> project.save()
<redminelib.resources.Project #123 "Vacation">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Project resource from Redmine by its id or identifier.
Parameters
  • resource_id (int or string) – (required). Project id or identifier.
  • include (list) – .INDENT 2.0
  • trackers
  • issue_categories
  • enabled_modules (requires Redmine >= 2.6.0)
  • time_entry_activities (requires Redmine >= 3.4.0)
  • issue_custom_fields (requires Redmine >= 4.2.0)


Returns
Resource object



>>> project = redmine.project.get('vacation', include=['trackers', 'issue_categories', 'enabled_modules', 'time_entry_activities', 'issue_custom_fields'])
>>> project
<redminelib.resources.Project #123 "Vacation">


HINT:

Project resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Project resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Project resource object are the same as in the get() method above:

>>> project = redmine.project.get('vacation')
>>> project.trackers
<redminelib.resultsets.ResourceSet object with Tracker resources>




HINT:

Project resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a Project resource object. The relations provided by the Project resource object are:
  • wiki_pages
  • memberships
  • issue_categories
  • versions
  • news
  • files
  • issues
  • time_entries
  • deals (requires Pro Edition and CRM plugin)
  • contacts (requires Pro Edition and CRM plugin)
  • deal_categories (requires Pro Edition and CRM plugin >= 3.3.0)
  • invoices (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expenses (requires Pro Edition and Invoices plugin >= 4.1.3)
  • products (requires Pro Edition and Products plugin >= 2.1.5)
  • orders (requires Pro Edition and Products plugin >= 2.1.5)

>>> project = redmine.project.get('vacation')
>>> project.issues
<redminelib.resultsets.ResourceSet object with Issue resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Project resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.
  • include (list) – .INDENT 2.0
  • trackers
  • issue_categories
  • enabled_modules
  • time_entry_activities


Returns
ResourceSet object



>>> projects = redmine.project.all(offset=10, limit=100, include=['trackers', 'issue_categories', 'enabled_modules', 'time_entry_activities'])
>>> projects
<redminelib.resultsets.ResourceSet object with Project resources>


filter

Not supported by Redmine

Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Project resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Project id.
  • name (string) – (optional). Project name.
  • description (string) – (optional). Project description.
  • homepage (string) – (optional). Project homepage url.
  • is_public (bool) – (optional). Whether project is public.
  • parent_id (int) – (optional). Project’s parent project id.
  • inherit_members (bool) – (optional). Whether to inherit parent project’s members.
  • tracker_ids (list) – (optional). The ids of trackers for this project.
  • issue_custom_field_ids (list) – (optional). The ids of issue custom fields for this project.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • enabled_module_names (list) – (optional). The names of enabled modules for this project (requires Redmine >= 2.6.0).

Returns
True


>>> redmine.project.update(
...     1,
...     name='Vacation',
...     description='foo',
...     homepage='http://foo.bar',
...     is_public=True,
...     parent_id=345,
...     inherit_members=True,
...     tracker_ids=[1, 2],
...     issue_custom_field_ids=[1, 2],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     enabled_module_names=['calendar', 'documents', 'files', 'gantt']
... )
True


save

redminelib.resources.Project.save(**attrs)
Saves the current state of a Project resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> project = redmine.project.get(1)
>>> project.name = 'Vacation'
>>> project.description = 'foo'
>>> project.homepage = 'http://foo.bar'
>>> project.is_public = True
>>> project.parent_id = 345
>>> project.inherit_members = True
>>> project.tracker_ids = [1, 2]
>>> project.issue_custom_field_ids = [1, 2]
>>> project.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> project.enabled_module_names = ['calendar', 'documents', 'files', 'gantt']
>>> project.save()
<redminelib.resources.Project #1 "Vacation">


Added in version 2.1.0: Alternative syntax was introduced.

>>> project = redmine.project.get(1).save(
...     name='Vacation',
...     description='foo',
...     homepage='http://foo.bar',
...     is_public=True,
...     parent_id=345,
...     inherit_members=True,
...     tracker_ids=[1, 2],
...     issue_custom_field_ids=[1, 2],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     enabled_module_names=['calendar', 'documents', 'files', 'gantt']
... )
>>> project
<redminelib.resources.Project #1 "Vacation">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Project resource from Redmine by its id or identifier.
Parameters
resource_id (int or string) – (required). Project id or identifier.
Returns
True


>>> redmine.project.delete(1)
True


redminelib.resources.Project.delete()
Deletes current Project resource object from Redmine.
Returns
True


>>> project = redmine.project.get(1)
>>> project.delete()
True


Additional methods

Added in version 2.4.0.

close

redminelib.managers.ProjectManager.close(resource_id)
Closes single Project Redmine resource by its id or identifier.
Parameters
resource_id (int or string) – (required). Project id or identifier.
Returns
True


>>> redmine.project.close(1)
True


redminelib.resources.Project.close()
Closes current Project Redmine resource object.
Returns
True


>>> project = redmine.project.get(1)
>>> project.close()
True


reopen

redminelib.managers.ProjectManager.reopen(resource_id)
Reopens previously closed single Project Redmine resource by its id or identifier.
Parameters
resource_id (int or string) – (required). Project id or identifier.
Returns
True


>>> redmine.project.reopen(1)
True


redminelib.resources.Project.reopen()
Reopens previously closed current Project Redmine resource object.
Returns
True


>>> project = redmine.project.get(1)
>>> project.reopen()
True


archive

redminelib.managers.ProjectManager.archive(resource_id)
Archives single Project Redmine resource by its id or identifier.
Parameters
resource_id (int or string) – (required). Project id or identifier.
Returns
True


>>> redmine.project.archive(1)
True


redminelib.resources.Project.archive()
Archives current Project Redmine resource object.
Returns
True


>>> project = redmine.project.get(1)
>>> project.archive()
True


unarchive

redminelib.managers.ProjectManager.unarchive(resource_id)
Unarchives single Project Redmine resource by its id or identifier.
Parameters
resource_id (int or string) – (required). Project id or identifier.
Returns
True


>>> redmine.project.unarchive(1)
True


Export

Added in version 2.0.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Project resources in one of the following formats: atom
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> projects = redmine.project.all()
>>> projects.export('atom', savepath='/home/jsmith', filename='projects.atom')
'/home/jsmith/projects.atom'


Project Membership

Supported by Redmine starting from version 1.4

Manager

All operations on the ProjectMembership resource are provided by its manager. To get access to it you have to call redmine.project_membership where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new ProjectMembership resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of the project.
  • user_id (int) – (required). Id of the user or group to add to the project.
  • role_ids (list) – (required). Role ids to add to the user in this project.

Returns
Resource object


>>> membership = redmine.project_membership.create(project_id='vacation', user_id=1, role_ids=[1, 2])
>>> membership
<redminelib.resources.ProjectMembership #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty ProjectMembership resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> membership = redmine.project_membership.new()
>>> membership.project_id = 'vacation'
>>> membership.user_id = 1
>>> membership.role_ids = [1, 2]
>>> membership.save()
<redminelib.resources.ProjectMembership #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single ProjectMembership resource from Redmine by its id.
Parameters
resource_id (int) – (required). Project membership id.
Returns
Resource object


>>> membership = redmine.project_membership.get(521)
>>> membership
<redminelib.resources.ProjectMembership #521>


all

Not supported by Redmine

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns ProjectMembership resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Id or identifier of the project.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> memberships = redmine.project_membership.filter(project_id='vacation')
>>> memberships
<redminelib.resultsets.ResourceSet object with ProjectMembership resources>


HINT:

You can also get project memberships from a Project resource object directly using memberships relation:

>>> project = redmine.project.get('vacation')
>>> project.memberships
<redminelib.resultsets.ResourceSet object with ProjectMembership resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a ProjectMembership resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Project membership id.
  • role_ids (list) – (required). Role ids to add to the user in this project.

Returns
True


>>> redmine.project_membership.update(1, role_ids=[1, 2])
True


save

redminelib.resources.ProjectMembership.save(**attrs)
Saves the current state of a ProjectMembership resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> membership = redmine.project_membership.get(1)
>>> membership.role_ids = [1, 2]
>>> membership.save()
<redminelib.resources.ProjectMembership #1>


Added in version 2.1.0: Alternative syntax was introduced.

>>> membership = redmine.project_membership.get(1).save(role_ids=[1, 2])
>>> membership
<redminelib.resources.ProjectMembership #1>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single ProjectMembership resource from Redmine by its id.
Parameters
resource_id (int) – (required). Project membership id.
Returns
True


>>> redmine.project_membership.delete(1)
True


redminelib.resources.ProjectMembership.delete()
Deletes current ProjectMembership resource object from Redmine.
Returns
True


>>> membership = redmine.project_membership.get(1)
>>> membership.delete()
True


Export

Not supported by Redmine

User

Supported by Redmine starting from version 1.1

Manager

All operations on the User resource are provided by its manager. To get access to it you have to call redmine.user where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new User resource with given fields and saves it to the Redmine.
Parameters
  • login (string) – (required). User login.
  • password (string) – (optional). User password.
  • firstname (string) – (required). User name.
  • lastname (string) – (required). User surname.
  • mail (string) – (required). User email.
  • auth_source_id (int) – (optional). Authentication mode id.
  • mail_notification (string) – .INDENT 2.0
  • all
  • selected
  • only_my_events
  • only_assigned
  • only_owner
  • none

  • notified_project_ids (list) – (optional). Project IDs for a “selected” mail notification type.
  • must_change_passwd (bool) – (optional). Whether user must change password.
  • generate_password (bool) – (optional). Whether to generate password for the user.
  • send_information (bool) – (optional). Whether to send account information to the user.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • admin (bool) – (optional). Whether to give admin privileges to the user, requires Redmine >= 4.0.0.

Returns
Resource object



>>> user = redmine.user.create(
...     login='jsmith',
...     password='qwerty',
...     firstname='John',
...     lastname='Smith',
...     mail='john@smith.com',
...     auth_source_id=1,
...     mail_notification='selected',
...     notified_project_ids=[1, 2],
...     must_change_passwd=True,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> user
<redminelib.resources.User #32 "John Smith">


new

redminelib.managers.ResourceManager.new()
Creates new empty User resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> user = redmine.user.new()
>>> user.login = 'jsmith'
>>> user.password = 'qwerty'
>>> user.firstname = 'John
>>> user.lastname = 'Smith'
>>> user.mail = 'john@smith.com'
>>> user.auth_source_id = 1
>>> user.mail_notification = 'selected'
>>> user.notified_project_ids = [1, 2]
>>> user.must_change_passwd = True
>>> user.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> user.save()
<redminelib.resources.User #32 "John Smith">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single User resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). Id of the user.
  • include (list) – .INDENT 2.0
  • memberships
  • groups


Returns
Resource object



>>> user = redmine.user.get(17, include=['memberships', 'groups'])
>>> user
<redminelib.resources.User #17 "John Smith">


HINT:

You can easily get the details of the user whose credentials were used to access the API:

>>> user = redmine.user.get('current')
>>> user
<redminelib.resources.User #17 "John Smith">




HINT:

User resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a User resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the User resource object are the same as in the get() method above:

>>> user = redmine.user.get(17)
>>> user.groups
<redminelib.resultsets.ResourceSet object with Group resources>




HINT:

User resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a User resource object. The relations provided by the User resource object are:
  • time_entries
  • issues (alias to issues_assigned)
  • issues_assigned (requires Python-Redmine v2.5.0)
  • issues_authored (requires Python-Redmine v2.5.0)
  • deals (requires Pro Edition and CRM plugin)
  • contacts (requires Pro Edition and CRM plugin)
  • invoices (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expenses (requires Pro Edition and Invoices plugin >= 4.1.3)
  • products (requires Pro Edition and Products plugin >= 2.1.5)
  • orders (requires Pro Edition and Products plugin >= 2.1.5)

>>> user = redmine.user.get(17)
>>> user.issues
<redminelib.resultsets.ResourceSet object with Issue resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all User resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> users = redmine.user.all(offset=10, limit=100)
>>> users
<redminelib.resultsets.ResourceSet object with User resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns User resources that match the given lookup parameters.
Parameters
  • status (int) – .INDENT 2.0
  • 0 - anonymous
  • 1 - active (default)
  • 2 - registered
  • 3 - locked

  • name (string) – (optional). Filter users on their login, firstname, lastname and mail. If the pattern contains a space, it will also return users whose firstname match the first word or lastname match the second word.
  • group_id (int) – (optional). Get only members of the given group.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object



>>> users = redmine.user.filter(offset=10, limit=100, status=3)
>>> users
<redminelib.resultsets.ResourceSet object with User resources>


HINT:

You can also get users from a Group resource object directly using users on demand includes:

>>> group = redmine.group.get(524)
>>> group.users
<redminelib.resultsets.ResourceSet object with User resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a User resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). User id.
  • login (string) – (optional). User login.
  • password (string) – (optional). User password.
  • firstname (string) – (optional). User name.
  • lastname (string) – (optional). User surname.
  • mail (string) – (optional). User email.
  • status (int) – .INDENT 2.0
  • 1 - active
  • 2 - registered
  • 3 - locked

  • auth_source_id (int) – (optional). Authentication mode id.
  • mail_notification (string) – .INDENT 2.0
  • all
  • selected
  • only_my_events
  • only_assigned
  • only_owner
  • none

  • notified_project_ids (list) – (optional). Project IDs for a “selected” mail notification type.
  • must_change_passwd (bool) – (optional). Whether user must change password.
  • generate_password (bool) – (optional). Whether to generate password for the user.
  • send_information (bool) – (optional). Whether to send account information to the user.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • admin (bool) – (optional). Whether to give admin privileges to the user, requires Redmine >= 4.0.0.

Returns
True




>>> redmine.user.update(
...     1,
...     login='jsmith',
...     password='qwerty',
...     firstname='John',
...     lastname='Smith',
...     mail='john@smith.com',
...     status=3,
...     auth_source_id=1,
...     mail_notification='selected',
...     notified_project_ids=[1, 2],
...     must_change_passwd=True,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
True


HINT:

By default Python-Redmine uses /users/ID API endpoint which requires admin privileges, it is also possible to use /my/account endpoint which doesn’t by using me as an ID (requires Redmine >= 4.1.0):

>>> redmine.user.update('me', firstname='John')
True




save

redminelib.resources.User.save(**attrs)
Saves the current state of a User resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> user = redmine.user.get(1)
>>> user.login = 'jsmith'
>>> user.password = 'qwerty'
>>> user.firstname = 'John'
>>> user.lastname = 'Smith'
>>> user.mail = 'john@smith.com'
>>> user.status = 3
>>> user.auth_source_id = 1
>>> user.mail_notification = 'selected'
>>> user.notified_project_ids = [1, 2]
>>> user.must_change_passwd = True
>>> user.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> user.save()
<redminelib.resources.User #1 "John Smith">


Added in version 2.1.0: Alternative syntax was introduced.

>>> user = redmine.user.get(1).save(
...     login='jsmith',
...     password='qwerty',
...     firstname='John',
...     lastname='Smith',
...     mail='john@smith.com',
...     status=3,
...     auth_source_id=1,
...     mail_notification='selected',
...     notified_project_ids=[1, 2],
...     must_change_passwd=True,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> user
<redminelib.resources.User #1 "John Smith">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single User resource from Redmine by its id.
Parameters
resource_id (int) – (required). User id.
Returns
True


>>> redmine.user.delete(1)
True


redminelib.resources.User.delete()
Deletes current User resource object from Redmine.
Returns
True


>>> user = redmine.user.get(1)
>>> user.delete()
True


Export

Added in version 2.3.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None, columns=None, encoding='UTF-8')
Exports a resource set of User resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.
  • columns (iterable or string) – (optional). Iterable of column names or “all” string for all available columns or “all_gui” string for GUI like behaviour or iterable of elements with “all_gui” string and additional columns to export.
  • encoding – (optional). Encoding that will be used for the result file.

Returns
String or Object


>>> users = redmine.user.all()
>>> users.export('csv', savepath='/home/jsmith', filename='users.csv', columns='all')
'/home/jsmith/users.csv'


Time Entry

Supported by Redmine starting from version 1.1

Manager

All operations on the TimeEntry resource are provided by its manager. To get access to it you have to call redmine.time_entry where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new TimeEntry resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int issue_id or) – (required). The issue id or project id to log time on.
  • hours (int or float) – (required). The number of spent hours.
  • spent_on (string or date object) – (optional). The date the time was spent (current date if not set).
  • activity_id (int) – (optional). The id of the time activity. This parameter is required unless a default activity is defined in Redmine. Available activity ids can be retrieved per project using include=['time_entry_activities'], requires Redmine >= 3.4.0.
  • user_id (int) – (optional). Will create a time entry on behalf of this user id.
  • comments (string) – (optional). Short description for the entry (255 characters max).

Returns
Resource object


>>> time_entry = redmine.time_entry.create(
...     issue_id=123,
...     spent_on=datetime.date(2014, 1, 14),
...     hours=3,
...     activity_id=10,
...     user_id=5,
...     comments='hello'
... )
>>> time_entry
<redminelib.resources.TimeEntry #12345>


new

redminelib.managers.ResourceManager.new()
Creates new empty TimeEntry resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> time_entry = redmine.time_entry.new()
>>> time_entry.issue_id = 123
>>> time_entry.spent_on = datetime.date(2014, 1, 14)
>>> time_entry.hours = 3
>>> time_entry.activity_id = 10
>>> time_entry.user_id = 5
>>> time_entry.comments = 'hello'
>>> time_entry.save()
<redminelib.resources.TimeEntry #12345>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single TimeEntry resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the time entry.
Returns
Resource object


>>> time_entry = redmine.time_entry.get(374)
>>> time_entry
<redminelib.resources.TimeEntry #374>


all

redminelib.managers.ResourceManager.all(**params)
Returns all TimeEntry resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> time_entries = redmine.time_entry.all(offset=10, limit=100)
>>> time_entries
<redminelib.resultsets.ResourceSet object with TimeEntry resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns TimeEntry resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Get time entries from the project with given id.
  • issue_id (int) – (optional). Get time entries from the issue with given id.
  • user_id (int) – (optional). Get time entries for the user with given id.
  • spent_on (string or date object) – (optional). Redmine >= 2.3.0 only. Date when time was spent.
  • from_date (string or date object) – (optional). Limit time entries from this date.
  • to_date (string or date object) – (optional). Limit time entries until this date.
  • hours (string) – (optional). Get only time entries that are =, >=, <= hours.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> time_entries = redmine.time_entry.filter(offset=10, limit=100, project_id='vacation', hours='>=8')
>>> time_entries
<redminelib.resultsets.ResourceSet object with TimeEntry resources>


HINT:

You can also get time entries from an Issue, Project and User resource objects directly using time_entries relation:

>>> issue = redmine.issue.get(34213)
>>> issue.time_entries
<redminelib.resultsets.ResourceSet object with TimeEntry resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a TimeEntry resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Time entry id.
  • project_id (int issue_id or) – (optional). The issue id or project id to log time on.
  • hours (int) – (optional). The number of spent hours.
  • spent_on (string or date object) – (optional). The date the time was spent.
  • activity_id (int) – (optional). The id of the time activity. Available activity ids can be retrieved per project using include=['time_entry_activities'], requires Redmine >= 3.4.0.
  • user_id (int) – (optional). Will update a time entry on behalf of this user id.
  • comments (string) – (optional). Short description for the entry (255 characters max).

Returns
True


>>> redmine.time_entry.update(
...     1,
...     issue_id=123,
...     spent_on=datetime.date(2014, 1, 14),
...     hours=3,
...     activity_id=10,
...     user_id=5,
...     comments='hello'
... )
True


save

redminelib.resources.TimeEntry.save(**attrs)
Saves the current state of a TimeEntry resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> time_entry = redmine.time_entry.get(1)
>>> time_entry.issue_id = 123
>>> time_entry.spent_on = datetime.date(2014, 1, 14)
>>> time_entry.hours = 3
>>> time_entry.activity_id = 10
>>> time_entry.user_id = 5
>>> time_entry.comments = 'hello'
>>> time_entry.save()
<redminelib.resources.TimeEntry #1>


Added in version 2.1.0: Alternative syntax was introduced.

>>> time_entry = redmine.time_entry.get(1).save(
...     issue_id=123,
...     spent_on=datetime.date(2014, 1, 14),
...     hours=3,
...     activity_id=10,
...     comments='hello'
... )
>>> time_entry
<redminelib.resources.TimeEntry #1>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single TimeEntry resource from Redmine by its id.
Parameters
resource_id (int) – (required). Time entry id.
Returns
True


>>> redmine.time_entry.delete(1)
True


redminelib.resources.TimeEntry.delete()
Deletes current TimeEntry resource object from Redmine.
Returns
True


>>> entry = redmine.time_entry.get(1)
>>> entry.delete()
True


Export

Added in version 2.0.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None, columns=None, encoding='UTF-8')
Exports a resource set of TimeEntry resources in one of the following formats: atom, csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.
  • columns (iterable or string) – (optional). Iterable of column names or “all” string for all available columns or “all_gui” string for GUI like behaviour or iterable of elements with “all_gui” string and additional columns to export.
  • encoding – (optional). Encoding that will be used for the result file.

Returns
String or Object


>>> entries = redmine.time_entry.all()
>>> entries.export('csv', savepath='/home/jsmith', filename='entries.csv', columns='all')
'/home/jsmith/entries.csv'


News

Supported by Redmine starting from version 1.1

Manager

All operations on the News resource are provided by its manager. To get access to it you have to call redmine.news where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Added in version 2.3.0.

create

redminelib.managers.ResourceManager.create(**fields)
Creates new News resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of News’s project.
  • title (string) – (required). News title.
  • description (string) – (required). News description.
  • summary (string) – (optional). News summary.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object



>>> news = redmine.news.create(title='Foo', description='foobar')
>>> news
<redminelib.resources.News #8 "Foo">


new

redminelib.managers.ResourceManager.new()
Creates new empty News resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> news = redmine.news.new()
>>> news.title = 'Foo'
>>> news.description = 'foobar'
>>> news.save()
<redminelib.resources.News #8 "Foo">


WARNING:

Redmine’s News API doesn’t return a news object after create operation. Due to the fact that it goes against the behaviour of all other API endpoints, Python-Redmine has to do some tricks under the hood to return a resource object which involve an additional API request. If that isn’t desired one should use the following technique:

with redmine.session(return_response=False):

news = redmine.news.new()
news.title = 'Foo'
news.description = 'foobar'
news.save()




Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single News resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). News id.
  • include (list) – .INDENT 2.0
  • comments
  • attachments


Returns
Resource object



>>> news = redmine.news.get(123, include=['comments', 'attachments'])
>>> news
<redminelib.resources.News #123 "Vacation">


HINT:

News resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a News resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the News resource object are the same as in the get() method above:

>>> news = redmine.news.get(123)
>>> news.attachments
<redminelib.resultsets.ResourceSet object with Attachment resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all News resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> news = redmine.news.all(offset=10, limit=100)
>>> news
<redminelib.resultsets.ResourceSet object with News resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns News resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Id or identifier of news project.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> news = redmine.news.filter(project_id='vacation')
>>> news
<redminelib.resultsets.ResourceSet object with News resources>


HINT:

You can also get news from a Project resource object directly using news relation:

>>> project = redmine.project.get('vacation')
>>> project.news
<redminelib.resultsets.ResourceSet object with News resources>




Update methods

Added in version 2.3.0.

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a News resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). News id.
  • title (string) – (optional). News title.
  • description (string) – (optional). News description.
  • summary (string) – (optional). News summary.

Returns
True


>>> redmine.news.update(1, title='Bar', description='barfoo', summary='bar')
True


save

redminelib.resources.News.save(**attrs)
Saves current state of a News resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> news = redmine.news.get(1)
>>> news.title = 'Bar'
>>> news.description = 'barfoo'
>>> news.summary = 'bar'
>>> news.save()
<redminelib.resources.News #1 "Bar">


Added in version 2.1.0: Alternative syntax was introduced.

>>> news = redmine.news.get(1).save(
...     title='Bar',
...     description='barfoo',
...     summary='bar'
... )
>>> news
<redminelib.resources.News #1 "Bar">


Delete methods

Added in version 2.3.0.

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single News resource from Redmine by its id.
Parameters
resource_id (int) – (required). News id.
Returns
True


>>> redmine.news.delete(1)
True


redminelib.resources.News.delete()
Deletes current News resource object from Redmine.
Returns
True


>>> news = redmine.news.get(1)
>>> news.delete()
True


Export

Added in version 2.0.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of News resources in one of the following formats: atom
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> news = redmine.news.all()
>>> news.export('atom', savepath='/home/jsmith', filename='news.atom')
'/home/jsmith/news.atom'


Issue Relation

Supported by Redmine starting from version 1.3

Manager

All operations on the IssueRelation resource are provided by its manager. To get access to it you have to call redmine.issue_relation where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new IssueRelation resource with given fields and saves it to the Redmine.
Parameters
  • issue_id (int) – (required). Creates a relation for the issue of given id.
  • issue_to_id (int) – (required). Id of the related issue.
  • relation_type (string) – .INDENT 2.0
  • relates
  • duplicates
  • duplicated
  • blocks
  • blocked
  • precedes
  • follows
  • copied_to
  • copied_from

delay (int) – (optional). Delay in days for a “precedes” or “follows” relation.

Returns
Resource object



>>> relation = redmine.issue_relation.create(
...     issue_id=12345,
...     issue_to_id=54321,
...     relation_type='precedes',
...     delay=5
... )
>>> relation
<redminelib.resources.IssueRelation #667>


new

redminelib.managers.ResourceManager.new()
Creates new empty IssueRelation resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object



>>> relation = redmine.issue_relation.new()
>>> relation.issue_id = 12345
>>> relation.issue_to_id = 54321
>>> relation.relation_type = 'precedes'
>>> relation.delay = 5
>>> relation.save() <redminelib.resources.IssueRelation #667>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single IssueRelation resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the issue relation.
Returns
Resource object


>>> relation = redmine.issue_relation.get(606)
>>> relation
<redminelib.resources.IssueRelation #606>


all

Not supported by Redmine

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns IssueRelation resources that match the given lookup parameters.
Parameters
  • issue_id (int) – (required). Get relations from the issue with given id.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> relations = redmine.issue_relation.filter(issue_id=6543)
>>> relations
<redminelib.resultsets.ResourceSet object with IssueRelation resources>


HINT:

You can also get issue relations from an Issue resource object directly using relations relation:

>>> issue = redmine.issue.get(6543)
>>> issue.relations
<redminelib.resultsets.ResourceSet object with IssueRelation resources>




Update methods

Not supported by Redmine

Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single IssueRelation resource from Redmine by its id.
Parameters
resource_id (int) – (required). Issue relation id.
Returns
True


>>> redmine.issue_relation.delete(1)
True


redminelib.resources.IssueRelation.delete()
Deletes current IssueRelation resource object from Redmine.
Returns
True


>>> relation = redmine.issue_relation.get(1)
>>> relation.delete()
True


Export

Not supported by Redmine

Version

Supported by Redmine starting from version 1.3

Manager

All operations on the Version resource are provided by its manager. To get access to it you have to call redmine.version where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Version resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of version’s project.
  • name (string) – (required). Version name.
  • status (string) – .INDENT 2.0
  • open (default)
  • locked
  • closed

  • sharing (string) – .INDENT 2.0
  • none (default)
  • descendants
  • hierarchy
  • tree
  • system

  • due_date (string or date object) – (optional). Expiration date.
  • description (string) – (optional). Version description.
  • wiki_page_title (string) – (optional). Version wiki page title.

Returns
Resource object




>>> version = redmine.version.create(
...     project_id='vacation',
...     name='Vacation',
...     status='open',
...     sharing='none',
...     due_date=datetime.date(2014, 1, 30),
...     description='my vacation',
...     wiki_page_title='Vacation'
... )
>>> version
<redminelib.resources.Version #235 "Vacation">


new

redminelib.managers.ResourceManager.new()
Creates new empty Version resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> version = redmine.version.new()
>>> version.project_id = 'vacation'
>>> version.name = 'Vacation'
>>> version.status = 'open'
>>> version.sharing = 'none'
>>> version.due_date = datetime.date(2014, 1, 30)
>>> version.description = 'my vacation'
>>> version.wiki_page_title = 'Vacation'
>>> version.save()
<redminelib.resources.Version #235 "Vacation">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single Version resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the version.
Returns
Resource object


>>> version = redmine.version.get(1)
>>> version
<redminelib.resources.Version #1 "Release 1">


all

Not supported by Redmine

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Version resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Id or identifier of version’s project.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> versions = redmine.version.filter(project_id='vacation')
>>> versions
<redminelib.resultsets.ResourceSet object with Versions resources>


HINT:

You can also get versions from a Project resource object directly using versions relation:

>>> project = redmine.project.get('vacation')
>>> project.versions
<redminelib.resultsets.ResourceSet object with Version resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Version resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Version id.
  • name (string) – (optional). Version name.
  • status (string) – .INDENT 2.0
  • open (default)
  • locked
  • closed

  • sharing (string) – .INDENT 2.0
  • none (default)
  • descendants
  • hierarchy
  • tree
  • system

  • due_date (string or date object) – (optional). Expiration date.
  • description (string) – (optional). Version description.
  • wiki_page_title (string) – (optional). Version wiki page title.

Returns
True




>>> redmine.version.update(
...     1,
...     name='Vacation',
...     status='open',
...     sharing='none',
...     due_date=datetime.date(2014, 1, 30),
...     description='my vacation',
...     wiki_page_title='Vacation'
... )
True


save

redminelib.resources.Version.save(**attrs)
Saves the current state of a Version resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> version = redmine.version.get(1)
>>> version.name = 'Vacation'
>>> version.status = 'open'
>>> version.sharing = 'none'
>>> version.due_date = datetime.date(2014, 1, 30)
>>> version.description = 'my vacation'
>>> version.wiki_page_title = 'Vacation'
>>> version.save()
<redminelib.resources.Version #1 "Vacation">


Added in version 2.1.0: Alternative syntax was introduced.

>>> version = redmine.version.get(1).save(
...     name='Vacation',
...     status='open',
...     sharing='none',
...     due_date=datetime.date(2014, 1, 30),
...     description='my vacation',
...     wiki_page_title='Vacation'
... )
>>> version
<redminelib.resources.Version #1 "Vacation">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Version resource from Redmine by its id.
Parameters
resource_id (int) – (required). Version id.
Returns
True


>>> redmine.version.delete(1)
True


redminelib.resources.Version.delete()
Deletes current Version resource object from Redmine.
Returns
True


>>> version = redmine.version.get(1)
>>> version.delete()
True


Export

Not supported by Redmine

Wiki Page

Supported by Redmine starting from version 2.2

Manager

All operations on the WikiPage resource are provided by its manager. To get access to it you have to call redmine.wiki_page where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.WikiPageManager.create(**fields)
Creates new WikiPage resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of wiki page’s project.
  • text (string) – (required). Text of the wiki page.
  • title (string) – (required). Title of the wiki page.
  • parent_title (string) – (optional). Title of parent wiki page.
  • comments (string) – (optional). Comments of the wiki page.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object



>>> from io import BytesIO
>>> wiki_page = redmine.wiki_page.create(
...     project_id='vacation',
...     title='FooBar',
...     text='foo',
...     parent_title='Yada',
...     comments='bar',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> wiki_page
<redminelib.resources.WikiPage "FooBar">


new

redminelib.managers.WikiPageManager.new()
Creates new empty WikiPage resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> wiki_page = redmine.wiki_page.new()
>>> wiki_page.project_id = 'vacation'
>>> wiki_page.title = 'FooBar'
>>> wiki_page.text = 'foo'
>>> wiki_page.parent_title = 'Yada'
>>> wiki_page.comments = 'bar'
>>> wiki_page.uploads = [{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
>>> wiki_page.save()
<redminelib.resources.WikiPage "FooBar">


Read methods

get

redminelib.managers.WikiPageManager.get(resource_id, **params)
Returns single WikiPage resource from Redmine by its title.
Parameters
  • resource_id (string) – (required). Title of the wiki page.
  • project_id (int or string) – (required). Id or identifier of wiki page’s project.
  • version (int) – (optional). Version of the wiki page.
  • include (list) – .INDENT 2.0
  • attachments


Returns
Resource object



>>> wiki_page = redmine.wiki_page.get('Photos', project_id='vacation', version=12, include=['attachments'])
>>> wiki_page
<redminelib.resources.WikiPage "Photos">


HINT:

WikiPage resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a WikiPage resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the WikiPage resource object are the same as in the get() method above:

>>> wiki_page = redmine.wiki_page.get('Photos', project_id='vacation')
>>> wiki_page.attachments
<redminelib.resultsets.ResourceSet object with Attachment resources>




all

Not supported by Redmine

filter

redminelib.managers.WikiPageManager.filter(**filters)
Returns WikiPage resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Id or identifier of wiki page’s project.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> wiki_pages = redmine.wiki_page.filter(project_id='vacation')
>>> wiki_pages
<redminelib.resultsets.ResourceSet object with WikiPage resources>


HINT:

You can also get wiki pages from a Project resource object directly using wiki_pages relation:

>>> project = redmine.project.get('vacation')
>>> project.wiki_pages
<redminelib.resultsets.ResourceSet object with WikiPage resources>




Update methods

update

redminelib.managers.WikiPageManager.update(resource_id, **fields)
Updates values of given fields of a WikiPage resource and saves them to the Redmine.
Parameters
  • resource_id (string) – (required). Title of the wiki page.
  • project_id (int or string) – (required). Id or identifier of wiki page’s project.
  • text (string) – (required). Text of the wiki page.
  • title (string) – (optional). Title of the wiki page.
  • parent_title (string) – (optional). Title of parent wiki page.
  • comments (string) – (optional). Comments of the wiki page.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True



>>> from io import BytesIO
>>> redmine.wiki_page.update(
...     'Foo',
...     project_id='vacation',
...     title='FooBar',
...     text='foo',
...     parent_title='Yada',
...     comments='bar',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.WikiPage.save(**attrs)
Saves the current state of a WikiPage resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> wiki_page = redmine.wiki_page.get('Foo', project_id='vacation')
>>> wiki_page.title = 'Bar'
>>> wiki_page.text = 'bar'
>>> wiki_page.parent_title = 'Yada'
>>> wiki_page.comments = 'changed foo to bar'
>>> wiki_page.uploads = [{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
>>> wiki_page.save()
<redminelib.resources.WikiPage "Bar">


Added in version 2.1.0: Alternative syntax was introduced.

>>> wiki_page = redmine.wiki_page.get('Foo', project_id='vacation').save(
...     title='Bar',
...     text='bar',
...     parent_title='Yada',
...     comments='changed foo to bar',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': '/absolute/path/to/file2'}]
... )
>>> wiki_page
<redminelib.resources.WikiPage "Bar">


Delete methods

delete

redminelib.managers.WikiPageManager.delete(resource_id, **params)
Deletes single WikiPage resource from Redmine by its title.
Parameters
  • resource_id (string) – (required). Title of the wiki page.
  • project_id (int or string) – (required). Id or identifier of wiki page’s project.

Returns
True


>>> redmine.wiki_page.delete('Foo', project_id=1)
True


redminelib.resources.WikiPage.delete()
Deletes current WikiPage resource object from Redmine.
Returns
True


>>> wiki = redmine.wiki_page.get('Foo', project_id=1)
>>> wiki.delete()
True


Export

Added in version 2.0.0.

redminelib.resources.WikiPage.export(fmt, savepath=None, filename=None)
Exports WikiPage resource in one of the following formats: pdf, html, txt
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> wiki = redmine.wiki_page.get('Foo', project_id=1)
>>> wiki.export('pdf', savepath='/home/jsmith')
'/home/jsmith/123.pdf'


Query

Supported by Redmine starting from version 1.3

Manager

All operations on the Query resource are provided by its manager. To get access to it you have to call redmine.query where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single Query resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the query.
Returns
Resource object


>>> query = redmine.query.get(654)
>>> query
<redminelib.resources.Query #654 "Done">


all

redminelib.managers.ResourceManager.all(**params)
Returns all Query resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> queries = redmine.query.all(offset=10, limit=100)
>>> queries
<redminelib.resultsets.ResourceSet object with Query resources>


filter

Not supported by Redmine

Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

File

Supported by Redmine starting from version 3.4

Manager

All operations on the File resource are provided by its manager. To get access to it you have to call redmine.file where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.FileManager.create(**fields)
Creates new File resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of file’s project.
  • path (string) – (required). Absolute file path or file-like object that should be uploaded.
  • filename (string) – (optional). Name of the file after upload.
  • description (string) – (optional). Description of the file.
  • content_type (string) – (optional). Content type of the file.
  • version_id (int) – (optional). File’s version id.

Returns
Resource object


>>> f = redmine.file.create(
...     project_id='vacation',
...     path='/absolute/path/to/file',
...     filename='foo.txt',
...     description='foobar',
...     content_type='text/plain',
...     version_id=1
... )
>>> f
<redminelib.resources.File #1 "foo.txt">


new

redminelib.managers.FileManager.new()
Creates new empty File resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> f = redmine.file.new()
>>> f.project_id = 'vacation'
>>> f.path = '/absolute/path/to/file'
>>> f.filename = 'foo.txt'
>>> f.description = 'foobar'
>>> f.content_type = 'text/plain'
>>> f.version_id = 1
>>> f.save()
<redminelib.resources.File #1 "foo.txt">


WARNING:

Redmine’s File API doesn’t return a file object after create operation. Due to the fact that it goes against the behaviour of all other API endpoints, Python-Redmine has to do some tricks under the hood to return a resource object with at least an id attribute. That doesn’t involve any additional API requests. In most cases that should be enough, but if it’s not and a complete resource object is needed, one has to use a refresh() method to make an additional query to the Redmine to retrieve a complete resource:

>>> f = redmine.file.new()
>>> f.project_id = 'vacation'
>>> f.path = '/absolute/path/to/file'
>>> f.filename = 'foo.txt'
>>> f.description = 'foobar'
>>> f.content_type = 'text/plain'
>>> f.version_id = 1
>>> f.save()
<redminelib.resources.File #1>
>>> f.refresh()
>>> f
<redminelib.resources.File #1 "foo.txt">




Read methods

get

redminelib.managers.FileManager.get(resource_id)
Returns single File resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the file.
Returns
Resource object


>>> f = redmine.file.get(12345)
>>> f
<redminelib.resources.File #12345 "foo.txt">


HINT:

Files can be easily downloaded via the provided download() method which is a proxy to the redmine.download() method which provides several options to control the saving process (see docs for details):

>>> f = redmine.file.get(12345)
>>> filepath = f.download(savepath='/usr/local/', filename='image.jpg')
>>> filepath
'/usr/local/image.jpg'




all

Not supported by Redmine

filter

redminelib.managers.FileManager.filter(**filters)
Returns File resources that match the given lookup parameters.
Parameters
project_id (int or string) – (optional). Get files from the project with given id.
Returns
ResourceSet object


>>> files = redmine.file.filter(project_id='vacation')
>>> files
<redminelib.resultsets.ResourceSet object with File resources>


HINT:

You can also get files from a Project resource object directly using files relation:

>>> project = redmine.project.get('vacation')
>>> project.files
<redminelib.resultsets.ResourceSet object with File resources>




Update methods

update

redminelib.managers.FileManager.update(resource_id, **fields)
Updates values of given fields of a File resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). File id.
  • filename (string) – (optional). File name.
  • description (string) – (optional). File description.
  • content_type (string) – (optional). File content-type.

Returns
True


>>> redmine.file.update(
...     1,
...     filename='foo.txt',
...     description='foobar',
...     content_type='text/plain'
... )
True


save

redminelib.resources.File.save(**attrs)
Saves the current state of a File resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> f = redmine.file.get(1)
>>> f.filename = 'foo.txt'
>>> f.description = 'foobar'
>>> f.content_type = 'text/plain'
>>> f.save()
<redminelib.resources.File #1 "foo.txt">


Added in version 2.1.0: Alternative syntax was introduced.

>>> f = redmine.file.get(1).save(
...     filename='foo.txt',
...     description='foobar',
...     content_type='text/plain'
... )
>>> f
<redminelib.resources.File #1 "foo.txt">


Delete methods

delete

redminelib.managers.FileManager.delete(resource_id)
Deletes single File resource from Redmine by its id.
Parameters
resource_id (int) – (required). File id.
Returns
True


>>> redmine.file.delete(12345)
True


redminelib.resources.File.delete()
Deletes current File resource object from Redmine.
Returns
True


>>> f = redmine.file.get(12345)
>>> f.delete()
True


Export

Export functionality doesn’t make sense for files as they can be downloaded

Attachment

Supported by Redmine starting from version 1.3

Manager

All operations on the Attachment resource are provided by its manager. To get access to it you have to call redmine.attachment where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine. Some resources support adding attachments via their create/update methods, e.g. Issue, WikiPage.

Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single Attachment resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the attachment.
Returns
Resource object


>>> attachment = redmine.attachment.get(76905)
>>> attachment
<redminelib.resources.Attachment #76905 "1(a).png">


HINT:

Attachment can be easily downloaded via the provided download() method which is a proxy to the redmine.download() method which provides several options to control the saving process (see docs for details):

>>> attachment = redmine.attachment.get(76905)
>>> filepath = attachment.download(savepath='/usr/local/', filename='image.jpg')
>>> filepath
'/usr/local/image.jpg'




all

Not supported by Redmine

filter

Not supported by Redmine

Update methods

Added in version 2.1.0.

Requires Redmine >= 3.4.0

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an Attachment resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Attachment id.
  • filename (string) – (optional). File name.
  • description (string) – (optional). File description.
  • content_type (string) – (optional). File content-type.

Returns
True


>>> redmine.attachment.update(
...     1,
...     filename='foo.txt',
...     description='foobar',
...     content_type='text/plain'
... )
True


save

redminelib.resources.Attachment.save(**attrs)
Saves the current state of an Attachment resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> attachment = redmine.attachment.get(1)
>>> attachment.filename = 'foo.txt'
>>> attachment.description = 'foobar'
>>> attachment.content_type = 'text/plain'
>>> attachment.save()
<redminelib.resources.Attachment #1 "foo.txt">


Added in version 2.1.0: Alternative syntax was introduced.

>>> attachment = redmine.attachment.get(1).save(
...     filename='foo.txt',
...     description='foobar',
...     content_type='text/plain'
... )
>>> attachment
<redminelib.resources.Attachment #1 "foo.txt">


Delete methods

Added in version 2.0.0.

Requires Redmine >= 3.3.0

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Attachment resource from Redmine by its id.
Parameters
resource_id (int) – (required). Attachment id.
Returns
True


>>> redmine.attachment.delete(76905)
True


redminelib.resources.Attachment.delete()
Deletes current Attachment resource object from Redmine.
Returns
True


>>> attachment = redmine.attachment.get(76905)
>>> attachment.delete()
True


Export

Export functionality doesn’t make sense for attachments as they can be downloaded

Issue Status

Supported by Redmine starting from version 1.3

Manager

All operations on the IssueStatus resource are provided by its manager. To get access to it you have to call redmine.issue_status where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single IssueStatus resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the issue status.
Returns
Resource object


>>> status = redmine.issue_status.get(1)
>>> status
<redminelib.resources.IssueStatus #1 "Rejected">


all

redminelib.managers.ResourceManager.all()
Returns all IssueStatus resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> statuses = redmine.issue_status.all()
>>> statuses
<redminelib.resultsets.ResourceSet object with IssueStatus resources>


HINT:

IssueStatus resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to an IssueStatus resource object. The relations provided by the IssueStatus resource object are:
issues

>>> statuses = redmine.issue_status.all()
>>> statuses[0]
<redminelib.resources.IssueStatus #1 "New">
>>> statuses[0].issues
<redminelib.resultsets.ResourceSet object with Issue resources>




filter

Not supported by Redmine

Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

Tracker

Supported by Redmine starting from version 1.3

Manager

All operations on the Tracker resource are provided by its manager. To get access to it you have to call redmine.tracker where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single Tracker resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the tracker.
Returns
Resource object


>>> tracker = redmine.tracker.get(1)
>>> tracker
<redminelib.resources.Tracker #1 "Task">


all

redminelib.managers.ResourceManager.all()
Returns all Tracker resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> trackers = redmine.tracker.all()
>>> trackers
<redminelib.resultsets.ResourceSet object with Tracker resources>


HINT:

Tracker resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a Tracker resource object. The relations provided by the Tracker resource object are:
issues

>>> trackers = redmine.tracker.all()
>>> trackers[0]
<redminelib.resources.Tracker #1 "FooBar">
>>> trackers[0].issues
<redminelib.resultsets.ResourceSet object with Issue resources>




filter

Not supported by Redmine

Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

Enumeration

Supported by Redmine starting from version 2.2

Manager

All operations on the Enumeration resource are provided by its manager. To get access to it you have to call redmine.enumeration where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Enumeration resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). Enumeration id.
  • resource (string) – .INDENT 2.0
  • issue_priorities
  • time_entry_activities
  • document_categories


Returns
Resource object



>>> enumeration = redmine.enumeration.get(1, resource='time_entry_activities')
>>> enumeration
<redminelib.resources.Enumeration #1 "Documenting">


all

Not supported by Redmine

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Enumeration resources that match the given lookup parameters.
Parameters
  • resource (string) – .INDENT 2.0
  • issue_priorities
  • time_entry_activities
  • document_categories

  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object



>>> enumerations = redmine.enumeration.filter(resource='time_entry_activities')
>>> enumerations
<redminelib.resultsets.ResourceSet object with Enumeration resources>


Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

Issue Category

Supported by Redmine starting from version 1.3

Manager

All operations on the IssueCategory resource are provided by its manager. To get access to it you have to call redmine.issue_category where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new IssueCategory resource with given fields and saves it to the Redmine.
Parameters
  • project_id (int or string) – (required). Id or identifier of issue category’s project.
  • name (string) – (required). Issue category name.
  • assigned_to_id (int) – (optional). The id of the user assigned to the category (new issues with this category will be assigned by default to this user).

Returns
Resource object


>>> category = redmine.issue_category.create(project_id='vacation', name='woohoo', assigned_to_id=13)
>>> category
<redminelib.resources.IssueCategory #810 "woohoo">


new

redminelib.managers.ResourceManager.new()
Creates new empty IssueCategory resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> category = redmine.issue_category.new()
>>> category.project_id = 'vacation'
>>> category.name = 'woohoo'
>>> category.assigned_to_id = 13
>>> category.save()
<redminelib.resources.IssueCategory #810 "woohoo">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single IssueCategory resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the issue category.
Returns
Resource object


>>> category = redmine.issue_category.get(794)
>>> category
<redminelib.resources.IssueCategory #794 "Malibu">


all

Not supported by Redmine

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns IssueCategory resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Get issue categories from the project with the given id, where id is either project id or project identifier.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> categories = redmine.issue_category.filter(project_id='vacation')
>>> categories
<redminelib.resultsets.ResourceSet object with IssueCategory resources>


HINT:

You can also get issue categories from a Project resource object directly using issue_categories relation:

>>> project = redmine.project.get('vacation')
>>> project.issue_categories
<redminelib.resultsets.ResourceSet object with IssueCategory resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an IssueCategory resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Issue category id.
  • name (string) – (optional). Issue category name.
  • assigned_to_id (int) – (optional). The id of the user assigned to the category (new issues with this category will be assigned by default to this user).

Returns
True


>>> redmine.issue_category.update(1, name='woohoo', assigned_to_id=13)
True


save

redminelib.resources.IssueCategory.save(**attrs)
Saves the current state of an IssueCategory resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> category = redmine.issue_category.get(1)
>>> category.name = 'woohoo'
>>> category.assigned_to_id = 13
>>> category.save()
<redminelib.resources.IssueCategory #1 "woohoo">


Added in version 2.1.0: Alternative syntax was introduced.

>>> category = redmine.issue_category.get(1).save(
...     name='woohoo',
...     assigned_to_id=13
... )
>>> category
<redminelib.resources.IssueCategory #1 "woohoo">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id, **params)
Deletes single IssueCategory resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). Issue category id.
  • reassign_to_id (int) – (optional). When there are issues assigned to the category you are deleting, this parameter lets you reassign these issues to the category with given id.

Returns
True


>>> redmine.issue_category.delete(1, reassign_to_id=2)
True


redminelib.resources.IssueCategory.delete()
Deletes current IssueCategory resource object from Redmine.
Parameters
reassign_to_id (int) – (optional). When there are issues assigned to the category you are deleting, this parameter lets you reassign these issues to the category with given id.
Returns
True


>>> category = redmine.issue_category.get(794)
>>> category.delete(reassign_to_id=2)
True


Export

Not supported by Redmine

Role

Supported by Redmine starting from version 1.4

Manager

All operations on the Role resource are provided by its manager. To get access to it you have to call redmine.role where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single Role resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the role.
Returns
Resource object


>>> role = redmine.role.get(4)
>>> role
<redminelib.resources.Role #4 "Waiter">


all

redminelib.managers.ResourceManager.all()
Returns all Role resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> roles = redmine.role.all()
>>> roles
<redminelib.resultsets.ResourceSet object with Role resources>


filter

Not supported by Redmine

Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

Group

Supported by Redmine starting from version 2.1

Manager

All operations on the Group resource are provided by its manager. To get access to it you have to call redmine.group where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Group resource with given fields and saves it to the Redmine.
Parameters
  • name (string) – (required). Group name.
  • user_ids (list) – (optional). Ids of users who will be members of a group.

Returns
Resource object


>>> group = redmine.group.create(name='Developers', user_ids=[13, 15, 25])
>>> group
<redminelib.resources.Group #8 "Developers">


new

redminelib.managers.ResourceManager.new()
Creates new empty Group resource but saves it to the Redmine only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> group = redmine.group.new()
>>> group.name = 'Developers'
>>> group.user_ids = [13, 15, 25]
>>> group.save()
<redminelib.resources.Group #8 "Developers">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single group resource from Redmine by its id.
Parameters
  • resource_id (int) – (required). Id of the group.
  • include (list) – .INDENT 2.0
  • memberships
  • users


Returns
Resource object



>>> group = redmine.group.get(524, include=['memberships', 'users'])
>>> group
<redminelib.resources.Group #524 "DESIGN">


HINT:

Group resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Group resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Group resource object are the same as in the get() method above:

>>> group = redmine.group.get(524)
>>> group.users
<redminelib.resultsets.ResourceSet object with User resources>




all

redminelib.managers.ResourceManager.all()
Returns all Group resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> groups = redmine.group.all()
>>> groups
<redminelib.resultsets.ResourceSet object with Group resources>


filter

Not supported by Redmine

Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Group resource and saves them to the Redmine.
Parameters
  • resource_id (int) – (required). Group id.
  • name (string) – (optional). Group name.
  • user_ids (list) – (optional). Ids of users who will be members of a group.

Returns
True


>>> redmine.group.update(1, name='Developers', user_ids=[13, 15, 25])
True


save

redminelib.resources.Group.save(**attrs)
Saves current state of a Group resource to the Redmine. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> group = redmine.group.get(1)
>>> group.name = 'Developers'
>>> group.user_ids = [13, 15, 25]
>>> group.save()
<redminelib.resources.Group #1 "Developers">


Added in version 2.1.0: Alternative syntax was introduced.

>>> group = redmine.group.get(1).save(
...     name='Developers',
...     user_ids=[13, 15, 25]
... )
>>> group
<redminelib.resources.Group #1 "Developers">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Group resource from Redmine by its id.
Parameters
resource_id (int) – (required). Group id.
Returns
True


>>> redmine.group.delete(1)
True


redminelib.resources.Group.delete()
Deletes current Group resource object from Redmine.
Returns
True


>>> group = redmine.group.get(1)
>>> group.delete()
True


Export

Not supported by Redmine

Users

Python-Redmine provides 2 methods to work with group users:

add

redminelib.resources.Group.User.add(user_id)
Adds a user to a group by its id.
Parameters
user_id (int) – (required). User id.
Returns
True


>>> group = redmine.group.get(1)
>>> group.user.add(1)
True


remove

redminelib.resources.Group.User.remove(user_id)
Removes a user from a group by its id.
Parameters
user_id (int) – (required). User id.
Returns
True


>>> group = redmine.group.get(1)
>>> group.user.remove(1)
True


Custom Field

Supported by Redmine starting from version 2.4

Manager

All operations on the CustomField resource are provided by its manager. To get access to it you have to call redmine.custom_field where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Redmine

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single CustomField resource from Redmine by its id.
Parameters
resource_id (int) – (required). Id of the custom field.
Returns
Resource object


>>> field = redmine.custom_field.get(1)
>>> field
<redminelib.resources.CustomField #1 "Vendor">


all

redminelib.managers.ResourceManager.all()
Returns all CustomField resources from Redmine.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> fields = redmine.custom_field.all()
>>> fields
<redminelib.resultsets.ResourceSet object with CustomField resources>


filter

Not supported by Redmine

Update methods

Not supported by Redmine

Delete methods

Not supported by Redmine

Export

Not supported by Redmine

RedmineUP CRM

Contact

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the Contact resource are provided by its manager. To get access to it you have to call redmine.contact where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Contact resource with given fields and saves it to the CRM plugin.
Parameters
  • project_id (int or string) – (required). Id or identifier of contact’s project.
  • first_name (string) – (required). Contact first name.
  • last_name (string) – (optional). Contact last name.
  • middle_name (string) – (optional). Contact middle name.
  • company (string) – (optional). Contact company name.
  • phones (list) – (optional). List of phone numbers.
  • emails (list) – (optional). List of emails.
  • website (string) – (optional). Contact website.
  • skype_name (string) – (optional). Contact skype.
  • birthday (string or date object) – (optional). Contact birthday.
  • background (string) – (optional). Contact background.
  • job_title (string) – (optional). Contact job title.
  • tag_list (list) – (optional). List of tags.
  • is_company (bool) – (optional). Whether contact is a company.
  • assigned_to_id (int) – (optional). Contact will be assigned to this user id.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • address_attributes (dict) – .INDENT 2.0
  • street1 - first line for the street details
  • street2 - second line for the street details
  • city - city
  • region - region (state)
  • postcode - ZIP code
  • country_code - country code as two-symbol abbreviation (e.g. US)

  • visibility (int) – .INDENT 2.0
  • 0 - project
  • 1 - public
  • 2 - private

  • avatar (dict) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Required if a file-like object is provided.


Returns
Resource object




>>> contact = redmine.contact.create(
...     project_id='vacation',
...     first_name='Ivan',
...     last_name='Ivanov',
...     middle_name='Ivanovich',
...     company='Ivan Gmbh',
...     phones=['1234567'],
...     emails=['ivan@ivanov.com'],
...     website='ivanov.com',
...     skype_name='ivan.ivanov',
...     birthday=datetime.date(1980, 10, 21),
...     background='some background here',
...     job_title='CEO',
...     tag_list=['vip', 'online'],
...     is_company=False,
...     address_attributes={'street1': 'foo', 'street2': 'bar', 'city': 'Moscow', 'postcode': '111111', 'country_code': 'RU'},
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     visibility=0,
...     avatar={'path': '/absolute/path/to/file.jpg'}
... )
>>> contact
<redminelib.resources.Contact #1 "Ivan Ivanov">


new

redminelib.managers.ResourceManager.new()
Creates new empty Contact resource but saves it to the the CRM plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> contact = redmine.contact.new()
>>> contact.project_id = 'vacation'
>>> contact.first_name = 'Ivan'
>>> contact.last_name = 'Ivanov'
>>> contact.middle_name = 'Ivanovich'
>>> contact.company = 'Ivan Gmbh'
>>> contact.phones = ['1234567']
>>> contact.emails = ['ivan@ivanov.com']
>>> contact.website = 'ivanov.com'
>>> contact.skype_name = 'ivan.ivanov'
>>> contact.birthday = datetime.date(1980, 10, 21)
>>> contact.background = 'some background here'
>>> contact.job_title = 'CEO'
>>> contact.tag_list = ['vip', 'online']
>>> contact.is_company = False
>>> contact.address_attributes = {'street1': 'foo', 'street2': 'bar', 'city': 'Moscow', 'postcode': '111111', 'country_code': 'RU'}
>>> contact.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> contact.visibility = 0
>>> contact.avatar = {'path': '/absolute/path/to/file.jpg'}
>>> contact.save()
<redminelib.resources.Contact #1 "Ivan Ivanov">


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Contact resource from the CRM plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the contact.
  • include (list) – .INDENT 2.0
  • notes
  • contacts
  • deals
  • issues
  • projects
  • tickets (requires Pro Edition and Helpdesk plugin >= 4.1.12)


Returns
Resource object



>>> contact = redmine.contact.get(12345, include=['notes', 'contacts', 'deals', 'issues', 'projects'])
>>> contact
<redminelib.resources.Contact #12345 "Ivan Ivanov">


HINT:

Contact resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Contact resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Contact resource object are the same as in the get() method above:

>>> contact = redmine.contact.get(12345)
>>> contact.issues
<redminelib.resultsets.ResourceSet object with Issue resources>




HINT:

Contact resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a Contact resource object. The relations provided by the Contact resource object are:
  • invoices (requires Pro Edition and Invoices plugin >= 4.1.3)
  • payments (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expenses (requires Pro Edition and Invoices plugin >= 4.1.3)
  • orders (requires Pro Edition and Products plugin >= 2.1.5)

>>> contact = redmine.contact.get(12345)
>>> contact.invoices
<redminelib.resultsets.ResourceSet object with Invoice resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Contact resources from the CRM plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.
  • include (list) – .INDENT 2.0
  • projects


Returns
ResourceSet object



>>> contacts = redmine.contact.all(offset=10, limit=100, include=['projects'])
>>> contacts
<redminelib.resultsets.ResourceSet object with Contact resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Contact resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Id or identifier of contact’s project.
  • assigned_to_id (int) – (optional). Get contacts assigned to this user id.
  • query_id (int) – (optional). Get contacts for the given query id.
  • search (string) – (optional). Get contacts with given search string.
  • tags (string) – (optional). Get contacts with given tags (separated by ,).
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.
  • include (list) – .INDENT 2.0
  • projects


Returns
ResourceSet object



>>> contacts = redmine.contact.filter(project_id='vacation', assigned_to_id=123, search='Smith', tags='one,two', include=['projects'])
>>> contacts
<redminelib.resultsets.ResourceSet object with Contact resources>


HINT:

You can also get contacts from a Project and User resource objects directly using contacts relation:

>>> project = redmine.project.get('vacation')
>>> project.contacts
<redminelib.resultsets.ResourceSet object with Contact resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Contact resource and saves them to the CRM plugin.
Parameters
  • resource_id (int) – (required). Contact id.
  • first_name (string) – (optional). Contact first name.
  • last_name (string) – (optional). Contact last name.
  • middle_name (string) – (optional). Contact middle name.
  • company (string) – (optional). Contact company name.
  • phones (list) – (optional). List of phone numbers.
  • emails (list) – (optional). List of emails.
  • website (string) – (optional). Contact website.
  • skype_name (string) – (optional). Contact skype.
  • birthday (string or date object) – (optional). Contact birthday.
  • background (string) – (optional). Contact background.
  • job_title (string) – (optional). Contact job title.
  • tag_list (list) – (optional). List of tags.
  • is_company (bool) – (optional). Whether contact is a company.
  • assigned_to_id (int) – (optional). Contact will be assigned to this user id.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • address_attributes (dict) – .INDENT 2.0
  • street1 - first line for the street details
  • street2 - second line for the street details
  • city - city
  • region - region (state)
  • postcode - ZIP code
  • country_code - country code as two-symbol abbreviation (e.g. US)

  • visibility (int) – .INDENT 2.0
  • 0 - project
  • 1 - public
  • 2 - private

  • avatar (dict) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Required if a file-like object is provided.


Returns
True




>>> redmine.contact.update(
...     12345,
...     first_name='Ivan',
...     last_name='Ivanov',
...     middle_name='Ivanovich',
...     company='Ivan Gmbh',
...     phones=['1234567'],
...     emails=['ivan@ivanov.com'],
...     website='ivanov.com',
...     skype_name='ivan.ivanov',
...     birthday=datetime.date(1980, 10, 21),
...     background='some background here',
...     job_title='CEO',
...     tag_list=['vip', 'online'],
...     is_company=False,
...     address_attributes={'street1': 'foo', 'street2': 'bar', 'city': 'Moscow', 'postcode': '111111', 'country_code': 'RU'},
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     visibility=0,
...     avatar={'path': '/absolute/path/to/file.jpg'}
... )
True


save

redminelib.resources.Contact.save(**attrs)
Saves the current state of a Contact resource to the CRM plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> contact = redmine.contact.get(12345)
>>> contact.first_name = 'Ivan'
>>> contact.last_name = 'Ivanov'
>>> contact.middle_name = 'Ivanovich'
>>> contact.company = 'Ivan Gmbh'
>>> contact.phones = ['1234567']
>>> contact.emails = ['ivan@ivanov.com']
>>> contact.website = 'ivanov.com'
>>> contact.skype_name = 'ivan.ivanov'
>>> contact.birthday = datetime.date(1980, 10, 21)
>>> contact.background = 'some background here'
>>> contact.job_title = 'CEO'
>>> contact.tag_list = ['vip', 'online']
>>> contact.is_company = False
>>> contact.address_attributes = {'street1': 'foo', 'street2': 'bar', 'city': 'Moscow', 'postcode': '111111', 'country_code': 'RU'}
>>> contact.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> contact.visibility = 0
>>> contact.avatar = {'path': '/absolute/path/to/file.jpg'}
>>> contact.save()
<redminelib.resources.Contact #12345 "Ivan Ivanov">


Added in version 2.1.0: Alternative syntax was introduced.

>>> contact = redmine.contact.get(12345).save(
...     first_name='Ivan',
...     last_name='Ivanov',
...     middle_name='Ivanovich',
...     company='Ivan Gmbh',
...     phones=['1234567'],
...     emails=['ivan@ivanov.com'],
...     website='ivanov.com',
...     skype_name='ivan.ivanov',
...     birthday=datetime.date(1980, 10, 21),
...     background='some background here',
...     job_title='CEO',
...     tag_list=['vip', 'online'],
...     is_company=False,
...     address_attributes={'street1': 'foo', 'street2': 'bar', 'city': 'Moscow', 'postcode': '111111', 'country_code': 'RU'},
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     visibility=0,
...     avatar={'path': '/absolute/path/to/file.jpg'}
... )
>>> contact
<redminelib.resources.Contact #12345 "Ivan Ivanov">


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Contact resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Contact id.
Returns
True


>>> redmine.contact.delete(1)
True


redminelib.resources.Contact.delete()
Deletes current Contact resource object from the CRM plugin.
Returns
True


>>> contact = redmine.contact.get(1)
>>> contact.delete()
True


Export

Added in version 2.0.0.

redminelib.resources.Contact.export(fmt, savepath=None, filename=None)
Exports Contact resource in one of the following formats: atom, vcf
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> contact = redmine.contact.get(123)
>>> contact.export('pdf', savepath='/home/jsmith')
'/home/jsmith/123.pdf'


redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Contact resources in one of the following formats: atom, csv, vcf, xls
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> contacts = redmine.contact.all()
>>> contacts.export('csv', savepath='/home/jsmith', filename='contacts.csv')
'/home/jsmith/contacts.csv'


Projects

Python-Redmine provides 2 methods to work with contact projects:

add

redminelib.resources.Contact.Project.add(project_id)
Adds project to contact’s project list.
Parameters
project_id (int or string) – (required). Id or identifier of a project.
Returns
True


>>> contact = redmine.contact.get(1)
>>> contact.project.add('vacation')
True


remove

redminelib.resources.Contact.Project.remove(project_id)
Removes project from contact’s project list.
Parameters
project_id (int or string) – (required). Id or identifier of a project.
Returns
True


>>> contact = redmine.contact.get(1)
>>> contact.project.remove('vacation')
True


Contact Tag

Requires Pro Edition and CRM plugin >= 3.4.0.

Manager

All operations on the ContactTag resource are provided by its manager. To get access to it you have to call redmine.contact_tag where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by CRM plugin

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single ContactTag resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Id of the contact tag.
Returns
Resource object


>>> tag = redmine.contact_tag.get(1)
>>> tag
<redminelib.resources.ContactTag #1 "Online">


all

redminelib.managers.ResourceManager.all()
Returns all ContactTag resources from the CRM plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> tags = redmine.contact_tag.all()
>>> tags
<redminelib.resultsets.ResourceSet object with ContactTag resources>


filter

Not supported by CRM plugin

Update methods

Not supported by CRM plugin

Delete methods

Not supported by CRM plugin

Export

Not supported by CRM plugin

Note

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the Note resource are provided by its manager. To get access to it you have to call redmine.note where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Added in version 2.4.0.

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Note resource with given fields and saves it to the CRM plugin.
Parameters
  • project_id (int or string) – (required). Id or identifier of note’s project.
  • source_type (string) – (required). Resource type, note will belong to: Contact or Deal.
  • source_id (int) – (required). Id of the resource, note will belong to, depending on the chosen source_type.
  • content (string) – (optional). Note content.
  • subject (string) – (optional). Note subject.
  • type_id (int) – .INDENT 2.0
  • 0 - email
  • 1 - call
  • 2 - meeting

  • created_on (string or date object) – (optional). Date when note was created.
  • note_time (string) – (optional). Time when note was created.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object




>>> note = redmine.note.create(
...     project_id='vacation',
...     source_type='Contact',
...     source_id=12,
...     subject='note subject',
...     content='note content',
...     type_id=3,
...     created_on='2023-01-10',
...     note_time='11:11',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> note
<redminelib.resources.Note #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Note resource but saves it to the CRM plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> note = redmine.note.new()
>>> note.project_id = 'vacation'
>>> note.source_type = 'Contact'
>>> note.source_id = 12
>>> note.subject = 'note subject'
>>> note.content = 'note content'
>>> note.type_id = 3
>>> note.created_on = '2023-01-10'
>>> note.note_time = '11:11'
>>> note.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> note.save()
<redminelib.resources.Note #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single Note resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Id of the note.
Returns
Resource object


>>> note = redmine.note.get(12345)
>>> note
<redminelib.resources.Note #12345>


all

Not supported by CRM plugin

filter

Not supported by CRM plugin

Update methods

Added in version 2.4.0.

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Note resource and saves them to the CRM plugin.
Parameters
  • resource_id (int) – (required). Note id.
  • content (string) – (optional). Note content.
  • subject (string) – (optional). Note subject.
  • type_id (int) – .INDENT 2.0
  • 0 - email
  • 1 - call
  • 2 - meeting

  • created_on (string or date object) – (optional). Date when note was created.
  • note_time (string) – (optional). Time when note was created.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True




>>> redmine.note.update(
...     123,
...     subject='note subject',
...     content='note content',
...     type_id=3,
...     created_on='2023-01-10',
...     note_time='11:11',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Note.save(**attrs)
Saves the current state of a Note resource to the CRM plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> note = redmine.note.get(123)
>>> note.subject = 'note subject'
>>> note.content = 'note content'
>>> note.type_id = 3
>>> note.created_on = '2023-01-10'
>>> note.note_time = '11:11'
>>> note.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> note.save()
<redminelib.resources.Note #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> note = redmine.note.get(123).save(
...     subject='note subject',
...     content='note content',
...     type_id=3,
...     created_on='2023-01-10',
...     note_time='11:11',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> note
<redminelib.resources.Note #123>


Delete methods

Added in version 2.4.0.

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Note resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Note id.
Returns
True


>>> redmine.note.delete(123)
True


redminelib.resources.Note.delete()
Deletes current Note resource object from the CRM plugin.
Returns
True


>>> note = redmine.note.get(1)
>>> note.delete()
True


Export

Not supported by CRM plugin

Deal

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the Deal resource are provided by its manager. To get access to it you have to call redmine.deal where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Deal resource with given fields and saves it to the CRM plugin.
Parameters
  • project_id (int or string) – (required). Id or identifier of deal’s project.
  • name (string) – (required). Deal name.
  • contact_id (int) – (optional). Deal contact id.
  • price (int) – (optional). Deal price.
  • currency (string) – (optional). Deal currency.
  • probability (int) – (optional). Deal probability.
  • due_date (string or date object) – (optional). Deal should be won by this date.
  • background (string) – (optional). Deal background.
  • status_id (int) – (optional). Deal status id.
  • category_id (int) – (optional). Deal category id.
  • assigned_to_id (int) – (optional). Deal will be assigned to this user id.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].

Returns
Resource object


>>> deal = redmine.deal.create(
...     project_id='vacation',
...     name='FooBar',
...     contact_id=1,
...     price=1000,
...     currency='EUR',
...     probability=80,
...     due_date=datetime.date(2014, 12, 12),
...     background='some deal background',
...     status_id=1,
...     category_id=1,
...     assigned_to_id=12,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> deal
<redminelib.resources.Deal #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Deal resource but saves it to the CRM plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> deal = redmine.deal.new()
>>> deal.project_id = 'vacation'
>>> deal.name = 'FooBar'
>>> deal.contact_id = 1
>>> deal.price = 1000
>>> deal.currency = 'EUR'
>>> deal.probability = 80
>>> deal.due_date = datetime.date(2014, 12, 12)
>>> deal.background = 'some deal background'
>>> deal.status_id = 1
>>> deal.category_id = 1
>>> deal.assigned_to_id = 12
>>> deal.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> deal.save()
<redminelib.resources.Deal #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Deal resource from the CRM plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the deal.
  • include (list) – .INDENT 2.0
  • notes


Returns
Resource object



>>> deal = redmine.deal.get(123, include=['notes'])
>>> deal
<redminelib.resources.Deal #123>


HINT:

Deal resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Deal resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Deal resource object are the same as in the get() method above:

>>> deal = redmine.deal.get(123)
>>> deal.notes
<redminelib.resultsets.ResourceSet object with Note resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Deal resources from the CRM plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> deals = redmine.deal.all(limit=50)
>>> deals
<redminelib.resultsets.ResourceSet object with Deal resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Deal resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Id or identifier of deal’s project.
  • assigned_to_id (int) – (optional). Get deals which are assigned to this user id.
  • query_id (int) – (optional). Get deals for the given query id.
  • status_id (int) – (optional). Get deals which have this status id.
  • search (string) – (optional). Get deals with given search string.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> deals = redmine.deal.filter(project_id='vacation', assigned_to_id=123, status_id=1, search='Smith')
>>> deals
<redminelib.resultsets.ResourceSet object with Deal resources>


HINT:

You can also get deals from a Project, User, DealStatus and CrmQuery resource objects directly using deals relation:

>>> project = redmine.project.get('vacation')
>>> project.deals
<redminelib.resultsets.ResourceSet object with Deal resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Deal resource and saves them to the CRM plugin.
Parameters
  • resource_id (int) – (required). Deal id.
  • name (string) – (optional). Deal name.
  • contact_id (int) – (optional). Deal contact id.
  • price (int) – (optional). Deal price.
  • currency (string) – (optional). Deal currency.
  • probability (int) – (optional). Deal probability.
  • due_date (string or date object) – (optional). Deal should be won by this date.
  • background (string) – (optional). Deal background.
  • status_id (int) – (optional). Deal status id.
  • category_id (int) – (optional). Deal category id.
  • assigned_to_id (int) – (optional). Deal will be assigned to this user id.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].

Returns
True


>>> redmine.deal.update(
...     123,
...     name='FooBar',
...     contact_id=1,
...     price=1000,
...     currency='EUR',
...     probability=80,
...     due_date=datetime.date(2014, 12, 12),
...     background='some deal background',
...     status_id=1,
...     category_id=1,
...     assigned_to_id=12,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
True


save

redminelib.resources.Deal.save(**attrs)
Saves the current state of a Deal resource to the CRM plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> deal = redmine.deal.get(123)
>>> deal.name = 'FooBar'
>>> deal.contact_id = 1
>>> deal.price = 1000
>>> deal.currency = 'EUR'
>>> deal.probability = 80
>>> deal.due_date = datetime.date(2014, 12, 12)
>>> deal.background = 'some deal background'
>>> deal.status_id = 1
>>> deal.category_id = 1
>>> deal.assigned_to_id = 12
>>> deal.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> deal.save()
<redminelib.resources.Deal #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> deal = redmine.deal.get(123).save(
...     contact_id=1,
...     price=1000,
...     currency='EUR',
...     probability=80,
...     due_date=datetime.date(2014, 12, 12),
...     background='some deal background',
...     status_id=1,
...     category_id=1,
...     assigned_to_id=12,
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
... )
>>> deal
<redminelib.resources.Deal #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Deal resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Deal id.
Returns
True


>>> redmine.deal.delete(123)
True


redminelib.resources.Deal.delete()
Deletes current Deal resource object from the CRM plugin.
Returns
True


>>> deal = redmine.deal.get(1)
>>> deal.delete()
True


Export

Added in version 2.0.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Deal resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> deals = redmine.deal.all()
>>> deals.export('csv', savepath='/home/jsmith', filename='deals.csv')
'/home/jsmith/deals.csv'


Deal Status

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the DealStatus resource are provided by its manager. To get access to it you have to call redmine.deal_status where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by CRM plugin

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id)
Returns single DealStatus resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Id of the deal status.
Returns
Resource object


>>> status = redmine.deal_status.get(1)
>>> status
<redminelib.resources.DealStatus #1 "Lost">


HINT:

DealStatus resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a DealStatus resource object. The relations provided by the DealStatus resource object are:
deals

>>> statuses = redmine.deal_status.all()
>>> statuses[0]
<redminelib.resources.DealStatus #1 "New">
>>> statuses[0].deals
<redminelib.resultsets.ResourceSet object with Deal resources>




all

redminelib.managers.ResourceManager.all()
Returns all DealStatus resources from the CRM plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> statuses = redmine.deal_status.all()
>>> statuses
<redminelib.resultsets.ResourceSet object with DealStatus resources>


filter

Not supported by CRM plugin

Update methods

Not supported by CRM plugin

Delete methods

Not supported by CRM plugin

Export

Not supported by CRM plugin

Deal Category

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the DealCategory resource are provided by its manager. To get access to it you have to call redmine.deal_category where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Added in version 2.5.0.

create

redminelib.managers.ResourceManager.create(**fields)
Creates new DealCategory resource with given fields and saves it to the CRM plugin.
Parameters
  • project_id (int or string) – (required). Id or identifier of deal category’s project.
  • name (string) – (required). Category name.

Returns
Resource object


>>> category = redmine.deal_category.create(project_id='vacation', name='Integration')
>>> category
<redminelib.resources.DealCategory #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty DealCategory resource, but saves it to the CRM plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> category = redmine.deal_category.new()
>>> category.project_id = 'vacation'
>>> category.name = 'Integration'
>>> category.save()
<redminelib.resources.DealCategory #123>


Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single DealCategory resource from the CRM plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the deal category.
  • project_id (int or string) – (required). Id or identifier of deal category’s project.

Returns
Resource object


>>> category = redmine.deal_category.get(1, project_id='vacation')
>>> category
<redminelib.resources.DealCategory #1 "Design">


all

Not supported by CRM plugin

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns DealCategory resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (required). Id or identifier of deal category’s project.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> categories = redmine.deal_category.filter(project_id='vacation')
>>> categories
<redminelib.resultsets.ResourceSet object with DealCategory resources>


HINT:

You can also get deal categories from a Project resource object directly using deal_categories relation:

>>> project = redmine.project.get('vacation')
>>> project.deal_categories
<redminelib.resultsets.ResourceSet object with DealCategory resources>




Update methods

Added in version 2.5.0.

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a DealCategory resource and saves them to the CRM plugin.
Parameters
  • resource_id (int) – (required). Category id.
  • name (string) – (required). Category name.

Returns
True


>>> redmine.deal_category.update(123, name='Software')
True


save

redminelib.resources.DealCategory.save(**attrs)
Saves the current state of a DealCategory resource to the CRM plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> category = redmine.deal_category.get(123)
>>> category.name = 'Software'
>>> category.save()
<redminelib.resources.DealCategory #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> category = redmine.deal_category.get(123).save(name='Software')
>>> category
<redminelib.resources.DealCategory #123>


Delete methods

Added in version 2.5.0.

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single DealCategory resource from the CRM plugin by its id.
Parameters
resource_id (int) – (required). Category id.
Returns
True


>>> redmine.deal_category.delete(123)
True


redminelib.resources.DealCategory.delete()
Deletes current DealCategory resource object from the CRM plugin.
Returns
True


>>> category = redmine.deal_category.get(1)
>>> category.delete()
True


Export

Not supported by CRM plugin

CRM Query

Requires Pro Edition and CRM plugin >= 3.3.0.

Manager

All operations on the CrmQuery resource are provided by its manager. To get access to it you have to call redmine.crm_query where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by CRM plugin

Read methods

get

Added in version 2.1.0.

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single CrmQuery resource from the CRM plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the crm query.
  • resource (string) – .INDENT 2.0
  • contact
  • deal
  • invoice (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expense (requires Pro Edition and Invoices plugin >= 4.1.3)
  • product (requires Pro Edition and Products plugin >= 2.1.5)


Returns
Resource object



>>> query = redmine.crm_query.get(1, resource='contact')
>>> query
<redminelib.resources.CrmQuery #1 "By companies">


HINT:

CrmQuery resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to a CrmQuery resource object. The relations provided by the CrmQuery resource object are:
  • deals
  • contacts
  • invoices (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expenses (requires Pro Edition and Invoices plugin >= 4.1.3)
  • products (requires Pro Edition and Products plugin >= 2.1.5)

>>> queries = redmine.crm_query.filter(resource='deal')
>>> queries[0]
<redminelib.resources.CrmQuery #10 "Deals by category">
>>> queries[0].deals
<redminelib.resultsets.ResourceSet object with Deal resources>




all

Not supported by CRM plugin

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns crm query resources that match the given lookup parameters.
Parameters
  • resource (string) – .INDENT 2.0
  • contact
  • deal
  • invoice (requires Pro Edition and Invoices plugin >= 4.1.3)
  • expense (requires Pro Edition and Invoices plugin >= 4.1.3)
  • product (requires Pro Edition and Products plugin >= 2.1.5)

  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object



>>> queries = redmine.crm_query.filter(resource='contact')
>>> queries
<redminelib.resultsets.ResourceSet object with CrmQuery resources>


Update methods

Not supported by CRM plugin

Delete methods

Not supported by CRM plugin

Export

Not supported by CRM plugin

RedmineUP Helpdesk

Ticket

Added in version 2.4.0.

Requires Pro Edition and Helpdesk plugin >= 4.1.12.

Manager

All operations on the Ticket resource are provided by its manager. To get access to it you have to call redmine.ticket where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Ticket resource with given fields and saves it to the Helpdesk plugin.
Parameters
  • contact (dict) – (required). Can be either existing (the only required field is email then) contact or a new one, check Contact docs for a list of fields.
  • issue (dict) – .INDENT 2.0
  • project_id - ticket issue’s project id
  • tracker_id - be sure to set the correct tracker from Helpdesk plugin settings
  • subject - ticket issue’s subject
  • description - ticket issue’s content

  • ticket_date (string or date object) – (required). Ticket date.
  • ticket_time (string) – (required). Ticket time.
  • source (string) – .INDENT 2.0
  • 0 - email
  • 1 - web
  • 2 - phone
  • 4 - conversation

  • helpdesk_send_as (string) – .INDENT 2.0
  • 1 - notification
  • 2 - initial message

  • to_address (string) – (optional). To addresses (, separated).
  • cc_address (string) – (optional). Cc addresses (, separated).
  • is_incoming (bool) – (optional). Whether ticket is incoming.


Returns
Resource object




>>> ticket = redmine.ticket.create(
...     source='2',
...     helpdesk_send_as='2',
...     ticket_date='2023-01-10',
...     ticket_time='10:01',
...     to_address='support@product.com',
...     cc_address='managers@product.com,jsmith@product.com',
...     is_incoming=True,
...     issue={
...         'project_id': 'helpdesk',
...         'subject': 'ticket subject',
...         'tracker_id': 6,
...         'description': 'ticket content',
...     },
...     contact={
...         'email': 'existing_client@mail.com',
...     }
... )
>>> ticket
<redminelib.resources.Ticket #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Ticket resource, but saves it to the Helpdesk plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> ticket = redmine.ticket.new()
>>> ticket.source = '2'
>>> ticket.helpdesk_send_as = '2'
>>> ticket.ticket_date = '2023-01-10'
>>> ticket.ticket_time = '10:01'
>>> ticket.to_address = 'support@product.com'
>>> ticket.cc_address = 'managers@product.com,jsmith@product.com'
>>> ticket.is_incoming = True
>>> ticket.issue = {
...     'project_id': 'helpdesk',
...     'subject': 'ticket subject',
...     'tracker_id': 6,
...     'description': 'ticket content',
... }
>>> ticket.contact = {
...     'email': 'existing_client@mail.com',
... }
>>> ticket.save()
<redminelib.resources.Ticket #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Ticket resource from the Helpdesk plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the ticket.
  • include (list) – .INDENT 2.0
  • journals


Returns
Resource object



>>> ticket = redmine.ticket.get(123, include=['journals'])
>>> ticket
<redminelib.resources.Ticket #123>


HINT:

Ticket resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Ticket resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Ticket resource object are the same as in the get() method above:

>>> ticket = redmine.ticket.get(123)
>>> ticket.journals
<redminelib.resultsets.ResourceSet object with TicketJournal resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Ticket resources from the Helpdesk plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> tickets = redmine.ticket.all(limit=50)
>>> tickets
<redminelib.resultsets.ResourceSet object with Ticket resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Ticket resources that match the given lookup parameters.
Parameters
  • source (string) – (optional). Get tickets for the given source.
  • from_address (string) – (optional). Get tickets that were sent from this address.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> tickets = redmine.ticket.filter(source='2', from_address='client@mail.com')
>>> tickets
<redminelib.resultsets.ResourceSet object with Ticket resources>


HINT:

You can also get tickets from a Contact resource object directly using tickets on demand includes:

>>> contact = redmine.contact.get(123)
>>> contact.tickets
<redminelib.resultsets.ResourceSet object with Ticket resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Ticket resource and saves them to the Helpdesk plugin.
Parameters
  • resource_id (int) – (required). Ticket id.
  • ticket_date (string or date object) – (optional). Ticket date.
  • ticket_time (string) – (optional). Ticket time.
  • source (string) – .INDENT 2.0
  • 0 - email
  • 1 - web
  • 2 - phone
  • 4 - conversation

  • from_address (string) – (optional). Updates contact of the ticket.
  • to_address (string) – (optional). To addresses (, separated).
  • cc_address (string) – (optional). Cc addresses (, separated).
  • is_incoming (bool) – (optional). Whether ticket is incoming.

Returns
True



>>> redmine.ticket.update(
...     123,
...     source='2',
...     ticket_date='2023-01-10',
...     ticket_time='10:01',
...     from_address='client@mail.com',
...     to_address='support@product.com',
...     cc_address='managers@product.com,jsmith@product.com',
...     is_incoming=True
... )
True


save

redminelib.resources.Expense.save(**attrs)
Saves the current state of a Ticket resource to the Helpdesk plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> ticket = redmine.ticket.get(123)
>>> ticket.source = '2'
>>> ticket.ticket_date = '2023-01-10'
>>> ticket.ticket_time = '10:01'
>>> ticket.to_address = 'support@product.com'
>>> ticket.cc_address = 'managers@product.com,jsmith@product.com'
>>> ticket.is_incoming = True
>>> ticket.save()
<redminelib.resources.Ticket #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> ticket = redmine.ticket.get(123).save(
...     source='2',
...     ticket_date='2023-01-10',
...     ticket_time='10:01',
...     to_address='support@product.com',
...     cc_address='managers@product.com,jsmith@product.com',
...     is_incoming=True
... )
>>> ticket
<redminelib.resources.Ticket #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Ticket resource from the Helpdesk plugin by its id.
Parameters
resource_id (int) – (required). Ticket id.
Returns
True


>>> redmine.ticket.delete(123)
True


redminelib.resources.Ticket.delete()
Deletes current Ticket resource object from the Helpdesk plugin.
Returns
True


>>> ticket = redmine.ticket.get(1)
>>> ticket.delete()
True


Export

Not supported by Helpdesk plugin, but as tickets are basically issues and share the same ID, one can export Issue resources and get most of the ticket information from them.

Journals

The history of a ticket is represented as a ResourceSet of TicketJournal resources. Currently the following operations are possible:

create

To reply to a ticket, i.e. create a new record in ticket history, i.e. new journal:

>>> ticket = redmine.ticket.get(1)
>>> journal = ticket.reply(
...     status_id=2,
...     content='we are working on your issue',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> journal
<redminelib.resources.TicketJournal #321>


Or if you know the issue_id beforehand:

>>> journal = redmine.ticket_journal.create(
...     issue_id=123,
...     status_id=2,
...     content='we are working on your issue',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> journal
<redminelib.resources.TicketJournal #321>

read

Recommended way to access ticket journals is through associated data includes:

>>> ticket = redmine.ticket.get(1, include=['journals'])
>>> ticket.journals
<redminelib.resultsets.ResourceSet object with TicketJournal resources>


But they can also be accessed through on demand includes:

>>> ticket = redmine.ticket.get(1)
>>> ticket.journals
<redminelib.resultsets.ResourceSet object with TicketJournal resources>


After that they can be used as usual:

>>> for journal in ticket.journals:
...     print(journal.id, journal.notes)
...
1 foobar
2 lalala
3 hohoho


update

To update notes attribute (the only attribute that can be updated) of a journal:

>>> ticket = redmine.ticket.get(1, include=['journals'])
>>> for journal in ticket.journals:
...     journal.save(notes='setting notes to a new value')
...


Or if you know the id beforehand:

>>> redmine.ticket_journal.update(1, notes='setting notes to a new value')
True


delete

To delete a journal, set its notes attribute to an empty string:

>>> ticket = redmine.ticket.get(1, include=['journals'])
>>> for journal in ticket.journals:
...     journal.save(notes='')
...


Or if you know the id beforehand:

>>> redmine.ticket_journal.update(1, notes='')
True


NOTE:

You can only delete a journal that doesn’t have the associated details attribute.


RedmineUP Checklists

Checklist

Requires Pro Edition and Checklists plugin >= 3.0.0.

Manager

All operations on the Checklist resource are provided by its manager. To get access to it you have to call redmine.checklist where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Checklist resource item with given fields and saves it to the Checklists plugin.
Parameters
  • issue_id (int) – (required). Issue to which checklist item belongs to.
  • subject (string) – (required). Subject of checklist item.
  • is_done (bool) – (optional). Whether checklist item is done.

Returns
Resource object


>>> checklist = redmine.checklist.create(issue_id=1, subject='FooBar', is_done=False)
>>> checklist
<redminelib.resources.Checklist #1>


new

redminelib.managers.ResourceManager.new()
Creates new empty Checklist resource item but saves it to the Checklists plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> checklist = redmine.checklist.new()
>>> checklist.issue_id = 1
>>> checklist.subject = 'FooBar'
>>> checklist.is_done = False
>>> checklist.save()
<redminelib.resources.Checklist #1>


HINT:

Checklists can also be created/updated together with the Issue using checklists attribute:

>>> issue = redmine.issue.create(
...     project_id=123,
...     subject='foo',
...     checklists=[{'subject': 'foo', 'is_done': True}, {'subject': 'bar', 'is_done': False}]
... )
>>> issue
<redminelib.resources.Issue #3>




Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Checklist resource item from the Checklists plugin by its id.
Parameters
resource_id (int) – (required). Id of the checklist item.
Returns
Resource object


>>> checklist = redmine.checklist.get(123)
>>> checklist
<redminelib.resources.Checklist #123>


all

Not supported by Checklists plugin

filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Checklist resource items that match the given lookup parameters.
Parameters
issue_id (int) – (required). Issue to which these checklist items belong to.
Returns
ResourceSet object


>>> checklists = redmine.checklist.filter(issue_id=123)
>>> checklists
<redminelib.resultsets.ResourceSet object with Checklist resources>


HINT:

You can also get checklist items from an Issue resource objects directly using checklists relation:

>>> issue = redmine.issue.get(1)
>>> issue.checklists
<redminelib.resultsets.ResourceSet object with Checklist resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Checklist resource item and saves them to the Checklists plugin.
Parameters
  • resource_id (int) – (required). Checklist item id.
  • issue_id (int) – (optional). Checklist item issue id.
  • subject (string) – (optional). Subject of the checklist item.
  • is_done (bool) – (optional). Whether checklist item is done.
  • position (int) – (optional). Checklist item position.

Returns
True


>>> redmine.checklist.update(1, issue_id=1, subject='FooBar', is_done=False, position=1)
True


save

redminelib.resources.Checklist.save(**attrs)
Saves the current state of a Checklist item resource to the Checklists plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> checklist = redmine.checklist.get(123)
>>> checklist.issue_id = 1
>>> checklist.subject = 'FooBar'
>>> checklist.is_done = False
>>> checklist.position = 1
>>> checklist.save()
<redminelib.resources.Checklist #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> checklist = redmine.checklist.get(123).save(
...     issue_id=1,
...     subject='Foobar',
...     is_done=False,
...     position=1
... )
>>> checklist
<redminelib.resources.Checklist #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Checklist resource item from the Checklists plugin by its id.
Parameters
resource_id (int) – (required). Checklist item id.
Returns
True


>>> redmine.checklist.delete(123)
True


redminelib.resources.Checklist.delete()
Deletes current Checklist resource item object from the Checklists plugin.
Returns
True


>>> checklist = redmine.checklist.get(1)
>>> checklist.delete()
True


Export

Not supported by Checklists plugin

RedmineUP Invoices

Invoice

Added in version 2.4.0.

Requires Pro Edition and Invoices plugin >= 4.1.3.

Manager

All operations on the Invoice resource are provided by its manager. To get access to it you have to call redmine.invoice where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Invoice resource with given fields and saves it to the Invoices plugin.
Parameters
  • number (string) – (required). Invoice number.
  • project_id (int or string) – (required). Id or identifier of invoice’s project.
  • status_id (int) – .INDENT 2.0
  • 0 - estimate
  • 1 - draft
  • 2 - sent
  • 3 - paid
  • 4 - cancelled

  • invoice_date (string or date object) – (required). Date when invoice is issued.
  • subject (string) – (optional). Invoice subject.
  • contact_id (int) – (optional). Invoice contact id.
  • assigned_to_id (int) – (optional). Invoice will be assigned to this user id.
  • order_number (string) – (optional). Invoice order number.
  • is_recurring (bool) – (optional). Whether invoice is recurring.
  • recurring_period (string) – .INDENT 2.0
  • 1week - weekly
  • 2week - every 2 weeks
  • 1month - monthly
  • 2month - every 2 months
  • 3month - every 3 months
  • 6month - every 6 months
  • 1year - yearly

  • recurring_action (int) – .INDENT 2.0
  • 0 - create draft
  • 1 - send to client

  • recurring_occurrences (int) – (optional). Invoice recurring occurrences.
  • due_date (string or date object) – (optional). Invoice should be payed by this date.
  • discount (int) – (optional). Invoice percentage discount.
  • currency (string) – (optional). Invoice currency.
  • template_id (int) – (optional). Invoice template id.
  • language (string) – (optional). Invoice language.
  • description (string) – (optional). Invoice description.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • lines_attributes (list) – .INDENT 2.0
  • description (required). Product description.
  • position (optional). Position of the line among other invoice lines.
  • quantity (optional). Product quantity.
  • product_id (optional). ID of the product.
  • tax (optional). Tax in percentage.
  • price (optional). Price of the product.
  • units (optional). Unit type, i.e. hours, days, products etc.


  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.



Returns
Resource object




>>> invoice = redmine.invoice.create(
...     number='INV-001',
...     project_id='invoices',
...     status_id=1,
...     invoice_date='2023-01-11',
...     subject='invoice subject',
...     contact_id=3,
...     assigned_to_id=12,
...     due_date='2023-01-13',
...     discount=20,
...     currency='USD',
...     template_id=7,
...     language='en',
...     description='invoice description',
...     order_number='ON-0001',
...     is_recurring=True,
...     recurring_period='6month',
...     recurring_action=1,
...     recurring_occurrences=3,
...     lines_attributes=[{'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'units': 'hours'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> invoice
<redminelib.resources.Invoice #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Invoice resource, but saves it to the Invoices plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> invoice = redmine.invoice.new()
>>> invoice.number = 'INV-001'
>>> invoice.project_id = 'invoices'
>>> invoice.status_id = 1
>>> invoice.invoice_date = '2023-01-11'
>>> invoice.subject = 'invoice subject'
>>> invoice.contact_id = 3
>>> invoice.assigned_to_id = 12
>>> invoice.due_date = '2023-01-13'
>>> invoice.discount = 20
>>> invoice.currency = 'USD'
>>> invoice.template_id = 7
>>> invoice.language = 'en'
>>> invoice.description = 'invoice description'
>>> invoice.order_number = 'ON-0001'
>>> invoice.is_recurring = True
>>> invoice.recurring_period = '6month'
>>> invoice.recurring_action = 1
>>> invoice.recurring_occurrences = 3
>>> invoice.lines_attributes = [{'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'units': 'hours'}]
>>> invoice.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> invoice.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> invoice.save()
<redminelib.resources.Invoice #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Invoice resource from the Invoices plugin by its id.
Parameters
resource_id (int) – (required). Id of the invoice.
Returns
Resource object


>>> invoice = redmine.invoice.get(123)
>>> invoice
<redminelib.resources.Invoice #123>


all

redminelib.managers.ResourceManager.all(**params)
Returns all Invoice resources from the Invoices plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> invoices = redmine.invoice.all(limit=50)
>>> invoices
<redminelib.resultsets.ResourceSet object with Invoice resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Invoice resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Id or identifier of invoice’s project.
  • assigned_to_id (int) – (optional). Get invoices which are assigned to this user id.
  • query_id (int) – (optional). Get invoices for the given query id.
  • status_id (int) – (optional). Get invoices which have this status id.
  • contact_id (int) – (optional). Get invoices for the given contact id.
  • author_id (int) – (optional). Get invoices created by given author id.
  • recurring (bool) – (optional). Whether invoice is recurring.
  • due_date (string or date object) – (optional). Get invoices that should be payed by this date.
  • invoice_date (string or date object) – (optional). Get invoices issued on the given date.
  • currency (string) – (optional). Get invoices which have the given currency.
  • search (string) – (optional). Get invoices with given search string.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> invoices = redmine.invoice.filter(project_id='invoices', assigned_to_id=123, status_id=1, search='INV', recurring=True)
>>> invoices
<redminelib.resultsets.ResourceSet object with Invoice resources>


HINT:

You can also get invoices from a Project, User, Contact and CrmQuery resource objects directly using invoices relation:

>>> project = redmine.project.get('invoices')
>>> project.invoices
<redminelib.resultsets.ResourceSet object with Invoice resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an Invoice resource and saves them to the Invoices plugin.
Parameters
  • resource_id (int) – (required). Invoice id.
  • number (string) – (optional). Invoice number.
  • project_id (int or string) – (optional). Id or identifier of invoice’s project.
  • status_id (int) – .INDENT 2.0
  • 0 - estimate
  • 1 - draft
  • 2 - sent
  • 3 - paid
  • 4 - cancelled

  • invoice_date (string or date object) – (optional). Date when invoice is issued.
  • subject (string) – (optional). Invoice subject.
  • contact_id (int) – (optional). Invoice contact id.
  • assigned_to_id (int) – (optional). Invoice will be assigned to this user id.
  • order_number (string) – (optional). Invoice order number.
  • is_recurring (bool) – (optional). Whether invoice is recurring.
  • recurring_period (string) – .INDENT 2.0
  • 1week - weekly
  • 2week - every 2 weeks
  • 1month - monthly
  • 2month - every 2 months
  • 3month - every 3 months
  • 6month - every 6 months
  • 1year - yearly

  • recurring_action (int) – .INDENT 2.0
  • 0 - create draft
  • 1 - send to client

  • recurring_occurrences (int) – (optional). Invoice recurring occurrences.
  • due_date (string or date object) – (optional). Invoice should be payed by this date.
  • discount (int) – (optional). Invoice percentage discount.
  • currency (string) – (optional). Invoice currency.
  • template_id (int) – (optional). Invoice template id.
  • language (string) – (optional). Invoice language.
  • description (string) – (optional). Invoice description.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • lines_attributes (list) – .INDENT 2.0
  • id (optional). If not set, a new line will be created.
  • description (optional). Product description.
  • position (optional). Position of the line among other invoice lines.
  • quantity (optional). Product quantity.
  • product_id (optional). ID of the product.
  • tax (optional). Tax in percentage.
  • price (optional). Price of the product.
  • units (optional). Unit type, i.e. hours, days, products etc.
  • _destroy (optional). Whether to delete line with a specified id.


  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.



Returns
True




>>> redmine.invoice.update(
...     123,
...     number='INV-001',
...     project_id='invoices',
...     status_id=1,
...     invoice_date='2023-01-11',
...     subject='invoice subject',
...     contact_id=3,
...     assigned_to_id=12,
...     due_date='2023-01-13',
...     discount=20,
...     currency='USD',
...     template_id=7,
...     language='en',
...     description='invoice description',
...     order_number='ON-0001',
...     is_recurring=True,
...     recurring_period='6month',
...     recurring_action=1,
...     recurring_occurrences=3,
...     lines_attributes=[{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'units': 'hours'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Invoice.save(**attrs)
Saves the current state of an Invoice resource to the Invoices plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> invoice = redmine.invoice.get(123)
>>> invoice.number = 'INV-001'
>>> invoice.project_id = 'invoices'
>>> invoice.status_id = 1
>>> invoice.invoice_date = '2023-01-11'
>>> invoice.subject = 'invoice subject'
>>> invoice.contact_id = 3
>>> invoice.assigned_to_id = 12
>>> invoice.due_date = '2023-01-13'
>>> invoice.discount = 20
>>> invoice.currency = 'USD'
>>> invoice.template_id = 7
>>> invoice.language = 'en'
>>> invoice.description = 'invoice description'
>>> invoice.order_number = 'ON-0001'
>>> invoice.is_recurring = True
>>> invoice.recurring_period = '6month'
>>> invoice.recurring_action = 1
>>> invoice.recurring_occurrences = 3
>>> invoice.lines_attributes = [{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'units': 'hours'}]
>>> invoice.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> invoice.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> invoice.save()
<redminelib.resources.Invoice #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> invoice = redmine.invoice.get(123).save(
...     number='INV-001',
...     project_id='invoices',
...     status_id=1,
...     invoice_date='2023-01-11',
...     subject='invoice subject',
...     contact_id=3,
...     assigned_to_id=12,
...     due_date='2023-01-13',
...     discount=20,
...     currency='USD',
...     template_id=7,
...     language='en',
...     description='invoice description',
...     order_number='ON-0001',
...     is_recurring=True,
...     recurring_period='6month',
...     recurring_action=1,
...     recurring_occurrences=3,
...     lines_attributes=[{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'units': 'hours'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> invoice
<redminelib.resources.Invoice #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Invoice resource from the Invoices plugin by its id.
Parameters
resource_id (int) – (required). Invoice id.
Returns
True


>>> redmine.invoice.delete(123)
True


redminelib.resources.Invoice.delete()
Deletes current Invoice resource object from the Invoices plugin.
Returns
True


>>> invoice = redmine.invoice.get(1)
>>> invoice.delete()
True


Export

Added in version 2.0.0.

redminelib.resources.Invoice.export(fmt, savepath=None, filename=None)
Exports Invoice resource in one of the following formats: pdf
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> invoice = redmine.invoice.get(123)
>>> invoice.export('pdf', savepath='/home/jsmith')
'/home/jsmith/123.pdf'


redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Invoice resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> invoices = redmine.invoice.all()
>>> invoices.export('csv', savepath='/home/jsmith', filename='invoices.csv')
'/home/jsmith/invoices.csv'


Invoice Payment

Added in version 2.4.0.

Requires Pro Edition and Invoices plugin >= 4.1.3.

Manager

All operations on the InvoicePayment resource are provided by its manager. To get access to it you have to call redmine.invoice_payment where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new InvoicePayment resource with given fields and saves it to the Invoices plugin.
Parameters
  • invoice_id (int) – (required). Invoice id.
  • amount (string) – (required). Payment amount.
  • payment_date (string or date object) – (required). Payment date.
  • description (string) – (optional). Payment description.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object



>>> payment = redmine.invoice_payment.create(
...     invoice_id=6,
...     amount='12.34',
...     payment_date='2023-01-11',
...     description='description',
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> payment
<redminelib.resources.InvoicePayment #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty InvoicePayment resource, but saves it to the Invoices plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> payment = redmine.invoice_payment.new()
>>> payment.invoice_id = 6
>>> payment.amount = '12.34'
>>> payment.payment_date = '2023-01-11'
>>> payment.description = 'description'
>>> payment.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> payment.save()
<redminelib.resources.InvoicePayment #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single InvoicePayment resource from the Invoices plugin by its id.
Parameters
resource_id (int) – (required). Id of the payment.
Returns
Resource object


>>> payment = redmine.invoice_payment.get(123)
>>> payment
<redminelib.resources.InvoicePayment #123>


all

redminelib.managers.ResourceManager.all(**params)
Returns all InvoicePayment resources from the Invoices plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> payments = redmine.invoice_payment.all(limit=50)
>>> payments
<redminelib.resultsets.ResourceSet object with InvoicePayment resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns InvoicePayment resources that match the given lookup parameters.
Parameters
  • invoice_id (int) – (optional). Get payments for the given invoice id.
  • contact_id (int) – (optional). Get payments for the given contact id.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> payments = redmine.invoice_payment.filter(invoice_id=1, contact_id=1)
>>> payments
<redminelib.resultsets.ResourceSet object with InvoicePayment resources>


HINT:

You can also get payments from an Invoice and Contact resource objects directly using payments relation:

>>> invoice = redmine.invoice.get(123)
>>> invoice.payments
<redminelib.resultsets.ResourceSet object with InvoicePayment resources>




Update methods

Not supported by Invoices plugin

Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single InvoicePayment resource from the Invoices plugin by its id.
Parameters
  • resource_id (int) – (required). Payment id.
  • invoice_id (int) – (required). Invoice id which payment belongs to.

Returns
True


>>> redmine.invoice_payment.delete(123, invoice_id=1)
True


redminelib.resources.InvoicePayment.delete()
Deletes current InvoicePayment resource object from the Invoices plugin.
Returns
True


>>> payment = redmine.invoice_payment.get(123)
>>> payment.delete()
True


Export

Not supported by Invoices plugin

Expense

Added in version 2.4.0.

Requires Pro Edition and Invoices plugin >= 4.1.3.

Manager

All operations on the Expense resource are provided by its manager. To get access to it you have to call redmine.expense where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Expense resource with given fields and saves it to the Invoices plugin.
Parameters
  • project_id (int or string) – (required). Id or identifier of expense’s project.
  • status_id (int) – .INDENT 2.0
  • 1 - draft
  • 2 - new
  • 3 - billed
  • 4 - paid

  • expense_date (string or date object) – (required). Date when expense occurred.
  • price (string) – (optional). Expense amount.
  • currency (string) – (optional). Expense currency.
  • contact_id (int) – (optional). Expense contact id.
  • assigned_to_id (int) – (optional). Expense will be assigned to this user id.
  • is_billable (bool) – (optional). Whether expense is billable.
  • linked_issue_id (int) – (optional). Issue id to be linked with this expense.
  • description (string) – (optional). Expense description.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object




>>> expense = redmine.expense.create(
...     project_id='invoices',
...     status_id=2,
...     expense_date='2023-01-11',
...     price='13.56',
...     currency='USD',
...     contact_id=3,
...     assigned_to_id=12,
...     is_billable=True,
...     description='description',
...     linked_issue_id=557,
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> expense
<redminelib.resources.Expense #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Expense resource, but saves it to the Invoices plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> expense = redmine.expense.new()
>>> expense.project_id = 'invoices'
>>> expense.status_id = 2
>>> expense.expense_date = '2023-01-11'
>>> expense.price = '13.56'
>>> expense.currency = 'USD'
>>> expense.contact_id = 3
>>> expense.assigned_to_id = 12
>>> expense.is_billable = True
>>> expense.description = 'description'
>>> expense.linked_issue_id = 557
>>> expense.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> expense.save()
<redminelib.resources.Expense #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Expense resource from the Invoices plugin by its id.
Parameters
resource_id (int) – (required). Id of the expense.
Returns
Resource object


>>> expense = redmine.expense.get(123)
>>> expense
<redminelib.resources.Expense #123>


all

redminelib.managers.ResourceManager.all(**params)
Returns all Expense resources from the Invoices plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> expenses = redmine.expense.all(limit=50)
>>> expenses
<redminelib.resultsets.ResourceSet object with Expense resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Expense resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Id or identifier of expenses’s project.
  • assigned_to_id (int) – (optional). Get expenses which are assigned to this user id.
  • status_id (int) – (optional). Get expenses which have this status id.
  • contact_id (int) – (optional). Get expenses for the given contact id.
  • author_id (int) – (optional). Get expenses created by given author id.
  • is_billable (bool) – (optional). Whether expense is billable.
  • currency (string) – (optional). Get expenses which have the given currency.
  • expense_date (string or date object) – (optional). Get expenses occurred on the given date.
  • search (string) – (optional). Get expenses with given search string.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> expenses = redmine.expense.filter(project_id='invoices', assigned_to_id=123, status_id=3, search='EXP', is_billable=True)
>>> expenses
<redminelib.resultsets.ResourceSet object with Expense resources>


HINT:

You can also get expenses from a Project, User, Contact and CrmQuery resource objects directly using expenses relation:

>>> project = redmine.project.get('invoices')
>>> project.expenses
<redminelib.resultsets.ResourceSet object with Expense resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an Expense resource and saves them to the Invoices plugin.
Parameters
  • resource_id (int) – (required). Expense id.
  • project_id (int or string) – (required). Id or identifier of expense’s project.
  • status_id (int) – .INDENT 2.0
  • 1 - draft
  • 2 - new
  • 3 - billed
  • 4 - paid

  • expense_date (string or date object) – (required). Date when expense occurred.
  • price (string) – (optional). Expense amount.
  • currency (string) – (optional). Expense currency.
  • contact_id (int) – (optional). Expense contact id.
  • assigned_to_id (int) – (optional). Expense will be assigned to this user id.
  • is_billable (bool) – (optional). Whether expense is billable.
  • linked_issue_id (int) – (optional). Issue id to be linked with this expense.
  • description (string) – (optional). Expense description.
  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True




>>> redmine.expense.update(
...     123,
...     project_id='invoices',
...     status_id=2,
...     expense_date='2023-01-11',
...     price='13.56',
...     currency='USD',
...     contact_id=3,
...     assigned_to_id=12,
...     is_billable=True,
...     description='description',
...     linked_issue_id=557,
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Expense.save(**attrs)
Saves the current state of an Expense resource to the Invoices plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> expense = redmine.expense.get(123)
>>> expense.project_id = 'invoices'
>>> expense.status_id = 2
>>> expense.expense_date = '2023-01-11'
>>> expense.price = '13.56'
>>> expense.currency = 'USD'
>>> expense.contact_id = 3
>>> expense.assigned_to_id = 12
>>> expense.is_billable = True
>>> expense.description = 'description'
>>> expense.linked_issue_id = 557
>>> expense.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> expense.save()
<redminelib.resources.Expense #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> expense = redmine.expense.get(123).save(
...     project_id='invoices',
...     status_id=2,
...     expense_date='2023-01-11',
...     price='13.56',
...     currency='USD',
...     contact_id=3,
...     assigned_to_id=12,
...     is_billable=True,
...     description='description',
...     linked_issue_id=557,
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> expense
<redminelib.resources.Expense #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Expense resource from the Invoices plugin by its id.
Parameters
resource_id (int) – (required). Expense id.
Returns
True


>>> redmine.expense.delete(123)
True


redminelib.resources.Expense.delete()
Deletes current Expense resource object from the Invoices plugin.
Returns
True


>>> expense = redmine.expense.get(1)
>>> expense.delete()
True


Export

Added in version 2.0.0.

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Expense resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> expenses = redmine.expense.all()
>>> expenses.export('csv', savepath='/home/jsmith', filename='expenses.csv')
'/home/jsmith/expenses.csv'


RedmineUP Products

Product

Added in version 2.5.0.

Requires Pro Edition and Products plugin >= 2.1.5.

Manager

All operations on the Product resource are provided by its manager. To get access to it you have to call redmine.product where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Product resource with given fields and saves it to the Products plugin.
Parameters
  • name (string) – (required). Product name.
  • project_id (int or string) – (required). Id or identifier of product’s project.
  • status_id (int) – .INDENT 2.0
  • 1 - active
  • 2 - inactive

  • code (string) – (optional). Product code.
  • price (string) – (optional). Product price.
  • currency (string) – (optional). Product currency.
  • category_id (int) – (optional). Product category id.
  • description (string) – (optional). Product description.
  • tag_list (list) – (optional). List of tags.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • image (dict) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Required if a file-like object is provided.

  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object




>>> product = redmine.product.create(
...     project_id='products',
...     name='foobar',
...     status_id=2,
...     code='P-001',
...     price='9.99',
...     currency='USD',
...     category_id=8,
...     description='product description',
...     tag_list=['foo', 'bar'],
...     custom_fields=[{'id': 1, 'value': '11'}],
...     image={'path': '/absolute/path/to/file.jpg'},
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> product
<redminelib.resources.Product #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Product resource, but saves it to the Products plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> product = redmine.product.new()
>>> product.project_id = 'products'
>>> product.name = 'foobar'
>>> product.status_id = 2
>>> product.code = 'P-001'
>>> product.price = '9.99'
>>> product.currency = 'USD'
>>> product.category_id = 8
>>> product.description = 'product description'
>>> product.tag_list = ['foo', 'bar']
>>> product.custom_fields = [{'id': 1, 'value': '11'}]
>>> product.image = {'path': '/absolute/path/to/file.jpg'}
>>> product.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> product.save()
<redminelib.resources.Product #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Product resource from the Products plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the product.
  • include (list) – .INDENT 2.0
  • attachments


Returns
Resource object



>>> product = redmine.product.get(123, include=['attachments'])
>>> product
<redminelib.resources.Product #123>


HINT:

Product resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with a Product resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Product resource object are the same as in the get() method above:

>>> product = redmine.product.get(123)
>>> product.attachments
<redminelib.resultsets.ResourceSet object with Attachment resources>




all

redminelib.managers.ResourceManager.all(**params)
Returns all Product resources from the Products plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> products = redmine.product.all(limit=50)
>>> products
<redminelib.resultsets.ResourceSet object with Product resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Product resources that match the given lookup parameters.
Parameters
  • project_id (int or string) – (optional). Get products for the given project id.
  • author_id (int) – (optional). Get products created by given author id.
  • status_id (int) – .INDENT 2.0
  • 1 - active
  • 2 - inactive

  • category_id (int) – (optional). Get products for the given category id.
  • code (string) – (optional). Get products for the given code.
  • name (string) – (optional). Get products for the given name.
  • price (string) – (optional). Get products for the given price.
  • sort (string) – .INDENT 2.0
  • code
  • name
  • created_at
  • updated_at

  • search (string) – (optional). Get products for the given search string.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object




>>> products = redmine.product.filter(project_id='products', author_id=123, status_id=1, search='prod', sort='created_at:desc')
>>> products
<redminelib.resultsets.ResourceSet object with Product resources>


HINT:

You can also get products from a Project, User and CrmQuery resource objects directly using products relation:

>>> project = redmine.project.get('products')
>>> project.products
<redminelib.resultsets.ResourceSet object with Product resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a Product resource and saves them to the Products plugin.
Parameters
  • resource_id (int) – (required). Product id.
  • name (string) – (optional). Product name.
  • project_id (int or string) – (optional). Id or identifier of product’s project.
  • status_id (int) – .INDENT 2.0
  • 1 - active
  • 2 - inactive

  • code (string) – (optional). Product code.
  • price (string) – (optional). Product price.
  • currency (string) – (optional). Product currency.
  • category_id (int) – (optional). Product category id.
  • description (string) – (optional). Product description.
  • tag_list (list) – (optional). List of tags.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • image (dict) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Required if a file-like object is provided.

  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True




>>> redmine.product.update(
...     123,
...     project_id='products',
...     name='foobar',
...     status_id=2,
...     code='P-001',
...     price='9.99',
...     currency='USD',
...     category_id=8,
...     description='product description',
...     tag_list=['foo', 'bar'],
...     custom_fields=[{'id': 1, 'value': '11'}],
...     image={'path': '/absolute/path/to/file.jpg'},
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Product.save(**attrs)
Saves the current state of a Product resource to the Products plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> product = redmine.product.get(123)
>>> product.project_id = 'products'
>>> product.name = 'foobar'
>>> product.status_id = 2
>>> product.code = 'P-001'
>>> product.price = '9.99'
>>> product.currency = 'USD'
>>> product.category_id = 8
>>> product.description = 'product description'
>>> product.tag_list = ['foo', 'bar']
>>> product.custom_fields = [{'id': 1, 'value': '11'}]
>>> product.image = {'path': '/absolute/path/to/file.jpg'}
>>> product.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> product.save()
<redminelib.resources.Product #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> product = redmine.product.get(123).save(
...     project_id='products',
...     name='foobar',
...     status_id=2,
...     code='P-001',
...     price='9.99',
...     currency='USD',
...     category_id=8,
...     description='product description',
...     tag_list=['foo', 'bar'],
...     custom_fields=[{'id': 1, 'value': '11'}],
...     image={'path': '/absolute/path/to/file.jpg'},
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> product
<redminelib.resources.Product #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Product resource from the Products plugin by its id.
Parameters
resource_id (int) – (required). Product id.
Returns
True


>>> redmine.product.delete(123)
True


redminelib.resources.Product.delete()
Deletes current Product resource object from the Products plugin.
Returns
True


>>> product = redmine.product.get(1)
>>> product.delete()
True


Export

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Product resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> products = redmine.product.all()
>>> products.export('csv', savepath='/home/jsmith', filename='products.csv')
'/home/jsmith/products.csv'


Product Category

Added in version 2.5.0.

Requires Pro Edition and Products plugin >= 2.1.5.

Manager

All operations on the ProductCategory resource are provided by its manager. To get access to it you have to call redmine.product_category where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new ProductCategory resource with given fields and saves it to the Products plugin.
Parameters
  • name (string) – (required). Category name.
  • code (string) – (optional). Category code.
  • parent_id (int) – (optional). Category parent id.

Returns
Resource object


>>> category = redmine.product_category.create(
...     name='Software',
...     code='S-001',
...     parent_id=13
... )
>>> category
<redminelib.resources.ProductCategory #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty ProductCategory resource, but saves it to the Products plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> category = redmine.product_category.new()
>>> category.name = 'Software'
>>> category.code = 'S-001'
>>> category.parent_id = 13
>>> category.save()
<redminelib.resources.ProductCategory #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single ProductCategory resource from the Products plugin by its id.
Parameters
resource_id (int) – (required). Id of the product category.
Returns
Resource object


>>> category = redmine.product_category.get(123)
>>> category
<redminelib.resources.ProductCategory #123>


all

redminelib.managers.ResourceManager.all(**params)
Returns all ProductCategory resources from the Products plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> categories = redmine.product_category.all(limit=50)
>>> categories
<redminelib.resultsets.ResourceSet object with ProductCategory resources>


filter

Not supported by Products plugin

Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of a ProductCategory resource and saves them to the Products plugin.
Parameters
  • resource_id (int) – (required). Category id.
  • name (string) – (optional). Category name.
  • code (string) – (optional). Category code.
  • parent_id (int) – (optional). Category parent id.

Returns
True


>>> redmine.product_category.update(
...     123,
...     name='Software',
...     code='S-001',
...     parent_id=13
... )
True


save

redminelib.resources.ProductCategory.save(**attrs)
Saves the current state of a ProductCategory resource to the Products plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> category = redmine.product_category.get(123)
>>> category.name = 'Software'
>>> category.code = 'S-001'
>>> category.parent_id = 13
>>> category.save()
<redminelib.resources.ProductCategory #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> category = redmine.product_category.get(123).save(
...     name='Software',
...     code='S-001',
...     parent_id=13
... )
>>> category
<redminelib.resources.ProductCategory #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single ProductCategory resource from the Products plugin by its id.
Parameters
resource_id (int) – (required). Category id.
Returns
True


>>> redmine.product_category.delete(123)
True


redminelib.resources.ProductCategory.delete()
Deletes current ProductCategory resource object from the Products plugin.
Returns
True


>>> category = redmine.product_category.get(1)
>>> category.delete()
True


Export

Not supported by Products plugin

Order

Added in version 2.5.0.

Requires Pro Edition and Products plugin >= 2.1.5.

Manager

All operations on the Order resource are provided by its manager. To get access to it you have to call redmine.order where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

create

redminelib.managers.ResourceManager.create(**fields)
Creates new Order resource with given fields and saves it to the Products plugin.
Parameters
  • number (string) – (required). Order number.
  • project_id (int) – (required). Order project id.
  • status_id (int) – (required). Order status id.
  • order_date (string or datetime object) – (required). Date and time of the order.
  • subject (string) – (optional). Order subject.
  • contact_id (int) – (optional). Order contact id.
  • assigned_to_id (int) – (optional). Order will be assigned to this user id.
  • currency (string) – (optional). Order currency.
  • description (string) – (optional). Order description.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • lines_attributes (list) – .INDENT 2.0
  • position (optional). Position of the line among other order lines.
  • product_id (optional). ID of the product.
  • description (required). Product description.
  • quantity (optional). Product quantity.
  • price (optional). Price of the product.
  • tax (optional). Tax in percentage.
  • discount (optional). Discount in percentage.

  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
Resource object




>>> order = redmine.order.create(
...     number='O-001',
...     project_id=12,
...     status_id=1,
...     order_date='2023-01-11',
...     subject='order subject',
...     contact_id=3,
...     assigned_to_id=12,
...     currency='USD',
...     description='order description',
...     lines_attributes=[{'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'discount': '2'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> order
<redminelib.resources.Order #123>


new

redminelib.managers.ResourceManager.new()
Creates new empty Order resource, but saves it to the Products plugin only when save() is called, also calls pre_create() and post_create() methods of the Resource object. Valid attributes are the same as for create() method above.
Returns
Resource object


>>> order = redmine.order.new()
>>> order.number = 'O-001'
>>> order.project_id = 12
>>> order.status_id = 1
>>> order.order_date = '2023-01-11'
>>> order.subject = 'order subject'
>>> order.contact_id = 3
>>> order.assigned_to_id = 12
>>> order.currency = 'USD'
>>> order.description = 'order description'
>>> order.lines_attributes = [{'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'discount': '2'}]
>>> order.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> order.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> order.save()
<redminelib.resources.Order #123>


Read methods

get

redminelib.managers.ResourceManager.get(resource_id, **params)
Returns single Order resource from the Products plugin by its id.
Parameters
  • resource_id (int) – (required). Id of the order.
  • include (list) – .INDENT 2.0
  • lines


Returns
Resource object



>>> order = redmine.order.get(123, include=['lines'])
>>> order
<redminelib.resources.Order #123>


HINT:

Order resource object provides you with on demand includes. On demand includes are the other resource objects wrapped in a ResourceSet which are associated with an Order resource object. Keep in mind that on demand includes are retrieved in a separate request, that means that if the speed is important it is recommended to use get() method with include keyword argument. On demand includes provided by the Order resource object are the same as in the get() method above:

>>> order = redmine.order.get(123)
>>> order.lines




all

redminelib.managers.ResourceManager.all(**params)
Returns all Order resources from the Products plugin.
Parameters
  • include (list) – .INDENT 2.0
  • lines

  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object



>>> orders = redmine.order.all(limit=50, include=['lines'])
>>> orders
<redminelib.resultsets.ResourceSet object with Order resources>


filter

redminelib.managers.ResourceManager.filter(**filters)
Returns Order resources that match the given lookup parameters.
Parameters
  • project_id (int) – (optional). Get orders for the given project id.
  • assigned_to_id (int) – (optional). Get orders which are assigned to this user id.
  • status_id (int) – (optional). Get orders which have this status id.
  • contact_id (int) – (optional). Get orders for the given contact id.
  • author_id (int) – (optional). Get orders created by given author id.
  • number (string) – (optional). Get orders for the given number.
  • amount (string) – (optional). Get orders which have given amount.
  • completed_date (string or date object) – (optional). Get orders that should be completed by this date.
  • order_date (string or date object) – (optional). Get orders created on the given date.
  • sort (string) – .INDENT 2.0
  • order_date
  • status_id
  • created_at
  • updated_at

  • search (string) – (optional). Get orders for the given search string.
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object



>>> orders = redmine.order.filter(project_id=12, assigned_to_id=123, status_id=1, search='SO', sort='order_date:desc')
>>> orders
<redminelib.resultsets.ResourceSet object with Order resources>


HINT:

You can also get orders from a Project, User and Contact resource objects directly using orders relation:

>>> project = redmine.project.get('products')
>>> project.orders
<redminelib.resultsets.ResourceSet object with Order resources>




Update methods

update

redminelib.managers.ResourceManager.update(resource_id, **fields)
Updates values of given fields of an Order resource and saves them to the Products plugin.
Parameters
  • resource_id (int) – (required). Order id.
  • number (string) – (optional). Order number.
  • project_id (int) – (optional). Order project id.
  • status_id (int) – (optional). Order status id.
  • order_date (string or datetime object) – (optional). Date and time of the order.
  • subject (string) – (optional). Order subject.
  • contact_id (int) – (optional). Order contact id.
  • assigned_to_id (int) – (optional). Order will be assigned to this user id.
  • currency (string) – (optional). Order currency.
  • description (string) – (optional). Order description.
  • custom_fields (list) – (optional). Custom fields as [{‘id’: 1, ‘value’: ‘foo’}].
  • lines_attributes (list) – .INDENT 2.0
  • id (optional). If not set, a new line will be created.
  • position (optional). Position of the line among other order lines.
  • product_id (optional). ID of the product.
  • description (optional). Product description.
  • quantity (optional). Product quantity.
  • price (optional). Price of the product.
  • tax (optional). Tax in percentage.
  • discount (optional). Discount in percentage.
  • _destroy (optional). Whether to delete line with a specified id.

  • uploads (list) – .INDENT 2.0
  • path (required). Absolute file path or file-like object that should be uploaded.
  • filename (optional). Name of the file after upload.
  • description (optional). Description of the file.
  • content_type (optional). Content type of the file.


Returns
True




>>> redmine.order.update(
...     123,
...     number='O-001',
...     project_id=12,
...     status_id=1,
...     order_date='2023-01-11',
...     subject='order subject',
...     contact_id=3,
...     assigned_to_id=12,
...     currency='USD',
...     description='order description',
...     lines_attributes=[{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'discount': '2'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
True


save

redminelib.resources.Order.save(**attrs)
Saves the current state of an Order resource to the Products plugin. Attrs that can be changed are the same as for update() method above.
Returns
Resource object


>>> order = redmine.order.get(123)
>>> order.number = 'O-001'
>>> order.project_id = 12
>>> order.status_id = 1
>>> order.order_date = '2023-01-11'
>>> order.subject = 'order subject'
>>> order.contact_id = 3
>>> order.assigned_to_id = 12
>>> order.currency = 'USD'
>>> order.description = 'order description'
>>> order.lines_attributes = [{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'discount': '2'}]
>>> order.custom_fields = [{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}]
>>> order.uploads = [{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
>>> order.save()
<redminelib.resources.Order #123>


Added in version 2.1.0: Alternative syntax was introduced.

>>> order = redmine.order.get(123).save(
...     number='O-001',
...     project_id=12,
...     status_id=1,
...     order_date='2023-01-11',
...     subject='order subject',
...     contact_id=3,
...     assigned_to_id=12,
...     currency='USD',
...     description='order description',
...     lines_attributes=[{'id': 1, '_destroy': True}, {'position': 1, 'quantity': '3', 'description': 'product description', 'product_id': 1, 'tax': '10', 'price': '5', 'discount': '2'}],
...     custom_fields=[{'id': 1, 'value': 'foo'}, {'id': 2, 'value': 'bar'}],
...     uploads=[{'path': '/absolute/path/to/file'}, {'path': BytesIO(b'I am content of file 2')}]
... )
>>> order
<redminelib.resources.Order #123>


Delete methods

delete

redminelib.managers.ResourceManager.delete(resource_id)
Deletes single Order resource from the Products plugin by its id.
Parameters
resource_id (int) – (required). Order id.
Returns
True


>>> redmine.order.delete(123)
True


redminelib.resources.Order.delete()
Deletes current Order resource object from the Products plugin.
Returns
True


>>> order = redmine.order.get(1)
>>> order.delete()
True


Export

redminelib.resultsets.ResourceSet.export(fmt, savepath=None, filename=None)
Exports a resource set of Order resources in one of the following formats: csv
Parameters
  • fmt (string) – (required). Format to use for export.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.

Returns
String or Object


>>> orders = redmine.order.all()
>>> orders.export('csv', savepath='/home/jsmith', filename='orders.csv')
'/home/jsmith/orders.csv'


Order Status

Added in version 2.5.0.

Requires Pro Edition and Products plugin >= 2.1.5.

Manager

All operations on the OrderStatus resource are provided by its manager. To get access to it you have to call redmine.order_status where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Create methods

Not supported by Products plugin

Read methods

get

redminelib.managers.ResourceManager.get(resource_id)
Returns single OrderStatus resource from the Products plugin by its id.
Parameters
resource_id (int) – (required). Id of the order status.
Returns
Resource object


>>> status = redmine.order_status.get(1)
>>> status
<redminelib.resources.OrderStatus #1 "Paid">


HINT:

OrderStatus resource object provides you with some relations. Relations are the other resource objects wrapped in a ResourceSet which are somehow related to an OrderStatus resource object. The relations provided by the OrderStatus resource object are:
orders

>>> statuses = redmine.order_status.all()
>>> statuses[0]
<redminelib.resources.OrderStatus #1 "Paid">
>>> statuses[0].orders
<redminelib.resultsets.ResourceSet object with Order resources>




all

redminelib.managers.ResourceManager.all()
Returns all OrderStatus resources from the Products plugin.
Parameters
  • limit (int) – (optional). How much resources to return.
  • offset (int) – (optional). Starting from what resource to return the other resources.

Returns
ResourceSet object


>>> statuses = redmine.order_status.all()
>>> statuses
<redminelib.resultsets.ResourceSet object with OrderStatus resources>


filter

Not supported by Products plugin

Update methods

Not supported by Products plugin

Delete methods

Not supported by Products plugin

Export

Not supported by Products plugin

Advanced Usage

Request Engines

Added in version 2.0.0.

Python-Redmine has an extensible and customizable request engine system that allows to define how requests to Redmine are made. Basically a request engine is a Python class that inherits from redminelib.engines.BaseEngine class and redefines a few methods to achieve the needed behaviour. Engine can be set while configuring a redmine object, after it’s set, there is nothing else to be done to use it, i.e. it will be used by Python-Redmine automatically while making requests to Redmine.

Engines

Sync

Default engine in Standard Edition. Requests are made in a sequential fashion, i.e. one by one. There is nothing to do to use it, but just for the purpose of example, this is how we can explicitly ask Python-Redmine to use it:

from redminelib import engines, Redmine
redmine = Redmine('https://redmine.url', engine=engines.SyncEngine)


Thread

Available only in Pro Edition.

Default engine in Pro Edition. Requests are made in an asynchronous fashion using Python threads. The amount of threads is calculated by Python-Redmine automatically, but can be adjusted manually passing workers argument to the Redmine class:

from redminelib import engines, Redmine
redmine = Redmine('https://redmine.url', engine=engines.ThreadEngine, workers=4)


Process

Available only in Pro Edition.

Requests are made in an asynchronous fashion using Python processes. The amount of processes is calculated by Python-Redmine automatically, but can be adjusted manually passing workers argument to the Redmine class:

from redminelib import engines, Redmine
redmine = Redmine('https://redmine.url', engine=engines.ProcessEngine, workers=4)


NOTE:

Please keep in mind that currently only read operations are possible using async engines, all other types of operations, i.e. create/update/delete are made using sync engine.


Session

Sometimes there is a need to change engine/connection options only for one or few requests. Python-Redmine provides a convenient session() context manager for that. Options that can be redefined are as follows:

  • key. API key used for authentication.
  • username. Username used for authentication.
  • password. Password used for authentication.
  • requests. Connection options.
  • impersonate. Username to impersonate.
  • ignore_response. If True no response processing will be done at all.
  • return_response. Whether to return response or None.
  • return_raw_response. Whether to return raw or json encoded response.
  • workers. How many workers to use. Available only in Pro Edition.

with redmine.session(workers=24):

issues = redmine.issue.all()
projects = redmine.project.all() with redmine.session(username='jsmith', password='secret'):
issue = redmine.issue.create(project_id=123, subject='foo')


Custom Engine

It is possible to create additional engines if needed. To do that, create a class and inherit it from engines.BaseEngine class. The only methods that must be implemented are create_session() and process_bulk_request(), please see code of engines.BaseEngine for details. Below you will find methods and attributes which can be redefined in your custom engine:

class redminelib.engines.BaseEngine(**options)
static create_session(**params)
Creates a session object that will be used to make requests to Redmine.
Parameters
params (dict) – (optional). Session params.


static construct_request_kwargs(method, headers, params, data)
Constructs kwargs that will be used in all requests to Redmine.
Parameters
  • method (string) – (required). HTTP verb to use for the request.
  • headers (dict) – (required). HTTP headers to send with the request.
  • params (dict) – (required). Params to send in the query string.
  • data (dict, bytes or file-like object) – (required). Data to send in the body of the request.



request(method, url, headers=None, params=None, data=None)
Makes a single request to Redmine and returns processed response.
Parameters
  • method (string) – (required). HTTP verb to use for the request.
  • url (string) – (required). URL of the request.
  • headers (dict) – (optional). HTTP headers to send with the request.
  • params (dict) – (optional). Params to send in the query string.
  • data (dict, bytes or file-like object) – (optional). Data to send in the body of the request.



bulk_request(method, url, container, **params)
Makes needed preparations before launching the active engine’s request process.
Parameters
  • method (string) – (required). HTTP verb to use for the request.
  • url (string) – (required). URL of the request.
  • container (string) – (required). Key in the response that should be used to access retrieved resources.
  • params (dict) – (optional). Params that should be used for resource retrieval.



process_bulk_request(method, url, container, bulk_params)
Makes several requests in blocking or non-blocking fashion depending on the engine.
Parameters
  • method (string) – (required). HTTP verb to use for the request.
  • url (string) – (required). URL of the request.
  • container (string) – (required). Key in the response that should be used to access retrieved resources.
  • bulk_params (list) – (required). Params that should be used for resource retrieval.



process_response(response)
Processes response received from Redmine.
Parameters
response (obj) – (required). Response object with response details.



Custom Resources

Sometimes there is a need to redefine a resource behaviour to achieve the needed goal. Python-Redmine provides a feature for such a case called custom resources. Basically this is just a normal class inheritance made specifically for Python-Redmine.

Existing Resources

The list of existing resource class names that can be inherited from is available here.

Creation

To create a custom resource choose which resource behavior you want to change, e.g. WikiPage:

from redminelib.resources import WikiPage
class CustomWikiPage(WikiPage):

pass


Name

Python-Redmine converts underscore to camelcase when it tries to import the resource, which means that it is important to follow this convention to make everything work properly, e.g when you do:

custom_wiki_page = redmine.custom_wiki_page.get('Foo')


Python-Redmine is searching for a resource class named CustomWikiPage. The location of the class doesn’t matter since all classes that inherit from any Python-Redmine resource class are automatically added to the special resource registry.

Methods and Attributes

All existing resources are derived from a BaseResource class which you usually won’t inherit from directly unless you want to add support for a new resource which Python-Redmine doesn’t support. Below you will find methods and attributes which can be redefined in your custom resource:

class redminelib.resources.BaseResource(manager, attributes)
Implementation of Redmine resource.
__getattr__(attr)
Returns the requested attribute and makes a conversion if needed.

__setattr__(attr, value)
Sets the requested attribute.

classmethod decode(attr, value, manager)
Decodes a single attr, value pair from Python representation to the needed Redmine representation.
Parameters
  • attr (string) – (required). Attribute name.
  • value (any) – (required). Attribute value.
  • manager (managers.ResourceManager) – (required). Manager object.



classmethod encode(attr, value, manager)
Encodes a single attr, value pair retrieved from Redmine to the needed Python representation.
Parameters
  • attr (string) – (required). Attribute name.
  • value (any) – (required). Attribute value.
  • manager (managers.ResourceManager) – (required). Manager object.



classmethod bulk_decode(attrs, manager)
Decodes resource data from Python representation to the needed Redmine representation.
Parameters
  • attrs (dict) – (required). Attributes in the form of key, value pairs.
  • manager (managers.ResourceManager) – (required). Manager object.



classmethod bulk_encode(attrs, manager)
Encodes resource data retrieved from Redmine to the needed Python representation.
Parameters
  • attrs (dict) – (required). Attributes in the form of key, value pairs.
  • manager (managers.ResourceManager) – (required). Manager object.



raw()
Returns resource data as it was received from Redmine.

refresh(itself=True, **params)
Reloads resource data from Redmine.
Parameters
  • itself (bool) – (optional). Whether to refresh itself or return a new resource.
  • params (dict) – (optional). Parameters used for resource retrieval.



pre_create()
Tasks that should be done before creating the Resource.

post_create()
Tasks that should be done after creating the Resource.

pre_update()
Tasks that should be done before updating the Resource.

post_update()
Tasks that should be done after updating the Resource.

pre_delete()
Tasks that should be done before deleting the Resource.

post_delete()
Tasks that should be done after deleting the Resource.

save(**attrs)
Creates or updates a Resource.
Parameters
attrs (dict) – (optional). Attrs to be set for a resource before create/update operation.


delete(**params)
Deletes Resource from Redmine.
Parameters
params (dict) – (optional). Parameters used for resource deletion.


export(fmt, savepath=None, filename=None)
Exports Resource to requested format if Resource supports that.
Parameters
  • fmt (string) – (required). Format to use for export, e.g. atom, csv, txt, pdf, html etc.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.



export_url(fmt)
Returns export URL for the Resource according to format.
Parameters
fmt (string) – (required). Export format, e.g. atom, csv, txt, pdf, html etc.


is_new()
Checks if Resource was just created and not yet saved to Redmine, or it is an existing Resource.


External Authentication

It is possible to use Python-Redmine as a provider for external authentication based on the Redmine user database, e.g. imagine you are making a website and you want to only authenticate your users if they provide the same login/password they use to login to Redmine:

username = 'john'    # username comes from the POST request on form submit
password = 'qwerty'  # password comes from the POST request on form submit
user = Redmine('https://redmine.url', username=username, password=password).auth()


If authentication succeeded, user variable will contain details about the current user, if there was an error during authentication process, an AuthError exception will be thrown.

If you need more control, for example you want to return your own error message, you can intercept AuthError exception and do what you need, for example:

from redminelib.exceptions import AuthError
username = 'john'    # username comes from the POST request on form submit
password = 'qwerty'  # password comes from the POST request on form submit
try:

user = Redmine('https://redmine.url', username=username, password=password).auth() except AuthError:
raise Exception('Invalid login or password provided')


Working with Files

It is possible to use Python-Redmine to upload/download files to/from Redmine. This document describes low-level interfaces that Python-Redmine provides, in most cases they shouldn’t be used directly and high-level interfaces, e.g. uploads parameter in Issue resource or download() method in Attachment resource should be used instead. To get access to these low-level interfaces you have to call either redmine.upload() or redmine.download() where redmine is a configured redmine object. See the Configuration about how to configure redmine object.

Upload

redminelib.Redmine.upload(f)
Uploads file from file path / file stream to Redmine and returns an assigned token.
Parameters
  • f (string or file-like object) – (required). File path / stream that will be uploaded.
  • filename – (optional). Filename for the file that will be uploaded.

Returns
dict with id and token string (Redmine >= 3.4.0) or dict with token string only (Redmine < 3.4.0)


>>> data = redmine.upload('/usr/local/image.jpg', filename='beauty.jpg')
>>> data
{'id': 7167, 'token': '7167.ed1ccdb093229ca1bd0b043618d88743'}


If a filename isn’t specified, Python-Redmine will use the original filename from a path, if any. If a file-like object is provided, be sure that it contains bytes and not str, otherwise Python-Redmine will have to make additional conversion, which will affect performance.

Download

redminelib.Redmine.download(url, savepath=None, filename=None, params=None)
Downloads file from Redmine and saves it to savepath or returns a response directly for maximum control over file processing.
Parameters
  • url (string) – (required). URL of the file that will be downloaded.
  • savepath (string) – (optional). Path where to save the file.
  • filename (string) – (optional). Name that will be used for the file.
  • params (dict) – (optional). Params to send in the query string.

Returns
string or requests.Response object


If a savepath argument is provided, then a file will be saved into the provided path with its own name, if a filename argument is provided together with the savepath argument, then a file will be saved into the provided path under the provided name and the resulting path to the file will be returned.

>>> filepath = redmine.download('https://redmine.url/foobar.jpg', savepath='/usr/local', filename='image.jpg')
>>> filepath
'/usr/local/image.jpg'


If only a url argument is provided, then a requests.Response object will be returned which can be used for a maximum control over file processing. For example, you can call a iter_content() method with the needed arguments to have full control over the content reading process:

>>> response = redmine.download('https://redmine.url/foobar.jpg')
>>> for chunk in response.iter_content(chunk_size=1024):

# do something with chunk


Frequently Asked Questions

Create/Update/Delete resource operations don’t work

Your Redmine server is probably using https as the primary protocol and you’re trying to connect to it under http protocol. Please use the https protocol and it should work.

The problem described above happens because when you’re trying to connect using the http protocol, your server issues a redirect to the https which changes the request method, e.g. if your were trying to create/update/delete a resource, then POST/PUT/DELETE is changing to GET which expectedly causes the create/update/delete operations to fail.

The detailed explanation about why this happens is available here.

Can I use Python-Redmine with ChiliProject fork

Yes, you can. But keep in mind that ChiliProject is not actively developed and some features in REST API are missing, not all filters will work, etc. Several problems are described in issues #37 and #38.

Exceptions

Python-Redmine tries its best to provide human-readable errors in all situations. This is a list of all exceptions or warnings that Python-Redmine can throw/raise.

exception redminelib.exceptions.BaseRedmineWarning
Base warning class for Redmine warnings.

exception redminelib.exceptions.PerformanceWarning
Warning raised when there’s a possible performance impact.

exception redminelib.exceptions.BaseRedmineError
Base exception class for Redmine exceptions.

exception redminelib.exceptions.ResourceError
Unsupported Redmine resource exception.

exception redminelib.exceptions.NoFileError
File doesn’t exist or is empty exception.

exception redminelib.exceptions.FileObjectError
File-like object isn’t supported as it doesn’t support the read(size) method.

exception redminelib.exceptions.ResourceNotFoundError
Requested resource doesn’t exist.

exception redminelib.exceptions.ConflictError
Resource version on the server is newer than on the client.

exception redminelib.exceptions.AuthError
Invalid authentication details.

exception redminelib.exceptions.ImpersonateError
Invalid impersonate login provided.

exception redminelib.exceptions.ServerError
Redmine internal error.

exception redminelib.exceptions.RequestEntityTooLargeError
Size of the request exceeds the capacity limit on the server.

exception redminelib.exceptions.UnknownError(status_code)
Redmine returned unknown error.

exception redminelib.exceptions.ValidationError(error)
Redmine validation errors occurred on create/update resource.

exception redminelib.exceptions.ResourceSetIndexError
Index doesn’t exist in the ResourceSet.

exception redminelib.exceptions.ResourceSetFilterLookupError(lookup, f)
Resource set filter method received an invalid lookup in one of the filters.

exception redminelib.exceptions.ResourceBadMethodError
Resource doesn’t support the requested method.

exception redminelib.exceptions.ResourceFilterError
Resource doesn’t support requested filter(s).

exception redminelib.exceptions.ResourceNoFiltersProvidedError
No filter(s) provided.

exception redminelib.exceptions.ResourceNoFieldsProvidedError
No field(s) provided.

exception redminelib.exceptions.ResourceAttrError
Resource doesn’t have the requested attribute.

exception redminelib.exceptions.ReadonlyAttrError
Resource can’t set attribute that is read only.

exception redminelib.exceptions.VersionFormatError(version)
Version format provided isn’t supported. SemVer is the only format accepted.

exception redminelib.exceptions.VersionMismatchError(feature)
Feature isn’t supported on specified Redmine version.

exception redminelib.exceptions.ResourceVersionMismatchError
Resource isn’t supported on specified Redmine version.

exception redminelib.exceptions.ResultSetTotalCountError
ResultSet hasn’t been yet evaluated and cannot yield a total_count.

exception redminelib.exceptions.CustomFieldValueError
Custom fields should be passed as a list of dictionaries.

exception redminelib.exceptions.ResourceRequirementsError(requirements)
Resource requires specific Redmine plugin(s) to function.

exception redminelib.exceptions.FileUrlError
URL provided to download a file can’t be parsed.

exception redminelib.exceptions.ForbiddenError
Requested resource is forbidden.

exception redminelib.exceptions.JSONDecodeError(response)
Unable to decode received JSON.

exception redminelib.exceptions.ExportNotSupported
Export functionality not supported by resource.

exception redminelib.exceptions.ExportFormatNotSupportedError
The given format isn’t supported by resource.

exception redminelib.exceptions.HTTPProtocolError
Wrong HTTP protocol usage.

exception redminelib.exceptions.TimezoneError
Timezone is neither a string, suitable for a strptime %z, nor is an instance of tzinfo class.

exception redminelib.exceptions.EngineClassError
Engine isn’t a class or isn’t a BaseEngine subclass.

License

Standard Edition

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0


Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Pro Edition

Licensed under Python-Redmine Pro Edition License Version 1.0.

Changelog

2.5.0 (2024-03-31)

Deprecations:

Requests version required >= 2.31.0

New Features:

  • Pro Edition: RedmineUP Products plugin support
  • Issue copying (see docs for details) (Issue #203)

Improvements:

  • Migrated CI to GitHub Actions, also we now test not only on Linux, but on macOS and Windows as well
  • dir(resource) and list(resource) now also show properties of an object
  • Support for issues_assigned and issues_authored relations in User object (Issue #317)
  • Original filename will be used as a filename for all uploaded files if a path was provided and filename wasn’t set
  • Pro Edition: Added support for RedmineUP Contact avatar add/update operations (see docs for details)
  • Pro Edition: Added support for RedmineUP DealCategory create(), update(), delete() operations (see docs for details)
  • Pro Edition: RedmineUP CrmQuery resource now supports invoices and expenses relation attributes
  • PerformanceWarning will be issued when Python-Redmine does some unnecessary redirects before the actual request is made

Changes:

  • Backwards Incompatible: API key is now being sent in the X-Redmine-API-Key header instead of the key GET parameter which makes things more secure in case of a failed connection, but it might created issues for servers that don’t do custom request header forwarding by default, so be sure to check your web server before upgrading (Issue #328 and Issue #330) (thanks to Tom Misilo and Ricardo Branco)
  • Backwards Incompatible: User all operation now really returns all users, i.e. not only active, but locked, registered and anonymous as well instead of only returning just active users in previous versions due to the respect to Redmine’s standard behaviour (Issue #327)

Bugfixes:

  • Tests were failing on Windows OS
  • Tests were failing on Python 3.12 (Issue #332) (thanks to Michał Górny)
  • Some closed Issues weren’t converted to Resource objects using redmine.search()
  • Pro Edition: RedmineUP Invoice resource order attribute was returned as a dict instead of being converted to Resource object
  • Pro Edition: RedmineUP CrmQuery resource deals and contacts relation attributes didn’t work
  • Pro Edition: RedmineUP DealStatus resource deals relation attribute didn’t work

Documentation:

Mentioned support for author_id in Issue’s resource filter operation

2.4.0 (2023-01-18)

Deprecations:

  • Requests version required >= 2.28.2
  • Removed Python 2.7, 3.5, 3.6 support as it’s not supported by Requests anymore
  • Removed support for python setup.py test as it became deprecated by setuptools

New Features:

  • Pro Edition: RedmineUP Helpdesk plugin support (Issue #116)
  • Pro Edition: RedmineUP Invoices plugin support (Issue #301)
  • Timezone support (see docs for details) (Issue #271)

Improvements:

  • Added support for Python 3.10, 3.11 and latest PyPy
  • Added support for allowed_statuses to include param and on demand includes for Issue resource (requires Redmine >= 5.0.0)
  • Added support for issue_custom_fields to include param and on demand includes for Project resource (requires Redmine >= 4.2.0)
  • Added support for comments and attachments to include param and on demand includes for News resource (requires Redmine >= 4.1.0)
  • Pro Edition: Added support for RedmineUP Contact projects to include param and on demand includes for all() and filter() operations
  • Pro Edition: Added support for RedmineUP Note create(), update(), delete() operations (see docs for details)
  • Added support for Project close(), reopen(), archive(), unarchive() operations (see docs for details, requires Redmine >= 5.0.0)
  • Added support for updating and deleting issue journals (see docs for details, requires Redmine >= 5.0.0)

Changes:

  • Backwards Incompatible: Switched to pytest instead of nose as nose project is dead (Issue #312)
  • Backwards Incompatible: Removed usage of distutils.LooseVersion internally since it became deprecated and caused warnings, because of that all version info internally is now being represented as tuples and not strings as before

Bugfixes:

  • Stop raising ResourceAttrError for attributes that actually exist, but their value is None (Issue #261)
  • Pro Edition: RedmineUP Deal resource related_contacts attribute was returned as a list instead of being converted to ResourceSet object
  • Project resource default_assignee attribute was returned as a dict instead of being converted to Resource object
  • Project resource time_entry_activities attribute was returned as a list instead of being converted to ResourceSet object

Documentation:

  • Document requirement of project_id param for query_id filter (Issue #285) (thanks to Doezer)
  • Mentioned support for user_id in TimeEntry’s resource create/update (Issue #298)
  • Mentioned support for additional scopes for Search API

2.3.0 (2020-05-21)

Deprecations:

  • Requests version required >= 2.23.0
  • Removed Python 3.4 support as it’s not supported by Requests anymore

Improvements:

  • Support custom filename in redmine.upload()
  • Support for get() and update() operations for /my/account endpoint which doesn’t require admin privileges by using me as an id, i.e. redmine.user.get('me') or redmine.user.update('me',firstname='John') (requires Redmine >= 4.1.0)
  • News create(), update(), delete() operations support (requires Redmine >= 4.1.0)
  • ResourceSet’s export() method now supports columns keyword argument which can be either an iterable of column names, an “all” string which tells Python-Redmine to export all available columns, “all_gui” string for GUI like behaviour or iterable of elements with “all_gui” string and additional columns to export
  • Added support for special characters in WikiPage titles (Issue #222) (thanks to Radek Czajka)
  • Added return_response and ignore_response parameters to engine which allow to skip response processing and speed up the create/update/delete operation in case response body isn’t needed (see docs for details)

Bugfixes:

  • User’s send_information field wasn’t sent correctly to Redmine so account information emails were never sent (Issue #227) (thanks to wodny)
  • Project resource default_version attribute was returned as a dict instead of being converted to Resource object
  • Resource object was leaking memory during initialization (Issue #257) (thanks to yihli)

Documentation:

  • Introduced detailed parameter list for redmine.session
  • Mentioned support for admin in User’s resource create/update

2.2.1 (2019-02-28)

Bugfixes:

ProjectMembership resource group attribute was returned as a dict instead of being converted to Resource object (Issue #220) (thanks to Samuel Harmer)

2.2.0 (2019-01-13)

Deprecations:

  • Removed vendored Requests package and make it an external dependency as Requests did the same with its own dependencies
  • Removed Python 2.6 and 3.3 support as they’re not supported by Requests anymore

Improvements:

PerformanceWarning will be issued when Python-Redmine does some unnecessary work under the hood to fix the clients code problems

Bugfixes:

  • Redmine.upload() fails under certain circumstances when used with a file-like object and it contains unicode instead of bytes (Issue #216)
  • Redmine.session() doesn’t restore previous engine if fails (Issue #211) (thanks to Dmitry Logvinenko)

2.1.1 (2018-05-02)

Fix PyPI package

2.1.0 (2018-05-02)

This release concentrates mostly on stability and adds small features here and there. Some of them are backwards incompatible and are marked as such. They shouldn’t affect many users since most of them were used internally by Python-Redmine. A support for the Files API has been finally added, but please be sure to check its documentation as the implementation on the Redmine side is horrible and there are things to keep in mind while working with Files API. Lastly, only until the end of May 2018 there is a chance to buy a Pro Edition for only 14.99$ instead of the usual 24.99$, this is your chance to get an edition with additional features for a good price and to support the further development of Python-Redmine, more info here.

New Features:

Files API support (Issue #117)

Improvements:

  • Backwards Incompatible: ResourceSet’s filter() method became more advanced. It is now possible to filter on all available resource attributes, to follow resource relationships and apply lookups to the filters (see docs for details)
  • ResourceManager class has been refactored:
  • manager_class attribute on the Resource class can now be used to assign a separate ResourceManager to a resource, that allows outsourcing a resource specific functionality to a separate manager class (see WikiPageManager as an example)
  • Backwards Incompatible: request() method has been removed
  • _construct_*_url(), _prepare_*_request(), _process_*_response() methods have been added for create, update and delete methods to allow a fine-grained control over these operations

  • Ability to upload file-like objects (Issue #186) (thanks to hjpotter92)
  • Support for retrieving project’s time entry activities (see docs for details)
  • Attachment update() operation support (requires Redmine >= 3.4.0)
  • Resource.save() now accepts **attrs that need to be changed/set and returns self instead of a boolean True, which makes it chainable, so you can now do something like project.save(name='foo', description='bar').export('txt', '/home/foo')
  • get operation support for News, Query, Enumeration, IssueStatus, Tracker, CustomField, ContactTag, DealStatus, DealCategory and CRMQuery resources
  • include param in get, all and filter operations now accepts lists and tuples instead of comma-separated string which is still accepted for backward compatibility reasons, i.e. one can use include=['foo', 'bar'] instead of include='foo,bar'
  • It is now possible to use None and 0 in addition to '' in assigned_to_id attribute in Issue resource if an assignee needs to be removed from an issue

Changes:

  • Backwards Incompatible: Issue all operation now really returns all issues, i.e. both open and closed, instead of only returning open issues in previous versions due to the respect to Redmine’s standard behaviour
  • Backwards Incompatible: Instead of only returning a token string, upload() method was modified to return a dict that contains all the data for an upload returned from Redmine, i.e. id and token for Redmine >= 3.4.0, token only for Redmine < 3.4.0. Also it is now possible to use this token and pass it using a token key instead of the path key with path to the file in uploads parameter when doing an upload, this gives more control over the uploading process if needed
  • Backwards Incompatible: Removed resource_paths argument from Redmine object since ResourceManager now uses a special resource registry, to which, all resources that inherit from any Python-Redmine resource are being automatically added
  • Backwards Incompatible: Removed container_many in favor of container_filter, container_create and container_update attributes on Resource object to allow more fine-grained resource setup
  • Backwards Incompatible: return_raw parameter on engine.request() and engine.process_response() methods has been removed in favor of return_raw_response attribute on engine object
  • Updated bundled requests library to v2.15.1

Bugfixes:

  • Support 204 status code when deleting a resource (Issue #189) (thanks to dotSlashLu)
  • Raise ValidationError instead of not helpful TypeError exception when trying to create a WikiPage resource that already exists (Issue #182)
  • Enumeration, Version, Group and Notes custom_fields attribute was returned as a list of dicts instead of being converted to ResourceSet object
  • Downloads were downloaded fully into memory instead of being streamed as needed
  • ResourceRequirementsError exception was broken since v2.0.0
  • Pro Edition: RedmineUP CRM Contact and Deal resources export functionality didn’t work
  • Pro Edition: RedmineUP CRM Contact and Deal resources sometimes weren’t converted to Resource objects using Search API

Documentation:

Mentioned support for generate_password and send_information in User’s resource create/update methods, status in User’s resource update method, parent_id in Issue’s filter method and include in Issue’s all method

2.0.2 (2017-04-19)

Bugfixes:

Filter doesn’t work when there are > 100 resources requested (Issue #175) (thanks to niwatolli3)

2.0.1 (2017-04-10)

Fix PyPI package

2.0.0 (2017-04-10)

This version brings a lot of new features and changes, some of them are backward-incompatible, so please look carefully at the changelog below to find out what needs to be changed in your code to make it work with this version. Also Python-Redmine now comes in 2 editions: Standard and Pro, please have a look at this document for more details. Documentation was also significantly rewritten, so it is recommended to reread it even if you are an experienced Python-Redmine user.

New Features:

  • Pro Edition: RedmineUP Checklist plugin support
  • Request Engines support. It is now possible to create engines to define how requests to Redmine are made, e.g. synchronous (one by one) or asynchronous using threads or processes etc
  • redmine.session() context manager which allows to temporary redefine engine’s behaviour
  • Search API support (Issue #138)
  • Export functionality (Issue #58)
  • REDMINE_USE_EXTERNAL_REQUESTS environmental variable for emergency cases which allows to use external requests instead of bundled one even if external requests version is lower than the bundled one
  • Wrong HTTP protocol usage detector, e.g. one use HTTP when HTTPS should be used

Improvements:

ResourceSet objects were completely rewritten:
  • ResourceSet object that was already sliced now supports reslicing
  • ResourceSet object’s delete(), update(), filter() and get() methods have been optimized for speed
  • ResourceSet object’s delete() and update() methods now call the corresponding Resource’s pre_*() and post_*() methods
  • ResourceSet object’s get() and filter() methods now supports non-integer id’s, e.g. WikiPage’s title can now be used with it
  • Backwards Incompatible: ValuesResourceSet class has been removed
  • Backwards Incompatible: ResourceSet.values() method now returns an iterable of dicts instead of ValuesResourceSet object
  • ResourceSet.values_list() method has been added which returns an iterable of tuples with Resource values or single values if flattened, i.e. flat=True

New Resource object methods:
  • delete() deletes current resource from Redmine
  • pre_delete() and post_delete() can be used to execute tasks that should be done before/after deleting the resource through delete() method
  • bulk_decode(), bulk_encode(), decode() and encode() which are used to translate attributes of the resource to/from Python/Redmine

  • Attachment delete() method support (requires Redmine >= 3.3.0)
  • Pro Edition: RedmineUP CRM Note resource now provides type attribute which shows text representation of type_id
  • Pro Edition: RedmineUP CRM DealStatus resource now provides status attribute which shows text representation of status_type
  • WikiPage resource now provides project_id attribute
  • Unicode handling was significantly rewritten and shouldn’t cause any more troubles
  • UnknownError exception now contains status_code attribute which can be used to handle the exception instead of parsing code from exception’s text
  • Sync engine’s speed improved to 8-12% depending on the amount of resources fetched

Changes:

  • Backwards Incompatible: Renamed package name from redmine to redminelib
  • Resource class attributes that were previously tuples are now lists
  • Backwards Incompatible: _Resource class renamed to Resource
  • Backwards Incompatible: Redmine.custom_resource_paths keyword argument renamed to resource_paths
  • Backwards Incompatible: Redmine.download() method now returns a requests.Response object directly instead of iter_content() method if a savepath param wasn’t provided, this gives user even more control over response data
  • Backwards Incompatible: Resource.refresh() now really refreshes itself instead of returning a new refreshed resource, to get the previous behaviour use itself param, e.g. Resource.refresh(itself=False)
  • Backwards Incompatible: Removed Python 3.2 support
  • Backwards Incompatible: Removed container_filter, container_create and container_update attributes on Resource object in favor of container_many attribute
  • Backwards Incompatible: Removed Resource.translate_params() and ResourceManager.prepare_params() in favor of Resource.bulk_decode()
  • Backwards Incompatible: Removed is_unicode(), is_string() and to_string() from redminelib.utilities
  • Updated bundled requests library to v2.13.0

Bugfixes:

  • Infinite loop when uploading zero-length files (Issue #152)
  • Unsupported Redmine resource error while trying to use Python-Redmine without installation (Issue #156)
  • It was impossible to set data, params and headers via requests keyword argument on Redmine object
  • Calling str() or repr() on a Resource was giving incorrect results if exception raising was turned off for a resource

Documentation:

  • Switched to the alabaster theme
  • Added new sections:
  • Editions
  • Introduction
  • Request Engines

  • Added info about Issue Journals (Issue #120)
  • Added note about open/closed issues (Issue #136)
  • Added note about regexp custom field filter (Issue #164)
  • Added some new information here and there

1.5.1 (2016-03-27)

  • Changed: Updated bundled requests package to 2.9.1
  • Changed: Issue #124 (project.url now uses identifier rather than id to generate url for the project resource)
  • Fixed: Issue #122 (ValidationError for empty custom field values was possible under some circumstances with Redmine < 2.5.0)
  • Fixed: Issue #112 (UnicodeEncodeError on Python 2 if resource_id was of unicode type) (thanks to Digenis)

1.5.0 (2015-11-26)

  • Added: Documented support for new fields and values in User, Issue and IssueRelation resources
  • Added: Issue #109 (Smart imports for vendored packages (see docs for details)
  • Added: Issue #115 (File upload support for WikiPage resource)

1.4.0 (2015-10-18)

  • Added: Requests is now embedded into Python-Redmine
  • Added: Python-Redmine is now embeddable to other libraries
  • Fixed: Previous release was broken on PyPI

1.3.0 (2015-10-18)

Added: Issue #108 (Tests are now built-in into source package distributed via PyPI)

1.2.0 (2015-07-09)

  • Added: wheel support
  • Added: Issue #93 (JSONDecodeError exception now contains a response attribute which can be inspected to identify the cause of the exception)
  • Added: Issue #98 (Support for setting WikiPage resource parent title and converting parent attribute to Resource object instead of being a dict)

1.1.2 (2015-05-20)

Fixed: Issue #90 (Python-Redmine fails to install on systems with LC_ALL=C) (thanks to spikergit1)

1.1.1 (2015-03-26)

Fixed: Issue #85 (Python-Redmine was trying to convert field to date/datetime even when it shouldn’t, i.e. if a field looked like YYYY-MM-DD but wasn’t actually a date/datetime field, e.g. wiki page title or issue subject)

1.1.0 (2015-02-20)

  • Added: PyPy2/3 is now officially supported
  • Added: Introduced enabled_modules on demand include in Project resource
  • Fixed: Issue #78 (Redmine <2.5.2 returns only single tracker instead of a list of all available trackers when requested from a CustomField resource which caused an Exception in Python-Redmine, see this for details)
  • Fixed: Issue #80 (If a project is read-only or doesn’t have CRM plugin enabled, an attempt to add/remove Contact resource to/from it will lead to improper error message)
  • Fixed: Issue #81 (Contact’s resource tag_list attribute was always splitted into single chars) (thanks to Alexander Loechel)

1.0.3 (2015-02-03)

  • Fixed: Issue #72 (If an exception is raised during JSON decoding process, it should be catched and reraised as Python-Redmine’s own exception, i.e redmine.exceptions.JSONDecodeError)
  • Fixed: Issue #76 (It was impossible to retrieve more than 100 resources for resources which don’t support limit/offset natively by Redmine, i.e. this functionality is emulated by Python-Redmine, e.g. WikiPage, Groups, Roles etc)

1.0.2 (2014-11-13)

  • Fixed: Issue #55 (TypeError was raised during processing validation errors from Redmine when one of the errors was returned as a list)
  • Fixed: Issue #59 (Raise ForbiddenError when a 403 is encountered) (thanks to Rick Harris)
  • Fixed: Issue #64 (Redmine and Resource classes weren’t picklable) (thanks to Rick Harris)
  • Fixed: A ResourceSet object with a limit=100, actually returned 125 Resource objects

1.0.1 (2014-09-23)

Fixed: Issue #50 (IssueJournal’s notes attribute was converted to Note resource by mistake, bug was introduced in v1.0.0)

1.0.0 (2014-09-22)

Added: Support for the CRM plugin resources:
  • Contact
  • ContactTag
  • Note
  • Deal
  • DealStatus
  • DealCategory
  • CrmQuery

Added: Introduced new relations for the following resource objects:
  • Project - time_entries, deals, contacts and deal_categories relations
  • User - issues, time_entries, deals and contacts relations
  • Tracker - issues relation
  • IssueStatus - issues relation

  • Added: Introduced a values() method in a ResourceSet which returns ValuesResourceSet - a ResourceSet subclass that returns dictionaries when used as an iterable, rather than resource-instance objects (see docs for details)
  • Added: Introduced update() and delete() methods in a ResourceSet object which allow to bulk update or bulk delete all resources in a ResourceSet object (see docs for details)
  • Fixed: It was impossible to use ResourceSet’s get() and filter() methods with WikiPage resource
  • Fixed: Several small fixes and enhancements here and there

0.9.0 (2014-09-11)

  • Added: Introduced support for file downloads (see docs for details)
  • Added: Introduced new _Resource.requirements class attribute where all Redmine plugins required by resource should be listed (preparations to support non-native resources)
  • Added: New exceptions:
ResourceRequirementsError

  • Fixed: It was impossible to set a custom field of date/datetime type using date/datetime Python objects
  • Fixed: Issue #46 (A UnicodeEncodeError was raised in Python 2.x while trying to access a url property of a WikiPage resource if it contained non-ascii characters)

0.8.4 (2014-08-08)

  • Added: Support for anonymous Attachment resource (i.e. attachment with id attr only)
  • Fixed: Issue #42 (It was impossible to create a Project resource via new() method)

0.8.3 (2014-08-01)

Fixed: Issue #39 (It was impossible to save custom_fields in User resource via new() method)

0.8.2 (2014-05-27)

  • Added: ResourceSet’s get() method now supports a default keyword argument which is returned when a requested Resource can’t be found in a ResourceSet and defaults to None, previously this was hardcoded to None
  • Added: It is now possible to use getattr() with default value without raising a ResourceAttrError when calling non-existent resource attribute, see Issue #30 for details (thanks to hsum)
  • Fixed: Issue #31 (Unlimited recursion was possible in some situations when on demand includes were used)

0.8.1 (2014-04-02)

Added: New exceptions:
  • RequestEntityTooLargeError
  • UnknownError

Fixed: Issue #27 (Project and Issue resources parent attribute was returned as a dict instead of being converted to Resource object)

0.8.0 (2014-03-27)

  • Added: Introduced the detection of conflicting packages, i.e. if a conflicting package is found (PyRedmineWS at this time is the only one), the installation procedure will be aborted and a warning message will be shown with the detailed description of the problem
  • Added: Introduced new _Resource._members class attribute where all instance attributes which are not started with underscore should be listed. This will resolve recursion issues in custom resources because of how __setattr__() works in Python
  • Changed: _Resource.attributes renamed to _Resource._attributes
  • Fixed: Python-Redmine was unable to upload any binary files
  • Fixed: Issue #20 (Lowered Requests version requirements. Python-Redmine now requires Requests starting from 0.12.1 instead of 2.1.0 in previous versions)
  • Fixed: Issue #23 (File uploads via update() method didn’t work)

0.7.2 (2014-03-17)

  • Fixed: Issue #19 (Resources obtained via filter() and all() methods have incomplete url attribute)
  • Fixed: Redmine server url with forward slash could cause errors in rare cases
  • Fixed: Python-Redmine was incorrectly raising ResourceAttrError when trying to call repr() on a News resource

0.7.1 (2014-03-14)

Fixed: Issue #16 (When a resource was created via a new() method, the next resource created after that inherited all the attribute values of the previous resource)

0.7.0 (2014-03-12)

  • Added: WikiPage resource now automatically requests all of its available attributes from Redmine in case if some of them are not available in an existent resource object
  • Added: Support for setting date/datetime resource attributes using date/datetime Python objects
  • Added: Support for using date/datetime Python objects in all ResourceManager methods, i.e. new(), create(), update(), delete(), get(), all(), filter()
  • Fixed: Issue #14 (Python-Redmine was incorrectly raising ResourceAttrError when trying to call repr(), str() and int() on resources, created via new() method)

0.6.2 (2014-03-09)

Fixed: Project resource status attribute was converted to IssueStatus resource by mistake

0.6.1 (2014-02-27)

Fixed: Issue #10 (Python Redmine was incorrectly raising ResourceAttrError while creating some resources via new() method)

0.6.0 (2014-02-19)

  • Added: Redmine.auth() shortcut for the case if we just want to check if user provided valid auth credentials, can be used for user authentication on external resource based on Redmine user database (see docs for details)
  • Fixed: JSONDecodeError was raised in some Redmine versions during some create/update operations (thanks to 0x55aa)
  • Fixed: User resource status attribute was converted to IssueStatus resource by mistake

0.5.0 (2014-02-09)

  • Added: An ability to create custom resources which allow to easily redefine the behaviour of existing resources (see docs for details)
  • Added: An ability to add/remove watcher to/from issue (see docs for details)
  • Added: An ability to add/remove users to/from group (see docs for details)

0.4.0 (2014-02-08)

Added: New exceptions:
  • ConflictError
  • ReadonlyAttrError
  • ResultSetTotalCountError
  • CustomFieldValueError

Added: Update functionality via update() and save() methods for resources (see docs for details):
  • User
  • Group
  • IssueCategory
  • Version
  • TimeEntry
  • ProjectMembership
  • WikiPage
  • Project
  • Issue

Added: Limit/offset support via all() and filter() methods for resources that doesn’t support that feature via Redmine:
  • IssueRelation
  • Version
  • WikiPage
  • IssueStatus
  • Tracker
  • Enumeration
  • IssueCategory
  • Role
  • Group
  • CustomField

  • Added: On demand includes, e.g. in addition to redmine.group.get(1, include='users') users for a group can also be retrieved on demand via group.users if include wasn’t set (see docs for details)
  • Added: total_count attribute to ResourceSet object which holds the total number of resources for the current resource type available in Redmine (thanks to Andrei Avram)
  • Added: An ability to return None instead of raising a ResourceAttrError for all or selected resource objects via raise_attr_exception kwarg on Redmine object (see docs for details or Issue #6)
  • Added: pre_create(), post_create(), pre_update(), post_update() resource object methods which can be used to execute tasks that should be done before/after creating/updating the resource through save() method
  • Added: Allow to create resources in alternative way via new() method (see docs for details)
  • Added: Allow daterange TimeEntry resource filtering via from_date and to_date keyword arguments (thanks to Antoni Aloy)
  • Added: An ability to retrieve Issue version via version attribute in addition to fixed_version to be more obvious
  • Changed: Documentation for resources rewritten from scratch to be more understandable
  • Fixed: Saving custom fields to Redmine didn’t work in some situations
  • Fixed: Issue’s fixed_version attribute was retrieved as dict instead of Version resource object
  • Fixed: Resource relations were requested from Redmine every time instead of caching the result after first request
  • Fixed: Issue #2 (limit/offset as keyword arguments were broken)
  • Fixed: Issue #5 (Version resource status attribute was converted to IssueStatus resource by mistake) (thanks to Andrei Avram)
  • Fixed: A lot of small fixes, enhancements and refactoring here and there

0.3.1 (2014-01-23)

  • Added: An ability to pass Requests parameters as a dictionary via requests keyword argument on Redmine initialization, i.e. Redmine(’http://redmine.url’, requests={}).
  • Fixed: Issue #1 (unable to connect to Redmine server with invalid ssl certificate).

0.3.0 (2014-01-18)

Added: Delete functionality via delete() method for resources (see docs for details):
  • User
  • Group
  • IssueCategory
  • Version
  • TimeEntry
  • IssueRelation
  • ProjectMembership
  • WikiPage
  • Project
  • Issue

Changed: ResourceManager get() method now raises a ValidationError exception if required keyword arguments aren’t passed

0.2.0 (2014-01-16)

Added: New exceptions:
  • ServerError
  • NoFileError
  • ValidationError
  • VersionMismatchError
  • ResourceNoFieldsProvidedError
  • ResourceNotFoundError

Added: Create functionality via create() method for resources (see docs for details):
  • User
  • Group
  • IssueCategory
  • Version
  • TimeEntry
  • IssueRelation
  • ProjectMembership
  • WikiPage
  • Project
  • Issue

  • Added: File upload support, see upload() method in Redmine class
  • Added: Integer representation to all resources, i.e. __int__()
  • Added: Informal string representation to all resources, i.e. __str__()
  • Changed: Renamed version attribute to redmine_version in all resources to avoid name intersections
  • Changed: ResourceManager get() method now raises a ResourceNotFoundError exception if resource wasn’t found instead of returning None in previous versions
  • Changed: reimplemented fix for __repr__() from 0.1.1
  • Fixed: Conversion of issue priorities to enumeration resource object didn’t work

0.1.1 (2014-01-10)

  • Added: Python 2.6 support
  • Changed: WikiPage resource refresh() method now automatically determines its project_id
  • Fixed: Resource representation, i.e. __repr__(), was broken in Python 2.7
  • Fixed: dir() call on a resource object didn’t work in Python 3.2

0.1.0 (2014-01-09)

Initial release

AUTHOR

Author name not set

COPYRIGHT

2025, Maxim Tepkeev

July 2, 2025