Skip to content

jira_api

JiraAPI

Source code in src/rich_jira_release_notes/libs/jira/jira_api.py
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
class JiraAPI:
    def __init__(self, base_url: str, credentials: JiraCredentialsModel) -> None:
        self.base_url = base_url
        self.credentials = credentials

    def get_issues(self, jql_query: str, fields: list[str]) -> list:
        """Get issues from Jira utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-jql-get

        Args:
            jql_query (str): JQL query to search for issues

        Returns:
            list: List of issues
        """
        url = f"{self.base_url}/rest/api/3/search/jql"
        auth = HTTPBasicAuth(self.credentials.username, self.credentials.token)

        headers = {"Accept": "application/json"}

        query = {
            "jql": jql_query,
            "fields": "*all",
            "fieldsByKeys": "true",
            "expand": "renderedFields,names",
        }

        response = requests.request(
            "GET", url, headers=headers, params=query, auth=auth
        )

        data = json.loads(response.text)

        # Resolve Jira internal field names to clear text representation of desired fields
        field_maps = {}
        for field, value in data["names"].items():
            if value in fields:
                field_maps[value] = field

        # Extract desired fields from issues
        result = []
        for issue in data["issues"]:
            entry = {"id": issue["id"], "key": issue["key"], "fields": {}}
            for field_key, field_value in field_maps.items():
                if (
                    field_value in issue["renderedFields"]
                    and issue["renderedFields"][field_value] is not None
                ):
                    entry["fields"][field_key] = JiraField(
                        value=issue["renderedFields"][field_value],
                        type=JiraFieldType.RICH_TEXT,
                    )
                elif (
                    field_value in issue["fields"]
                    and issue["fields"][field_value] is not None
                ):
                    print(issue["fields"][field_value])
                    if isinstance(issue["fields"][field_value], list):
                        entry["fields"][field_key] = JiraField(
                            value=[
                                entry["value"] for entry in issue["fields"][field_value]
                            ],
                            type=JiraFieldType.CHECKBOX,
                        )
                    else:
                        entry["fields"][field_key] = JiraField(
                            value=issue["fields"][field_value], type=JiraFieldType.TEXT
                        )
            result.append(entry)
        return [JiraIssue(**issue) for issue in result]

    def download_attachment(self, url: str, output_path: str) -> None:
        """Get attachment specified by id utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments#api-group-issue-attachments

        Args:
            id (str): ID of attachment
            output_dir (str): Output directory to save attachment to
        """
        url = f"{self.base_url}{url}"
        auth = HTTPBasicAuth(self.credentials.username, self.credentials.token)

        headers = {"Accept": "application/json"}

        response = requests.request("GET", url, headers=headers, auth=auth)

        with open(output_path, "wb") as f:
            f.write(response.content)

download_attachment(url, output_path)

Get attachment specified by id utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments#api-group-issue-attachments

Parameters:

Name Type Description Default
id str

ID of attachment

required
output_dir str

Output directory to save attachment to

required
Source code in src/rich_jira_release_notes/libs/jira/jira_api.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
def download_attachment(self, url: str, output_path: str) -> None:
    """Get attachment specified by id utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments#api-group-issue-attachments

    Args:
        id (str): ID of attachment
        output_dir (str): Output directory to save attachment to
    """
    url = f"{self.base_url}{url}"
    auth = HTTPBasicAuth(self.credentials.username, self.credentials.token)

    headers = {"Accept": "application/json"}

    response = requests.request("GET", url, headers=headers, auth=auth)

    with open(output_path, "wb") as f:
        f.write(response.content)

get_issues(jql_query, fields)

Get issues from Jira utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-jql-get

Parameters:

Name Type Description Default
jql_query str

JQL query to search for issues

required

Returns:

Name Type Description
list list

List of issues

Source code in src/rich_jira_release_notes/libs/jira/jira_api.py
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def get_issues(self, jql_query: str, fields: list[str]) -> list:
    """Get issues from Jira utilizing https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-jql-get

    Args:
        jql_query (str): JQL query to search for issues

    Returns:
        list: List of issues
    """
    url = f"{self.base_url}/rest/api/3/search/jql"
    auth = HTTPBasicAuth(self.credentials.username, self.credentials.token)

    headers = {"Accept": "application/json"}

    query = {
        "jql": jql_query,
        "fields": "*all",
        "fieldsByKeys": "true",
        "expand": "renderedFields,names",
    }

    response = requests.request(
        "GET", url, headers=headers, params=query, auth=auth
    )

    data = json.loads(response.text)

    # Resolve Jira internal field names to clear text representation of desired fields
    field_maps = {}
    for field, value in data["names"].items():
        if value in fields:
            field_maps[value] = field

    # Extract desired fields from issues
    result = []
    for issue in data["issues"]:
        entry = {"id": issue["id"], "key": issue["key"], "fields": {}}
        for field_key, field_value in field_maps.items():
            if (
                field_value in issue["renderedFields"]
                and issue["renderedFields"][field_value] is not None
            ):
                entry["fields"][field_key] = JiraField(
                    value=issue["renderedFields"][field_value],
                    type=JiraFieldType.RICH_TEXT,
                )
            elif (
                field_value in issue["fields"]
                and issue["fields"][field_value] is not None
            ):
                print(issue["fields"][field_value])
                if isinstance(issue["fields"][field_value], list):
                    entry["fields"][field_key] = JiraField(
                        value=[
                            entry["value"] for entry in issue["fields"][field_value]
                        ],
                        type=JiraFieldType.CHECKBOX,
                    )
                else:
                    entry["fields"][field_key] = JiraField(
                        value=issue["fields"][field_value], type=JiraFieldType.TEXT
                    )
        result.append(entry)
    return [JiraIssue(**issue) for issue in result]