Metadata-Version: 2.4
Name: pybrightree
Version: 0.1.4
Summary: Python SOAP wrapper for Brightree
Author: Nick
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: zeep>=4.3.1

# pybrightree

`pybrightree` is a Python wrapper around the Brightree SOAP services.

The package name is `pybrightree`, but the import path is `brightree`.

[PyPI package](https://pypi.org/project/pybrightree/)

## Installation

Install from PyPI:

```bash
pip install pybrightree
```

Install from a checked-out copy of the repository:

```bash
cd /path/to/Brightree-python
pip install .
```

For local development:

```bash
pip install -e .
```

## Requirements

- Python 3.10+
- Valid Brightree SOAP credentials
- Network access to the Brightree service endpoints you intend to call

## Quick Start

```python
from brightree import Brightree

client = Brightree("username", "password")

patient = client.Patient().PatientFetchByBrightreeID(12345)

doctors = client.Doctor().DoctorSearch(
    {
        "searchRequest": {"LastName": "Smith"},
        "sortRequest": [],
        "pageSize": 25,
        "page": 1,
    }
)

print(patient)
print(doctors)
```

More examples:

- [examples/basic_usage.py](/Users/nicholascheek/code/Brightree-python/examples/basic_usage.py)
- [examples/custom_config.py](/Users/nicholascheek/code/Brightree-python/examples/custom_config.py)

## How The Client Works

Create a top-level client, then request a service object:

```python
from brightree import Brightree

client = Brightree("username", "password")

patient_service = client.Patient()
doctor_service = client.Doctor()
invoice_service = client.Invoice()
```

Available service accessors on `Brightree`:

- `Patient()`
- `Doctor()`
- `Document()`
- `Documentation()`
- `CustomField()`
- `Insurance()`
- `Inventory()`
- `Pickup()`
- `Reference()`
- `SalesOrder()`
- `Pricing()`
- `Security()`
- `Invoice()`

## Calling Conventions

This wrapper exposes Brightree operations in three patterns.

### 1. No-argument calls

These methods send an empty payload:

```python
groups = client.Security().UserGroupFetchAll()
```

### 2. Dictionary payload calls

These methods expect a dictionary-like payload and pass it through to Brightree:

```python
result = client.Patient().PatientSearch(
    {
        "searchRequest": {"LastName": "Smith"},
        "sortRequest": [],
        "pageSize": 25,
        "page": 1,
    }
)
```

### 3. Positional convenience calls

These methods accept one or more positional arguments and map them to Brightree parameter names:

```python
patient = client.Patient().PatientFetchByBrightreeID(12345)
invoice = client.Invoice().InvoiceFetchByInvoiceID(9001)
```

When a method has a handwritten Python wrapper, follow the Python signature shown in this README.

## Building Search Payloads

`Brightree` inherits helper methods for building common paged search payloads:

```python
from brightree import Brightree

client = Brightree("username", "password")

payload = (
    client
    .search({"SearchParams": {"Branch": {"Value": 102}}})
    .sort()
    .page(2)
    .pageSize(25)
    .build()
)

results = client.Doctor().DoctorSearch(payload)
```

That builds:

```python
{
    "SearchParams": {"Branch": {"Value": 102}},
    "SortParams": [],
    "page": 2,
    "pageSize": 25,
}
```

## Custom Service Configuration

By default, the client uses the Brightree SOAP endpoints defined in [src/brightree/config.py](/Users/nicholascheek/code/Brightree-python/src/brightree/config.py). You can override only the services you need and the rest will keep their default values.

```python
from brightree import Brightree

client = Brightree(
    "username",
    "password",
    config={
        "service": {
            "patient": "https://your-brightree-endpoint.example.com/OrderEntryService/patientservice.svc",
        }
    },
)
```

Current default endpoint versions:

- `patient`: `v0100-2410`
- `salesorder`: `v0100-2408`
- `security`: `v0100-2407`

## Recent Changes

- Updated the default Patient endpoint to `v0100-2410`.
- Kept the default Sales Order endpoint on `v0100-2408` because `v0100-2409` is not working in this wrapper's target environment.
- Kept the default Security endpoint on `v0100-2407`.
- Added convenience wrappers for patient opt-in status, additional patient contacts, sales order note comment fetch aliases, sales order passthrough methods, and security BDM permission operations.

## Error Handling

The library raises `BrightreeException` for configuration issues, authentication problems, parameter validation failures, and SOAP faults.

```python
from brightree import Brightree, BrightreeException

try:
    client = Brightree("username", "password")
    patient = client.Patient().PatientFetchByBrightreeID(12345)
except BrightreeException as exc:
    print(exc)
    print(exc.code)
    print(exc.request_data)
```

## Service Reference

The lists below are grouped by how each method is called.

### `CustomField`

Dictionary payload methods:

- `CustomFieldValueSaveMultiple(query)`

Positional convenience methods:

- `CustomFieldFetchAllByCategory(category, includeInactive=0)`
- `CustomFieldValueFetchAllByBrightreeID(brightree_id, category)`

### `Doctor`

No-argument methods:

- `DoctorGroupFetchAll()`
- `FacilityFetchAll()`
- `FacilityGroupFetchAll()`
- `MarketingRepFetchAll()`

Dictionary payload methods:

- `DoctorCreate(query)`
- `DoctorNoteCreate(query)`
- `DoctorNoteUpdate(query)`
- `DoctorSearch(query)`
- `DoctorUpdate(query)`

Positional convenience methods:

- `AddDoctorReferralContact(doctor_brightree_id, referral_contact_brightree_id)`
- `DoctorFetchByBrightreeID(brightree_id)`
- `DoctorFetchByExternalID(external_id)`
- `DoctorNoteFetchByKey(brightree_id)`
- `DoctorNoteFetchByDoctor(brightree_id)`
- `DoctorReferralContactsFetchByDoctorKey(doctor_brightree_id)`
- `RemoveDoctorReferralContact(doctor_brightree_id, referral_contact_brightree_id)`

### `Document`

No-argument methods:

- `DocumentTypesFetchAll()`

Dictionary payload methods:

- `DocumentBatchCreate(query)`
- `DocumentBatchSearch(query)`
- `DocumentPropertyUpdate(query)`
- `DocumentReviewUpdate(query)`
- `DocumentSearch(query)`
- `GenerateDocumentID(query)`
- `StoreDocument(query)`

Positional convenience methods:

- `FetchDocumentContent(document_key)`

### `Documentation`

No-argument methods:

- `PARTaskReasonFetchAll()`

Dictionary payload methods:

- `CMNCreateFromPatient(query)`
- `CMNDetailCreate(query)`
- `CMNDetailDelete(query)`
- `CMNDetailUpdate(query)`
- `CMNFetchByBrightreeID(query)`
- `CMNFetchByExternalID(query)`
- `CMNFetchByPatientBrightreeID(query)`
- `CMNFetchBySalesOrderBrightreeID(query)`
- `CMNFrequencyUpdate(query)`
- `CMNLog(query)`
- `CMNPreview(query)`
- `CMNPrint(query)`
- `CMNQuestionAnswerConfiguration(query)`
- `CMNReasonFetchAll(query)`
- `CMNRenew(query)`
- `CMNRevise(query)`
- `CMNSearch(query)`
- `CMNTaskCreate(query)`
- `CMNTaskUpdate(query)`
- `CMNUpdate(query)`
- `PARAddPurchaseLimit(query)`
- `PARCreateFromPatient(query)`
- `PARDelete(query)`
- `PARFetchByBrightreeID(query)`
- `PARFetchByExternalID(query)`
- `PARFetchByPatientBrightreeID(query)`
- `PARFetchBySalesOrderBrightreeID(query)`
- `PARFetchBySalesOrderTemplateBrightreeID(query)`
- `PARLog(query)`
- `PARRenew(query)`
- `PARSearch(query)`
- `PARTaskCreate(query)`
- `PARTaskUpdate(query)`
- `PARUpdate(query)`
- `PARUpdatePurchaseLimit(query)`
- `SalesOrderItemLinkCMN(query)`
- `SalesOrderItemLinkNewCMN(query)`
- `SalesOrderItemLinkToNewPAR(query)`
- `SalesOrderItemLinkToPAR(query)`
- `SalesOrderItemsLinkCMN(query)`
- `SalesOrderItemsLinkNewCMN(query)`
- `SalesOrderItemsLinkToNewPAR(query)`
- `SalesOrderItemsLinkToPAR(query)`
- `SalesOrderItemsUnlinkCMN(query)`
- `SalesOrderItemsUnlinkPAR(query)`
- `SalesOrderItemUnlinkCMN(query)`
- `SalesOrderItemUnlinkPAR(query)`
- `SalesOrderTemplateItemLinkToPAR(query)`
- `SalesOrderTemplateItemsLinkToPAR(query)`
- `SalesOrderTemplateItemsUnlinkPAR(query)`
- `SalesOrderTemplateItemUnlinkPAR(query)`
- `SetParticipantComplianceDate(query)`

Positional convenience methods:

- `CMNFrequencyFetchbyBrightreeID(brightree_id)`
- `PARTaskFetchByPARBrightreeID(par_brightree_id)`

### `Insurance`

No-argument methods:

- `BundleBillingRuleSetFetchAll()`
- `ClaimFormFetchAll()`
- `CoverageLimitFetchAll()`
- `CustomAppealFormFetchAll()`
- `InsuranceCompanyFetchAll()`
- `InsuranceGroupFetchAll()`
- `InsurancePlanTypeFetchAll()`
- `InsurancePrintedFormsClaimFieldsFetch()`
- `InsurancePrintedFormsPARFieldsFetch()`
- `ItemGroupFetchAll()`
- `PARFormFetchAll()`
- `Ping()`

Dictionary payload methods:

- `InsuranceSearch(query)`
- `InsuranceUpdate(query)`
- `BranchOfficeInsuranceUpdate(query)`
- `CommercialEligibilityPayerSearch(query)`
- `CommercialPayerSearch(query)`
- `InsuranceCarrierCodeCreate(query)`
- `InsuranceCarrierCodeUpdate(query)`
- `InsuranceCreate(query)`
- `InsuranceSpanDateHoldInclusionCreate(query)`
- `InsuranceSpanDateOverrideCreate(query)`
- `InsuranceSpanDateOverrideUpdate(query)`
- `PriceTableSearch(query)`
- `SpanDateSplit(query)`

Positional convenience methods:

- `InsuranceFetchByBrightreeID(brightree_id)`
- `InsuranceFetchByExternalID(external_id)`
- `BranchOfficeInsuranceFetchByBranchBrightreeIDAndInsuranceBrightreeID(branch_brightree_id, insurance_brightree_id)`
- `FetchPmtSubTypeByPmtTypeBrightreeID(payment_type_brightree_id)`
- `InsuranceCarrierCodeDelete(brightree_id)`
- `InsuranceSpanDateHoldInclusionDelete(brightree_id)`
- `InsuranceSpanDateOverrideDelete(brightree_id)`
- `InsuranceValidationRuleSetCreate(validation_rule_set_brightree_id, insurance_brightree_id)`
- `InsuranceValidationRuleSetDelete(brightree_id)`
- `ItemGroupFetchByInsuranceBrightreeID(brightree_id)`

### `Inventory`

No-argument methods:

- `CoverageTypeFetchAll()`
- `ClaimNoteTypeFetchAll()`
- `KitTypeFetchAll()`
- `NDCFetchAll()`
- `StockingUOMFetchAll()`

Dictionary payload methods:

- `FetchItemLocations(query)`
- `FetchItemQuantitiesAtLocation(query)`
- `InventoryItemAddLots(query)`
- `InventoryItemAddSerialNumbers(query)`
- `InventoryItemAdjustment(query)`
- `InventoryItemTransfer(query)`
- `ItemAddToLocation(query)`
- `ItemAddToLocations(query)`
- `ItemCreate(query)`
- `ItemFetchByBrightreeID(query)`
- `ItemFetchByExternalID(query)`
- `ItemFetchByItemID(query)`
- `ItemFetchReplacementItemsByBrightreeID(query)`
- `ItemFetchReplacementItemsByItemID(query)`
- `ItemLocationsUpdate(query)`
- `ItemLocationUpdate(query)`
- `ItemSearch(query)`
- `ItemUpdate(query)`

### `Invoice`

Dictionary payload methods:

- `InvoiceItemUpdate(query)`
- `InvoiceUpdate(query)`
- `ResubmitInvoices(query)`

Positional convenience methods:

- `InvoiceCreatePrintActivity(brightree_id)`
- `InvoiceFetchByBrightreeID(brightree_id)`
- `InvoiceFetchByInvoiceID(invoice_id)`
- `OpenInvoiceAgedBalanceFetchByPatient(patient_brightree_id)`
- `OpenInvoiceBalanceFetchByPatient(patient_brightree_id)`

### `Patient`

No-argument methods:

- `FacilityMasterInfoFetchAll()`

Dictionary payload methods:

- `FacilityResidentCreate(query)`
- `PatientCreate(query)`
- `PatientSearch(query)`
- `PatientUpdate(query)`
- `PatientNoteCreate(query)`
- `PatientNoteSearch(query)`
- `PatientNoteUpdate(query)`
- `PatientPayorAdd(query)`
- `PatientPayorFetch(query)`
- `PatientPayorUpdate(query)`
- `PatientPhoneNumberSearch(query)`
- `PatientUpdateSleepTherapyPatientID(query)`
- `PharmacyPatientClinicalInfoFetchByBrightreeID(query)`
- `FetchPatientOptInStatus(query)`
- `UpdatePatientOptInStatus(query)`
- `AdditionalPatientContactCreate(query)`
- `AdditionalPatientContactFetchByBrightreeID(query)`
- `AdditionalPatientContactUpdate(query)`

Positional convenience methods:

- `PatientAddMarketingReferral(brightree_id, referral_id)`
- `PatientFetchByExternalID(external_id)`
- `PatientFetchByPatientID(patient_id)`
- `PatientFetchByBrightreeID(brightree_id)`
- `PatientNoteFetchByKey(brightree_id)`
- `PatientNoteFetchByPatient(brightree_id)`
- `PatientPayorFetchAll(patient_key)`
- `PatientPayorRemove(brightree_id)`
- `PatientRemoveMarketingReferral(brightree_id)`
- `PharmacyPatientLabResultsFetchByBrightreeIDAndPatientBrightreeID(patient_brightree_id, brightree_id)`
- `PharmacyPatientMedicationHistoryFetchByBrightreeIDAndPatientBrightreeID(brightree_id, patient_brightree_id)`
- `PharmacyPatientMostRecentLabResultsFetchByPatientBrightreeID(brightree_id)`
- `fetch_patient_opt_in_status(brightree_id, patient_phone)`
- `update_patient_opt_in_status(patient_opt_in_status)`
- `additional_patient_contact_create(additional_patient_contact)`
- `additional_patient_contact_fetch_by_brightree_id(patient_brightree_id)`
- `additional_patient_contact_update(brightree_patient_contact_key, additional_patient_contact)`

### `Pickup`

Dictionary payload methods:

- `PickupExchangeAddAllRentalItems(query)`
- `PickupExchangeAddDeliveryException(query)`
- `PickupExchangeAddPickupItem(query)`
- `PickupExchangeCancelPOD(query)`
- `PickupExchangeConfirm(query)`
- `PickupExchangeCreate(query)`
- `PickupExchangeDelete(query)`
- `PickupExchangeFetchByBrightreeID(query)`
- `PickupExchangeFetchByExternalID(query)`
- `PickupExchangeItemAddDeliveryException(query)`
- `PickupExchangeItemSpecifyExchangeItem(query)`
- `PickupExchangeMessagesFetchByBrightreeID(query)`
- `PickupExchangePayorSearch(query)`
- `PickupExchangeRemoveItem(query)`
- `PickupExchangeSearch(query)`
- `PickupExchangeSendPOD(query)`
- `PickupExchangeUpdate(query)`
- `PickupExchangeUpdateItem(query)`
- `PickupExchangeUpdatePODStatus(query)`

### `Pricing`

No-argument methods:

- `Ping()`

Dictionary payload methods:

- `CMNFormFetchAll(query)`
- `NonTaxReasonFetchAll(query)`
- `PriceCreateItem(query)`
- `PriceCreateStandard(query)`
- `PriceDetailCreate(query)`
- `PriceDetailFetchByBrightreeDetailID(query)`
- `PriceDetailUpdate(query)`
- `PriceFetch(query)`
- `PriceOptionLetterTypeFetchAll(query)`
- `PriceTableFetchAll(query)`

### `Reference`

No-argument methods:

- `AccountGroupFetchAll()`
- `BranchInfoFetchAll()`
- `ClaimNoteTypeFetchAll()`
- `ContactTypeFetchAll()`
- `DeliveryTechnicianFetchAll()`
- `DepreciationTypesFetchAll()`
- `EPSDTConditionCodeFetchAll()`
- `FacilityInfoFetchAll()`
- `FetchCurrentSecUser()`
- `FunctionalAssessmentFetchAll()`
- `GLAccountGroupsFetchAll()`
- `ItemGroupFetchAll()`
- `ItemManufacturerFetchAll()`
- `ItemStatusFetchAll()`
- `ItemTypesFetchAll()`
- `LocationInfoFetchAll()`
- `MarketingRepFetchAll()`
- `MSPInsTypeFetchAll()`
- `PatientNoteReasonFetchAll()`
- `PlaceOfServiceFetchAll()`
- `PolicyClaimCodeFetchAll()`
- `PolicyTypeCodeFetchAll()`
- `PractitionerInfoFetchAll()`
- `SalesOrderClassificationFetchAll()`
- `SalesOrderManualHoldReasonFetchAll()`
- `SalesOrderVoidReasonFetchAll()`
- `SalesTypesFetchAll()`
- `SecUsersFetchAll()`
- `ShippingCarriersFetchAll()`
- `TaxZoneFetchAll()`
- `VendorsFetchAll()`
- `WIPStatesFetchAll()`

Dictionary payload methods:

- `AddFacilityReferralContact(query)`
- `BranchInfoFetchByBrightreeID(query)`
- `ContactTypeCreate(query)`
- `ContactTypeDelete(query)`
- `ContactTypeFetchByBrightreeID(query)`
- `ContactTypeUpdate(query)`
- `FacilityCreate(query)`
- `FacilityDelete(query)`
- `FacilityFetchByBrightreeID(query)`
- `FacilityFetchByExternalID(query)`
- `FacilityReferralContactsFetchByFacilityKey(query)`
- `FacilityUpdate(query)`
- `MarketingRepFetchByBrightreeID(query)`
- `MarketingRepFetchByExternalID(query)`
- `MarketingRepUpdateExternalID(query)`
- `ReferralContactCreate(query)`
- `ReferralContactFetchByBrightreeID(query)`
- `ReferralContactFetchByExternalID(query)`
- `ReferralContactSearch(query)`
- `ReferralContactUpdate(query)`
- `ReferralFetchByBrightreeID(query)`
- `ReferralSearch(query)`
- `RemoveFacilityReferralContact(query)`
- `SiteInfoFetch(query)`
- `VendorFetchByBrightreeID(query)`

### `SalesOrder`

No-argument methods:

- `SalesOrderFulfillmentVendorsFetchAll()`
- `StopReasonFetchAll()`

Dictionary payload methods:

- `BrightSHIPSalesOrderAck(query)`
- `BrightShipSalesOrderFetch(query)`
- `OrderImport(query)`
- `SalesOrderAddDeliveryException(query)`
- `SalesOrderAddMarketingReferral(query)`
- `SalesOrderConfirm(query)`
- `SalesOrderCreate(query)`
- `SalesOrderEvaluateDropShip(query)`
- `SalesOrderEvaluateDropShipWithAccountNumber(query)`
- `SalesOrderFetchByBrightreeID(query)`
- `SalesOrderFetchByExternalID(query)`
- `SalesOrderFetchByPurchaseOrderID(query)`
- `SalesOrderFetchPendingByShippingCarrierKey(query)`
- `SalesOrderFetchReadyforShipping(query)`
- `SalesOrderItemAddDeliveryException(query)`
- `SalesOrderItemPriceOptionFetchByBrightreeID(query)`
- `SalesOrderItemReplaceGeneric(query)`
- `SalesOrderItemUpdateLotNumbers(query)`
- `SalesOrderItemUpdatePriceOption(query)`
- `SalesOrderItemUpdateSerialNumbers(query)`
- `SalesOrderMessagesFetchByBrightreeID(query)`
- `SalesOrderOverrideValidationDetailMessage(query)`
- `SalesOrderOverrideValidationHeaderMessage(query)`
- `SalesOrderPayorSearch(query)`
- `SalesOrderQuickAddItem(query)`
- `SalesOrderQuickAddItemWithItemsDataReturn(query)`
- `SalesOrderRemoveItem(query)`
- `SalesOrderRemoveMarketingReferral(query)`
- `SalesOrderSearch(query)`
- `SalesOrderSendPOD(query)`
- `SalesOrderSubmitDropShip(query)`
- `SalesOrderTemplateCreate(query)`
- `SalesOrderTemplateCreateSalesOrder(query)`
- `SalesOrderTemplateDelete(query)`
- `SalesOrderTemplateFetchByBrightreeID(query)`
- `SalesOrderTemplateFetchByExternalID(query)`
- `SalesOrderTemplateItemFrequencyUpdate(query)`
- `SalesOrderTemplateItemPriceOptionFetchByBrightreeID(query)`
- `SalesOrderTemplateItemUpdatePriceOption(query)`
- `SalesOrderTemplateQuickAddItem(query)`
- `SalesOrderTemplateRemoveItem(query)`
- `SalesOrderTemplateScheduleFetchBySOTemplateKey(query)`
- `SalesOrderTemplateScheduleLogSearch(query)`
- `SalesOrderTemplateScheduleSearch(query)`
- `SalesOrderTemplateScheduleUpdate(query)`
- `SalesOrderTemplateSearch(query)`
- `SalesOrderTemplateUpdate(query)`
- `SalesOrderTemplateUpdateInsurance(query)`
- `SalesOrderTemplateUpdateItem(query)`
- `SalesOrderTemplateUpdateItemPayor(query)`
- `SalesOrderTemplateUpdateItemsWithDefaultPriceOption(query)`
- `SalesOrderTemplateUpdateWIPState(query)`
- `SalesOrderUpdate(query)`
- `SalesOrderUpdateInsurance(query)`
- `SalesOrderUpdateItem(query)`
- `SalesOrderUpdateItemGeneric(query)`
- `SalesOrderUpdateItemNextBilling(query)`
- `SalesOrderUpdateItemPayor(query)`
- `SalesOrderUpdateItemsWithDefaultPriceOption(query)`
- `SalesOrderUpdatePODStatus(query)`
- `SalesOrderUpdateTracking(query)`
- `SalesOrderUpdateWIPState(query)`
- `SalesOrderVoid(query)`
- `SalesOrderVoidSearch(query)`
- `SearchWIPStatusWithUpdate(query)`
- `StopReasonSalesOrderTemplateUpdate(query)`
- `StopReasonSalesOrderUpdate(query)`
- `PatientNoteCommentCreate(query)`
- `PatientNoteCommentFetch(query)`
- `PatientNoteCommentUpdate(query)`

Positional convenience methods:

- `SalesOrderTemplateItemFrequencyFetchByBrightreeID(brightree_id)`
- `StopReasonSalesOrderFetchByBrightreeID(brightree_id)`
- `StopReasonSalesOrderTemplateFetchByBrightreeID(brightree_id)`
- `patient_notes_comment_fetch(patient_note_key)`
- `patient_note_comment_fetch(patient_note_key)`

### `Security`

No-argument methods:

- `UserGroupFetchAll()`

Dictionary payload methods:

- `UserCreate(query)`
- `UserSearch(query)`
- `UserUpdate(query)`
- `UserGroupCreate(query)`
- `UserGroupUpdate(query)`
- `UserGroupFetchByBrightreeID(query)`
- `UserGroupBDMPermissionsFetchByUserGroupBrightreeID(query)`
- `UserGroupBDMPermissionsUpdate(query)`
- `UserGroupPermissionsFetchByUserGroupBrightreeID(query)`
- `UserGroupPermissionsUpdate(query)`

Positional convenience methods:

- `UserFetchByBrightreeID(brightree_id)`
- `user_group_bdm_permissions_fetch_by_user_group_brightree_id(user_group_brightree_id)`
- `user_group_bdm_permissions_update(user_group_brightree_id, user_group_bdm_permissions)`

## Notes

- The wrapper preserves Brightree-style service accessor names such as `client.Patient()` and operation names such as `PatientFetchByBrightreeID(...)`.
- Some methods include extra validation in Python before the SOAP request is sent.
- Dictionary payload shapes are Brightree-specific. Use your Brightree SOAP documentation and existing request examples to build the correct payloads for your account and endpoint version.
