Package: pyBunniApi
pyBunniApi - a Bunni Python Api Client.RequirementsYou need a Bunni Account.You need to generate an API key for your Bunni Account.Python 3.10Installation$pipinstallpyBunniApiGetting started with pyBunniApiLet's start with importing the API ClientfrompyBunniApi.clientimportClientOnce this is done we have to initialize it.py_bunni_api=Client()py_bunni_api.set_api_key('YOUR API KEY HERE')py_bunni_api.set_business_id('YOUR BUSINESS ID HERE')Optionally you can select if you want to receive all responses in a typed, or a flat dict. You can set this parameter with the following code:py_bunni_api.use_typing(True)The default value of this parameter isTrueReceiving the contacts listIf your API key has access to 'READ' on the specific parts of contacts, we can usecontacts.listto view all contacts.contacts=py_bunni_api.contacts.list()This will return a list of contacts. The response looks like this:[{'id':'co_XXXXXX','companyName':'CompanyName','toTheAttentionOf':'BerrytheBunny','street':'Carrotstreet','streetNumber':'9','postalCode':'1234AB','city':'','phoneNumber':'123456789','vatIdentificationNumber':None,'chamberOfCommerceNumber':None,'color':'#112233','fields':[],'emailAddresses':['berry_the_bunny@bunni.nl']}]Receiving a list of invoicesIf your API key has access to 'READ' on the invoices section, we can useinvoices.listto gather a list of all
invoices.invoice_list=py_bunni_api.invoices.list()This will return a list with all invoices, the response looks like this:[{'id':'in_XXXXXX','invoiceDate':'2023-08-09','invoiceNumber':'2023005','isFinalized':True,'duePeriodDays':30,'pdfUrl':'https://superlongpdfurl.pdf','rows':[{'description':'Thisisthedescriptionofyourrow.','quantity':1.0,'unitPrice':100}]}]Creating an invoice PDFThis feature only generates a PDF. Said invoice will not be placed in your bookkeeping
software as of now.
You can however write your own piece of code that stores this pdf somewhere on your webserver, and sends it
toYOUR_BUSINESS_ID@postbode.bunni.nlin order to get it automatically placed in your bookkeeping.Anyways, this part is a little bit more spicy and requires a few more steps.
Again, this only works if your API key has access to theWRITEpermissions of Invoice.First, let's start by defining our rows. A row requires four parameters. One invoice can contain varying rows. We append
these bu putting rows in a list.To create row we can initialize aRow(). The complete syntax would look like this:row=PyBunniApi.Row(unit_price=12.5,# This should be a float.description="This is a test description",quantity=5,tax="NL_High_21",# This should be a string.)For explaining how this works, one row will be enough. The next step is to create aContact()This can be done like
this:contact=PyBunniApi.Contact(company_name="The Carrot Company",attn='Jim Carrot',street='Carrot Street',street_number=20,postal_code='1122AB',city='Bunny Town',phone_number='123456789',)Now we can build a complete invoice usingInvoicePDF()by the following manner:invoicePdf=PyBunniApi.InvoicePDF(invoice_date='YYYY-MM-DD',invoice_number='12345.67',tax_mode='excl',# This can be either `incl` or `excl`,design='INVOICE_DESIGN_ID',# A little down here I'll explain how you can fetch this ID.contact=contact,# We made a contact above here.rows=[row])We now have a initializedInvoicePdfobject which we can use to create a invoice (pdf) in Bunni.
We can do this by usingpy_bunni_api.invoices.create_pdfA complete snippet of this code would look like this:invoice_pdf=py_bunni_api.invoices.create_pdf(invoicePdf)This will return a single pdf url, so the expected response should look like this:https://restpack.io/cache/pdf/069aba16b0ced81a42ecba6d7fd841885f53dd9bcac71cbbcb08756bad73e1acCreating an invoice###This feature creates an invoice which is placed in your bookkeeping.
It also allows you to fetch the invoice PDF.First, let's start by defining our rows. A row requires four parameters. One invoice can contain varying rows. We append
these bu putting rows in a list.To create row we can initialize aRow(). The complete syntax would look like this:row=PyBunniApi.Row(unit_price=12.5,# This should be a float.description="This is a test description",quantity=5,tax="NL_High_21",# This should be a string.)For explaining how this works, one row will be enough. The next step is to create aContact()This can be done like
this:contact=PyBunniApi.Contact(company_name="The Carrot Company",attn='Jim Carrot',street='Carrot Street',street_number=20,postal_code='1122AB',city='Bunny Town',phone_number='123456789',)Now we can build a complete invoice usingInvoicePDF()by the following manner:invoicePdf=PyBunniApi.Invoice(external_id='Your own ID',invoice_date='YYYY-MM-DD',invoice_number='12345.67',tax_mode='excl',# This can be either `incl` or `excl`,design='INVOICE_DESIGN_ID',# A little down here I'll explain how you can fetch this ID.contact=contact,# We made a contact above here.rows=[row])We now have a initializedInvoiceobject which we can use to create a invoice in Bunni.
We can do this by usingpy_bunni_api.invoices.create_or_updateA complete snippet of this code would look like this:invoice_pdf=py_bunni_api.invoices.create_or_update(invoice)This function will not return anything if your invoice object is all good. Otherwise it returns the error received from bunni.Retreiving the list of invoice designsFor retrieving a list of invoice designs you can useinvoice_designs.listA complete snippet of this code would look like this:invoice_designs=py_bunni_api.invoice_designs.list()The variableinvoice_designsnow looks like this:[{id:"de_10XXX",name:"invoice THE CARROT COMPANY",createdOn:"2023-08-09T18:22:15.21Z"},{id:"de_10XXX",name:"New Design",createdOn:"2023-08-09T16:45:21.32Z"}]Retrieving a list of projectsFor retrieving a list of projects we can useprojects.list.
A complete snippet looks like this:projects=py_bunni_api.projects.list()The variableprojectsshould now contain a JSON structure like this:[{id:"pr_17413",color:"#eeeeee",name:"Project auto voor Danny",externalId:"1100"}]Retieving a list of timeFor retrieving a list of time objects we can usetime.list. A complete snippet would look like this:time_list=py_bunni_api.time.list()As a result of this piece of code time_list should contain an object which looks alot like this:[{id:"ti_29XXXX",date:"2023-08-10",duration:{m:3,h:5},project:{id:"pr_17XXX",color:"#123456",name:"Project name",externalId:"XXX"},description:"Time description"}]Creating or updating a timeWe can create or update a time with the use oftime.create_or_update.
For creating or updating a time we first need to build a time object.A time object requires two items calledDurationandProject. So let's create those two first.A duration object can be initialized like this:duration=PyBunniApi.Duration(h=10,# This is a integer which stands for whole hours.m=30# This is a integer which stands for whole minutes.)The next thing we need to setup is aProject. We can initialize one like this:project=PyBunniApi.Project(id="pr_XXXXX",external_id="YOUR EXTERNAL ID",# Bunni documentation shows this as optional. In my experience it seems mandatory.color="#123456",name="YOUR PROJECT NAME",)With those two objects initialized we can create atimeobject. You can do that the following way:time=PyBunniApi.TimeObject(date="2023-08-10",duration=duration,description="YOUR TIME DESCRIPTION",external_id="YOUR EXTERNAL ID",project=project,)Now that we have created all key elements we can submit it to Bunni in the following manner:py_bunni_api.time.create_or_update(time)A little footnoteYou have made it to the end of the documentation! Well done. Please note that this project is in early development.
There might be some bugs here and there. But please let me know when you find one!Do you want to thank me, because this project helped with a puzzle you needed to solve?
You can do that bybuying me a coffee ;)