Getting Started - Nioron07/Easy-Acumatica GitHub Wiki

This page provides a practical guide to using the AcumaticaClient wrapper in easy-acumatica. You’ll learn how to import, initialize, manage sessions, and perform common API calls with concise, real-world examples.

1. Installation

Easy-Acumatica is published on PyPI and has only one runtime dependency (requests).

pip install easy-acumatica

2. Client Configuration

All interactions with the API begin with creating an AcumaticaClient instance. By default, the client logs in immediately upon creation.

from easy_acumatica import AcumaticaClient

client = AcumaticaClient(  
    base_url="https://example.acumatica.com",  
    username="Example-User",  
    password="Super-Secret-Password",  
    tenant="Example-Tenant",  
    branch="test-branch",  
    # Optional parameters below  
    locale="en-US",  
    verify_ssl=True,  
    persistent_login=True,  
    retry_on_idle_logout=True  
)

Key Parameters:

  • persistent_login: If True (default), the client logs in once and re-uses the session. If False, it logs in and out for every API call.
  • retry_on_idle_logout: If True (default), the client will automatically re-authenticate and retry a failed request once, which is useful for long-running scripts where sessions might time out.

3. Usage Examples

Functionality is organized into sub-services (like client.contacts, client.records, etc.) that are attached to the client instance. Here are some examples of how to use them.

Example 1: Create a Contact and Add a Follow-Up Task

This example shows how to use two different services (contacts and activities) together to perform a common business workflow.

from easy_acumatica.models.contact_builder import ContactBuilder

# Step 1: Create a new contact using the ContactsService  
try:  
    contact_payload = (  
        ContactBuilder()  
        .first_name("Jane")  
        .last_name("Doe")  
        .email("[email protected]")  
        .contact_class("LEAD")  
    )  
    new_contact = client.contacts.create_contact("24.200.001", contact_payload)  
    print(f"Successfully created contact: {new_contact['DisplayName']['value']}")

    # Step 2: Get the NoteID of the new contact to link an activity to it  
    contact_note_id = new_contact['NoteID']['value']

    # Step 3: Use the ActivitiesService to create a follow-up task  
    client.activities.create_activity_linked_to_contact(  
        api_version="24.200.001",  
        contact_note_id=contact_note_id,  
        summary="Initial follow-up call",  
        details="Call Jane to discuss their project requirements.",  
        activity_type="T"  # 'T' for Task  
    )  
    print("Successfully created follow-up task for the new contact.")

except Exception as e:  
    print(f"An error occurred: {e}")

Example 2: Find a Stock Item and Download its Attachment

This example demonstrates how to find a specific record using a filter and then use the FilesService to retrieve an associated file.

from easy_acumatica.models.filter_builder import F  
from easy_acumatica.models.query_builder import QueryOptions

try:  
    # Step 1: Find the 'CPU-I7' stock item using the RecordsService  
    item_filter = (F.InventoryID == 'CPU-I7')  
    opts = QueryOptions(filter=item_filter, expand=["files"]) # Expand 'files' to get metadata

    stock_items = client.records.get_records_by_filter(  
        "24.200.001", "StockItem", options=opts  
    )

    if not stock_items:  
        print("Stock item not found.")  
    else:  
        # Step 2: Get the first file's ID from the metadata  
        files = stock_items[0].get("files", [])  
        if not files:  
            print("No files attached to this item.")  
        else:  
            first_file_id = files[0]['id']  
            print(f"Found file with ID: {first_file_id}. Downloading...")

            # Step 3: Use the FilesService to download the file content  
            file_bytes = client.files.get_file("24.200.001", first_file_id)

            # Step 4: Save the file locally  
            with open("item_spec_sheet.pdf", "wb") as f:  
                f.write(file_bytes)  
            print("File downloaded successfully.")

except Exception as e:  
    print(f"An error occurred: {e}")

Example 3: Create a New Earning Type and Apply It

This example shows how to use the specialized CodesService to create a new payroll code and then use the ActionsService to simulate its application.

from easy_acumatica.models.code_builder import EarningTypeCodeBuilder  
from easy_acumatica.models.record_builder import RecordBuilder

try:  
    # Step 1: Create a new 'BONUS' earning type using the CodesService  
    earning_payload = (  
        EarningTypeCodeBuilder()  
        .code_id("BONUS")  
        .description("Annual Performance Bonus")  
        .category("Wage")  
        .active(True)  
    )  
    new_code = client.codes.create_earning_type_code("24.200.001", earning_payload)  
    print(f"Created new earning type: {new_code['EarningTypeCodeID']['value']}")

    # Step 2: Use the ActionsService to apply this new code in a (conceptual) action  
    # This example simulates applying a bonus to a specific payroll document.  
    payroll_doc = RecordBuilder().field("ReferenceNbr", "PR000123")  
    bonus_params = {  
        "EarningType": "BONUS",  
        "Amount": 5000.00  
    }

    client.actions.execute_action(  
        api_version="24.200.001",  
        entity_name="PayrollBatch",  
        action_name="ApplyBonus",  
        entity=payroll_doc,  
        parameters=bonus_params  
    )  
    print("Bonus action executed successfully.")

except Exception as e:  
    print(f"An error occurred: {e}")

4. Session Management

The client handles login and logout for you. It logs in when created and logs out automatically when your script finishes. If you need to, you can also log out manually.

client.logout()