Skip to main content

Python bindings for Enki's Rust agent runtime.

Project description

enki-py

Python bindings for Enki's Rust agent runtime.

enki-py exposes two layers:

  • A high-level Python API built around Agent and MultiAgentRuntime
  • The lower-level native bindings generated from the Rust runtime, including workflow APIs

The package is designed for Python-first usage without giving up the native runtime features that already exist in the Rust core.

Requirements

  • Python >=3.8
  • A supported model string such as openai::gpt-4o, anthropic::claude-sonnet-4-6, or ollama::qwen3.5:latest

Install

Published package:

pip install enki-py

With the built-in LiteLLM adapter:

pip install "enki-py[litellm]"

Using uv:

uv add enki-py
uv add "enki-py[litellm]"

What It Exports

High-level Python API

The main Python-facing exports are:

  • Agent
  • AgentLoopRequest
  • AgentLoopResult
  • AgentRunResult
  • ExecutionStep
  • Tool
  • RunContext
  • MemoryBackend
  • MemoryModule
  • MemoryEntry
  • MemoryKind
  • MultiAgentRuntime
  • MultiAgentMember
  • AgentCard
  • LiteLlmProvider
  • LlmProviderBackend

Low-level native bindings

The generated module is also re-exported, so lower-level runtime types remain available when you want to work closer to the Rust layer. Commonly used native types include:

  • EnkiAgent
  • EnkiWorkflowRuntime
  • EnkiTool and EnkiToolSpec
  • EnkiMemoryEntry
  • EnkiMemoryModule

Agent API

Agent is the main Python entrypoint. Its constructor supports:

  • model: required provider and model string
  • deps_type: optional dependency type used with RunContext
  • instructions: system guidance / prompt preamble
  • agentic_loop: optional prompt-level loop instructions
  • agent_loop_handler: optional Python callback that overrides the runtime loop
  • name: display name for the agent
  • max_iterations: iteration cap for the runtime loop
  • workspace_home: optional workspace root for persisted runtime state
  • tools: optional list of pre-registered Tool objects
  • memories: optional list of MemoryModule objects
  • llm: optional Python-side LLM backend or callback

Main methods:

  • run(...): async single-agent execution
  • run_sync(...): sync wrapper around run(...)
  • set_agent_loop_handler(...)
  • clear_agent_loop_handler(...)
  • tool_plain(...): decorator for plain Python tools
  • tool(...): decorator for tools that receive RunContext
  • register_tool(...)
  • register_memory(...)
  • as_workflow_agent(...): converts the wrapper into a workflow-configured low-level agent

The result of run(...) or run_sync(...) is AgentRunResult, which contains:

  • output: final model response text
  • steps: ExecutionStep entries describing runtime progress

Both run(...) and run_sync(...) accept:

  • session_id: optional explicit session id
  • deps: optional dependency object passed into RunContext
  • on_step: optional callback for streaming step visibility

Basic Agent

Synchronous example:

import uuid

from enki_py import Agent


agent = Agent(
    "anthropic::claude-sonnet-4-6",
    name="Simple Agent",
    instructions="Answer clearly and keep responses short.",
)

result = agent.run_sync(
    "Explain what this Enki Python example demonstrates.",
    session_id=f"simple-agent-{uuid.uuid4()}",
)

print(result.output)
for step in result.steps:
    print(f"{step.index}. [{step.phase}] {step.kind}: {step.detail}")

Async version:

import asyncio

from enki_py import Agent


async def main() -> None:
    agent = Agent(
        "ollama::qwen3.5:latest",
        name="Async Agent",
        instructions="Answer clearly and keep responses short.",
    )

    result = await agent.run("What does enki-py provide?")
    print(result.output)


asyncio.run(main())

Tools

The high-level wrapper lets you register Python functions directly as tools.

@agent.tool_plain

Use this when the tool only needs its declared arguments:

from enki_py import Agent


agent = Agent(
    "ollama::qwen3.5:latest",
    name="Researcher",
    instructions="Use tools when they help answer factual questions.",
)


@agent.tool_plain
def lookup_example_topics(topic: str) -> str:
    """Return a canned fact for an example topic."""
    facts = {
        "memory": "Memory lets the agent persist and recall useful session context.",
        "tools": "Tools let the agent call Python functions to fetch or compute structured results.",
        "multi-agent": "Multi-agent runtimes let a coordinator route work to specialized agents.",
    }
    return facts.get(topic.lower(), f"No prepared fact exists for '{topic}'.")

@agent.tool

Use this when the tool should receive a RunContext with typed dependencies:

from dataclasses import dataclass

from enki_py import Agent, RunContext


@dataclass
class AppDeps:
    project_name: str


agent = Agent(
    "ollama::qwen3.5:latest",
    deps_type=AppDeps,
    name="Context Agent",
    instructions="Use the provided context when it helps answer.",
)


@agent.tool
def project_name(ctx: RunContext[AppDeps]) -> str:
    """Return the active project name from runtime dependencies."""
    return ctx.deps.project_name

Tool schemas are inferred from Python signatures and type annotations. Required parameters come from arguments without defaults, and optional parameters come from arguments with defaults.

If you need lower-level control, you can also build Tool(...) values directly and register them with register_tool(...).

Memory

enki-py supports Python-defined memory modules through MemoryBackend and MemoryModule.

Implement MemoryBackend when you want custom record and recall behavior:

from dataclasses import dataclass, field
from time import time_ns

from enki_py import MemoryBackend, MemoryEntry, MemoryKind


@dataclass
class SessionMemory(MemoryBackend):
    name: str = "session_memory"
    _entries: dict[str, list[MemoryEntry]] = field(default_factory=dict)

    def record(self, session_id: str, user_msg: str, assistant_msg: str) -> None:
        entries = self._entries.setdefault(session_id, [])
        entries.append(
            MemoryEntry(
                key=f"{session_id}-{len(entries)}",
                content=f"User: {user_msg}\nAssistant: {assistant_msg}",
                kind=MemoryKind.RECENT_MESSAGE,
                relevance=1.0,
                timestamp_ns=time_ns(),
            )
        )

    def recall(self, session_id: str, query: str, max_entries: int) -> list[MemoryEntry]:
        entries = self._entries.get(session_id, [])
        return entries[-max_entries:]

    def flush(self, session_id: str) -> None:
        return None

Register it like this:

memory = SessionMemory()
agent = Agent(
    "ollama::qwen3.5:latest",
    memories=[memory.as_memory_module()],
)

Supported memory kinds:

  • MemoryKind.RECENT_MESSAGE
  • MemoryKind.SUMMARY
  • MemoryKind.ENTITY
  • MemoryKind.PREFERENCE

Memory callbacks may be synchronous or async def coroutines.

Multi-Agent Runtime

MultiAgentRuntime wires multiple Agent instances together and installs the coordination tools used for agent discovery and delegation.

Available methods:

  • registry()
  • discover(...)
  • process(...)
  • process_sync(...)

The runtime automatically installs two reserved tools on member agents:

  • discover_agents
  • delegate_task

Minimal example:

from enki_py import Agent, MultiAgentMember, MultiAgentRuntime


coordinator = Agent(
    "ollama::qwen3.5:latest",
    name="Coordinator",
    instructions=(
        "Use discover_agents first. "
        "Delegate research work to the researcher with delegate_task."
    ),
)

researcher = Agent(
    "ollama::qwen3.5:latest",
    name="Researcher",
    instructions="Answer delegated questions clearly and briefly.",
)

runtime = MultiAgentRuntime(
    [
        MultiAgentMember(
            agent_id="coordinator",
            agent=coordinator,
            capabilities=["planning", "orchestration"],
        ),
        MultiAgentMember(
            agent_id="researcher",
            agent=researcher,
            capabilities=["research"],
        ),
    ]
)

result = runtime.process_sync(
    "coordinator",
    "Use discover_agents first, then delegate to the researcher.",
    session_id="simple-multi-agent-example",
)

print(result.output)

Repository examples:

Workflow Runtime

For workflow execution, the lower-level EnkiWorkflowRuntime is the main entrypoint. A common pattern is:

  1. Create Python Agent wrappers
  2. Convert them with as_workflow_agent(agent_id=..., capabilities=[...])
  3. Provide JSON task definitions and JSON workflow definitions
  4. Start and inspect runs through the workflow runtime

Methods used in the checked-in Python examples include:

  • list_workflows_json()
  • list_runs_json()
  • inspect_json(run_id)
  • start_json(payload_json)
  • resume_json(run_id)
  • submit_intervention_json(run_id, intervention_id, response)

Workflow example:

import asyncio
import json
from pathlib import Path

import enki_py


WORKSPACE_HOME = Path("./example/enki-py/.enki-workflow")
MODEL = "ollama::qwen3.5:latest"


async def main() -> None:
    researcher = enki_py.Agent(
        MODEL,
        name="Researcher",
        instructions="Return short factual notes.",
        workspace_home=str(WORKSPACE_HOME),
    )
    writer = enki_py.Agent(
        MODEL,
        name="Writer",
        instructions="Turn notes into a concise summary.",
        workspace_home=str(WORKSPACE_HOME),
    )

    runtime = enki_py.EnkiWorkflowRuntime(
        agents=[
            researcher.as_workflow_agent(agent_id="researcher", capabilities=["research"]),
            writer.as_workflow_agent(agent_id="writer", capabilities=["writing"]),
        ],
        tasks_json=[],
        workflows_json=[],
        workspace_home=str(WORKSPACE_HOME),
    )

    print(json.loads(await runtime.list_workflows_json()))


asyncio.run(main())

For a complete runnable version with task and edge definitions, see example/enki-py/agent_workflow.py.

Human Intervention

Workflow runs can pause for human input and then resume from persisted state.

Two built-in patterns are demonstrated in the repository examples:

  • human_gate workflow nodes that pause and wait for a human response
  • task nodes with failure_policy: "pause_for_intervention" that convert a failure into a human resolution step

The runtime interaction loop is:

  1. start_json(...) starts the workflow and may return a paused response
  2. inspect_json(run_id) exposes pending_interventions
  3. submit_intervention_json(run_id, intervention_id, response) resolves the intervention
  4. resume_json(run_id) continues the persisted run

See example/enki-py/human_intervention_workflow.py.

Custom LLM Providers

You can keep model execution on the Python side by passing either:

  • an instance of LlmProviderBackend
  • a compatible Python callable matching the LLM completion shape

The built-in LiteLlmProvider is the default adapter for LiteLLM-backed usage. It is useful when you want:

  • provider-specific configuration in Python
  • LiteLLM-managed credentials or routing
  • a Python extension point without changing Rust code

Notes from the current implementation:

  • LiteLlmProvider raises a clear error if litellm is not installed
  • for Ollama, the default base URL comes from OLLAMA_URL or falls back to http://127.0.0.1:11434
  • ENKI_LITELLM_TIMEOUT controls the request timeout used by the adapter
  • Ollama tool calling is only forwarded when ENKI_OLLAMA_TOOLS is truthy

The repository workflow example also includes a custom OllamaProvider implementation in example/enki-py/agent_workflow.py.

Custom Agentic Loop

There are two different customization levels.

Use agentic_loop= when you want to keep the normal Rust runtime loop but replace the default loop instructions that the model sees:

from enki_py import Agent


agent = Agent(
    "anthropic::claude-sonnet-4-6",
    name="Custom Agentic Loop",
    instructions="Answer clearly and keep responses short.",
    agentic_loop=(
        "1. Understand the user request.\n"
        "2. Decide whether a tool is necessary before acting.\n"
        "3. If you use a tool, summarize what you learned.\n"
        "4. Verify that the answer is complete.\n"
        "5. Return the final response."
    ),
)

Use agent_loop_handler= when you want Python to own the turn-by-turn control flow:

from enki_py import Agent, AgentLoopRequest, AgentLoopResult, ExecutionStep


def custom_loop(request: AgentLoopRequest[None]) -> AgentLoopResult:
    return AgentLoopResult(
        output=f"Handled in Python for: {request.user_message}",
        steps=[
            ExecutionStep(
                index=1,
                phase="Custom",
                kind="final",
                detail="Returned a final answer from Python",
            )
        ],
    )


agent = Agent(
    "ollama::qwen3.5:latest",
    instructions="Answer clearly and keep responses short.",
    agent_loop_handler=custom_loop,
)

The loop request includes:

  • session_id
  • user_message
  • system_prompt
  • messages
  • tools
  • agent_dir
  • workspace_dir
  • sessions_dir
  • model
  • max_iterations
  • deps

You can also update the loop handler after construction with:

  • agent.set_agent_loop_handler(handler)
  • agent.clear_agent_loop_handler()

Repository examples:

Running The Examples

After building the local package with maturin develop, you can run the checked-in examples from the repository root:

python example\enki-py\simple_agent.py
python example\enki-py\simple_agent_ollama.py
python example\enki-py\simple_multi_agent.py
python example\enki-py\multi_agent_with_memory_and_tools.py
python example\enki-py\agent_workflow.py
python example\enki-py\human_intervention_workflow.py
python example\enki-py\custom_agentic_loop.py
python example\enki-py\react_custom_agentic_loop.py
python example\enki-py\compare_agent_loops.py

Model notes:

  • simple_agent.py uses anthropic::claude-sonnet-4-6
  • simple_agent_ollama.py uses ollama::qwen3.5
  • several other checked-in examples use ollama::qwen3.5:latest
  • agent_workflow.py reads ENKI_MODEL and falls back to ollama::qwen3.5:latest

Make sure the selected provider and model are available in your local environment before running the examples.

Development

From crates/bindings/enki-py:

pip install maturin
maturin develop
pytest python/tests

Useful commands:

  • maturin develop: build the Rust extension and install the package in editable form
  • pytest python/tests: run the Python-side tests and examples under test coverage

Project Layout

crates/bindings/enki-py/
|-- Cargo.toml
|-- pyproject.toml
|-- python/enki_py/
|-- python/tests/
`-- src/
  • src/: Rust UniFFI binding implementation
  • python/enki_py/: Python wrapper and generated native module
  • python/tests/: Python-side tests and usage coverage

Related Docs

Project details


Download files

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

Source Distribution

enki_py-0.5.41.tar.gz (422.5 kB view details)

Uploaded Source

Built Distributions

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

enki_py-0.5.41-py3-none-win_arm64.whl (1.5 MB view details)

Uploaded Python 3Windows ARM64

enki_py-0.5.41-py3-none-win_amd64.whl (1.5 MB view details)

Uploaded Python 3Windows x86-64

enki_py-0.5.41-py3-none-win32.whl (1.4 MB view details)

Uploaded Python 3Windows x86

enki_py-0.5.41-py3-none-musllinux_1_2_x86_64.whl (1.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

enki_py-0.5.41-py3-none-musllinux_1_2_i686.whl (1.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ i686

enki_py-0.5.41-py3-none-musllinux_1_2_armv7l.whl (1.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

enki_py-0.5.41-py3-none-musllinux_1_2_aarch64.whl (1.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

enki_py-0.5.41-py3-none-manylinux_2_28_x86_64.whl (1.5 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

enki_py-0.5.41-py3-none-manylinux_2_28_s390x.whl (1.6 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ s390x

enki_py-0.5.41-py3-none-manylinux_2_28_ppc64le.whl (1.5 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ppc64le

enki_py-0.5.41-py3-none-manylinux_2_28_i686.whl (1.5 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ i686

enki_py-0.5.41-py3-none-manylinux_2_28_armv7l.whl (1.4 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARMv7l

enki_py-0.5.41-py3-none-manylinux_2_28_aarch64.whl (1.4 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

enki_py-0.5.41-py3-none-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

enki_py-0.5.41-py3-none-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file enki_py-0.5.41.tar.gz.

File metadata

  • Download URL: enki_py-0.5.41.tar.gz
  • Upload date:
  • Size: 422.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enki_py-0.5.41.tar.gz
Algorithm Hash digest
SHA256 82d580579c018ea3ee1524fa134622966912d32744819bce15ee21f15d3046fd
MD5 dc539511761e18ecc795c8049bdbb4fa
BLAKE2b-256 9246680e8ea74f3e071a3afb1cbe7f338df164c0625a73ff9adc702594e508b3

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-win_arm64.whl.

File metadata

  • Download URL: enki_py-0.5.41-py3-none-win_arm64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enki_py-0.5.41-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 2d08d4cd25d587626c9cac5154a153054fe6a36cbc21a55f2738fdeae69f7746
MD5 30e0626f3986265553f21e5dc609b4a5
BLAKE2b-256 262f50972fe695ee4495e52f330a011713d82854d1d936369d737cf9a80734a2

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-win_amd64.whl.

File metadata

  • Download URL: enki_py-0.5.41-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enki_py-0.5.41-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 998555fb2961f71512f2116b546a1986b468e8f453837fc8a02668dd240151d0
MD5 123cc2e63b2c5fc29ab04ffcf2a9642f
BLAKE2b-256 ca39c98f569ea3ce75bca71c448040f8c8847ee5d5156dd3ec3317a140395567

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-win32.whl.

File metadata

  • Download URL: enki_py-0.5.41-py3-none-win32.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enki_py-0.5.41-py3-none-win32.whl
Algorithm Hash digest
SHA256 9df81a01cf9d715aecfe980f6f5bccb50a3848386971ac1e430a26f0d13f8119
MD5 3b1dc6116a72698f6e12e6fe5efc2a0c
BLAKE2b-256 df930b980204b12b758cf7bee0663e42e3c77b134177ed5184bd9ddfaceaf622

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 73e44e8c441f6a12a9e3f4a722402f11314978ef3e2fa44780ef601cd1f21903
MD5 3529c77c7215e2a3568e3002e46b8fff
BLAKE2b-256 82cddc2e0049f9fac28a7a248e7f318e238198088781e28d2400bbc9e80530a7

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 3be9b132db15a8fe127395b0b047af012ce2cab9804835d59eeda336d2ce091b
MD5 659740fa6261f38daa3d8a3e5a6bf0b3
BLAKE2b-256 554385a81ba0dd654490ee74053c768580307713ab8d13944f4f454787d82d76

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 c3d5df1891957ddaf4c418c779d88d8619879515cc9774dc1bab5d35af41c7c7
MD5 066388ef7f81797fd38053568b941b22
BLAKE2b-256 66aecec23ea42161c5329c2c987ecc046774cc682fbedf99e22b4d5105bbd8b6

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b078e9721a5b00f85becd9a822ce70d569f8f69d7de64744b6ea1b08b01b6ef8
MD5 9b231ad3ed1e0c365160922f7aca53e9
BLAKE2b-256 ee2e37ba44580d4e720730fe65bdd69ef061cc8622192a827736a295e4d11b5f

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a57a48a05152932d4145c7ced37ebd1549dd3117adf3071b4e970a8ae742cb49
MD5 70447fc5e7adcb4c8d674c60bb40a675
BLAKE2b-256 1bacefb7ac55a59c8c9dcd896bbe8744a6d128c1965550d8a22819452d72ad55

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 efdbc3435d476497c933a4a2e48d06f482fd87dfeef8e3d6d4965df57cfd1763
MD5 432c396f1470490971622b6e0adff1c7
BLAKE2b-256 281857b39c7fddc03a64a8e78dc20cb7c09d5d5330d175c835363f1ad7b37abf

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 291f549d24cfa4328599b9e9020ba52c5ef466f06ae56cd47b6ab9aa515638a2
MD5 b5ba46e03095c9849cd51325dd16f4d6
BLAKE2b-256 756b874c1eca62812d115195a41db241ae67431a0d429dc4e0d1c1cebceeb72a

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_i686.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_i686.whl
Algorithm Hash digest
SHA256 f9e21260c0a7c15b488a2f7d7b744aec30d61a657b8b970517892858003f050e
MD5 07fd7e0817761a6defb6ddfe66869597
BLAKE2b-256 13a4a53c9f8a7b68b16dfd6a33a20b6e99be0c01a5f651aa2990de4005fe2ef0

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 345843be244863832ef9285b445d42ff44621b99aec54e06613009975a0b2a3d
MD5 68985186f67034c3eff9e3243e774df9
BLAKE2b-256 b9222d72097fdc18abdbdd78fef07f7fef62b699838d3fc994128c5edeafbcfe

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1dbc39e4f8b97af573b5f178e2e808549d8f86a2a142543aa666fc943f55dcd5
MD5 fa67c385b18aed19474cb01ea6528cd8
BLAKE2b-256 1e999e0fbc9f50dd396682f7e604574fe1680cebed990e39db86cff03e5f353e

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 33c2e87be6df317ef468ff5978dde1e728b50023ee247f558dc8bdfcaef42ab2
MD5 4e981cfed705625615cfad06e755f67a
BLAKE2b-256 5f6f7df548efcd634f959715e07727807b3d525885d96174c1095935b4a185dd

See more details on using hashes here.

File details

Details for the file enki_py-0.5.41-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for enki_py-0.5.41-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 eeca3844423e16b1028666416fd2eea0f40fe22a63bf3986a006e5a4ca2b528d
MD5 88241f3dc0df1c32bc84c651788b92d6
BLAKE2b-256 87d99538381b8faa5dad858664fae134da732120ab6dff2277e3f0046c187fc8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page