1- from requests . exceptions import HTTPError
1+ import backoff
22import singer
3- from singer import metadata , metrics , Transformer
3+ from requests .exceptions import HTTPError
4+ from singer import Transformer , metadata , metrics
45from singer .utils import strptime_with_tz
5- import backoff
6+
7+ from tap_xero .context import Context
8+
69from . import transform
10+ from .client import XeroForbiddenError , XeroUnauthorizedError
711
812LOGGER = singer .get_logger ()
913FULL_PAGE_SIZE = 100
@@ -54,6 +58,28 @@ def __init__(self, tap_stream_id, pk_fields, bookmark_key="UpdatedDateUTC", form
5458 self .bookmark_key = bookmark_key
5559 self .replication_method = "INCREMENTAL"
5660 self .filter_options = {}
61+ self .probe_filter_options = {}
62+
63+ def check_access (self , ctx : Context ):
64+ """
65+ Verify that the API credentials have read access to this stream.
66+ Returns True if accessible, False if a 403 Forbidden or 401 Unauthorized error is raised.
67+ """
68+ ctx .refresh_credentials ()
69+
70+ try :
71+ LOGGER .info ("Checking access for stream %s..." , self .tap_stream_id )
72+ ctx .client .filter (self .tap_stream_id , self .probe_filter_options )
73+ LOGGER .info ("Stream %s is accessible with the provided credentials." , self .tap_stream_id )
74+
75+ return True
76+ except (XeroUnauthorizedError , XeroForbiddenError ):
77+ LOGGER .warning (
78+ "Stream '%s' does not have read permission, "
79+ "excluding from catalog." ,
80+ self .tap_stream_id ,
81+ )
82+ return False
5783
5884 def metrics (self , records ):
5985 with metrics .record_counter (self .tap_stream_id ) as counter :
@@ -135,6 +161,8 @@ class Journals(Stream):
135161 """The Journals endpoint is a special case. It has its own way of ordering
136162 and paging the data. See
137163 https://developer.xero.com/documentation/api/journals"""
164+ probe_filter_options = {"offset" : 0 }
165+
138166 def sync (self , ctx ):
139167 bookmark = [self .tap_stream_id , self .bookmark_key ]
140168 journal_number = ctx .get_bookmark (bookmark ) or 0
@@ -158,6 +186,8 @@ class LinkedTransactions(Stream):
158186 the UpdatedDateUTC timestamp in them. Therefore we must always iterate over
159187 all of the data, but we can manually omit records based on the
160188 UpdatedDateUTC property."""
189+ probe_filter_options = {"page" : 1 }
190+
161191 def sync (self , ctx ):
162192 bookmark = [self .tap_stream_id , self .bookmark_key ]
163193 offset = [self .tap_stream_id , "page" ]
0 commit comments