Python Redmine
Python Redmine est une bibliothèque Python qui communique avec Redmine.
Il présente les caractéristiques suivantes.
・ Prise en charge à 100% des fonctions de l'API Redmine (Vous pouvez même créer un projet) · Python 2.7, 3.4-3.7
Les détails sont décrits ci-dessous. https://python-redmine.com/
Il peut être installé à l'aide de pip ou easy_install.
$ pip install python-redmine
Ou
$ easy_install python-redmine
Comme paramètre côté Redmine, cochez «Activer le service Web par l'API REST» dans l'onglet API de l'écran «Administration» -> «Paramètres».
Si vous activez l'API ici, vous pouvez vérifier la clé API sur l'écran des paramètres personnels.
Un exemple est décrit ci-dessous. Cet exemple est confirmé avec Python 3.7 + python redmine 2.2.1 + Redmine 4.0.3. Stable sous Windows.
Vous pouvez vous connecter à redmine en spécifiant un nom d'utilisateur et un mot de passe.
from redminelib import Redmine
redmine = Redmine('http://localhost/redmine', username='admin', password='admin')
Vous pouvez également vous connecter à l'aide de la clé API comme suit.
from redminelib import Redmine
redmine = Redmine('http://localhost/redmine', key='e4a413a3b7a3c238102b7393c035bbc5f5eb6409')
Voir ci-dessous pour les opérations de billetterie https://python-redmine.com/resources/issue.html
Vous pouvez créer un ticket en créant un objet ticket avec redmine.issue.new (), en y définissant des propriétés et en l'enregistrant.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issue = redmine.issue.new()
issue.project_id = 'Test1'
issue.subject = 'Matière'
issue.tracker_id = 1 #Traqueur
issue.description = 'Montrez le contenu du ticket.\n Les sauts de ligne sont également possibles.'
issue.status_id = 1 #statut
issue.priority_id = 1 #priorité
issue.assigned_to_id = 1 #ID de la personne responsable
issue.watcher_user_ids = [1] #ID de l'utilisateur à regarder
issue.parent_issue_id = 12 #ID du ticket parent
issue.start_date = datetime.date(2014, 1, 1) #date de début
issue.due_date = datetime.date(2014, 2, 1) #Date limite
issue.estimated_hours = 4 #Effectif attendu
issue.done_ratio = 40
issue.custom_fields = [{'id': 1, 'value': 'foo'}]
issue.uploads = [{'path': 'C:\\dev\\python3\\redmine\\test.txt'}]
issue.custom_fields = [{'id': 1, 'value': 'foo'}]
issue.save()
Spécifiez l'ID du ticket avec redmine.issue.get (). Si ça n'existe pas redmine.exceptions.ResourceNotFoundError Une exception se produit.
import datetime
from redminelib import Redmine
from redminelib.exceptions import ResourceNotFoundError
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
try:
issue = redmine.issue.get(60)
print (dir(issue))
print ('id:%d' % issue.id)
print ('project:%s' % issue.project.name)
print ('project_id:%d' % issue.project.id)
print ('subject:%s' % issue.subject)
print ('tracker:%s' % issue.tracker.name)
print ('tracker_id:%d' % issue.tracker.id)
print ('description:%s' % issue.description)
print ('status:%s' % issue.status.name)
print ('status:%d' % issue.status.id)
print ('author:%s' % issue.author.name)
print ('author_id:%d' % issue.author.id)
if hasattr(issue, 'assigned'):
print ('assigned:%s' % issue.assigned_to.name)
print ('assigned_id:%d' % issue.assigned_to.id)
print ('watcher--------')
for u in issue.watchers:
print (' %d:%s' % (u.id, u.name))
print ('Date de création:%s' % issue.created_on)
print ('Date de mise à jour:%s' % issue.updated_on)
if hasattr(issue, 'start_date'):
print ('start_date:%s' % issue.start_date)
if hasattr(issue, 'due_date'):
print ('issue_date:%s' % issue.due_date)
if hasattr(issue, 'issue.estimated_hours'):
print ('estimated_hours:%d' % issue.estimated_hours)
print ('Heures d'ouverture:%d' % issue.spent_hours)
print ('Enregistrement du temps de travail----------')
for t in issue.time_entries:
print(' ID:%d' % t.id)
print('Activités:%s' % t.activity)
print('commentaire:%s' % str(t.comments))
print('Date de création:%s' % t.created_on)
print('temps:%s' %t.hours)
print('ID de billets:%s' % t.issue)
print('ID du projet:%s' % t.project)
print('Date:%s' % t.spent_on)
print('Date de mise à jour:%s' % t.updated_on)
print(' user:%d %s' % (t.user.id,t.user.name))
print ('done_ratio:%d' % issue.done_ratio)
print ('priority:%s' % issue.priority.name)
print ('priority_id:%d' % issue.priority.id)
print ('custom_fields----')
for c in issue.custom_fields:
print (' %d:%s = %s' % (c.id, c.name, c.value))
print ('attachements---')
for f in issue.attachments:
print (' id:%d' % (f.id))
print (' author:%s' % (f.author))
print (' content_url:%s' % (f.content_url))
print (' created_on:%s' % (f.created_on))
print (' description:%s' % (f.description))
print (' filename:%s' % (f.filename))
print (' filesize:%d' % (f.filesize))
print (' ---------------')
print ('changeset---')
for c in issue.changesets:
#Journal de validation stocké en tant que type de dictionnaire
print (' %s' % c)
if hasattr(issue, 'parent'):
print ('parent:%s' % issue.parent)
print ('children----------')
for c in issue.children:
print (' %s:%s' % (c.id, c.subject))
print ('relation----------')
for r in issue.relations:
print (' %d:%d->%d(%s)' % (r.id, r.issue_id, r.issue_to_id, r.relation_type))
except (ResourceNotFoundError):
print ('Not found')
Les éléments pour lesquels l'entrée est omise n'ont pas de propriétés proprement dites. Par conséquent, vous devez vérifier l'existence avec hasattr.
Les informations utilisateur des observateurs, du responsable et du créateur ne contiennent que les informations minimales nécessaires. Si vous souhaitez obtenir le nom de connexion, etc., obtenez les détails de l'utilisateur à partir de l'ID utilisateur comme suit.
user = redmine.user.get(u.id)
Il peut être obtenu avec redmine.issue.all (). Les paramètres qui peuvent être omis sont les suivants.
sort (chaîne): ordre de tri limit (entier): limite supérieure du nombre d'acquisitions offset (entier): position de début d'acquisition
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.all(sort='category:desc')
for issue in issues:
print ('%d:%s' % (issue.id, issue.subject))
Les tickets avec des conditions spécifiques peuvent être extraits en utilisant redmine.issue.filter. Dans ce qui suit, le responsable extrait son ticket.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='me')
for issue in issues:
print ('%d:%s' % (issue.id, issue.subject))
Vous pouvez également effectuer une recherche par requête enregistrée à l'aide de query_id.
Après tout, vous ne faites que lire l'API REST, vous pouvez donc l'utiliser avec des opérateurs pris en charge par Redmine. http://www.redmine.org/projects/redmine/wiki/Rest_Issues
Dans le document ci-dessus, des exemples tels que "! \ " ">" "<" "" "~" Sont présentés.
Ainsi, par exemple, pour obtenir une tâche qui n'est attribuée à personne, la mise en œuvre est la suivante.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='!*')
for issue in issues:
print ('%d:%s' % (issue.id, issue.subject))
Aussi, si vous souhaitez confier la tâche à un responsable autre que vous-même, ce sera comme suit.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
issues = redmine.issue.filter(assigned_to_id='!me')
for issue in issues:
print ('%d:%s' % (issue.id, issue.subject))
Nous pouvons voir que divers conditionnements sont possibles en utilisant des opérateurs tels que le refus et la spécification de plage, mais le problème est que la documentation de l'API REST ne nous dit pas de quel type d'opérateur il s'agit.
Par conséquent, il est nécessaire de se référer au code réel.
redmine/app/models/query.rb https://github.com/redmine/redmine/blob/9746ab7e5be2db5e2d233ee37365cf21ba4b893a/app/models/query.rb#L254
Si vous regardez cette implémentation, vous pouvez voir quels types d'opérateurs sont définis. Cependant, tous les éléments ne peuvent pas être utilisés par tous les opérateurs. Par exemple, dans le sujet, "\ *: all", "! \ *: None" et "~: include" peuvent être utilisés, mais "^: begin with" ne peut pas être utilisé. Que cela puisse être utilisé ou non est les mêmes que les conditions qui peuvent être effectuées sur l'écran de réglage du filtre ci-dessous.
Les tickets obtenus avec redmine.issue.get peuvent être modifiés et enregistrés. L'exemple suivant est un exemple de modification de l'état du ticket.
# -*- coding: utf-8 -*-
import datetime
from redmine import Redmine
redmine = Redmine('http://localhost/redmine', key='e4a413a3b7a3c238102b7393c035bbc5f5eb6409')
issue = redmine.issue.get(51)
issue.status_id = 2
issue.save()
Voir ci-dessous pour les opérations sur le temps de travail https://python-redmine.com/resources/time_entry.html
Voici un exemple d'énumération des heures de travail.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
time_entries = redmine.time_entry.all()
for t in time_entries:
print(' ID:%d' % t.id)
print('Activités:%s' % t.activity)
print('commentaire:%s' % str(t.comments))
print('Date de création:%s' % t.created_on)
print('temps:%s' %t.hours)
print('ID de billets:%s' % t.issue)
print('ID du projet:%s' % t.project)
print('Date:%s' % t.spent_on)
print('Date de mise à jour:%s' % t.updated_on)
print(' user:%d %s' % (t.user.id,t.user.name))
print('Classification du travail%d %s' % (t.activity.id, t.activity.name))
Un exemple d'enregistrement du temps de travail est présenté ci-dessous.
import datetime
from redminelib import Redmine
redmine = Redmine('http://192.168.0.200/', key='60076966cebf71506ae3f2391da649235a2b1d46')
time_entry = redmine.time_entry.new()
time_entry.issue_id = 60
time_entry.spent_on = datetime.date(2014, 1, 14)
time_entry.hours = 3
time_entry.activity_id = 4
time_entry.comments = 'hello'
time_entry.activity_id = 8
time_entry.save()
Cette fois, nous n'avons vérifié qu'une partie de l'API fournie, mais il a été confirmé que les opérations pouvant être effectuées sur l'écran Web sont couvertes.
En utilisant Python Redmine, vous pouvez vous attendre à pouvoir utiliser Redmine librement avec Python. On peut s'attendre à ce que ce qui suit puisse être réalisé.
-Émission d'un ticket du programme lorsque le test automatique échoue ・ Conversion automatique des documents de conception écrits dans Excel vers Wiki -Agréger les heures de travail et notifier un autre système.
c'est tout
Recommended Posts