Skip to main content

A Jira REST API toolkit for querying, creating, and managing tickets from Python or the CLI

Project description

jiracommandkit

A Jira REST API toolkit for querying, creating, and managing tickets — usable as a Python library or as a jiracommandkit command-line tool.

Supports Jira Cloud's v3 issues API and the Service Desk API: JQL search, ticket creation (service-desk and regular projects), comments, attachments, label management, and mandatory-field discovery for projects with required custom fields.

Installation

pip install jiracommandkit

For local development, install from a clone in editable mode:

pip install -e ".[dev]"

Configuration

jiracommandkit reads credentials and settings in this order:

  1. A JIRACOMMANDKIT_<KEY> environment variable
  2. A value saved in ~/.config/jiracommandkit/jiracommandkit.json
  3. A caller-supplied default (None if not given)
Key Required Description
JIRA_USERNAME yes Jira account email/username.
JIRA_API_KEY yes Jira API token.
JIRA_BASE_URL yes Base URL, e.g. https://yourcompany.atlassian.net.
JIRA_SERVICE_DESK_ID no Default service desk ID used by create_ticket.
JIRA_REQUEST_TYPE_ID no Default request type ID used by create_ticket.
JIRA_SECURITY_LABELS no Comma-separated labels applied by create_security_ticket.
JIRA_MANDATORY_FIELDS_FILE no Path to a JSON file of per-project required fields (see below).

Setting credentials via environment variables

export JIRACOMMANDKIT_JIRA_USERNAME="you@example.com"
export JIRACOMMANDKIT_JIRA_API_KEY="your-api-token"
export JIRACOMMANDKIT_JIRA_BASE_URL="https://yourcompany.atlassian.net"

Setting credentials via the CLI (writes to ~/.config/jiracommandkit/jiracommandkit.json)

jiracommandkit config set JIRA_USERNAME you@example.com
jiracommandkit config set JIRA_API_KEY your-api-token
jiracommandkit config set JIRA_BASE_URL https://yourcompany.atlassian.net

jiracommandkit config list        # list saved keys
jiracommandkit config get JIRA_USERNAME

CLI usage

Search tickets with JQL

jiracommandkit search "project = ENG AND status = Open"
jiracommandkit search "project = ENG" --format json
jiracommandkit search "project = ENG" --fields summary status assignee --max-results 50

Get a single ticket

jiracommandkit get ENG-123
jiracommandkit get ENG-123 --format json

Comments

jiracommandkit comment add ENG-123 "Investigating now."
jiracommandkit comment add ENG-123 "Internal note" --internal
jiracommandkit comment list ENG-123

Labels

jiracommandkit label ENG-123 security backend        # overwrite the labels field
jiracommandkit label ENG-123 security --merge         # merge into existing labels

Update a field

jiracommandkit set-field ENG-123 summary "Updated summary text"
jiracommandkit set-field ENG-123 priority '{"id": "2"}'

Attachments

jiracommandkit attach ENG-123 ./screenshot.png

Create a ticket

# Service desk ticket, using JIRACOMMANDKIT_JIRA_SERVICE_DESK_ID / JIRACOMMANDKIT_JIRA_REQUEST_TYPE_ID
jiracommandkit create --summary "Printer on fire" --description "Send help" --priority 2

# Regular (non-service-desk) project ticket
jiracommandkit create --project ENG --issue-type Bug \
    --summary "Null pointer on checkout" \
    --description "Crashes when cart is empty" \
    --field customfield_10005='"Backend"'

# Override the service desk / request type for one call
jiracommandkit create --service-desk-id 4 --request-type-id 12 \
    --summary "New laptop" --description "Onboarding request"

Create a security ticket

Creates a ticket and applies JIRACOMMANDKIT_JIRA_SECURITY_LABELS to it:

jiracommandkit create-security \
    --summary "Suspicious login activity" \
    --description "Multiple failed logins from unfamiliar IP" \
    --priority 1 \
    --attachment ./evidence.log

Discover required fields for your Jira instance

Queries every service desk and project you have access to, and writes a starter JSON file listing required custom fields and their selectable values:

jiracommandkit discover-fields ~/.config/jiracommandkit/mandatory_fields.json
jiracommandkit config set JIRA_MANDATORY_FIELDS_FILE ~/.config/jiracommandkit/mandatory_fields.json

Edit the generated file to pick one requestTypeId (service desk projects) or issueType (regular projects) per project, and a single value for each required custom field. Once configured, create_ticket/create-security calls with a matching --project automatically include those fields:

{
    "SEC": {
        "serviceDeskId": 2,
        "requestTypeId": 36,
        "customfield_10001": {"value": "Security"}
    },
    "ENG": {
        "issueType": "Bug",
        "customfield_10005": "Backend"
    }
}

Library usage

Every CLI command has a corresponding method on jiracommandkit.JiraClient, so you can use jiracommandkit directly in other Python projects without shelling out.

from jiracommandkit import JiraClient

client = JiraClient()  # reads JIRACOMMANDKIT_JIRA_* env vars / jiracommandkit.json

Search

issues = client.query_jql("project = ENG AND status = Open", max_results=100)

tickets_by_project = client.format_tickets(issues)
for ticket in tickets_by_project["ENG"]:
    print(ticket.key, ticket.status, ticket.summary)

Get a ticket

issue = client.get_jira_by_id("ENG-123")

Comments

client.add_comment_to_ticket("ENG-123", "Investigating now.", public=True)
comments = client.get_comments_for_ticket("ENG-123")

Labels

client.set_custom_labels("ENG-123", "labels", ["security", "backend"])   # overwrite
client.add_labels("ENG-123", ["security"])                                # merge

Update a field

client.edit_ticket_field("ENG-123", "summary", "Updated summary text")

Attachments

client.add_attachment_to_ticket("ENG-123", "./screenshot.png")

Create a ticket

ticket_key, ticket_id = client.create_ticket(
    summary="Null pointer on checkout",
    desc="Crashes when cart is empty",
    project_key="ENG",
    issue_type="Bug",
    extra_fields={"customfield_10005": "Backend"},
)

Create a security ticket

ticket_key, ticket_id = client.create_security_ticket(
    summary="Suspicious login activity",
    desc="Multiple failed logins from unfamiliar IP",
    priority=1,
    attachment_path="./evidence.log",
)

Discover mandatory fields

mapping = client.discover_mandatory_fields("~/.config/jiracommandkit/mandatory_fields.json")

Working with configuration directly

from jiracommandkit import JiraConfig

config = JiraConfig()
config.save_api_key("JIRA_USERNAME", "you@example.com")
username = config.get_api_key("JIRA_USERNAME")

Handling errors

from jiracommandkit import JiraClient, JiraConfigError, JiraAPIError

try:
    client = JiraClient()
    issues = client.query_jql("project = ENG")
except JiraConfigError as e:
    print(f"Missing configuration: {e}")
except JiraAPIError as e:
    print(f"Jira API request failed: {e}")

Data models

JiraTicket and JiraComment (in jiracommandkit.models) are plain dataclasses returned by JiraClient.format_tickets() / JiraTicket.from_api():

from jiracommandkit import JiraTicket

ticket = JiraTicket.from_api(issue)  # issue: a raw dict from the Jira API
ticket.key            # "ENG-123"
ticket.project         # "ENG"
ticket.summary
ticket.priority
ticket.assignee
ticket.status
ticket.description      # HTML-escaped, newlines converted to <br>
ticket.comments         # list[JiraComment], newest first, capped at 5
ticket.comments_as_html()
ticket.to_dict()

Development

pip install -e ".[dev]"
pytest

Building and publishing to PyPI

python -m pip install --upgrade build twine
python -m build                       # produces dist/*.whl and dist/*.tar.gz
python -m twine upload --repository testpypi dist/*   # verify on TestPyPI first
python -m twine upload dist/*                          # publish to PyPI
git tag v<version>
git push origin v<version>

License

BSD-3-Clause. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jiracommandkit-1.0.0.tar.gz (23.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jiracommandkit-1.0.0-py3-none-any.whl (22.5 kB view details)

Uploaded Python 3

File details

Details for the file jiracommandkit-1.0.0.tar.gz.

File metadata

  • Download URL: jiracommandkit-1.0.0.tar.gz
  • Upload date:
  • Size: 23.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for jiracommandkit-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d9f15df19362a4cc676d1102621e8b0345eadd9fb39073776a2cab3eabff9829
MD5 d92ae44b1b23a4d874581d9e86953b02
BLAKE2b-256 60887c570ecfc690ebbb142f72cba2d25ce91eb8faa9769cf6c65f040200eadc

See more details on using hashes here.

File details

Details for the file jiracommandkit-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: jiracommandkit-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 22.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for jiracommandkit-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7bc9361b27619ce302d74bfc032bab2a55ebbaf383966dd047bb8a7702040183
MD5 b6f6a637cffdf342cda8560822bafbb0
BLAKE2b-256 cb4381d050e153fed2c36bfd3ddb1138cb2d6e67dab984ef341e3eb60eeb3721

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page