Skip to main content

engini

Agent-first Python SDK for the Engini Public API — discover tools, execute them against your connected apps, and wrap them as LLM tool definitions.

pip install engini

Quickstart

from engini import Engini

client = Engini(api_key="eng_…")  # or set ENGINI_API_KEY

# Discover canonical tool schemas
tools = client.tools.get(applications=["salesforce"], search="accounts", limit=5)

# Execute a tool against a connection
conn_id = next(c.connection_id for c in client.connections.list(application="salesforce"))
result = client.tools.execute(
    "salesforce_getrecords", {"sobject": "Account"}, connection_id=conn_id
)
print(result.output)

JWT auth is the fallback: Engini(token="<jwt>", company_token="<id>"), or set ENGINI_API_TOKEN / ENGINI_COMPANY_TOKEN. With an API key the company is bound to the key, so no company token is needed. Point at another host with Engini(..., base_url=…).

Every request carries a User-Agent identifying this SDK and its runtime (e.g. engini-sdk-python/0.13.0 python/3.11.6 darwin). If you're embedding the SDK inside your own product, prepend your own token with user_agent_prefix:

client = Engini(api_key="eng_…", user_agent_prefix="my-product/1.4.0")
# -> "my-product/1.4.0 engini-sdk-python/0.13.0 python/3.11.6 darwin"

user_agent_prefix only prepends a token — it can't override or remove the SDK's own identity.

Use with an LLM

Provider adapters wrap canonical schemas into vendor tool definitions client-side, with no vendor SDK dependency. OpenAI is the default; Anthropic is also available.

# Bind applications → connections once, then drive a tool-calling loop
toolset = client.toolset(tools=["salesforce_getrecords"], connections={"salesforce": "Prod"})

openai_tools = client.provider.wrap_tools(toolset.tools())  # plain OpenAI tool-JSON dicts
# … send openai_tools to the model, get a response …
results = toolset.handle_tool_calls(llm_response)  # runs the calls, returns results

client.mcp inspects and maintains the account's MCP servers — the endpoints Engini exposes over the Model Context Protocol:

servers = client.mcp.list()  # includes deactivated ones
client.mcp.deactivate(servers[0].mcp_server_token)  # reversible; sends only is_active
tools = client.mcp.available_tools(token, connection_id=2139)  # candidates for tool_slugs

update() replaces connections/workflows rather than merging them, and every connection entry needs an explicit connection_id (MCP servers are account-wide, so there is no per-user default). There is no create/delete: those stay in the engini.io UI.

client.opa provisions, inspects, configures and credentials on-premise agents — the Engini component a customer installs behind their own firewall to reach SQL Server, Oracle, Priority ERP and file shares:

# Provision one and hand the token to the installer
agent = client.opa.create("Warehouse SQL", pull_period_seconds=30)
print(agent.token)  # a credential - store it, do not log it

# Later: is it healthy?
a = client.opa.get(agent.agent_id)
print(a.status, a.version, a.last_seen_at)

# Change its log level; the agent picks it up on its next poll
r = client.opa.update(agent.agent_id, log_level="Debug")
if not r.applied_to_agent:
    print("stored; the agent is not Online yet")

An agent polls Engini, so anything that "talks to" it waits for its next poll. update() merges — an omitted keyword leaves that field alone, unlike connections.update(), which replaces its whole field map. Settings you omit take the server's defaults, and the minimums come from the connector's own declared metadata rather than the client. Agents are not connections: client.connections never returns them.

client.toolset(...) builds a local toolset (no I/O until used) or loads a server one via toolset_id=….

Files

Tools whose input_schema marks a field "format": "engini/file" accept files. Wrap a file with engini.File and pass it as the field value — the SDK base64-encodes it into the {base64_content, mime_type, filename} wire shape. A field can take a single file or a list, per the tool's schema.

from engini import Engini, File

client = Engini(api_key="eng_…")
client.tools.execute(
    "doc_summarize",
    {
        "document": File.from_path("report.pdf"),  # single file
        "attachments": [File.from_path("a.png"), File.from_path("b.png")],  # list of files
    },
    connection_id=conn_id,
)

File.from_path infers the filename and mime type; File.from_bytes(data, filename=…, mime_type=…) and File.from_base64(…) cover in-memory content.

In the LLM loop an agent can't produce base64, so file fields are presented to it as string fields. Register the files you'll allow and let the model reference one by key:

results = toolset.handle_tool_calls(llm_response, files={"report": File.from_path("report.pdf")})

What this adds over the raw REST client

Built on the autogenerated engini-client, the SDK adds what the generated client deliberately lacks: typed errors (the EnginiError family), retry/backoff, auto-pagination, pluggable auth (ApiKeyAuth / BearerAuth), Provider adapters for OpenAI/Anthropic, and the ergonomic Toolset object.

Command-line interface

The engini CLI is npm-only now: npm install -g @engini/cli. See https://www.npmjs.com/package/@engini/cli (or ts/packages/cli/README.md in the source repo) for install, commands, and the machine-readable output/exit-code contract. This package (engini, PyPI) is the Python SDK only.

Source & docs: https://github.com/engini/engini-sdk

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

engini-0.19.0.tar.gz (51.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

engini-0.19.0-py3-none-any.whl (40.7 kB view details)

Uploaded Python 3

File details

Details for the file engini-0.19.0.tar.gz.

File metadata

  • Download URL: engini-0.19.0.tar.gz
  • Upload date:
  • Size: 51.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for engini-0.19.0.tar.gz
Algorithm Hash digest
SHA256 29786e057a3ce6a64262adecb073df968d35bae3e5c1d22bb5aa5c0a212ffd6f
MD5 75600b2ee4f3d6370d8089762811c129
BLAKE2b-256 e5bd78be511e1919c5917e338eb8a0c14caa7385bbd86d40226344147b8fe85a

See more details on using hashes here.

Provenance

The following attestation bundles were made for engini-0.19.0.tar.gz:

Publisher: release-python.yml on engini/engini-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file engini-0.19.0-py3-none-any.whl.

File metadata

  • Download URL: engini-0.19.0-py3-none-any.whl
  • Upload date:
  • Size: 40.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for engini-0.19.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3da78da8c6c60c15e2a328873c952f26507d29e2bd74a18e2916da4f29039461
MD5 6560c5271822c52113dc3b794ddb6f5e
BLAKE2b-256 4578b1908d42b8163ac466e4030a76441fba06b2bdd5a3c64cf25283743b3520

See more details on using hashes here.

Provenance

The following attestation bundles were made for engini-0.19.0-py3-none-any.whl:

Publisher: release-python.yml on engini/engini-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.19.0 This release

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.14.0

2 files

0.11.1

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.7.1

2 files

0.6.0

2 files

0.5.1

2 files

0.5.0

2 files

0.3.0

2 files

0.2.0

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page