removed lru_cache, made get_all_invoices_for_org_name faster, started revising readme
This commit is contained in:
17
README.md
17
README.md
@@ -1,23 +1,18 @@
|
||||
# AVT Fresh!
|
||||
|
||||
This is a wrapper of [the Freshbooks web API](https://www.freshbooks.com/api/start). It is far from comprehensive: It was created for the specific client- and invoice-related needs of [Averbach Transcription](https://avtranscription.com).
|
||||
This is a wrapper of [the Freshbooks web API](https://www.freshbooks.com/api/start). It is far from comprehensive: It was created for the specific client- and invoice-related needs of [Averbach Transcription](https://avtranscription.com). However, there are "band-aids" here to work around some of the API's shortcomings. For example, you don't have to deal with pagination at all. 🎉
|
||||
|
||||
There are "band-aids" here to work around some of the API's shortcomings. For example, you don't have to deal with pagination at all. 🎉
|
||||
Install it with `pip install avt-fresh`.
|
||||
|
||||
# Installation
|
||||
|
||||
```
|
||||
pip install avt-fresh
|
||||
```
|
||||
|
||||
# Usage
|
||||
Instantiate the avt_fresh `Client` like so, and you're off to the races:
|
||||
Here's how you use it:
|
||||
|
||||
```python
|
||||
from avt_fresh import ApiClient
|
||||
|
||||
client = ApiClient(client_secret="...", client_id="...", redirect_uri="https://...", account_id="...")
|
||||
|
||||
monster_invoices = client.get_all_invoices_for_org_name("Monsters Inc")
|
||||
client.get_one_invoice(12345)
|
||||
```
|
||||
|
||||
You can get and set the required arguments to `ApiClient` [here](https://my.freshbooks.com/#/developer). Well, all of them except `FRESHBOOKS_ACCOUNT_ID`, which you can see (there's got to be another way??) by clicking on one of your invoices and grabbing the substring here: `https://my.freshbooks.com/#/invoice/<THIS THING>-1234567`.
|
||||
@@ -146,7 +141,7 @@ client = Client(
|
||||
redirect_uri="https://...",
|
||||
account_id="...",
|
||||
token_store=avt_fresh.token.TokenStoreOnRedis,
|
||||
connection_string="rediss://..." ,
|
||||
connection_string="redis://..." ,
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import datetime as dt
|
||||
from decimal import Decimal
|
||||
from functools import partial, lru_cache
|
||||
import decimal
|
||||
import functools
|
||||
import typing
|
||||
|
||||
WHAT = "invoice"
|
||||
@@ -27,22 +27,22 @@ class FreshbooksLine(typing.NamedTuple):
|
||||
client_id: int
|
||||
description: str
|
||||
name: str
|
||||
rate: Decimal
|
||||
rate: decimal.Decimal
|
||||
line_id: int
|
||||
quantity: Decimal
|
||||
amount: Decimal
|
||||
quantity: decimal.Decimal
|
||||
amount: decimal.Decimal
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, **kwargs):
|
||||
return cls(
|
||||
invoice_id=kwargs["invoice_id"],
|
||||
client_id=kwargs["client_id"],
|
||||
rate=Decimal(kwargs["unit_cost"]["amount"]),
|
||||
rate=decimal.Decimal(kwargs["unit_cost"]["amount"]),
|
||||
description=kwargs["description"],
|
||||
name=kwargs["name"],
|
||||
quantity=Decimal(kwargs["qty"]),
|
||||
quantity=decimal.Decimal(kwargs["qty"]),
|
||||
line_id=kwargs["lineid"],
|
||||
amount=Decimal(kwargs["amount"]["amount"]),
|
||||
amount=decimal.Decimal(kwargs["amount"]["amount"]),
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -63,9 +63,9 @@ class FreshbooksInvoice(typing.NamedTuple):
|
||||
invoice_id: int
|
||||
number: str
|
||||
organization: str
|
||||
amount: Decimal
|
||||
amount: decimal.Decimal
|
||||
status: str
|
||||
amount_outstanding: Decimal
|
||||
amount_outstanding: decimal.Decimal
|
||||
po_number: str
|
||||
line_id_line_dict: dict
|
||||
line_description_line_dict: dict
|
||||
@@ -101,8 +101,8 @@ class FreshbooksInvoice(typing.NamedTuple):
|
||||
number=kwargs["invoice_number"],
|
||||
organization=kwargs["organization"],
|
||||
allowed_gateways=kwargs["allowed_gateways"],
|
||||
amount=Decimal(kwargs["amount"]["amount"]),
|
||||
amount_outstanding=Decimal(kwargs["outstanding"]["amount"]),
|
||||
amount=decimal.Decimal(kwargs["amount"]["amount"]),
|
||||
amount_outstanding=decimal.Decimal(kwargs["outstanding"]["amount"]),
|
||||
contacts={contact["email"]: contact for contact in kwargs["contacts"]},
|
||||
status=kwargs["v3_status"],
|
||||
)
|
||||
@@ -115,10 +115,11 @@ def get_all_draft_invoices(*, get_func: typing.Callable) -> list[FreshbooksInvoi
|
||||
def get_all_invoices_for_org_name(
|
||||
*, get_func: typing.Callable, org_name: str
|
||||
) -> list[FreshbooksInvoice]:
|
||||
return _get(get_func=get_func, org_name=org_name)
|
||||
from avt_fresh.client import get_freshbooks_client_from_org_name
|
||||
client_id = get_freshbooks_client_from_org_name(get_func=get_func, org_name=org_name).client_id
|
||||
return get_all_invoices_for_client_id(get_func=get_func, client_id=client_id)
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_all_invoices_for_client_id(
|
||||
*, get_func: typing.Callable, client_id: int
|
||||
) -> list[FreshbooksInvoice]:
|
||||
@@ -147,7 +148,7 @@ def _get(
|
||||
org_name=None,
|
||||
status=None,
|
||||
) -> list[FreshbooksInvoice]:
|
||||
get_func = partial(get_func, what=WHAT)
|
||||
get_func = functools.partial(get_func, what=WHAT)
|
||||
|
||||
if client_id is not None and org_name is not None:
|
||||
raise ArgumentError("Please provide either client_id or org_name")
|
||||
|
||||
Reference in New Issue
Block a user