Basic wrapper for the Exact Online REST API (v1)
Project description
python-exact-online
Basic wrapper for the Exact Online REST API (v1)
Limitations
Only functionalities that I need are worked out. No intention to develop any further.
Getting started
Install
Install with pip.
pip install python-exact-online
Import
Import the package and the ExactOnlineAPI.
from exactonline.api import ExactOnlineAPI
Setup connection
Make the connection with your provided CLIENTID and CLIENTSECRET.
api = ExactOnlineAPI(CLIENTID, CLIENTSECRET)
Exact Online authentication is build on OAuth2. A basic script to obtain your first tokens can be found below. After you've obtained your tokens, the refresh tokens are automatically used to renew the token if needed. No manual action is required after that.
from exactonline.api import ExactOnlineAPI
REDIRECT_URI = 'https://any-url-will-do.com/callback/'
api = ExactOnlineAPI(CLIENTID, CLIENTSECRET)
authUrl = api.authHandler.getAuthURL(REDIRECT_URI)
print('visit url: ', authUrl)
response = input('paste response: ')
token = api.authHandler.retrieveToken(response, redirectUri=REDIRECT_URI)
When using the script above, any REDIRECT_URI will do. Simply copy and paste the response URI so the handler can obtain the right tokens.
!! The Redirect URI has to be registered in your Exact App Center.
Available functionalities
Object | Endpoint | Actions |
---|---|---|
SalesEntry/SalesEntryLine | salesEntries | List, Get, Filter, Create, Update, Delete |
Documents/Attachments | documents | List, Get, Filter, Create, Update, Delete |
Journals | journals | List, Get, Filter, Create, Update, Delete |
GLAccounts | glAccounts | List, Get, Filter, Create, Update, Delete |
Accounts | accounts | List, Get, Filter, Create, Update, Delete |
Contacts | contacts | List, Get, Filter, Create, Update, Delete |
VATCodes | vatCodes | List, Get, Filter, Create, Update, Delete |
Basic setup
The above endpoints can be used together with their actions. The way to use them are similar to each other. The examples below are used with the 'accounts' endpoint. Replace them with their respective endpoints in the table above to call other objects.
List
journals = api.journals.list()
for journal in journals.items():
print(journal.ID)
Some endpoints require you to use a filter. If you do not filter, it will return an error.
# raises ValueError
accounts = api.accounts.list()
# uses mandatory filtering
accounts = api.accounts.list(filter={ 'Blocked' : 'false' })
for account in accounts.items():
print(account.ID)
Get
accounts = api.accounts.get('uid')
Specific fields can be selected while using the get function. This function takes an optional array which contains the fields that need to be returned.
accounts = api.accounts.get('uid', select=['Name', 'Email'])
Filter
Filter on field and value. Returns a list always.
accounts = api.accounts.filter('Email', 'test@test.com')
for account in accounts.items():
print(account.ID, account.Name)
This function also supports the optional select parameter.
accounts = api.accounts.filter('Email', 'test@test.com', select=['Name', 'Email'])
Create
Before creating an object in Exact Online, you need to create the object within Python itself.
account = Account(
Name='New Account',
Status='C'
)
exactAccount = api.accounts.create(account)
Update
You can retrieve an object, update its attributes and then push it back to Exact Online.
account = api.accounts.get('uid')
account.Name = 'Updated Account'
api.account.update(acc)
Returns True if succeeded.
Delete
accounts = api.accounts.delete('uid')
Returns True if succeeded.
Creating documents
Creating documents has a slightly different approach, because it allows you to also upload files directly to Exact, linked to the document. Multiple files are supported.
doc = Document(
Account='uid',
Type=10,
Subject='New Document',
)
exactDocument = api.documents.create(doc, ['/path/to/pdf/file.pdf'])
Creating sales entries
When creating sales entries, the corresponding sales lines are expected to be given as well.
salesEntry = SalesEntry(
Customer='uid',
Journal='700',
YourRef='MyREF',
)
lines = SalesEntryLineList()
line1 = SalesEntryLine(AmountFC=100, GLAccount='uid')
line2 = SalesEntryLine(AmountFC=150, GLAccount='uid')
lines.add(line1)
lines.add(line2)
salesEntry.SalesEntryLines = lines
exactEntry = api.salesEntries.create(salesEntry)
print(exactEntry.EntryID, exactEntry.InvoiceNumber, exactEntry.AmountDC)
Retrieving VATPercentages
VATCodes have VATPercentages linked to them. By default, these percentages are not given when requesting a list of VAT Codes.
vatCodes = api.vatCodes.list()
for entry in vatCodes.items():
for perc in entry.VATPercentages.items():
# This will contain an empty VATPercentage object
print(vars(perc))
To get the VATPercentages for a VATCode, you need to make a new GET request for that specific VATCode. You can then loop over all the available percentages.
entry = api.vatCodes.get(UID)
for perc in entry.VATPercentages.items():
print(vars(perc))
Error handling
Basic error handling has been added. You can check if an error has occured during a call by checking the hasError attribute on the object. If the hasError attribute has been set to True, an Error object will be attached to the error attribute of the same object. The Error object contains two attributes: code and message. Usually code will be empty. Message is the error message.
account = api.accounts.get('uid')
if account.hasError:
print(account.error.message)
else:
print(account.ID)
Documentation
Find the official Exact Online documentation here: https://start.exactonline.nl/docs/HlpRestAPIResources.aspx?SourceAction=10
You can find what is expected and required for each call.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file python-exact-online-1.0.0.tar.gz
.
File metadata
- Download URL: python-exact-online-1.0.0.tar.gz
- Upload date:
- Size: 28.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.8.3 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.10.1 urllib3/1.26.12 tqdm/4.64.1 importlib-metadata/4.8.3 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.5 CPython/3.6.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3fd70d9833f236cd057d4691da46496888e564218f966211459c7f20eefde420 |
|
MD5 | 75d54cfc06102d1f0a23df9414b5746e |
|
BLAKE2b-256 | 976c4ccb4228bbc50b0d2b76bb0786c5aae116969270dbe63f3455daf2b9dfac |