Metadata-Version: 2.4
Name: facilio-connections-sdk
Version: 0.1.0
Summary: Python client for Facilio Connections cloud-server /api/v1 Tier 1 API
Author: Facilio
License-Expression: LicenseRef-Facilio-Proprietary
Keywords: facilio,connections,api,http,client,httpx
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx<0.29,>=0.27
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# Facilio Connections SDK (Python)

Integrator client for Connections **`/api/v1`** using **httpx**. Concepts: [../README.md](../README.md). HTTP paths, JSON shapes, headers: [../docs/api-reference.md](../docs/api-reference.md).

**Requirements:** Python **3.10+**. **Import package:** `facilio_connections_sdk`.

---

## Installation

**PyPI** (when published):

```bash
pip install facilio-connections-sdk
```

---

## Complete walkthrough (code)

Linear script-style example. With the default internal **httpx** client, call **`client.close()`** when finished (or pass your own **`http_client`**).

```python
from facilio_connections_sdk import ConnectionsClient

client = ConnectionsClient("https://your-host", "your-service-token")

'''
Using Cookies instead of service token

 cfg = ConnectionsClientConfig(
    base_url="https://connections.facilio.com",
    service_token=None,
    csrf_token="",
    extra_headers={
        "Cookie": "fc.idToken.connections=xxxxxxxx; JSESSIONID=xxxxxx",
    },
    timeout_seconds=120.0,
)

client = ConnectionsClient.from_config(cfg) '''


# list connections
print(client.list_connections())


# get connection name
print(client.get_connection("servicenow-connection").get("connection").get("display_name"))

# get actions for the connection
print(client.list_actions("servicenow-connection"))

# get action inputs for the action
print(client.list_action_inputs("servicenow-connection", "add-comment-in-servicenow-task"))

result = client.connection("servicenow-connection").actions().execute("add-comment-in-servicenow-task", {
    "input": {
        "parentId": "1234567890",
        "body": "This is a test comment",
    }
})

print(result)
if result.get("job_id"):
    client.get_job_result(str(result["job_id"]))

# Same calls via fluent: client.connection("crm-prod").actions().execute("fetch-deal", {...})

client.close()
```

Request/response JSON uses **`snake_case`**. Failures raise **`ConnectionsApiError`** (`status_code`, `body`).

---

## Method reference

### Client construction

| Method | Purpose |
|--------|---------|
| `ConnectionsClient(base_url, service_token="")` | `base_url` = origin only. Empty token → no **`X-Service-Token`**. |
| `ConnectionsClient.from_config(ConnectionsClientConfig, http_client=…)` | Cookies, org, CSRF, timeouts — see [Local development](#local-development-without-a-service-token-cookies--csrf). |

### Fluent entry points

| Method | Maps to |
|--------|---------|
| `client.jobs().result(job_id)` | `GET /jobs/{id}` |
| `client.connections().list(relay_id=None, *, authorized=None)` | `GET /connections` |
| `client.actions_catalog().list()` | `GET /actions` |
| `client.connection(slug)` | Scope for one connection |

### Jobs

| Method | Purpose |
|--------|---------|
| `get_job_result(job_id)` | Poll after **`job_id`** from async execute. |

### Connections (flat)

| Method | Purpose |
|--------|---------|
| `list_connections(relay_id=None, *, authorized=None)` | Query **`relay_id`**, **`authorized=true`**. |
| `get_connection(slug)` | `GET /connections/{slug}`. |
| `authorize_connection(slug)` | `POST …/authorize`. |
| `unauthorize_connection(slug)` | `POST …/unauthorize`. |
| `toggle_connection_active(slug, active)` | `POST …/toggle-active`. |

### Connection scope (`client.connection(slug)`)

| Method | Purpose |
|--------|---------|
| `get()` | Connection metadata. |
| `authorize()` / `unauthorize()` | OAuth lifecycle. |
| `set_active(active)` | Enable/disable connection. |
| `http()` | **`_HttpExecutor`**. |
| `file()` | **`_FileExecutor`**. |
| `sql()` | **`_SqlExecutor`**. |
| `actions()` | Saved actions on this connection. |

### Actions — read

| Method | Purpose |
|--------|---------|
| `list_all_actions()` | Org-wide **`GET /actions`**. |
| `list_actions(connection_slug)` | **`GET …/connections/{slug}/actions`**. |
| `get_action(connection_slug, action_slug)` | Single action definition. |
| `list_action_inputs(connection_slug, action_slug)` | Resolved fields for **`input`**. |

Fluent: **`connection(slug).actions().list()`**, **`.get(action_slug)`**, **`.list_inputs(action_slug)`**.

### Saved action execute

| Method | Purpose |
|--------|---------|
| `execute_action(connection_slug, action_slug, body=None, *, async_=False, timeout_ms=None)` | **`body`** → JSON **`input`** / **`options`**. |

Fluent: **`connection(slug).actions().execute(action_slug, body, *, async_=False, timeout_ms=None)`**.

### Typed HTTP (flat)

**`execute_http_get|post|patch|put|delete(connection_slug, parameters=None, *, async_=False, timeout_ms=None)`** — **`parameters`**: **`path`**, **`query`**, **`headers`**, **`body`**.

Fluent: **`connection(slug).http().get|post|patch|put|delete(parameters, *, async_=False, timeout_ms=None)`**.

### Filesystem (flat)

**`execute_file_read_file`**, **`execute_file_upload_file`**, **`execute_file_append_file`**, **`execute_file_list_files`**, **`execute_file_rename_file`**, **`execute_file_move_file`**, **`execute_file_delete_file`** — same **`async_`**, **`timeout_ms`** pattern.

Fluent: **`connection(slug).file().read|upload|append|list_files|rename|move|delete(...)`**.

### SQL (flat)

**`execute_sql_query`**, **`execute_sql_select`**, **`execute_sql_insert`**, **`execute_sql_update`**, **`execute_sql_delete`**, **`execute_sql_execute`** — body keys per [api-reference.md](../docs/api-reference.md).

Fluent: **`connection(slug).sql().query|select|insert|update|delete|execute(...)`**.

---

## Local development without a service token (cookies + CSRF)

```python
from facilio_connections_sdk import ConnectionsClient, ConnectionsClientConfig

cfg = ConnectionsClientConfig(
    base_url="http://localhost:8081",
    service_token=None,
    org_domain="your-org-domain",
    csrf_token="paste-fc-csrfToken-cookie-value",
    extra_headers={
        "Cookie": "JSESSIONID=...; fc.idToken.connections=...; fc.csrfToken=...; fc.currentOrg=...",
    },
    timeout_seconds=120.0,
)

client = ConnectionsClient.from_config(cfg)
```


