# Euno SDK

The Euno SDK (v0.5) is a Python library and command-line tool that provides programmatic access to Euno functionality. It allows you to interact with your Euno instance from scripts, applications, and the command line.

### Installation

Install the Euno SDK using pip:

```bash
pip install euno
```

**Requirements:** Python 3.12+. The SDK depends on `click`, `pydantic`, and `requests`, which are installed automatically.

### Quick Start

#### 1. Initialize the SDK

After installation, initialize the SDK with your Euno API credentials:

```bash
euno init
```

This command will prompt you for:

* Your Euno API token
* Your account ID
* A **persona** to use for account-scoped requests (selected from a list of your available personas)

The credentials and selected persona will be stored securely for future use.

> **Tip:** To obtain an API token, go to Euno → click the user card at the bottom of the sidebar → **Personal API Keys**.

> **Tip:** To use the SDK without going through the interactive initialization, use environment variables. See the [Configuration](https://claude.ai/chat/791caa91-ed1f-431e-af27-d17f9190a6e8#configuration) section below.

#### 2. Explore Available Commands

Use the `--help` flag to discover all available capabilities:

```bash
euno --help
```

This will show you all available commands and their descriptions.

***

### CLI Reference

All commands support a `--help` flag for inline documentation.

#### Authentication Commands

**`euno init`**

Initialize the SDK with your API token, account ID, and persona.

```bash
euno init
```

During initialization you will be prompted to select a persona from those available to your user in the configured account. The selected persona is stored and sent as the `X-Euno-Persona` header on all subsequent account-scoped requests.

**`euno status`**

Display the current configuration and verify that the stored token is valid.

```bash
euno status
```

Output includes backend URL, masked token, account ID, active persona, authenticated user email, and account permission check.

**`euno logout`**

Clear the stored configuration (token and persona).

```bash
euno logout
```

After logging out, you must run `euno init` again before using other commands.

***

#### Resources Commands

**`euno resources list`**

List resources from the Euno data model.

```bash
euno resources list [OPTIONS]
```

| Option                 | Alias | Default         | Description                                      |
| ---------------------- | ----- | --------------- | ------------------------------------------------ |
| `--eql TEXT`           | `-e`  |                 | EQL filter expression                            |
| `--properties TEXT`    | `-p`  | `uri,type,name` | Comma-separated list of properties to return     |
| `--page INT`           |       | `1`             | Page number                                      |
| `--page-size INT`      |       | `50`            | Number of resources per page                     |
| `--sorting TEXT`       | `-s`  |                 | Comma-separated sorting specification            |
| `--relationships TEXT` | `-r`  |                 | Comma-separated list of relationships to include |
| `--format TEXT`        | `-f`  | `json`          | Output format: `json`, `csv`, or `pretty`        |

**Examples:**

```bash
# List resources with default settings
euno resources list

# Filter using EQL with selected properties
euno resources list --eql "has child(true, 1)" --properties "uri,name,type" --format pretty

# Include relationships, paginate results
euno resources list --relationships "parent,child" --page-size 20

# Export to CSV
euno resources list --properties "uri,type,name,description" --format csv > resources.csv
```

***

#### Metadata Tags Commands

**`euno metadata-tags list`**

List all metadata tags (custom properties) defined for the configured account.

```bash
euno metadata-tags list [OPTIONS]
```

| Option          | Alias | Default | Description                               |
| --------------- | ----- | ------- | ----------------------------------------- |
| `--format TEXT` | `-f`  | `json`  | Output format: `json`, `csv`, or `pretty` |

**Examples:**

```bash
euno metadata-tags list
euno metadata-tags list --format pretty
euno metadata-tags list --format csv
```

**`euno metadata-tags set-value`**

Set values for a metadata tag (custom property) on one or more resources.

```bash
euno metadata-tags set-value CP_ID VALUE_UPDATES [OPTIONS]
```

| Argument / Option | Description                                                              |
| ----------------- | ------------------------------------------------------------------------ |
| `CP_ID`           | The custom property ID (integer)                                         |
| `VALUE_UPDATES`   | JSON array string of `{ "resource_uri": "...", "value": "..." }` objects |
| `--format / -f`   | Output format: `json` or `pretty` (default: `json`)                      |

**Examples:**

```bash
# Set a tag value on a single resource
euno metadata-tags set-value 123 '[{"resource_uri": "table://schema.table", "value": "production"}]'

# Set values on multiple resources, pretty output
euno metadata-tags set-value 456 '[{"resource_uri": "table://schema.orders", "value": "pii"}, {"resource_uri": "table://schema.users", "value": "pii"}]' --format pretty
```

***

#### Glossary Commands

**`euno glossary list`**

List glossary terms with optional filters.

```bash
euno glossary list [OPTIONS]
```

| Option            | Default | Description                                           |
| ----------------- | ------- | ----------------------------------------------------- |
| `--domain-id INT` |         | Filter by domain ID (repeatable for multiple domains) |
| `--owner TEXT`    |         | Filter by owner                                       |
| `--tag TEXT`      |         | Filter by tag — AND semantics (repeatable)            |
| `--search TEXT`   |         | Substring search over name/synonyms                   |
| `--skip INT`      | `0`     | Offset for pagination                                 |
| `--limit INT`     | `100`   | Maximum number of results                             |
| `--format / -f`   | `json`  | Output format: `json` or `pretty`                     |

**Examples:**

```bash
euno glossary list
euno glossary list --domain-id 1 --domain-id 2 --search "revenue"
euno glossary list --owner alice@example.com --format pretty
euno glossary list --tag certified --tag finance --limit 20
```

**`euno glossary get`**

Get a single glossary term by its numeric ID.

```bash
euno glossary get TERM_ID [--format json|pretty]
```

**Example:**

```bash
euno glossary get 42
euno glossary get 42 --format pretty
```

**`euno glossary get-by-name`**

Resolve a glossary term by its exact name. Use `--domain-id` to disambiguate when the same name exists in multiple domains.

```bash
euno glossary get-by-name NAME [--domain-id INT] [--format json|pretty]
```

**Examples:**

```bash
euno glossary get-by-name "Monthly Active Users"
euno glossary get-by-name "Revenue" --domain-id 3
```

**`euno glossary create`**

Create a new glossary term from a JSON payload.

```bash
euno glossary create TERM_JSON [--format json|pretty]
```

**Example:**

```bash
euno glossary create '{"name": "Churn Rate", "domain_id": 1, "description": "Percentage of customers lost in a period.", "owner": "alice@example.com"}'
```

**`euno glossary update`**

Update an existing glossary term using a JSON patch object. Optionally supply a change note (max 500 characters) for the version history.

```bash
euno glossary update TERM_ID PATCH_JSON [--change-note TEXT] [--format json|pretty]
```

**Example:**

```bash
euno glossary update 42 '{"description": "Updated definition."}' --change-note "Clarified wording per data team review"
```

**`euno glossary delete`**

Delete a glossary term by ID.

```bash
euno glossary delete TERM_ID
```

**Example:**

```bash
euno glossary delete 42
```

**`euno glossary versions`**

List the version history for a glossary term.

```bash
euno glossary versions TERM_ID [--format json|pretty]
```

**Example:**

```bash
euno glossary versions 42 --format pretty
```

**`euno glossary export`**

Export glossary terms to a ZIP file. Optionally filter by domain ID(s) or tag(s).

```bash
euno glossary export [--domain-id INT]... [--tag TEXT]... [--output PATH]
```

| Option            | Default               | Description                      |
| ----------------- | --------------------- | -------------------------------- |
| `--domain-id INT` |                       | Domain(s) to export (repeatable) |
| `--tag TEXT`      |                       | Tag filter(s) (repeatable)       |
| `--output / -o`   | `glossary_export.zip` | Output file path                 |

**Examples:**

```bash
euno glossary export
euno glossary export --domain-id 1 --domain-id 2 --output finance_glossary.zip
euno glossary export --tag certified --output certified_terms.zip
```

***

#### Glossary Relationship Commands

**`euno glossary relationships list`**

List all relationships for a glossary term.

```bash
euno glossary relationships list TERM_ID [--format json|pretty]
```

**`euno glossary relationships get`**

Get a single glossary relationship by term ID and relationship ID.

```bash
euno glossary relationships get TERM_ID RELATIONSHIP_ID [--format json|pretty]
```

**`euno glossary relationships create`**

Create a relationship for a glossary term from a JSON payload.

```bash
euno glossary relationships create TERM_ID RELATIONSHIP_JSON [--format json|pretty]
```

**Example:**

```bash
euno glossary relationships create 42 '{"relationship_name": "related_to", "mode": "bidirectional", "target_term_id": 99}'
```

**`euno glossary relationships update`**

Update (patch) a glossary relationship.

```bash
euno glossary relationships update TERM_ID RELATIONSHIP_ID PATCH_JSON [--format json|pretty]
```

**Example:**

```bash
euno glossary relationships update 42 7 '{"mode": "unidirectional"}'
```

**`euno glossary relationships delete`**

Delete a glossary relationship.

```bash
euno glossary relationships delete TERM_ID RELATIONSHIP_ID
```

***

### Python Library Usage

All CLI functionality is also available as a Python API by importing the `euno` package directly.

#### Resources

```python
import euno

# List resources with defaults
resources = euno.list_resources()
print(f"Found {resources['count']} resources")

# Filter with EQL, select properties, paginate
resources = euno.list_resources(
    eql="has child(true, 1)",
    properties="uri,type,name,description",
    page=1,
    page_size=100,
    sorting="name",
    relationships="parent,child",
)

for resource in resources["resources"]:
    print(f"{resource['uri']}: {resource['name']}")
```

**Signature:**

```python
euno.list_resources(
    eql: Optional[str] = None,
    properties: str = "uri,type,name",
    page: int = 1,
    page_size: int = 50,
    sorting: Optional[str] = None,
    relationships: Optional[str] = None,
) -> Dict[str, Any]
```

> **Query parameters for list-valued fields (breaking change, API v2026-05):** Endpoints such as `/data_model/search` expect **repeated** query keys, not comma-separated values in a single key. For example, use `?properties=uri&properties=name&properties=type` instead of `?properties=uri,name,type`. This applies to `properties`, `relationships`, `sorting`, `uris` (impact analysis), `ids` (Luzmo columns), and similar `list[str]` parameters.
>
> * **Python `requests` / httpx:** pass a list: `params={"properties": ["uri", "name", "type"]}`.
> * **curl:** repeat the key: `curl '...?properties=uri&properties=name'`.
> * **Euno CLI/SDK:** comma-separated strings in the Python SDK CLI may still be accepted by the client layer if it expands them before HTTP; when calling the REST API directly, use repeated keys.

> **Large-scale export:** The Data Model screen's CSV download is limited to 10,000 resources per export. For exporting or processing more than 10K resources, use `euno.list_resources()` with pagination.

***

#### Metadata Tags

```python
import euno

# List all metadata tags for the account
tags = euno.list_metadata_tags()
for tag in tags:
    print(f"{tag['id']}: {tag['name']} ({tag['type']})")

# Set a tag value on a resource
result = euno.set_metadata_tag_value(
    cp_id=123,
    value_updates=[
        {"resource_uri": "table://schema.orders", "value": "production"},
        {"resource_uri": "table://schema.users",  "value": "pii"},
    ]
)
```

**Signatures:**

```python
euno.list_metadata_tags() -> List[Dict[str, Any]]

euno.set_metadata_tag_value(
    cp_id: int,
    value_updates: List[Dict[str, Any]],
) -> Dict[str, Any]
```

***

#### Glossary Terms

```python
import euno

# List terms, optionally filtered
terms = euno.list_glossary_terms(
    domain_ids=[1, 2],
    owner="alice@example.com",
    tags=["certified"],
    search="revenue",
    skip=0,
    limit=50,
)

# Get by ID
term = euno.get_glossary_term(42)

# Get by exact name (optionally scoped to a domain)
term = euno.get_glossary_term_by_name("Monthly Active Users", domain_id=1)

# Create
new_term = euno.create_glossary_term({
    "name": "Churn Rate",
    "domain_id": 1,
    "description": "Percentage of customers lost in a period.",
    "owner": "alice@example.com",
})

# Update (patch)
updated = euno.update_glossary_term(
    term_id=42,
    patch={"description": "Updated definition."},
    change_note="Clarified wording per data team review",
)

# Version history
versions = euno.list_glossary_term_versions(42)

# Export as ZIP bytes (save to file)
zip_bytes = euno.export_glossary(domain_ids=[1], tags=["certified"])
with open("glossary_export.zip", "wb") as f:
    f.write(zip_bytes)

# Delete
euno.delete_glossary_term(42)
```

***

#### Glossary Relationships

```python
import euno

# List relationships for a term
rels = euno.list_glossary_term_relationships(term_id=42)

# Get a single relationship
rel = euno.get_glossary_term_relationship(term_id=42, relationship_id=7)

# Create a relationship
new_rel = euno.create_glossary_term_relationship(
    term_id=42,
    relationship={"relationship_name": "related_to", "mode": "bidirectional", "target_term_id": 99},
)

# Update (patch) a relationship
updated_rel = euno.update_glossary_term_relationship(
    term_id=42,
    relationship_id=7,
    patch={"mode": "unidirectional"},
)

# Delete
euno.delete_glossary_term_relationship(term_id=42, relationship_id=7)
```

***

#### Personas

```python
import euno

# List personas available to the current user for the configured account
personas = euno.get_my_personas()
for persona in personas:
    default = " (default)" if persona.get("is_default") else ""
    print(f"{persona['name']}{default}")
```

The active persona (selected during `euno init` or set via `EUNO_PERSONA`) is automatically forwarded as the `X-Euno-Persona` header on all account-scoped API requests.

***

### Configuration

The SDK stores configuration in `~/.euno/config.json`. You can override any stored value using environment variables — environment variables always take precedence.

| Environment Variable | Config Key    | Default                   | Description                                     |
| -------------------- | ------------- | ------------------------- | ----------------------------------------------- |
| `EUNO_TOKEN`         | `token`       |                           | API token                                       |
| `EUNO_ACCOUNT`       | `account_id`  |                           | Account ID                                      |
| `EUNO_PERSONA`       | `persona`     | backend default           | Persona (role name) for account-scoped requests |
| `EUNO_BACKEND`       | `backend_url` | `https://api.app.euno.ai` | Euno backend URL (for self-hosted deployments)  |

**Example — using environment variables instead of `euno init`:**

```bash
export EUNO_TOKEN=your_api_token
export EUNO_ACCOUNT=116
export EUNO_PERSONA=analyst

euno resources list --format pretty
```

***

### Getting Help

For detailed help on any command, use:

```bash
euno <command> --help
```

**Examples:**

```bash
euno resources list --help
euno metadata-tags list --help
euno metadata-tags set-value --help
euno glossary list --help
euno glossary relationships create --help
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.euno.ai/developer-reference/euno-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
