arkiv-sdk


Namearkiv-sdk JSON
Version 1.0.0a5 PyPI version JSON
download
home_pageNone
SummaryPython SDK for Arkiv networks - Web3.py + Entities
upload_time2025-11-06 09:22:10
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords arkiv web3 blockchain ethereum storage entities l2 layer2
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Arkiv SDK

Arkiv is a permissioned storage system for decentralized apps, supporting flexible entities with binary data, attributes, and metadata.

The Arkiv SDK is the official Python library for interacting with Arkiv networks. It offers a type-safe, developer-friendly API for managing entities, querying data, subscribing to events, and offchain verification—ideal for both rapid prototyping and production use.

## Architecture

Principles:
- The SDK is based on a modern and stable client library.
- The SDK should feel like "Library + Entities"

As underlying library we use [Web3.py](https://github.com/ethereum/web3.py) (no good alternatives for Python).


### Arkiv Client

The Arkiv SDK should feel like "web3.py + entities", maintaining the familiar developer experience that Python web3 developers expect.

A `client.arkiv.*` approach is in line with web3.py's module pattern.
It clearly communicates that arkiv is a module extension just like eth, net, etc.

## Hello World

### Synchronous API
Here's a "Hello World!" example showing how to use the Python Arkiv SDK:

```python
from arkiv import Arkiv

# Create Arkiv client with default settings:
# - starting and connecting to a containerized Arkiv node
# - creating a funded default account
client = Arkiv()
print(f"Client: {client}, connected: {client.is_connected()}")
print(f"Account: {client.eth.default_account}")
print(f"Balance: {client.from_wei(client.eth.get_balance(client.eth.default_account), 'ether')} ETH")

# Create entity with data and attributes
entity_key, receipt = client.arkiv.create_entity(
    payload=b"Hello World!",
    content_type="text/plain",
    attributes={"type": "greeting", "version": 1},
    btl=1000
)

# Check and print entity key
exists = client.arkiv.entity_exists(entity_key)
print(f"Created entity: {entity_key} (exists={exists}), creation TX: {receipt.tx_hash}")

# Get individual entity and print its details
entity = client.arkiv.get_entity(entity_key)
print(f"Entity: {entity}")

# Clean up - delete entity
client.arkiv.delete_entity(entity_key)
print("Entity deleted")
```

### Asynchronous API
For async/await support, use `AsyncArkiv`:

```python
import asyncio
from arkiv import AsyncArkiv

async def main():
    # Create async client with default settings
    async with AsyncArkiv() as client:
        # Create entity with data and attributes
        entity_key, tx_hash = await client.arkiv.create_entity(
            payload=b"Hello Async World!",
            attributes={"type": "greeting", "version": 1},
            btl=1000
        )

        # Get entity and check existence
        entity = await client.arkiv.get_entity(entity_key)
        exists = await client.arkiv.entity_exists(entity_key)

        # Clean up - delete entity
        await client.arkiv.delete_entity(entity_key)

asyncio.run(main())
```

### Web3 Standard Support
```python
from web3 import HTTPProvider
provider = HTTPProvider('https://kaolin.hoodi.arkiv.network/rpc')

# Arkiv 'is a' Web3 client
client = Arkiv(provider)
balance = client.eth.get_balance(client.eth.default_account)
tx = client.eth.get_transaction(tx_hash)
```

### Arkiv Module Extension
```python
from arkiv import Arkiv

# Simple local setup
client = Arkiv()

# Or with custom provider and account
from arkiv.account import NamedAccount
account = NamedAccount.from_wallet('Alice', wallet, 's3cret')
client = Arkiv(provider, account=account)

entity_key, tx_hash = client.arkiv.create_entity(
    payload=b"Hello World!",
    attributes={"type": "greeting", "version": 1},
    btl = 1000
)

entity = client.arkiv.get_entity(entity_key)
exists = client.arkiv.exists(entity_key)
```

## Advanced Features

### Provider Builder

The snippet below demonstrates the creation of various nodes to connect to using the `ProviderBuilder`.

```python
from arkiv import Arkiv
from arkiv.account import NamedAccount
from arkiv.provider import ProviderBuilder

# Create account from wallet json
with open ('wallet_bob.json', 'r') as f:
    wallet = f.read()

bob = NamedAccount.from_wallet('Bob', wallet, 's3cret')

# Initialize Arkiv client connected to Kaolin (Akriv testnet)
provider = ProviderBuilder().kaolin().build()
client = Arkiv(provider, account=bob)

# Additional builder examples
provider_container = ProviderBuilder().node().build()
provider_kaolin_ws = ProviderBuilder().kaolin().ws().build()
provider_custom = ProviderBuilder().custom("https://my-rpc.io").build()
```

## Arkiv Topics/Features

### BTL

BTL (Blocks-To-Live) should be replaced with explicit `expires_at_block` values for predictability and composability.

Relative `BTL` depends on execution timing and creates unnecessary complexity:
- An entity created with `btl=100` will have different expiration blocks depending on when the transaction is mined
- Extending entity lifetimes requires fetching the entity, calculating remaining blocks, and adding more—a race-prone pattern
- Creates asymmetry between write operations (which use `btl`) and read operations (which return `expires_at_block`)
- Mempool management can accept any value

Absolute `expires_at_block` is predictable, composable, and matches what you get when reading entities:
- Deterministic regardless of execution timing
- Maps directly to `Entity.expires_at_block` field returned by queries
- Enables clean compositional patterns like `replace(entity, expires_at_block=entity.expires_at_block + 100)`
- Aligns write API with read API, making the SDK more intuitive
- Mempool needs to manage/delete tx with expires at values in the past

It's complicated. Deterministic mempool management vs predictable tx management in mempool.

```python
from dataclasses import replace

# Fetch entity
entity = client.arkiv.get_entity(entity_key)

# Modify payload and extend expiration by 100 blocks
updated_entity = replace(
    entity,
    payload=b"new data",
    expires_at_block=entity.expires_at_block + 100
)

# Update entity
client.arkiv.update_entity(updated_entity)
```

### Query DSL

To make querying entities as simple and natural as possible, rely on a suitable and existing query DSL. Since Arkiv currently uses a SQL database backend and is likely to support SQL databases in the future, the Arkiv query DSL is defined as a **subset of the SQL standard**.

**Rationale:**
- Leverages existing SQL knowledge - no new language to learn
- Well-defined semantics and broad tooling support
- Natural fit for relational data structures
- Enables familiar filtering, joining, and aggregation patterns

**Example:**
```python
# Query entities using SQL-like syntax
results = client.arkiv.query_entities(
    "SELECT entity_key, payload WHERE attributes.type = 'user' AND attributes.age > 18 ORDER BY attributes.name"
)
```

### Sorting

Querying entities should support sorting results by one or more fields.

**Requirements:**
- Sort by attributes (string and numeric)
- Sort by metadata (owner, expires_at_block)
- Support ascending and descending order
- Multi-field sorting with priority

**Example:**
```python
# SQL-style sorting
results = client.arkiv.query(
    "SELECT * FROM entities ORDER BY attributes.priority DESC, attributes.name ASC"
)
```

### Other Features

- **Creation Flags**: Entities should support creation-time flags with meaningful defaults.
Flags can only be set at creation and define entity behavior:
  - **Read-only**: Once created, entity data cannot be changed by anyone (immutable)
  - **Unpermissioned extension**: Entity lifetime can be extended by anyone, not just the owner
  ```python
  # Proposed API
  client.arkiv.create_entity(
      payload=b"data",
      attributes={"type": "public"},
      expires_at_block=future_block,
      flags=EntityFlags.READ_ONLY | EntityFlags.PUBLIC_EXTENSION
  )
  ```

- **ETH Transfers**: Arkiv chains should support ETH (or native token like GLM) transfers for gas fees and value transfer.
  ```python
  # Already supported via Web3.py compatibility
  tx_hash = client.eth.send_transaction({
      'to': recipient_address,
      'value': client.to_wei(1, 'ether'),
      'gas': 21000
  })
  ```

- **Offline Entity Verification**: Provide cryptographic verification of entity data without querying the chain.
  - Currently not supported
  - Proposal: Store entity keys (and block number) in smart contracts and work with an optimistic oracle approach (challenger may take entity key and checks claimed data against the data of an Arkiv archival node)

## Development Guide

### Branches, Versions, Changes

#### Branches

The current stable branch on Git is `main`.
Currently `main` hosts the initial SDK implementation.

The branch `v1-dev` hosts the future V1.0 SDK release.

#### Versions

For version management the [uv](https://github.com/astral-sh/uv) package and project manger is used.
Use the command below to display the current version
```bash
uv version
```

SDK versions are tracked in the following files:
- `pyproject.toml`
- `uv.lock`

### Testing

Pytest is used for unit and integration testing.
```bash
uv run pytest # Run all tests
uv run pytest -k test_create_entity_simple --log-cli-level=info # Specific tests via keyword, print at info log level
```

If an `.env` file is present the unit tests are run against the specifice RPC coordinates and test accounts.
An example wallet file is provided in `.env.testing`
Make sure that the specified test accounts are properly funded before running the tests.

Otherwise, the tests are run against a testcontainer containing an Arkiv RPC Node.
Test accounts are created on the fly and using the CLI inside the local RPC Nonde.

Account wallets for such tests can be created via the command shown below.
The provided example creates the wallet file `wallet_alice.json` using the password provided during the execution of the command.

```bash
uv run python uv run python -m arkiv.account alice
```

### Code Quality

This project uses comprehensive unit testing, linting and type checking to maintain high code quality:

#### Quick Commands

Before any commit run quality checks:
```bash
./scripts/check-all.sh
```

#### Tools Used

- **MyPy**: Static type checker with strict configuration
- **Ruff**: Fast linter and formatter (replaces black, isort, flake8, etc.)
- **Pre-commit**: Automated quality checks on git commits

#### Individual commands
```bash
uv run ruff check . --fix    # Lint and auto-fix
uv run ruff format .         # Format code
uv run mypy src/ tests/      # Type check
uv run pytest tests/ -v     # Run tests
uv run pytest --cov=src   # Run code coverage
uv run pre-commit run --all-files # Manual pre commit checks
```

#### Pre-commit Hooks

Pre-commit hooks run automatically on `git commit` and will:
- Fix linting issues with ruff
- Format code consistently
- Run type checking with mypy
- Check file formatting (trailing whitespace, etc.)

#### MyPy Settings

- `strict = true` - Enable all strict checks
- `no_implicit_reexport = true` - Require explicit re-exports
- `warn_return_any = true` - Warn about returning Any values
- Missing imports are ignored for third-party libraries without type stubs

#### Ruff Configuration

- Use 88 character line length (Black-compatible)
- Target Python 3.12+ features
- Enable comprehensive rule sets (pycodestyle, pyflakes, isort, etc.)
- Auto-fix issues where possible
- Format with double quotes and trailing commas

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "arkiv-sdk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "arkiv, web3, blockchain, ethereum, storage, entities, l2, layer2",
    "author": null,
    "author_email": "Arkiv Network <matthias.zimmermann@golem.network>",
    "download_url": "https://files.pythonhosted.org/packages/90/c9/44fcf85c73b45cf101f8d7e511530ff749841bf18bb95b288f1fa616d45c/arkiv_sdk-1.0.0a5.tar.gz",
    "platform": null,
    "description": "# Arkiv SDK\n\nArkiv is a permissioned storage system for decentralized apps, supporting flexible entities with binary data, attributes, and metadata.\n\nThe Arkiv SDK is the official Python library for interacting with Arkiv networks. It offers a type-safe, developer-friendly API for managing entities, querying data, subscribing to events, and offchain verification\u2014ideal for both rapid prototyping and production use.\n\n## Architecture\n\nPrinciples:\n- The SDK is based on a modern and stable client library.\n- The SDK should feel like \"Library + Entities\"\n\nAs underlying library we use [Web3.py](https://github.com/ethereum/web3.py) (no good alternatives for Python).\n\n\n### Arkiv Client\n\nThe Arkiv SDK should feel like \"web3.py + entities\", maintaining the familiar developer experience that Python web3 developers expect.\n\nA `client.arkiv.*` approach is in line with web3.py's module pattern.\nIt clearly communicates that arkiv is a module extension just like eth, net, etc.\n\n## Hello World\n\n### Synchronous API\nHere's a \"Hello World!\" example showing how to use the Python Arkiv SDK:\n\n```python\nfrom arkiv import Arkiv\n\n# Create Arkiv client with default settings:\n# - starting and connecting to a containerized Arkiv node\n# - creating a funded default account\nclient = Arkiv()\nprint(f\"Client: {client}, connected: {client.is_connected()}\")\nprint(f\"Account: {client.eth.default_account}\")\nprint(f\"Balance: {client.from_wei(client.eth.get_balance(client.eth.default_account), 'ether')} ETH\")\n\n# Create entity with data and attributes\nentity_key, receipt = client.arkiv.create_entity(\n    payload=b\"Hello World!\",\n    content_type=\"text/plain\",\n    attributes={\"type\": \"greeting\", \"version\": 1},\n    btl=1000\n)\n\n# Check and print entity key\nexists = client.arkiv.entity_exists(entity_key)\nprint(f\"Created entity: {entity_key} (exists={exists}), creation TX: {receipt.tx_hash}\")\n\n# Get individual entity and print its details\nentity = client.arkiv.get_entity(entity_key)\nprint(f\"Entity: {entity}\")\n\n# Clean up - delete entity\nclient.arkiv.delete_entity(entity_key)\nprint(\"Entity deleted\")\n```\n\n### Asynchronous API\nFor async/await support, use `AsyncArkiv`:\n\n```python\nimport asyncio\nfrom arkiv import AsyncArkiv\n\nasync def main():\n    # Create async client with default settings\n    async with AsyncArkiv() as client:\n        # Create entity with data and attributes\n        entity_key, tx_hash = await client.arkiv.create_entity(\n            payload=b\"Hello Async World!\",\n            attributes={\"type\": \"greeting\", \"version\": 1},\n            btl=1000\n        )\n\n        # Get entity and check existence\n        entity = await client.arkiv.get_entity(entity_key)\n        exists = await client.arkiv.entity_exists(entity_key)\n\n        # Clean up - delete entity\n        await client.arkiv.delete_entity(entity_key)\n\nasyncio.run(main())\n```\n\n### Web3 Standard Support\n```python\nfrom web3 import HTTPProvider\nprovider = HTTPProvider('https://kaolin.hoodi.arkiv.network/rpc')\n\n# Arkiv 'is a' Web3 client\nclient = Arkiv(provider)\nbalance = client.eth.get_balance(client.eth.default_account)\ntx = client.eth.get_transaction(tx_hash)\n```\n\n### Arkiv Module Extension\n```python\nfrom arkiv import Arkiv\n\n# Simple local setup\nclient = Arkiv()\n\n# Or with custom provider and account\nfrom arkiv.account import NamedAccount\naccount = NamedAccount.from_wallet('Alice', wallet, 's3cret')\nclient = Arkiv(provider, account=account)\n\nentity_key, tx_hash = client.arkiv.create_entity(\n    payload=b\"Hello World!\",\n    attributes={\"type\": \"greeting\", \"version\": 1},\n    btl = 1000\n)\n\nentity = client.arkiv.get_entity(entity_key)\nexists = client.arkiv.exists(entity_key)\n```\n\n## Advanced Features\n\n### Provider Builder\n\nThe snippet below demonstrates the creation of various nodes to connect to using the `ProviderBuilder`.\n\n```python\nfrom arkiv import Arkiv\nfrom arkiv.account import NamedAccount\nfrom arkiv.provider import ProviderBuilder\n\n#\u00a0Create account from wallet json\nwith open ('wallet_bob.json', 'r') as f:\n    wallet = f.read()\n\nbob = NamedAccount.from_wallet('Bob', wallet, 's3cret')\n\n# Initialize Arkiv client connected to Kaolin (Akriv testnet)\nprovider = ProviderBuilder().kaolin().build()\nclient = Arkiv(provider, account=bob)\n\n# Additional builder examples\nprovider_container = ProviderBuilder().node().build()\nprovider_kaolin_ws = ProviderBuilder().kaolin().ws().build()\nprovider_custom = ProviderBuilder().custom(\"https://my-rpc.io\").build()\n```\n\n## Arkiv Topics/Features\n\n### BTL\n\nBTL (Blocks-To-Live) should be replaced with explicit `expires_at_block` values for predictability and composability.\n\nRelative `BTL` depends on execution timing and creates unnecessary complexity:\n- An entity created with `btl=100` will have different expiration blocks depending on when the transaction is mined\n- Extending entity lifetimes requires fetching the entity, calculating remaining blocks, and adding more\u2014a race-prone pattern\n- Creates asymmetry between write operations (which use `btl`) and read operations (which return `expires_at_block`)\n- Mempool management can accept any value\n\nAbsolute `expires_at_block` is predictable, composable, and matches what you get when reading entities:\n- Deterministic regardless of execution timing\n- Maps directly to `Entity.expires_at_block` field returned by queries\n- Enables clean compositional patterns like `replace(entity, expires_at_block=entity.expires_at_block + 100)`\n- Aligns write API with read API, making the SDK more intuitive\n- Mempool needs to manage/delete tx with expires at values in the past\n\nIt's complicated. Deterministic mempool management vs predictable tx management in mempool.\n\n```python\nfrom dataclasses import replace\n\n# Fetch entity\nentity = client.arkiv.get_entity(entity_key)\n\n# Modify payload and extend expiration by 100 blocks\nupdated_entity = replace(\n    entity,\n    payload=b\"new data\",\n    expires_at_block=entity.expires_at_block + 100\n)\n\n# Update entity\nclient.arkiv.update_entity(updated_entity)\n```\n\n### Query DSL\n\nTo make querying entities as simple and natural as possible, rely on a suitable and existing query DSL. Since Arkiv currently uses a SQL database backend and is likely to support SQL databases in the future, the Arkiv query DSL is defined as a **subset of the SQL standard**.\n\n**Rationale:**\n- Leverages existing SQL knowledge - no new language to learn\n- Well-defined semantics and broad tooling support\n- Natural fit for relational data structures\n- Enables familiar filtering, joining, and aggregation patterns\n\n**Example:**\n```python\n# Query entities using SQL-like syntax\nresults = client.arkiv.query_entities(\n    \"SELECT entity_key, payload WHERE attributes.type = 'user' AND attributes.age > 18 ORDER BY attributes.name\"\n)\n```\n\n### Sorting\n\nQuerying entities should support sorting results by one or more fields.\n\n**Requirements:**\n- Sort by attributes (string and numeric)\n- Sort by metadata (owner, expires_at_block)\n- Support ascending and descending order\n- Multi-field sorting with priority\n\n**Example:**\n```python\n# SQL-style sorting\nresults = client.arkiv.query(\n    \"SELECT * FROM entities ORDER BY attributes.priority DESC, attributes.name ASC\"\n)\n```\n\n### Other Features\n\n- **Creation Flags**: Entities should support creation-time flags with meaningful defaults.\nFlags can only be set at creation and define entity behavior:\n  - **Read-only**: Once created, entity data cannot be changed by anyone (immutable)\n  - **Unpermissioned extension**: Entity lifetime can be extended by anyone, not just the owner\n  ```python\n  # Proposed API\n  client.arkiv.create_entity(\n      payload=b\"data\",\n      attributes={\"type\": \"public\"},\n      expires_at_block=future_block,\n      flags=EntityFlags.READ_ONLY | EntityFlags.PUBLIC_EXTENSION\n  )\n  ```\n\n- **ETH Transfers**: Arkiv chains should support ETH (or native token like GLM) transfers for gas fees and value transfer.\n  ```python\n  # Already supported via Web3.py compatibility\n  tx_hash = client.eth.send_transaction({\n      'to': recipient_address,\n      'value': client.to_wei(1, 'ether'),\n      'gas': 21000\n  })\n  ```\n\n- **Offline Entity Verification**: Provide cryptographic verification of entity data without querying the chain.\n  - Currently not supported\n  - Proposal: Store entity keys (and block number) in smart contracts and work with an optimistic oracle approach (challenger may take entity key and checks claimed data against the data of an Arkiv archival node)\n\n## Development Guide\n\n### Branches, Versions, Changes\n\n#### Branches\n\nThe current stable branch on Git is `main`.\nCurrently `main` hosts the initial SDK implementation.\n\nThe branch `v1-dev` hosts the future V1.0 SDK release.\n\n#### Versions\n\nFor version management the [uv](https://github.com/astral-sh/uv) package and project manger is used.\nUse the command below to display the current version\n```bash\nuv version\n```\n\nSDK versions are tracked in the following files:\n- `pyproject.toml`\n- `uv.lock`\n\n### Testing\n\nPytest is used for unit and integration testing.\n```bash\nuv run pytest # Run all tests\nuv run pytest -k test_create_entity_simple --log-cli-level=info # Specific tests via keyword, print at info log level\n```\n\nIf an `.env` file is present the unit tests are run against the specifice RPC coordinates and test accounts.\nAn example wallet file is provided in `.env.testing`\nMake sure that the specified test accounts are properly funded before running the tests.\n\nOtherwise, the tests are run against a testcontainer containing an Arkiv RPC Node.\nTest accounts are created on the fly and using the CLI inside the local RPC Nonde.\n\nAccount wallets for such tests can be created via the command shown below.\nThe provided example creates the wallet file `wallet_alice.json` using the password provided during the execution of the command.\n\n```bash\nuv run python uv run python -m arkiv.account alice\n```\n\n### Code Quality\n\nThis project uses comprehensive unit testing, linting and type checking to maintain high code quality:\n\n#### Quick Commands\n\nBefore any commit run quality checks:\n```bash\n./scripts/check-all.sh\n```\n\n#### Tools Used\n\n- **MyPy**: Static type checker with strict configuration\n- **Ruff**: Fast linter and formatter (replaces black, isort, flake8, etc.)\n- **Pre-commit**: Automated quality checks on git commits\n\n#### Individual commands\n```bash\nuv run ruff check . --fix    # Lint and auto-fix\nuv run ruff format .         # Format code\nuv run mypy src/ tests/      # Type check\nuv run pytest tests/ -v     # Run tests\nuv run pytest --cov=src   # Run code coverage\nuv run pre-commit run --all-files # Manual pre commit checks\n```\n\n#### Pre-commit Hooks\n\nPre-commit hooks run automatically on `git commit` and will:\n- Fix linting issues with ruff\n- Format code consistently\n- Run type checking with mypy\n- Check file formatting (trailing whitespace, etc.)\n\n#### MyPy Settings\n\n- `strict = true` - Enable all strict checks\n- `no_implicit_reexport = true` - Require explicit re-exports\n- `warn_return_any = true` - Warn about returning Any values\n- Missing imports are ignored for third-party libraries without type stubs\n\n#### Ruff Configuration\n\n- Use 88 character line length (Black-compatible)\n- Target Python 3.12+ features\n- Enable comprehensive rule sets (pycodestyle, pyflakes, isort, etc.)\n- Auto-fix issues where possible\n- Format with double quotes and trailing commas\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python SDK for Arkiv networks - Web3.py + Entities",
    "version": "1.0.0a5",
    "project_urls": {
        "Changelog": "https://github.com/Arkiv-Network/arkiv-sdk-python/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/Arkiv-Network/arkiv-sdk-python#readme",
        "Homepage": "https://github.com/Arkiv-Network/arkiv-sdk-python",
        "Issues": "https://github.com/Arkiv-Network/arkiv-sdk-python/issues",
        "Repository": "https://github.com/Arkiv-Network/arkiv-sdk-python"
    },
    "split_keywords": [
        "arkiv",
        " web3",
        " blockchain",
        " ethereum",
        " storage",
        " entities",
        " l2",
        " layer2"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "da6e1c62efe7f4205160fe47e7046fe50dfa0ddb079f0185fc7859361257ec7a",
                "md5": "ba1142cfce370b51df9d3056ed100fc4",
                "sha256": "a37ae8e50d86d22379bc5187c9762decac8390f350c8a960d18f1e3a87b11bae"
            },
            "downloads": -1,
            "filename": "arkiv_sdk-1.0.0a5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ba1142cfce370b51df9d3056ed100fc4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 54581,
            "upload_time": "2025-11-06T09:22:09",
            "upload_time_iso_8601": "2025-11-06T09:22:09.374582Z",
            "url": "https://files.pythonhosted.org/packages/da/6e/1c62efe7f4205160fe47e7046fe50dfa0ddb079f0185fc7859361257ec7a/arkiv_sdk-1.0.0a5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "90c944fcf85c73b45cf101f8d7e511530ff749841bf18bb95b288f1fa616d45c",
                "md5": "b09200f23dc7c362acb63612c2e929df",
                "sha256": "39393de91190709f945edee0fa57a12f3f86012936b889a92555dec3f1d37023"
            },
            "downloads": -1,
            "filename": "arkiv_sdk-1.0.0a5.tar.gz",
            "has_sig": false,
            "md5_digest": "b09200f23dc7c362acb63612c2e929df",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 95800,
            "upload_time": "2025-11-06T09:22:10",
            "upload_time_iso_8601": "2025-11-06T09:22:10.810863Z",
            "url": "https://files.pythonhosted.org/packages/90/c9/44fcf85c73b45cf101f8d7e511530ff749841bf18bb95b288f1fa616d45c/arkiv_sdk-1.0.0a5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-06 09:22:10",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Arkiv-Network",
    "github_project": "arkiv-sdk-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "arkiv-sdk"
}
        
Elapsed time: 1.07085s