Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,30 @@ This tap:

## Limitations

- Only designed to work with Xero [Partner Applications](https://developer.xero.com/documentation/auth-and-limits/partner-applications), not Private Applications.
- Only designed to work with Xero [Partner Applications](https://developer.xero.com/documentation/auth-and-limits/partner-applications), not Private Applications.

## Authentication

This tap requires a client id, client secret, tenant id, and refresh token in order to authenticate (and thus receive an
access token).

See [the Xero documentation](https://developer.xero.com/documentation/guides/oauth2/auth-flow) for more info.

### Refresh token

The tap is able to use the refresh token to refresh the access token. Doing so also generates a new refresh token, which
the tap is able to write back to you.

There are two ways to pass in a refresh token, and two ways to have an updated refresh token written back to you.

To pass in a refresh token, either use the `refresh_token` arg or the `refresh_token_path` arg.
If `refresh_token` is not set, the refresh token will be read as the entire contents of the file at
`refresh_token_path`.
If `refresh_token_path` is set, a new refresh token will override the entire contents of the file **as well as** being
written to the config JSON (which is the default behavior if `refresh_token_path` is not set).

This is important for the use of this tap via Meltano. Since Meltano generates an ephemeral config JSON, writing the
new refresh token to it is not very helpful.

---

Expand Down
17 changes: 13 additions & 4 deletions tap_xero/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/usr/bin/env python3
import os
import json
import singer
from singer import metadata, metrics, utils
from singer import metadata, utils
from singer.catalog import Catalog, CatalogEntry, Schema
from . import streams as streams_
from .client import XeroClient
Expand All @@ -13,8 +12,8 @@
"client_id",
"client_secret",
"tenant_id",
"refresh_token",

# no longer required. can use "refresh_token_path" instead.
# "refresh_token",
]

LOGGER = singer.get_logger()
Expand Down Expand Up @@ -115,6 +114,16 @@ def sync(ctx):

def main_impl():
args = utils.parse_args(REQUIRED_CONFIG_KEYS)

if "refresh_token" not in args.config and "refresh_token_path" not in args.config:
raise Exception(
"Config requires either refresh_token or refresh_token_path to be set."
)

if "refresh_token" not in args.config:
with open(args.config["refresh_token_path"], "r") as f:
args.config["refresh_token"] = f.read()

if args.discover:
discover(Context(args.config, {}, {}, args.config_path)).dump()
print()
Expand Down
9 changes: 6 additions & 3 deletions tap_xero/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import sys
import math
from os.path import join
from os import environ
from datetime import datetime, date, time, timedelta
import requests
from singer.utils import strftime, strptime_to_utc
Expand Down Expand Up @@ -204,13 +205,15 @@ def refresh_credentials(self, config, config_path):
else:
resp = resp.json()

# Write to config file
config['refresh_token'] = resp["refresh_token"]
refresh_token = resp["refresh_token"]
config['refresh_token'] = refresh_token
update_config_file(config, config_path)
if "refresh_token_path" in config:
with open(config["refresh_token_path"], "w") as f:
f.write(refresh_token)
self.access_token = resp["access_token"]
self.tenant_id = config['tenant_id']


@backoff.on_exception(backoff.expo, (json.decoder.JSONDecodeError, XeroInternalError), max_tries=3)
@backoff.on_exception(retry_after_wait_gen, XeroTooManyInMinuteError, giveup=is_not_status_code_fn([429]), jitter=None, max_tries=3)
def check_platform_access(self, config, config_path):
Expand Down
8 changes: 3 additions & 5 deletions tap_xero/schemas/allocations.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Invoice": {
"$ref": "nested_invoice"
Expand Down
3 changes: 1 addition & 2 deletions tap_xero/schemas/attachments.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
"null",
"object"
],
"properties": {
},
"properties": {},
"additionalProperties": false
}
}
32 changes: 12 additions & 20 deletions tap_xero/schemas/bank_transactions.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-10,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 1E-10,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Url": {
"type": [
Expand All @@ -91,33 +89,27 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-06,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.000001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"TotalTax": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-06,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.000001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Total": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-06,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.000001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"BankTransactionID": {
"type": [
Expand Down
16 changes: 6 additions & 10 deletions tap_xero/schemas/bank_transfers.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Date": {
"type": [
Expand All @@ -45,11 +43,9 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-10,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 1E-10,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"FromBankTransactionID": {
"type": [
Expand Down
48 changes: 18 additions & 30 deletions tap_xero/schemas/credit_notes.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,44 +60,36 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"AppliedAmount": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"TotalTax": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Total": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"UpdatedDateUTC": {
"format": "date-time",
Expand Down Expand Up @@ -147,22 +139,18 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-10,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 1E-10,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"RemainingCredit": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"Allocations": {
"items": {
Expand Down
24 changes: 9 additions & 15 deletions tap_xero/schemas/expense_claims.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,27 @@
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"AmountDue": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"AmountPaid": {
"type": [
"null",
"number"
],
"minimum": -1e+33,
"maximum": 1e+33,
"multipleOf": 1e-05,
"exclusiveMinimum": true,
"exclusiveMaximum": true
"multipleOf": 0.00001,
"exclusiveMinimum": -1E+33,
"exclusiveMaximum": 1E+33
},
"PaymentDueDate": {
"type": [
Expand Down
Loading