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
| Change | Legacy SDK | dealcloud-sdk 1.x | Action Required |
|---|---|---|---|
| HTTP Client | requests | httpx (prefer intapp-rest-client) | Prefer RestClient + OAuth2 for custom calls; raw httpx is possible |
read_data() output | Defaults to "pandas" | Required parameter | Add explicit output= |
| Configuration | Simple 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.DataFrameIf 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:
| Feature | requests | intapp-rest-client | httpx |
|---|---|---|---|
| Async support | No | Yes (aget, apost, …) | Yes (native) |
| HTTP/2 | No | Yes (via httpx) | Yes |
JSON body on get-style helpers | N/A | get() / post() return parsed JSON | .json() on Response |
| OAuth2 client credentials | Manual | OAuth2Config | Manual |
| Retries / backoff | Manual | RetryConfig (optional) | Manual |
| Same stack as dealcloud-sdk 1.x | No | Yes | Under the hood only |
| Session / client | Session() | RestClient (context manager supported) | Client() |
| Timeout | Per-request | Client default + per call | Default 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.
| Piece | Role | Install |
|---|---|---|
| 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 backends | Optional 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 & auth | REST calls go through intapp-rest-client on httpx (not requests). Authentication is OAuth2 client credentials, aligned with the .NET SDK and documented in Authentication. | Core — intapp-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 objectBulk 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
| Feature | Legacy SDK | dealcloud-sdk 1.x | Notes |
|---|---|---|---|
| Python 3.8-3.9 | ✅ | ❌ | Not supported |
| Python 3.13+ | ❌ | ✅ | Required |
requests library | ✅ | ❌ | Replaced by httpx (via intapp-rest-client) |
httpx / OAuth2 stack | ❌ | ✅ | See 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 reads | ❌ | ✅ | New feature |
| Typed data | ❌ | ✅ | New feature |
| Delta sync | ❌ | ✅ | New feature |
| Async operations | Limited | Full | All operations async-ready |
| OpenTelemetry | ❌ | ✅ | Via opentelemetry-instrumentation-httpx |
Getting Help
- Check the full documentation for detailed API reference
- Review Configuration files for DealCloudConfig and file-based setup; Advanced configuration for timeouts, retries, and concurrency
- Contact your Intapp representative for migration support