Installation
pip install git+https://github.com/factify-inc/factify-python.git
Requirements: Python 3.8+
Client Setup
import os
from factify import Factify
factify = Factify(bearer_auth=os.environ["FACTIFY_KEY"])
The SDK supports both synchronous and asynchronous usage. Use the client as a context manager for proper resource cleanup:
with Factify(bearer_auth=os.environ["FACTIFY_KEY"]) as factify:
result = factify.documents.list()
Configuration Options
| Option | Type | Default | Description |
|---|
bearer_auth | str | — | API key (required). Format: ffy_... |
server_url | str | https://api.factify.com | API base URL |
timeout_ms | int | None | Request timeout in milliseconds |
retry_config | RetryConfig | SDK default | Retry strategy configuration |
from factify import Factify
from factify.utils import BackoffStrategy, RetryConfig
factify = Factify(
bearer_auth=os.environ["FACTIFY_KEY"],
server_url="https://api.factify.com",
timeout_ms=30000,
retry_config=RetryConfig(
strategy="backoff",
backoff=BackoffStrategy(
initial_interval=1,
max_interval=50,
exponent=1.1,
max_elapsed_time=100,
),
),
)
Available Resources
Documents
factify.documents.list(page_size=, query=, created_by_id=, access_level=, processing_status=, sort=, ownership=, trash_state=)
factify.documents.create(title=, payload={"file_name": ..., "content": ...})
factify.documents.get(document_id=)
factify.documents.update(document_id=, title=, description=)
factify.documents.export(document_id=)
factify.documents.process(document_id=)
factify.documents.trash(document_id=)
factify.documents.untrash(document_id=)
factify.documents.transfer_ownership(document_id=, new_owner_user_id=)
factify.documents.list_duplicates(document_id=)
factify.documents.get_quota()
Versions
factify.versions.list(document_id=)
factify.versions.create(document_id=, payload={"file_name": ..., "content": ...})
factify.versions.get(version_id=)
factify.versions.update(version_id=, description=)
Organizations
factify.organizations.list()
factify.organizations.get(organization_id=)
factify.organizations.update(organization_id=, name=)
factify.organizations.get_public_profile(organization_id=)
Members
factify.organizations.members.list(organization_id=)
factify.organizations.members.add(organization_id=, user_id=, role=)
factify.organizations.members.update(organization_id=, user_id=, role=)
factify.organizations.members.remove(organization_id=, user_id=)
Invites
factify.organizations.invites.list(organization_id=)
factify.organizations.invites.create(organization_id=, email=, role=)
factify.organizations.invites.accept(organization_id=)
factify.organizations.invites.resend(organization_id=, invite_id=)
factify.organizations.invites.revoke(organization_id=, invite_id=)
API Keys
factify.api_keys.list(organization_id=)
factify.api_keys.create(organization_id=, name=)
factify.api_keys.revoke(api_key_id=)
Sharing
factify.sharing.list(document_id=)
factify.sharing.grant(document_id=, recipient_id=, role=)
factify.sharing.update(document_id=, recipient_id=, role=)
factify.sharing.revoke(document_id=, recipient_id=)
factify.sharing.get_general_access(document_id=)
factify.sharing.set_general_access(document_id=, access_level=)
factify.sharing.create_share_link(document_id=)
Policies
factify.policies.list(document_id=)
factify.policies.attach(document_id=, kind=)
factify.policies.detach(document_id=, policy_id=)
Access Requests
factify.access_requests.list(document_id=)
factify.access_requests.create(document_id=)
factify.access_requests.check_status(document_id=)
factify.access_requests.approve(document_id=, access_request_id=)
factify.access_requests.deny(document_id=, access_request_id=)
factify.access_requests.inspect(document_id=)
Usage & Quotas
factify.usage.get()
factify.usage.get_history()
factify.usage.list_key_quotas()
factify.usage.set_key_quota(api_key_id=, monthly_limit=)
factify.usage.delete_key_quota(api_key_id=)
Timelines
factify.timelines.get(document_id=)
Users
factify.users.get_me()
factify.users.preferences.get()
List endpoints support manual pagination via .next():
result = factify.documents.list(page_size=10)
while result is not None:
for doc in result.documents:
print(doc.title)
result = result.next()
File Uploads
Pass a file stream as the content field:
with open("./report.pdf", "rb") as f:
result = factify.documents.create(
title="Q4 Financial Report",
payload={"file_name": "report.pdf", "content": f},
)
Using streams is recommended for large files to avoid loading the entire file into memory.
Error Handling
from factify import Factify
from factify.models import errors
try:
doc = factify.documents.get(document_id="doc_abc123")
except errors.ErrorT as e:
print(e.data.error)
print(e.status_code)
except errors.FactifyError as e:
print(e.message)
print(e.status_code)
| Error Class | When |
|---|
FactifyError | Base class for all HTTP errors |
ErrorT | Structured API error (4xx/5xx with body) |
ConnectionError | Unable to reach server |
RequestTimeoutError | Request timed out |
RequestAbortedError | Request was cancelled |
ResponseValidationError | Response doesn’t match expected schema |
Retries
Override retry behavior per-call:
from factify.utils import BackoffStrategy, RetryConfig
result = factify.documents.list(
page_size=10,
retries=RetryConfig(
strategy="backoff",
backoff=BackoffStrategy(1, 50, 1.1, 100),
),
)
Context Manager
The SDK uses httpx under the hood. Use the context manager to ensure connections are properly closed:
with Factify(bearer_auth=os.environ["FACTIFY_KEY"]) as factify:
docs = factify.documents.list()
# connections are cleaned up on exit
Async Support
import asyncio
from factify import Factify
async def main():
async with Factify(bearer_auth=os.environ["FACTIFY_KEY"]) as factify:
result = await factify.documents.list_async(page_size=10)
print(result)
asyncio.run(main())
Source & Issues