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:
- A
JIRACOMMANDKIT_<KEY>environment variable - A value saved in
~/.config/jiracommandkit/jiracommandkit.json - A caller-supplied default (
Noneif 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9f15df19362a4cc676d1102621e8b0345eadd9fb39073776a2cab3eabff9829
|
|
| MD5 |
d92ae44b1b23a4d874581d9e86953b02
|
|
| BLAKE2b-256 |
60887c570ecfc690ebbb142f72cba2d25ce91eb8faa9769cf6c65f040200eadc
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bc9361b27619ce302d74bfc032bab2a55ebbaf383966dd047bb8a7702040183
|
|
| MD5 |
b6f6a637cffdf342cda8560822bafbb0
|
|
| BLAKE2b-256 |
cb4381d050e153fed2c36bfd3ddb1138cb2d6e67dab984ef341e3eb60eeb3721
|