Getting Started
Migration Guide

Migration Guide

🚨

Breaking Changes: dealcloud-sdk 1.x is a complete rewrite versus the legacy SDK (v0.1.x). Review all changes before upgrading.

Breaking Changes Summary

ChangeLegacy SDKdealcloud-sdk 1.xAction Required
HTTP Clientrequestshttpx (prefer intapp-rest-client)Prefer RestClient + OAuth2 for custom calls; raw httpx is possible
read_data() outputDefaults to "pandas"Required parameterAdd explicit output=
ConfigurationSimple env / legacy JSON (snake_case credentials)DealCloudConfig (full typed model, .NET-aligned)Optional: adopt from_config / from_config_object for timeouts, retries, concurrency (not just key casing)

Step-by-Step Migration

Step 1: Update read_data() Calls

The output parameter is now required. This prevents ambiguity about return types.

# Legacy: output defaulted to "pandas"
data = dc.read_data("Company")
 
# Would return pandas.DataFrame
⚠️

If you omit output=, the SDK will raise a ValueError with a clear migration message.

Quick Fix: Search your codebase for read_data( and add output="pandas" to maintain previous behavior:

# Find all read_data calls
grep -rn "read_data(" --include="*.py" .

Step 2: Update HTTP-Dependent Code

If you extended the SDK or used requests directly, move to httpx-based HTTP. Prefer intapp-rest-client — the same dependency dealcloud-sdk 1.x uses (RestClient, OAuth2, retries, logging). That keeps custom REST calls aligned with the SDK. Raw httpx remains an option for minimal scripts; compare all three below.

import requests
 
# Custom requests-based code
session = requests.Session()
response = session.get(url, headers=headers)
response.raise_for_status()
# intapp-rest-client: same client with a context manager
from intapp_rest_client import RestClient, OAuth2Config
 
site = "yoursite.dealcloud.com"
with RestClient(
    base_url=f"https://{site}/",
    oauth2_config=OAuth2Config(
        token_url=f"https://{site}/api/rest/v1/oauth/token",
        client_id="your_client_id",
        client_secret="your_client_secret",
        scope="data",
    ),
) as client:
    rows = client.post(
        "/api/rest/v4/data/entrydata/rows/query",
        json={
            "objectApiName": "Company",
            "query": "Status = 'Active'",
        },
    )
💡

If you already use DealCloud, the underlying HTTP client is exposed as dc.client (a DealCloudRestClient, subclass of intapp_rest_client.RestClient). Use it for custom endpoints instead of creating a second client when credentials already come from the SDK.

Key differences:

Featurerequestsintapp-rest-clienthttpx
Async supportNoYes (aget, apost, …)Yes (native)
HTTP/2NoYes (via httpx)Yes
JSON body on get-style helpersN/Aget() / post() return parsed JSON.json() on Response
OAuth2 client credentialsManualOAuth2ConfigManual
Retries / backoffManualRetryConfig (optional)Manual
Same stack as dealcloud-sdk 1.xNoYesUnder the hood only
Session / clientSession()RestClient (context manager supported)Client()
TimeoutPer-requestClient default + per callDefault required on client

Step 3: Configuration — easy factories vs DealCloudConfig

dealcloud-sdk 1.x centers configuration on DealCloudConfig (a Pydantic model): credentials plus querySettings, concurrencyLimits, responseRetrySettings, connectorTimeoutSeconds, and scope. That is the same structured shape as the .NET SDK config — not merely renaming site_url to siteUrl.

You can keep a minimal migration using the factory helpers you already use, or move to the full model when you need production tuning.

Easy path (minimal change)

Use DealCloud.from_env(), from_json(), or from_yaml() with the legacy credential shape (site_url, client_id, client_secret). The client is created with sensible defaults for everything else.

from dealcloud_sdk import DealCloud
 
# After setting DEALCLOUD_* environment variables (see Configuration files doc)
dc = DealCloud.from_env()
 
# Legacy JSON: only credentials (snake_case)
dc = DealCloud.from_json("credentials.json")
 
# Legacy YAML: only credentials
dc = DealCloud.from_yaml("credentials.yaml")
{
  "site_url": "yoursite.dealcloud.com",
  "client_id": "12345",
  "client_secret": "your-secret"
}

No need to introduce DealCloudConfig until you want to tune timeouts, pagination, or retries.

Full path — DealCloudConfig (recommended for production)

1. Config file — JSON or YAML in the DealCloudConfig shape (camelCase keys at the top level, nested objects for settings). Load with DealCloud.from_config(path) (preferred for full files).

from dealcloud_sdk import DealCloud
 
dc = DealCloud.from_config("dealcloud.json")
# or: DealCloud.from_config("dealcloud.yaml")
{
  "siteUrl": "yoursite.dealcloud.com",
  "clientId": "12345",
  "clientSecret": "your-secret",
  "connectorTimeoutSeconds": 100,
  "querySettings": {
    "pageSize": 1000,
    "cellPaginationLimit": 9000,
    "deletePageSize": 5000
  },
  "concurrencyLimits": {
    "read": 2,
    "delete": 2,
    "create": 2
  },
  "responseRetrySettings": {
    "tooManyRequests": 5,
    "backoffFactor": 2.0
  }
}

2. Programmatic — build DealCloudConfig in code (and nested QuerySettings, ConcurrencyLimits, ResponseRetrySettings) and pass it to DealCloud.from_config_object(config) — equivalent to DealCloud(config=config).

from dealcloud_sdk import DealCloud
from dealcloud_sdk.models import (
    DealCloudConfig,
    QuerySettings,
    ConcurrencyLimits,
    ResponseRetrySettings,
)
 
config = DealCloudConfig(
    siteUrl="yoursite.dealcloud.com",
    clientId="12345",
    clientSecret="your-secret",
    connectorTimeoutSeconds=120,
    querySettings=QuerySettings(pageSize=2000),
    concurrencyLimits=ConcurrencyLimits(read=2, delete=2, create=2),
    responseRetrySettings=ResponseRetrySettings(
        tooManyRequests=8,
        backoffFactor=2.0,
    ),
)
 
dc = DealCloud.from_config_object(config)
💡

from_json() / from_yaml() still accept legacy-only files. If the file contains a full DealCloud-style document, the SDK may warn and recommend from_config() instead — use from_config() for full JSON/YAML to avoid ambiguity.

See Configuration files and Advanced configuration for environment variables, file examples, and all fields on DealCloudConfig.

Step 4: Dependencies — fsspec, Polars, HTTP & auth

dealcloud-sdk 1.x builds on a few libraries you should be aware of when migrating—especially if you use remote config, cloud paths, or Polars.

PieceRoleInstall
fsspec (opens in a new tab)Single API for local paths and URIs (file://, s3://, abfs://, gs://, …). Used for loading DealCloudConfig from JSON/YAML, CSV/Excel helpers, storage backends, and any path the docs describe as supporting fsspec.Core — always installed with the SDK.
Cloud filesystem backendsOptional drivers so fsspec can read/write s3://, Azure, gs:// URIs (config files, exports, attachments).Optional extras: dealcloud-sdk[s3], [azure], [gcs], or [all].
Polars (opens in a new tab)output="polars" / "polars_lazy" on read_data and related APIs; Polars-oriented helpers (see Polars).dealcloud-sdk[polars] (pulls in pyarrow for pandas/Polars interchange).
HTTP & authREST calls go through intapp-rest-client on httpx (not requests). Authentication is OAuth2 client credentials, aligned with the .NET SDK and documented in Authentication.Coreintapp-rest-client is a required dependency.
# Examples: add Polars, YAML config parsing, and S3 for fsspec URIs
pip install "dealcloud-sdk[polars,yaml,s3]"
# uv: uv add "dealcloud-sdk[polars,yaml,s3]"

Migration angle: if you only used local files and pandas, you may not have thought about fsspec or Polars—defaults still work. When you move config or exports to object storage, install the matching extra so fsspec can open those URIs. For large reads or Polars-native pipelines, add [polars].

New Features Available After Migration

After updating your code, you gain access to these new features:

Streaming Reads

For memory-efficient processing of large datasets:

# Process millions of rows without loading all into memory
for company in dc.read_data_streaming("Company"):
    process(company)
 
# Async version
async for company in dc.aread_data_streaming("Company"):
    await process_async(company)

Typed Data with Pydantic

Type-safe data operations with IDE autocomplete:

from pydantic import BaseModel
from typing import Optional
 
class Company(BaseModel):
    EntryId: int
    CompanyName: str
    Industry: Optional[str] = None
 
# Read as typed models
companies = dc.typed_read_data(Company, object_id="Company")
 
for c in companies:
    print(c.CompanyName)  # Full IDE autocomplete!

Delta Synchronization

Efficient incremental data sync:

from datetime import datetime, timedelta
 
# Get what changed since last sync
last_sync = datetime.now() - timedelta(hours=1)
result = dc.sync_delta("Company", last_sync)
 
print(f"Modified: {len(result.modified_ids)}")
print(f"Deleted: {len(result.deleted_ids)}")
 
# Process changes
for row in result.modified_data:
    your_db.upsert(row)
 
for entry_id in result.deleted_ids:
    your_db.delete(entry_id)

Reference Display Options

Control how reference fields are formatted:

from dealcloud_sdk import ReferenceFormat, ReferenceCache
 
# Create a cache for efficient lookups
cache = ReferenceCache(max_entries=10000)
 
# Get just the display names
contacts = dc.read_data(
    "Contact",
    output="pandas",
    reference_format=ReferenceFormat.NAME,
    reference_cache=cache
)
# contacts["Company"] = "Acme Corp" instead of full object

Bulk File Export

Export images and documents in bulk:

# Export all company logos
result = dc.export_images(
    "./backup/logos",
    object_id="Company",
    field_ids=["Logo"]
)
print(f"Exported {result.exported} images")
 
# Export all documents
result = dc.export_documents("./backup/documents")

Compatibility Matrix

FeatureLegacy SDKdealcloud-sdk 1.xNotes
Python 3.8-3.9Not supported
Python 3.13+Required
requests libraryReplaced by httpx (via intapp-rest-client)
httpx / OAuth2 stackSee Authentication
fsspec (paths & URIs)Core; config files, file utils, storage
Cloud URIs (s3://, abfs://, gs://)Extras [s3], [azure], [gcs], or [all]
polars output✅ (optional)pip install dealcloud-sdk[polars]
Pandas output✅ (default)✅ (explicit)output= now required
Streaming readsNew feature
Typed dataNew feature
Delta syncNew feature
Async operationsLimitedFullAll operations async-ready
OpenTelemetryVia opentelemetry-instrumentation-httpx

Getting Help