Skip to main content

Storix

An async-first, streaming-first storage SDK for modern Python applications.

CI PyPI version Supported Python versions License

Documentation: storix.mghalix.com


Storix gives you one unix-flavored filesystem API over any storage backend. Write your application logic once with ls, cat, echo, mv, and stream, then swap between local disk, in-memory, Azure, S3, or GCS by changing one line.

Data flows through bounded memory as async streams, so application code can forward incremental byte streams directly into cloud storage or stream a large file back to a client without accumulating the complete object in memory.

import asyncio

from storix.aio import Storix
from storix.aio.backends import MemoryBackend


async def main() -> None:
    fs = Storix(MemoryBackend())  # zero setup, runs anywhere

    await fs.mkdir('/reports')
    await fs.echo(b'quarterly numbers', '/reports/q1.txt')

    print(await fs.cat('/reports/q1.txt'))  # b'quarterly numbers'
    print(await fs.ls('/reports'))  # [StorixPath('q1.txt')]
    print(await fs.du('/reports'))  # 17


if __name__ == '__main__':
    asyncio.run(main())

Install

pip install storix               # local filesystem + in-memory
pip install "storix[azure]"      # + Azure Storage (ADLS Gen2 + Blob)
pip install "storix[s3]"         # + Amazon S3 (also R2 / MinIO)
pip install "storix[gcs]"        # + Google Cloud Storage
pip install "storix[cli]"        # + the sx command-line shell
pip install "storix[all]"        # everything

Requires Python 3.12+.

Why Storix?

Streaming writes from any source. echo() accepts bytes, strings, iterators, async iterators, and file-like objects. Pipe data directly into storage without landing it on disk first:

from collections.abc import AsyncIterable

from storix.aio import get_storage


async def stream_upload_to_cloud(
    upload_chunks: AsyncIterable[bytes],
) -> None:
    """Stream data chunks directly into cloud storage."""
    fs = get_storage('s3', bucket='my-bucket')
    await fs.echo(upload_chunks, '/incoming/data.bin')
    # each chunk flows through bounded memory -> no temp file

Test without mocks or credentials. MemoryBackend is a full in-process backend. Write your tests against it, run them in CI, and deploy against any cloud provider:

import pytest

from storix import Storix
from storix.backends import MemoryBackend


@pytest.fixture
def fs() -> Storix:
    return Storix(MemoryBackend())


def test_pipeline(fs: Storix) -> None:
    fs.echo(b'data', '/input.csv')
    assert fs.cat('/input.csv') == b'data'

Change providers without changing code. Your application logic depends on Storix, never on a provider SDK. Flip one environment variable and the same code runs against a different backend:

from storix.aio import Storix, get_storage

# Reads STORIX_PROVIDER from the environment (+ STORIX_<PROVIDER>_* config).
# Local in development, Azure in staging, S3 in production.
fs: Storix = get_storage()

Composable middleware. Layers wrap any backend without touching your code:

  • SandboxLayer - escape-proof chroot for multi-tenant isolation
  • CacheLayer - configurable read-through cache with per-operation control
  • ObservabilityLayer - transfer events for progress bars and metrics
  • DataUrlLayer / MetadataLayer - backfill capabilities on any provider
from storix.aio import CacheLayer, get_storage

fs = get_storage('azure').with_layer(CacheLayer, ttl=300)
fresh = await fs.uncached.cat('/config.json')  # bypass cache for one read

Streaming

Storix treats streaming as the default path, not an afterthought. Reads and writes use async iterators through the full stack:

# Stream a file back chunk by chunk (feeds directly into StreamingResponse)
async for chunk in fs.stream('/large-file.bin', chunk_size=65536):
    yield chunk

# Write from any async source (e.g. an HTTP upload stream, subprocess pipe)
await fs.echo(async_upload_chunks, '/output.bin')

This is especially useful in containers, serverless environments, and web applications where disk space is limited. Application code can stream data incrementally (such as reading FastAPI UploadFile in chunks or forwarding raw Request.stream() chunks) without accumulating the complete object in memory.

The sx shell

The cli extra adds an interactive shell and one-shot commands:

pip install "storix[cli]"

sx                                    # interactive shell (tab-completes paths)
sx -p azure ls -l /media              # one-shot, any provider
sx upload ./video.mp4 /media/         # host -> provider, with a progress bar

Configure defaults in storix.toml, pyproject.toml, or ~/.config/storix/config.toml:

[tool.storix.cli]
provider = "azure"
layers = [{ name = "cache", ttl = 300 }]

Sync and async

Storix is async-first. The sync API is generated from the async source so the two never drift. Use storix for sync and storix.aio for async:

# Sync
from storix import Storix, get_storage
fs = get_storage('local')
fs.echo(b'hello', '/greeting.txt')

# Async - identical names, awaitable
from storix.aio import Storix, get_storage
fs = get_storage('local')
await fs.echo(b'hello', '/greeting.txt')

Backends

Backend Import Notes
Local disk LocalBackend Anchored at a base directory
In-memory MemoryBackend Full reference backend, ideal for tests
Azure ADLS Gen2 AzureBackend HNS accounts; the azure provider auto-detects account kind
Azure Blob AzureBlobBackend Any account kind, blob API
Amazon S3 S3Backend Also S3-compatible stores (MinIO, R2)
Google Cloud Storage GcsBackend

Third-party backends implement the StorageBackend protocol and register via register_backend(). See Write a custom backend.

Project status

Storix is pre-1.0 (currently v0.4.x) and under active development. It is used in the maintainer's own production projects.

What this means in practice:

  • The core API (ls, cat, echo, mv, stream, du, ...) is designed to remain stable. These operations follow unix conventions that leave little room for ambiguity.
  • Breaking changes are possible during 0.x, but they are not made casually. Each breaking change gets an ADR, migration guidance, and a minor version bump (0.4 -> 0.5).
  • 27 architecture decision records document the reasoning behind the design.
  • A conformance test suite runs against every backend in CI.
  • The library is fully typed (py.typed) and checked with strict BasedPyright and mypy.

If you are evaluating Storix for a project, the safest starting point is MemoryBackend for tests and LocalBackend or a single cloud provider for your application code. The API surface that touches your logic is small and unlikely to change in ways that are difficult to adapt to.

Roadmap

The roadmap is organized by the workflows it improves. Key areas under development or consideration:

  • Streaming reliability - resumable uploads, progress reporting, range reads
  • Provider capabilities - broader presigned URL support, content type handling
  • Framework integrations - pathlib-shaped adapter, flat object-store facade, fsspec compatibility
  • Observability - operation-level events, telemetry hooks
  • Testing tools - built-in test fixtures, snapshot testing

Community feedback influences priorities. If your workflow would benefit from a specific improvement, open a workflow discussion describing what you are building.

Get involved

Storix is looking for early users who want to build real things, share workflows, and help shape the project.

Share your workflow. The most useful contribution right now is describing what you are trying to build and where Storix fits or falls short. Start a discussion to explore new workflows, provider ideas, or API designs.

Report bugs. A clear reproduction against any backend is valuable. File a bug report.

Contribute code. See CONTRIBUTING.md for setup, conventions, and the pull request workflow. Small self-contained fixes can go directly to a pull request.

Challenge the design. Disagreement is welcome when it is respectful and grounded in a real use case. The project's architecture decisions are documented precisely so they can be questioned.

Resources

License

Apache 2.0. See LICENSE.

Download files

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

Source Distribution

storix-0.4.7.tar.gz (144.8 kB view details)

Uploaded Source

Built Distribution

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

storix-0.4.7-py3-none-any.whl (186.9 kB view details)

Uploaded Python 3

File details

Details for the file storix-0.4.7.tar.gz.

File metadata

  • Download URL: storix-0.4.7.tar.gz
  • Upload date:
  • Size: 144.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for storix-0.4.7.tar.gz
Algorithm Hash digest
SHA256 2a1e24f1b8b975df81f97f0dc16c82c82932481bf04b1e8d1adf5f4e419f5829
MD5 b952fdc7216370bb46d9e3895c0c8985
BLAKE2b-256 b7e25bff4fdb781dbf705e4f348c9d2de60dc0a6adc59063a2ba168ff8166e5f

See more details on using hashes here.

File details

Details for the file storix-0.4.7-py3-none-any.whl.

File metadata

  • Download URL: storix-0.4.7-py3-none-any.whl
  • Upload date:
  • Size: 186.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for storix-0.4.7-py3-none-any.whl
Algorithm Hash digest
SHA256 48822f2f649dc3fc480343f645c1df572ee22063a3012af9c584dc19ab81cf10
MD5 09b458a764f8a049a9e21ec9be55272e
BLAKE2b-256 1d85a8604a422eb70f51b5033193ecebb194affc637713c497d0aac8f275a36f

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.9

2 files

0.4.8

2 files

This release

0.4.7 This release

2 files

0.4.6

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Supported by

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