Cleaning Backlog with Python

Purpose

I used the Public API from Python to organize the Backlog. As a memorandum.

Digression

If you notice it, it's the end of the year. In the flow of the story, the place where I am in charge of cleaning is Backlog. We have a lot of issue management systems that we are indebted to on a daily basis.

What I wanted to do

Extraction of issue tickets for which no person has been set and automation of the process of assigning new people. I can't put it away on my own, so I decided to assign a person in charge to clarify the responsibility. At a glance, there are dozens of tickets for which the person in charge has not been set, and it is judged that it is troublesome to insert them manually. I want to do it automatically using a tool.

Source commentary

Command settings

setup.py


from setuptools import setup

setup(
    name='',
    version='1.0.0',
    author='The name of the person who made it',
    author_email='Contact email address',
    install_requires=[
        'requests==2.11.1',
        'docopt==0.6.2'
    ],
    entry_points="""\    #←←←←←←←← This!!!!!!!!!!!!
      [console_scripts]
      wariate = update_assignee_id:main
      """,
)

setup.py has a lot of useful features, one of which is entry_points. It's the same as pserve in Pyramid's setup.py, which saves you the trouble of running python commands. It's small, but it's useful when the name of the python file is long or the hierarchy is deep.

Example) If you want to run the tool without setting entry_points, activate it first

(venv)python /User/tool/backlog/update_assignee_id.py --api-key=uiwejaefdhpasid8fpa8etw3to

If you run the tool with entry_points set, activate it first (venv)wariate --api-key=uiwejaefdhpasid8fpa8etw3to

Optional parser

update_assignee_id.py


"""execute update assignee id

usage: wariate (--api-key=<api-key>)

options:
    --api-key=<api-key>     api key
"""

from docopt import docopt

def main():
    args = docopt(__doc__)
    update_assignee_id(args['--api-key'])

Pick up only the document at the beginning of the Python file and the main function. If you write it like this, it will check the required arguments. There are Other useful functions, so you should use them. Unlike other parsers, it refers to documents, so it is also an advantage that you can avoid the situation where only documents are left unmaintained.

API execution

update_assignee_id.py



import json
import requests

__API_KEY = '?apiKey={}'
__BASE_END_POINT = 'https://domein.backlog.jp/api/v2/'
__PROJECT_END_POINT = __BASE_END_POINT + 'projects'

def get_project_ids(api_key):
    r = requests.get(__PROJECT_END_POINT + __API_KEY.format(api_key))
    projects = json.loads(r.text)
    return list(map(lambda project: project['id'], projects))

Pick up the part to get the list of project IDs. After all, requests is a push, and it is easy to use it as an intuitive source that can be read by humans. By the way, this source has been confirmed to work with Python 3.5. In the case of Python2 series, I feel that the return type of the map function was a list, so in the case of 2 series, I feel that type conversion to list was not necessary. Perhaps.

Pick up records that have not been set by the person in charge

update_assignee_id.py



__GET_ISSUE_QUERY = {
    'statusId[]': [1, 2, 3],
    'sort': 'assignee',
    'order': 'asc'
}
__ISSUE_END_POINT = __BASE_END_POINT + 'issues'

def get_issues(api_key, project_ids):
    is_continue = True
    params = __GET_ISSUE_QUERY
    params['projectId[]'] = project_ids
    while is_continue:
        r = requests.get(__ISSUE_END_POINT + __API_KEY.format(api_key), params=params)
        issues = json.loads(r.text)
        for issue in issues:
            if issue['assignee'] is None:
                yield issue
            else:
                is_continue = False
                break

It is possible to get a list of issues by specifying a specific person in charge, but the person in charge cannot intentionally pick up an unset issue (API specification). Therefore, I did not dare to narrow down the person in charge, but sorted the person in charge in ascending order and responded by bringing in the issues for which the person in charge was not set first.

What is patch

update_assignee_id.py



def update_issue(issue, api_key):
    base_url = '/'.join([__ISSUE_END_POINT, issue['issueKey']]) + __API_KEY.format(api_key)
    params = {
        'assigneeId': issue['createdUser']['id']
    }
    r = requests.patch(base_url, params)
    if r.status_code != 200:
        raise Exception('update error occurred:{}'.format(issue['issueKey']))
    print('updated:{}'.format(issue['issueKey']))


By doing this, the person in charge can be updated by the creator. I'm ashamed to know the request category called patch for the first time. As a proper use with post post → whole update patch → Partially updated It seems. I learned something.

Finally

We are such a company, but if you are interested, we would be grateful if you could contact us from at the bottom of our engineer blog top page of Qiita. We look forward to!

Recommended Posts

Cleaning Backlog with Python
FizzBuzz with Python3
Scraping with Python
Statistics with python
Scraping with Python
Python with Go
Twilio with Python
Integrate with Python
Play with 2016-Python
AES256 with python
Tested with Python
python starts with ()
with syntax (Python)
Bingo with python
Zundokokiyoshi with python
Excel with Python
Microcomputer with Python
Cast with python
Serial communication with Python
Zip, unzip with python
Django 1.11 started with Python3.6
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Try scraping with Python.
Learning Python with ChemTHEATER 03
Sequential search with Python
"Object-oriented" learning with python
Run Python with VBA
Handling yaml with python
Solve AtCoder 167 with python
[Python] Use JSON with Python
Learning Python with ChemTHEATER 05-1
Learn Python with ChemTHEATER
Run prepDE.py with python3
1.1 Getting Started with Python
Collecting tweets with Python
Binarization with OpenCV / Python
3. 3. AI programming with Python
Non-blocking with Python + uWSGI
Scraping with Python + PhantomJS
Posting tweets with python
Drive WebDriver with python
Use mecab with Python3
[Python] Redirect with CGIHTTPServer
Voice analysis with python
Think yaml with python
Operate Kinesis with Python
Getting Started with Python
Use DynamoDB with Python
Data cleaning using Python
Handle Excel with python
Ohm's Law with Python
Primality test with python
Run Blender with python
Solve Sudoku with Python
Python starting with Windows 7
Heatmap with Python + matplotlib
Multi-process asynchronously with python