{ "info": { "author": "Yandex Team", "author_email": "smosker@yandex-team.ru", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "yandex_tracker_client\n=====================\n\n**yandex_tracker_client** provides python interface to `Yandex.Tracker\nv2 API `_.\n\nInstallation\n------------\n\n**yandex_tracker_client** could be installed by pip:\n\n.. code:: bash\n\n pip install yandex_tracker_client\n\nConfiguring\n-----------\n\nThe Yandex.Tracker API uses the OAuth 2.0 protocol for application\nauthorization. Applications use the OAuth 2.0 protocol to access Yandex\nservices on behalf of a user.\nYou can get your token `here `_.\n\nUsage\n-----\n\nTo use client you need to initialize client first:\n\n.. code:: python\n\n from yandex_tracker_client import TrackerClient\n\n client = TrackerClient(token=, org_id=)\n\n**Getting issue:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n print issue.deadline, issue.updatedAt\n\nHandling 404 exceptions:\n\n.. code:: python\n\n from yandex_tracker_client.exceptions import NotFound\n\n try:\n issue = client.issues['MYQUEUE-42']\n except NotFound:\n pass\n\n**Creating issue:**\n\n.. code:: python\n\n client.issues.create(\n queue='MYQUEUE',\n summary='API Test Issue',\n type={'name': 'Bug'},\n description='test description'\n )\n\n**Updating issue:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n issue.update(summary='East or west, Yandex.Tracker is the best', priority='minor')\n\n**Searching for issues:**\n\n.. code:: python\n\n issues = client.issues.find('Queue: MYQUEUE Assignee: me()') #You can copy this query from ui tracker interface\n print [issue.key for issue in issues]\n\nUsing the 'filter' parameter possible to pass the parameters of the\nfiltering as a dictionary:\n\n.. code:: python\n\n issues = client.issues.find(\n filter={'queue': 'MYQUEUE', 'assignee': 'me()', 'created': {'from': '2019-03-02'}},\n order=['update','-status', '+priority'],\n per_page=15\n )\n print [issue.key for issue in issues]\n\n**Obtaining list of transitions:**\n\n.. code:: python\n\n transitions = issue.transitions.get_all()\n for transition in transitions:\n print transition\n\n**Executing transition:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n issue.transitions['close'].execute()\n\nExecuting transition with comment and resolution:\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n transition = issue.transitions['close']\n transition.execute(comment='Fixed', resolution='fixed')\n\n**Queue info:**\n\n.. code:: python\n\n queue = client.queues['MYQUEUE']\n\nor:\n\n.. code:: python\n\n queue = client.issues['MYQUEUE-42'].queue\n\n**Queue list:**\n\n.. code:: python\n\n queues = client.queues.get_all()[:3]\n\n**List issue attachments:**\n\n.. code:: python\n\n attachments = client.issues['MYQUEUE-42'].attachments\n\n**Downloading attachments to specified directory:**\n\n.. code:: python\n\n [attachment.download_to('some/path') for attachments in client.get_attachments('MYQUEUE-42')]\n\n**Uploading an attachment**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n client.attachments.create('path/to/file')\n\n**Deleting an attachment**\n\n.. code:: python\n\n ATTACHMENTS_TO_DELETE = {'to_delete.txt', 'smth.jpeg'}\n issue = client.issues['MYQUEUE-42']\n for attach in issue.attachments:\n if attach.name in ATTACHMENTS_TO_DELETE:\n attach.delete()\n\nor\n\n.. code:: python\n\n client.attachments[42].delete()\n\n**List issue comments:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n comments = list(issue.comments.get_all())[:3]\n\n**Add comment:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n comment = issue.comments.create(text='Test Comment')\n\n**Add comment with attachments:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n comment = issue.comments.create(text='Test comment', attachments=['path/to/file1', 'path/to/file2'])\n\n**Update comment:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n comment = issue.comments[42]\n comment.update(text='New Text')\n\n**Deleting a comment:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n comment = issue.comments[42]\n comment.delete()\n\n**List issue links:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n links = issue.links\n\n**Add link:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n link = issue.links.create(issue='TEST-42', relationship='relates')\n\n**Deleting a link:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n link = issue.links[42]\n link.delete()\n\n**Add remote link:**\n\n.. code:: python\n\n issue = client.issues['MYQUEUE-42']\n link = issue.remotelinks.create(origin=\"ru.yandex.lunapark\", key=\"MYQUEUE-42\", relationship=\"relates\")\n\nAdvanced Usage\n--------------\n\n**Bulk update:**\n\n.. code:: python\n\n bulkchange = client.bulkchange.update(\n ['MYQUEUE-42', 'MYQUEUE-43', 'MYQUEUE-44'],\n priority='minor',\n tags={'add': ['minored']})\n print bulkchange.status\n bulkchange = bulkchange.wait()\n print bulkchange.status\n\n**Bulk transition:**\n\n.. code:: python\n\n bulkchange = client.bulkchange.transition(\n ['MYQUEUE-42', 'MYQUEUE-43'], 'need_info', priority='minor')\n bulkchange.wait()\n\n**Bulk move:**\n\n.. code:: python\n\n bulkchange = client.bulkchange.move(['MYQUEUE-42', 'MYQUEUE-43'], 'TEST')\n bulkchange.wait()\n\n**Perform actions with objects**\n\nClient allows to make arbitrary subqueries to entities, for example in\norder to archive version you have to make request\n``POST /v2/versions//_archive``\n\nIn order to support such separate subqueries exists method\nperform_action, usage example:\n\n::\n\n version = client.versions[60031]\n version.perform_action('_archive', 'post', ignore_empty_body=True)\n\nSome of tracker api endpoints doesn't work correctly with blank (``{}``)\nbody, in this case you should pass ``ignore_empty_body=True`` to this\nmethod\n\nExamples\n--------\n\n**Change assignee in all tickets**\n\n.. code:: python\n\n from yandex_tracker_client import TrackerClient\n\n client = TrackerClient(token=, org_id=)\n\n def sent_employee_to_vacation(assignee, replace_with):\n \"\"\"\n :param assignee: login in Yandex.Tracker\n :type assignee: ``str``\n\n :param replace_with: login in Yandex.Tracker\n :type replace_with: ``str``\n\n :return: is operation was successful\n :rtype: ``bool``\n \"\"\"\n issues_to_transfer = client.issues.find(filter={'queue': 'MYQUEUE', 'assignee': assignee})\n bulk_change = client.bulkchange.update(issues_to_transfer, assignee=replace_with)\n bulk_change.wait()\n\n if bulk_change.status == 'COMPLETED':\n log.info('Successfully change assignee in bulkchange {}'.format(bulk_change.id))\n for issue in issues_to_transfer:\n issue.comments.create('Your ticket will be processed by another employee - {}'.format(replace_with))\n successful = True\n else:\n log.error('Bulkchange operation {} failed'.format(bulk_change.id))\n successful = False\n\n return successful\n\n**Create related issues**\n\n.. code:: python\n\n def start_new_feature_creation_process(feature):\n feature_type = get_feature_type(feature)\n manager = get_manager_by_type(feature_type)\n # manager = 'manager_login'\n main_issue = client.issues.create(\n queue='MAINQUEUE',\n assignee=manager,\n summary='New feature request: {}'.format(feature),\n type={'name': 'Task'},\n description='New feature request arrived'\n )\n if feature_type.need_design:\n design_issue = client.issues.create(\n queue='DESIGN',\n summary='Feature \"{}\" design'.format(feature),\n type={'name': 'Task'},\n description='Need design for new feature, main task: {}'.format(main_issue.id)\n )\n main_issue.links.create(issue=design_issue.id, relationship='relates')\n\n if feature_type.add_followers:\n followers = get_followers(feature_type)\n # followers = ['my_login', 'someoneelse_login']\n main_issue.update(followers={'add': followers})\n\n if feature_type.need_testing:\n tester = get_random_tester()\n # tester = 'tester_login'\n main_issue.update(qa=tester)\n\n log.info('Successfully start new feature creation process')\n return main_issue.id\n\nRun tests\n---------\n\n::\n\n ./run_tests.sh\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/yandex/yandex_tracker_client", "keywords": "python yandex.tracker api-client", "license": "", "maintainer": "", "maintainer_email": "", "name": "yandex_tracker_client", "package_url": "https://pypi.org/project/yandex_tracker_client/", "platform": "", "project_url": "https://pypi.org/project/yandex_tracker_client/", "project_urls": { "Homepage": "https://github.com/yandex/yandex_tracker_client" }, "release_url": "https://pypi.org/project/yandex_tracker_client/1.3/", "requires_dist": null, "requires_python": "", "summary": "Client for Yandex.Tracker", "version": "1.3" }, "last_serial": 5907494, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "d8461c5d5b303876733c552f16181af6", "sha256": "912a13562676394e6377087eeb85c02ee8f2b77a9ee58f9f86e09981c7235b42" }, "downloads": -1, "filename": "yandex_tracker_client-1.0.tar.gz", "has_sig": false, "md5_digest": "d8461c5d5b303876733c552f16181af6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18434, "upload_time": "2019-07-22T12:14:33", "url": "https://files.pythonhosted.org/packages/09/15/9505a0511b083c3ae1d5e3a817de3973fba7e39dc0d7309567cf650d359e/yandex_tracker_client-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "9cd287eee0a444a77506deb7c97899e7", "sha256": "ba9d3d76f3ddd24a5059b80dc333dcfceb02164e66588f39dae04b85cc524350" }, "downloads": -1, "filename": "yandex_tracker_client-1.1.tar.gz", "has_sig": false, "md5_digest": "9cd287eee0a444a77506deb7c97899e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18441, "upload_time": "2019-08-07T12:58:30", "url": "https://files.pythonhosted.org/packages/54/a2/0e9f0515bf038d09db6553758b5370070a883477fec4ffc3ece3fe12182c/yandex_tracker_client-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "6d59c112155b77cb841fd5cfebfaa1c7", "sha256": "89742c19e7ebb08195fa498cea146dc7dff7334fd742884b0c30edad3ffa5667" }, "downloads": -1, "filename": "yandex_tracker_client-1.2.tar.gz", "has_sig": false, "md5_digest": "6d59c112155b77cb841fd5cfebfaa1c7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18498, "upload_time": "2019-08-26T14:22:58", "url": "https://files.pythonhosted.org/packages/87/94/02231a02e9cc9dfcc977e0ee816d0052a16402ccf0faab6a9f6f5c48bb68/yandex_tracker_client-1.2.tar.gz" } ], "1.3": [ { "comment_text": "", "digests": { "md5": "e370af17a08b3878f34f86b1d0b7dc1b", "sha256": "8ccdae858ea26eed673fd6156e704ba8fb5d8bc6cd5eccd9ea424a85aa6c6e4c" }, "downloads": -1, "filename": "yandex_tracker_client-1.3.tar.gz", "has_sig": false, "md5_digest": "e370af17a08b3878f34f86b1d0b7dc1b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18557, "upload_time": "2019-09-30T15:25:09", "url": "https://files.pythonhosted.org/packages/3c/2b/3b3890339dd5e510987391b8903e63f55b575e6e87741db63e33aa6d30e6/yandex_tracker_client-1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e370af17a08b3878f34f86b1d0b7dc1b", "sha256": "8ccdae858ea26eed673fd6156e704ba8fb5d8bc6cd5eccd9ea424a85aa6c6e4c" }, "downloads": -1, "filename": "yandex_tracker_client-1.3.tar.gz", "has_sig": false, "md5_digest": "e370af17a08b3878f34f86b1d0b7dc1b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18557, "upload_time": "2019-09-30T15:25:09", "url": "https://files.pythonhosted.org/packages/3c/2b/3b3890339dd5e510987391b8903e63f55b575e6e87741db63e33aa6d30e6/yandex_tracker_client-1.3.tar.gz" } ] }