python-quickbooks

repository·main·Indexed 19 days ago

https://github.com/routablehq/python-quickbooks

A Python 3 library for accessing the QuickBooks Online API. It provides an object-oriented interface for managing accounting operations such as customers and invoices, supporting CRUD operations, batch processing, Change Data Capture (CDC), and PDF downloads. The library includes utilities for OAuth configuration via intuit-oauth, JSON serialization, date formatting, and webhook signature validation.

Tokens
4.1K
Snippets
15
Records
16
Agent score
17%

What's inside python-quickbooks

  1. Configure QuickBooks OAuth and Client access

    main

    To access the API, you must first set up an AuthClient using the intuit-oauth library, then initialize a QuickBooks client.

    1. Initialize AuthClient: Pass your CLIENT_ID, CLIENT_SECRET, and ACCESS_TOKEN. If access_token is not provided, the client will attempt to refresh it.
    2. Initialize QuickBooks client: Pass the auth_client, refresh_token, and company_id.
    3. Minor Versions: You can specify a minorversion (e.g., 69) in the QuickBooks constructor.

    Warning: Intuit is deprecating support for minor versions 1–74 starting August 1, 2025.

    from intuitlib.client import AuthClient
    from quickbooks import QuickBooks
    
    auth_client = AuthClient(
            client_id='CLIENT_ID',
            client_secret='CLIENT_SECRET',
            access_token='ACCESS_TOKEN',
            environment='sandbox',
            redirect_uri='http://localhost:8000/callback',
        )
    
    client = QuickBooks(
            auth_client=auth_client,
            refresh_token='REFRESH_TOKEN',
            company_id='COMPANY_ID',
            # minorversion=69 # Optional
        )
  2. Perform Object Operations (List, Filter, Query, Create, Update)

    main

    The library provides several ways to interact with QuickBooks objects (e.g., Customer, Invoice).

    Listing and Filtering

    • List all: Customer.all(qb=client)
    • Filter by attributes: Customer.filter(Active=True, FamilyName="Smith", qb=client)
    • Ordering: Use order_by parameter (e.g., 'TxnDate', 'TxnDate DESC', or multiple fields like 'FamilyName, GivenName').
    • Paging: Use start_position and max_results.
    • Choose from list: Customer.choose(['Name1', 'Name2'], field="DisplayName", qb=client)
    • Custom WHERE clause: Customer.where("Active = True", qb=client) (Do not include the word WHERE).
    • Custom SQL Query: Customer.query("SELECT * FROM Customer WHERE Active = True", qb=client)
    • Count: Customer.count("Active = True", qb=client)

    CRUD Operations

    • Get single object: Customer.get(id, qb=client)
    • Update: Modify an attribute on a retrieved object and call .save(qb=client).
    • Create: Instantiate a new object, set attributes, and call .save(qb=client).

    Warning: This library does not sanitize user input. Always sanitize input before passing it to queries to prevent injection attacks.

    from quickbooks.objects.customer import Customer
    from quickbooks.objects.invoice import Invoice
    
    # List all
    customers = Customer.all(qb=client)
    
    # Filtered and ordered
    invoices = Invoice.filter(CustomerRef='100', order_by='TxnDate DESC', qb=client)
    
    # Paging
    customers = Customer.filter(start_position=1, max_results=25, qb=client)
    
    # Custom Where
    customers = Customer.where("Active = True AND CompanyName LIKE 'S%'", qb=client)
    
    # Get and Update
    customer = Customer.get(1, qb=client)
    customer.CompanyName = "New Name"
    customer.save(qb=client)
    
    # Create
    customer = Customer()
    customer.CompanyName = "Test Company"
    customer.save(qb=client)
  3. Use Change Data Capture (CDC)

    main

    CDC returns a list of objects that have changed since a specific timestamp.

    • You can pass a list of entity types (e.g., [Invoice, Customer]).
    • The timestamp can be a string or a Python datetime object (which is automatically converted to a string).
    from quickbooks.cdc import change_data_capture
    from quickbooks.objects import Invoice, Customer
    from datetime import datetime
    
    # Using string timestamp
    cdc_response = change_data_capture([Invoice], "2017-01-01T00:00:00", qb=client)
    
    # Using datetime object
    cdc_response = change_data_capture([Invoice, Customer], datetime(2017, 1, 1), qb=client)
  4. Attach files or notes to objects

    main

    Use the Attachable and AttachableRef classes to link notes or files to an entity (like a Customer).

    • Notes: Set the Note attribute.
    • Files: Use either _FilePath (full path to file) or _FileBytes (bytes object). Do not use both at the same time.
    • Linking: Use customer.to_ref() to create the reference for the attachment.
    from quickbooks.objects.attachable import Attachable, AttachableRef
    
    attachment = Attachable()
    attachable_ref = AttachableRef()
    attachable_ref.EntityRef = customer.to_ref()
    attachment.AttachableRef.append(attachable_ref)
    
    # To attach a note
    attachment.Note = 'This is a note'
    attachment.save(qb=client)
    
    # To attach a file via path
    attachment.FileName = 'filename.pdf'
    attachment._FilePath = '/folder/filename.pdf'
    attachment.ContentType = 'application/pdf'
    attachment.save(qb=client)
  5. Perform Batch Operations

    main

    Batch operations allow multiple operations in a single request using batch_create, batch_update, or batch_delete.

    Batch Create, Update, and Delete

    • Create: batch_create(list_of_objects, qb=client)
    • Update: batch_update(list_of_objects, qb=client)
    • Delete: batch_delete(list_of_objects, qb=client) (Only for supported entities).

    Reviewing Batch Results

    The result object contains two main collections:

    • successes: A list of objects that were successfully processed.
    • faults: A list of failed operations. Each fault contains the original_object and a list of Error objects containing the Message.
    from quickbooks.batch import batch_create, batch_update, batch_delete
    
    # Batch Create
    c1 = Customer(); c1.CompanyName = "C1"
    c2 = Customer(); c2.CompanyName = "C2"
    results = batch_create([c1, c2], qb=client)
    
    # Reviewing Results
    for obj in results.successes:
        print(f"Success: {obj.DisplayName}")
    
    for fault in results.faults:
        print(f"Failed: {fault.original_object.DisplayName}")
        for error in fault.Error:
            print(f"Error: {error.Message}")
  6. Convert objects to and from JSON

    main

    All QuickBooks objects support JSON serialization and deserialization.

    • to_json(): Converts the object to a JSON string.
    • from_json(data): Loads a dictionary/JSON object into a new instance of the class.
    # To JSON
    json_data = account.to_json()
    
    # From JSON
    account = Account.from_json({
        "AccountType": "Accounts Receivable",
        "AcctNum": "123123",
        "Name": "MyJobs"
    })
    account.save(qb=client)
  7. Format dates for QuickBooks API

    main

    QuickBooks requires specific string formats for date and datetime fields. Use the provided helpers to format Python date or datetime objects.

    • qb_date_format(date_obj)
    • qb_datetime_format(datetime_obj)
    • qb_datetime_utc_offset_format(datetime_obj, offset)
    from datetime import date, datetime
    # Note: helpers are imported from the library's internal helpers
    
    date_string = qb_date_format(date(2016, 7, 22))
    date_time_string = qb_datetime_format(datetime(2016, 7, 22, 10, 35, 00))
    date_time_with_utc_string = qb_datetime_utc_offset_format(datetime(2016, 7, 22, 10, 35, 00), '-06:00')
  8. Handle QuickbooksException errors

    main

    When a QuickBooks operation fails, catch QuickbooksException to access specific error details from the API.

    Attributes:

    • message: The error message returned from QBO.
    • error_code: The specific QBO error code.
    • detail: Additional information if available.
    from quickbooks.exceptions import QuickbooksException
    
    try:
        # perform operation
        customer.save(qb=client)
    except QuickbooksException as e:
        print(f"Message: {e.message}")
        print(f"Code: {e.error_code}")
        print(f"Detail: {e.detail}")
  9. Use batch operations

    main

    To perform multiple operations in a single API call, use the batch_operation(request_body) method. This reduces the number of network requests and improves efficiency when performing bulk updates or creations.

    batch_payload = {
        "BatchRequest": {
            "Operations": [
                # ... list of operations ...
            ]
        }
    }
    client.batch_operation(batch_payload)
  10. Download a PDF of a business object

    main

    You can download the PDF representation of a business object (like an Invoice or SalesReceipt) using the download_pdf(qbbo, item_id) method. This returns the raw binary content of the PDF.

    pdf_content = client.download_pdf('Invoice', '123')
    with open('invoice_123.pdf', 'wb') as f:
        f.write(pdf_content)
  11. Retrieve reports and CDC data

    main

    The client provides specialized methods for reporting and Change Data Capture (CDC):

    • get_report(report_type, qs=None): Fetches data from the QuickBooks reports endpoint. report_type is the name of the report, and qs is an optional dictionary of query parameters.
    • change_data_capture(entity_string, changed_since): Retrieves changes for specific entities since a given timestamp. entity_string defines which entities to track, and changed_since is the timestamp.
    • get_current_user(): Returns data about the current user authenticated via the session.
    # Get a ProfitAndLoss report
    report = client.get_report('ProfitAndLoss', {'start_date': '2023-01-01'})
    
    # Get changes for Invoices since a specific time
    changes = client.change_data_capture('Invoice', '2023-01-01T00:00:00Z')