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) – (optional). Uploads as [{'': ''}, ...], accepted keys are:
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 callspre_create()
andpost_create()
methods of the Resource object. Valid attributes are the same as forcreate()
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) – (optional). Fetches associated data in one call. Accepted values:
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) – (optional). Fetches associated data in one call. Accepted values:
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) – (optional). Get issues with given status id. One of:
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) – (optional). Fetches associated data in one call. Accepted values:
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) – (optional). Uploads as [{'': ''}, ...], accepted keys are:
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) – (optional). Additional data to copy or
None
. Accepted values: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">
- redminelib.resources.Issue.copy(link_original=True, include=('subtasks', 'attachments'), **fields)
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