diff --git a/README.md b/README.md index 5267eb0..88feb40 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# tap-jira - -`tap-jira` is a Singer tap for tap-jira. +# `tap-jira` -Built with the [Meltano Tap SDK](https://sdk.meltano.com) for Singer Taps. +tap-jira tap class. + +Built with the [Meltano Singer SDK](https://sdk.meltano.com). ## Capabilities @@ -12,42 +12,32 @@ Built with the [Meltano Tap SDK](https://sdk.meltano.com) for Singer Taps. * `about` * `stream-maps` * `schema-flattening` - -## Configuration - -### Accepted Config Options - -| Setting | Required | Default | Description | -|:--------------------|:--------:|:-------:|:--------------------------------------------------------------------------------------------------------------------------------------------| -| start_date | False | None | Earliest record date to sync | -| end_date | False | None | Latest record date to sync | -| auth | True | None | Auth type for Jira API requires either access_token or username/password | -| domain | True | None | Site URL | -| stream_maps | False | None | Config object for stream maps capability. For more information check out [Stream Maps](https://sdk.meltano.com/en/latest/stream_maps.html). | -| stream_map_config | False | None | User-defined config values to be used within map expressions. | -| flattening_enabled | False | None | 'True' to enable schema flattening and automatically expand nested properties. | -| flattening_max_depth| False | None | The max depth to flatten schemas. | - -The auth setting works either with access token or username/password, set by the following configs: - -Auth with access token: -```bash -TAP_JIRA_AUTH_FLOW = 'oauth' -TAP_JIRA_AUTH_ACCESS_TOKEN = '' -``` - -Auth with username/password: -```bash -TAP_JIRA_AUTH_FLOW = 'password' -TAP_JIRA_AUTH_USERNAME = '' -TAP_JIRA_AUTH_PASSWORD = '' -``` - -A full list of supported settings and capabilities for this tap is available by running: - -```bash -tap-jira --about -``` +* `batch` + +## Settings + +| Setting | Required | Default | Description | +|:--------------------|:--------:|:-------:|:------------| +| start_date | False | None | Earliest record date to sync | +| end_date | False | None | Latest record date to sync | +| domain | True | None | The Domain for your Jira account, e.g. meltano.atlassian.net | +| api_token | True | None | Jira API Token. | +| Email | True | None | The user email for your Jira account. | +| page_size | False | None | | +| stream_maps | False | None | Config object for stream maps capability. For more information check out [Stream Maps](https://sdk.meltano.com/en/latest/stream_maps.html). | +| stream_map_config | False | None | User-defined config values to be used within map expressions. | +| flattening_enabled | False | None | 'True' to enable schema flattening and automatically expand nested properties. | +| flattening_max_depth| False | None | The max depth to flatten schemas. | +| batch_config | False | None | | + +A full list of supported settings and capabilities is available by running: `tap-jira --about` + +## Supported Python Versions + +* 3.8 +* 3.9 +* 3.10 +* 3.11 ## Elastic License 2.0 diff --git a/tap_jira/__main__.py b/tap_jira/__main__.py new file mode 100644 index 0000000..9380bce --- /dev/null +++ b/tap_jira/__main__.py @@ -0,0 +1,7 @@ +"""Jira entry point.""" + +from __future__ import annotations + +from tap_jira.tap import TapJira + +TapJira.cli() diff --git a/tap_jira/client.py b/tap_jira/client.py index 8c12409..1fbbd2e 100644 --- a/tap_jira/client.py +++ b/tap_jira/client.py @@ -3,12 +3,10 @@ from __future__ import annotations from pathlib import Path -from typing import Any, Callable, Iterable +from typing import Any, Callable import requests -from singer_sdk.authenticators import BasicAuthenticator, BearerTokenAuthenticator -from singer_sdk.helpers.jsonpath import extract_jsonpath -from singer_sdk.pagination import BaseAPIPaginator +from singer_sdk.authenticators import BasicAuthenticator from singer_sdk.streams import RESTStream _Auth = Callable[[requests.PreparedRequest], requests.PreparedRequest] @@ -43,19 +41,11 @@ def authenticator(self) -> _Auth: Returns: An authenticator instance. """ - auth_type = self.config["auth"]["flow"] - - if auth_type == "oauth": - return BearerTokenAuthenticator.create_for_stream( - self, - token=self.config["auth"]["access_token"], - ) - else: - return BasicAuthenticator.create_for_stream( - self, - password=self.config["auth"]["password"], - username=self.config["auth"]["username"], - ) + return BasicAuthenticator.create_for_stream( + self, + password=self.config["api_token"], + username=self.config["email"], + ) @property def http_headers(self) -> dict: diff --git a/tap_jira/streams.py b/tap_jira/streams.py index 04f2386..229c550 100644 --- a/tap_jira/streams.py +++ b/tap_jira/streams.py @@ -5,12 +5,11 @@ from pathlib import Path from typing import Optional +import requests from singer_sdk import typing as th # JSON Schema typing helpers from tap_jira.client import JiraStream -import requests - PropertiesList = th.PropertiesList Property = th.Property ObjectType = th.ObjectType @@ -25,7 +24,6 @@ class UsersStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-users/#api-rest-api-3-user-get """ @@ -89,7 +87,6 @@ def get_next_page_token( class FieldStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-fields/#api-rest-api-3-field-get """ @@ -158,7 +155,6 @@ class FieldStream(JiraStream): class ServerInfoStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-server-info/#api-rest-api-3-serverinfo-get """ @@ -198,7 +194,6 @@ class ServerInfoStream(JiraStream): class IssueTypeStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-types/#api-rest-api-3-issuetype-get """ @@ -248,7 +243,6 @@ class IssueTypeStream(JiraStream): class WorkflowStatusStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflow-statuses/#api-rest-api-3-status-get """ @@ -301,7 +295,6 @@ class WorkflowStatusStream(JiraStream): class ProjectStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-projects/#api-rest-api-3-project-get """ @@ -370,7 +363,6 @@ class ProjectStream(JiraStream): class IssueStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-get """ @@ -2350,7 +2342,6 @@ def post_process(self, row: dict, context: dict | None = None) -> dict | None: class PermissionStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-permissions/#api-rest-api-3-permissions-get """ @@ -2776,7 +2767,6 @@ class PermissionStream(JiraStream): class ProjectRoleStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-project-roles/#api-rest-api-3-role-get """ @@ -2842,7 +2832,6 @@ class ProjectRoleStream(JiraStream): class PriorityStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-priorities/#api-rest-api-3-priority-get """ @@ -2873,7 +2862,6 @@ class PriorityStream(JiraStream): class PermissionHolderStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-permission-schemes/#api-rest-api-3-permissionscheme-get """ @@ -3041,7 +3029,6 @@ def get_records(self, context: dict | None) -> Iterable[dict[str, Any]]: class ProjectRoleActorStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-project-role-actors/#api-rest-api-3-role-id-actors-get """ @@ -3143,7 +3130,6 @@ class ProjectRoleActor(JiraStream): class AuditingStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-audit-records/#api-rest-api-3-auditing-record-get """ @@ -3210,7 +3196,6 @@ class AuditingStream(JiraStream): class DashboardStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-dashboards/#api-rest-api-3-dashboard-get """ @@ -3260,7 +3245,6 @@ class DashboardStream(JiraStream): class FilterSearchStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-filters/#api-rest-api-3-filter-search-get """ @@ -3291,7 +3275,6 @@ class FilterSearchStream(JiraStream): class FilterDefaultShareScopeStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-filter-sharing/#api-rest-api-3-filter-defaultsharescope-get """ @@ -3317,7 +3300,6 @@ class FilterDefaultShareScopeStream(JiraStream): class GroupsPickerStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-groups/#api-rest-api-3-groups-picker-get """ @@ -3357,7 +3339,6 @@ class GroupsPickerStream(JiraStream): class LicenseStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-license-metrics/#api-rest-api-3-instance-license-get """ @@ -3386,7 +3367,6 @@ class LicenseStream(JiraStream): class ScreensStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-screens/#api-rest-api-3-screens-get """ @@ -3428,7 +3408,6 @@ class ScreensStream(JiraStream): class ScreenSchemesStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-screen-tab-fields/#api-rest-api-3-screens-screenid-tabs-tabid-fields-get """ @@ -3464,7 +3443,6 @@ class ScreenSchemesStream(JiraStream): class StatusesSearchStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-screen-tab-fields/#api-rest-api-3-screens-screenid-tabs-tabid-fields-get """ @@ -3501,7 +3479,6 @@ class StatusesSearchStream(JiraStream): class WorkflowStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-get """ @@ -3577,7 +3554,6 @@ class Resolutions(JiraStream): class WorkflowSearchStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-get """ @@ -3617,7 +3593,6 @@ class WorkflowSearchStream(JiraStream): class IssueWatchersStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-get """ @@ -3662,7 +3637,6 @@ def post_process(self, row: dict, context: dict) -> dict: class IssueChangeLogStream(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/#api-rest-api-3-workflow-get """ @@ -3721,7 +3695,6 @@ def post_process(self, row: dict, context: dict) -> dict: class IssueComments(JiraStream): - """ https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get """ diff --git a/tap_jira/tap.py b/tap_jira/tap.py index 3e465e0..6461707 100644 --- a/tap_jira/tap.py +++ b/tap_jira/tap.py @@ -27,31 +27,30 @@ class TapJira(Tap): th.Property( "domain", th.StringType, - description="Site URL", + description="The Domain for your Jira account, e.g. meltano.atlassian.net", required=True, ), th.Property( - "auth", - th.DiscriminatedUnion( - "flow", - oauth=th.ObjectType( - th.Property( - "access_token", th.StringType, required=True, secret=True - ), - additional_properties=False, - ), - password=th.ObjectType( - th.Property("username", th.StringType, required=True), - th.Property("password", th.StringType, required=True, secret=True), - additional_properties=False, - ), - ), + "api_token", + th.StringType, + description="Jira API Token.", + required=True, + ), + th.Property( + "email", + th.StringType, + description="The user email for your Jira account.", required=True, ), th.Property( "page_size", th.ObjectType( - th.Property("issues", th.IntegerType, description="Page size for issues stream", default=100), + th.Property( + "issues", + th.IntegerType, + description="Page size for issues stream", + default=100, + ), ), ), ).to_dict()