Python library for interacting with JIRA via REST APIs.
—
Manage external links from JIRA issues to external applications, web resources, and other systems. Remote links allow you to connect JIRA issues with external tools and documentation.
Create, retrieve, and manage remote links between JIRA issues and external resources.
def remote_links(self, issue: Issue) -> list[RemoteLink]:
"""
Get all remote links for an issue.
Parameters:
- issue: Issue object or issue key
Returns:
List of RemoteLink objects
"""
def remote_link(self, issue: Issue, id: str) -> RemoteLink:
"""
Get a specific remote link by ID.
Parameters:
- issue: Issue object or issue key
- id: Remote link ID
Returns:
RemoteLink object
"""
def add_remote_link(
self,
issue: Issue,
destination: dict,
globalId: str = None,
application: dict = None,
relationship: str = None
) -> RemoteLink:
"""
Add a remote link to an external application.
Parameters:
- issue: Issue object or issue key
- destination: Link destination details (url, title, summary, icon)
- globalId: Global identifier for the link
- application: Application details (type, name)
- relationship: Relationship type to the issue
Returns:
Created RemoteLink object
"""
def add_simple_link(self, issue: Issue, object: dict) -> RemoteLink:
"""
Add a simple remote link to a web resource.
Parameters:
- issue: Issue object or issue key
- object: Link object with url, title, summary, and icon
Returns:
Created RemoteLink object
"""Usage examples:
# Get all remote links for an issue
issue = jira.issue('PROJ-123')
remote_links = jira.remote_links(issue)
for link in remote_links:
print(f"Link: {link.object['title']} -> {link.object['url']}")
# Get specific remote link
specific_link = jira.remote_link(issue, '10001')
print(f"Link title: {specific_link.object['title']}")
print(f"Link URL: {specific_link.object['url']}")
# Add a simple web link
simple_link = jira.add_simple_link(
issue=issue,
object={
'url': 'https://docs.example.com/feature-spec',
'title': 'Feature Specification',
'summary': 'Detailed specification document for this feature',
'icon': {
'url16x16': 'https://docs.example.com/favicon.ico',
'title': 'Documentation'
}
}
)
print(f"Created simple link: {simple_link.id}")
# Add a complex application link
app_link = jira.add_remote_link(
issue=issue,
destination={
'url': 'https://github.com/company/repo/pull/123',
'title': 'Pull Request #123',
'summary': 'Implementation of feature PROJ-123',
'icon': {
'url16x16': 'https://github.com/favicon.ico',
'title': 'GitHub'
}
},
application={
'type': 'com.github.integration',
'name': 'GitHub'
},
relationship='implements',
globalId='github:pr:company/repo:123'
)
print(f"Created application link: {app_link.id}")Remove and update remote links.
def delete_remote_link(self, issue: Issue, id: str) -> None:
"""
Delete a remote link by ID.
Parameters:
- issue: Issue object or issue key
- id: Remote link ID to delete
"""
def update_remote_link(
self,
issue: Issue,
id: str,
object: dict,
globalId: str = None,
application: dict = None,
relationship: str = None
) -> RemoteLink:
"""
Update an existing remote link.
Parameters:
- issue: Issue object or issue key
- id: Remote link ID to update
- object: Updated link object details
- globalId: Updated global identifier
- application: Updated application details
- relationship: Updated relationship type
Returns:
Updated RemoteLink object
"""Usage examples:
# Delete a remote link
jira.delete_remote_link(issue, '10001')
print("Remote link deleted")
# Update remote link (if supported by JIRA version)
try:
updated_link = jira.update_remote_link(
issue=issue,
id='10002',
object={
'url': 'https://updated-docs.example.com/feature-spec',
'title': 'Updated Feature Specification',
'summary': 'Updated specification with new requirements'
}
)
print(f"Updated link: {updated_link.id}")
except AttributeError:
print("Update not supported in this JIRA version")Basic links to web resources:
# Documentation link
doc_link = jira.add_simple_link(
issue='PROJ-123',
object={
'url': 'https://confluence.company.com/display/PROJ/Requirements',
'title': 'Requirements Document',
'summary': 'Detailed requirements for PROJ-123',
'icon': {
'url16x16': 'https://confluence.company.com/favicon.ico',
'title': 'Confluence'
}
}
)
# Design mockup link
design_link = jira.add_simple_link(
issue='PROJ-124',
object={
'url': 'https://figma.com/file/ABC123/Feature-Design',
'title': 'UI Design Mockup',
'summary': 'User interface design for the new feature',
'icon': {
'url16x16': 'https://figma.com/favicon.ico',
'title': 'Figma'
}
}
)Links with application context:
# GitHub pull request
github_pr = jira.add_remote_link(
issue='PROJ-125',
destination={
'url': 'https://github.com/company/repo/pull/456',
'title': 'Fix authentication bug',
'summary': 'Pull request to resolve authentication issues',
'icon': {
'url16x16': 'https://github.com/favicon.ico',
'title': 'GitHub'
}
},
application={
'type': 'com.github.integration',
'name': 'GitHub for JIRA'
},
globalId='github:pr:company/repo:456',
relationship='fixes'
)
# Bitbucket commit
bitbucket_commit = jira.add_remote_link(
issue='PROJ-126',
destination={
'url': 'https://bitbucket.org/company/repo/commits/abc123def456',
'title': 'Implement feature PROJ-126',
'summary': 'Initial implementation of the requested feature',
'icon': {
'url16x16': 'https://bitbucket.org/favicon.ico',
'title': 'Bitbucket'
}
},
application={
'type': 'com.atlassian.bitbucket',
'name': 'Bitbucket'
},
globalId='bitbucket:commit:company/repo:abc123def456',
relationship='implements'
)Common properties available on RemoteLink objects:
remote_link = jira.remote_link('PROJ-123', '10001')
# Basic properties
print(f"ID: {remote_link.id}")
print(f"Self URL: {remote_link.self}")
# Object properties (the actual link)
link_obj = remote_link.object
print(f"Title: {link_obj['title']}")
print(f"URL: {link_obj['url']}")
print(f"Summary: {link_obj.get('summary', 'No summary')}")
# Icon information
if 'icon' in link_obj:
icon = link_obj['icon']
print(f"Icon URL: {icon.get('url16x16', 'No icon')}")
print(f"Icon Title: {icon.get('title', 'No title')}")
# Application information (if present)
if hasattr(remote_link, 'application'):
app = remote_link.application
print(f"Application Type: {app.get('type', 'Unknown')}")
print(f"Application Name: {app.get('name', 'Unknown')}")
# Global ID (if present)
if hasattr(remote_link, 'globalId'):
print(f"Global ID: {remote_link.globalId}")
# Relationship (if present)
if hasattr(remote_link, 'relationship'):
print(f"Relationship: {remote_link.relationship}")Working with multiple remote links:
def add_documentation_links(jira_client, issue_key, doc_links):
"""Add multiple documentation links to an issue."""
issue = jira_client.issue(issue_key)
created_links = []
for doc in doc_links:
try:
link = jira_client.add_simple_link(
issue=issue,
object={
'url': doc['url'],
'title': doc['title'],
'summary': doc.get('summary', ''),
'icon': doc.get('icon', {
'url16x16': 'https://example.com/doc-icon.png',
'title': 'Documentation'
})
}
)
created_links.append(link)
print(f"✓ Added link: {doc['title']}")
except Exception as e:
print(f"✗ Failed to add {doc['title']}: {e}")
return created_links
# Example usage
documentation_links = [
{
'url': 'https://docs.company.com/api/v1/auth',
'title': 'Authentication API Documentation',
'summary': 'Details on how to authenticate with the API'
},
{
'url': 'https://confluence.company.com/display/DEV/Setup',
'title': 'Development Setup Guide',
'summary': 'How to set up the development environment'
},
{
'url': 'https://wiki.company.com/Testing',
'title': 'Testing Guidelines',
'summary': 'Best practices for testing this feature'
}
]
created_links = add_documentation_links(jira, 'PROJ-127', documentation_links)
print(f"Created {len(created_links)} documentation links")def link_github_pr(jira_client, issue_key, repo, pr_number):
"""Link a GitHub pull request to a JIRA issue."""
pr_url = f"https://github.com/{repo}/pull/{pr_number}"
# First, you might fetch PR details from GitHub API
# This is a simplified example
pr_title = f"Pull Request #{pr_number}"
return jira_client.add_remote_link(
issue=issue_key,
destination={
'url': pr_url,
'title': pr_title,
'summary': f'GitHub pull request for {issue_key}',
'icon': {
'url16x16': 'https://github.com/favicon.ico',
'title': 'GitHub'
}
},
application={
'type': 'com.github.integration',
'name': 'GitHub'
},
globalId=f'github:pr:{repo}:{pr_number}',
relationship='implements'
)
# Link PR to issue
github_link = link_github_pr(jira, 'PROJ-128', 'company/backend', 789)
print(f"Linked GitHub PR: {github_link.id}")def link_confluence_page(jira_client, issue_key, page_url, page_title):
"""Link a Confluence page to a JIRA issue."""
return jira_client.add_simple_link(
issue=issue_key,
object={
'url': page_url,
'title': page_title,
'summary': f'Confluence documentation for {issue_key}',
'icon': {
'url16x16': 'https://confluence.atlassian.com/favicon.ico',
'title': 'Confluence'
}
}
)
# Link Confluence page
confluence_link = link_confluence_page(
jira,
'PROJ-129',
'https://company.atlassian.net/wiki/spaces/DEV/pages/12345/Feature+Spec',
'Feature Specification - PROJ-129'
)When working with remote links:
# Check existing links before adding
def add_unique_remote_link(jira_client, issue_key, link_url, link_title):
"""Add remote link only if URL doesn't already exist."""
issue = jira_client.issue(issue_key)
existing_links = jira_client.remote_links(issue)
# Check if URL already exists
for link in existing_links:
if link.object.get('url') == link_url:
print(f"Link already exists: {link_title}")
return link
# Add new link
return jira_client.add_simple_link(
issue=issue,
object={
'url': link_url,
'title': link_title,
'summary': f'External link for {issue_key}'
}
)
# Clean up broken links
def cleanup_broken_links(jira_client, issue_key):
"""Remove links that return 404 or are otherwise broken."""
import requests
issue = jira_client.issue(issue_key)
remote_links = jira_client.remote_links(issue)
for link in remote_links:
url = link.object.get('url')
if url:
try:
response = requests.head(url, timeout=10)
if response.status_code >= 400:
print(f"Removing broken link: {link.object['title']}")
jira_client.delete_remote_link(issue, link.id)
except requests.RequestException:
print(f"Could not check link: {link.object['title']}")
# Example usage
add_unique_remote_link(
jira,
'PROJ-130',
'https://docs.example.com/feature',
'Feature Documentation'
)Install with Tessl CLI
npx tessl i tessl/pypi-jira@2.0.2