fsspec filesystem for Lore (Epic Games' version control system)
Project description
lore-fsspec
An fsspec filesystem for
Lore, Epic Games' open-source version control
system — the Lore equivalent of fsspec's built-in GitFileSystem.
It lets any fsspec-aware tool (pandas, pyarrow, zarr, dask, fsspec.open, …) read
files out of a local Lore clone at an arbitrary branch or revision via lore://
URLs, backed by the official lore Python bindings (liblore).
Planned usage
import fsspec
fs = fsspec.filesystem("lore", path="/path/to/clone", ref="main")
fs.ls("Content/Maps")
with fs.open("Content/Config/Game.ini", "rt") as f:
print(f.read())
# URL form: lore://<clone-path>:<ref>@<in-repo-path>
with fsspec.open("lore:///path/to/clone:main@Content/Config/Game.ini", "rt") as f:
print(f.read())
lore exposes a real coroutine API, so LoreFileSystem is an fsspec
AsyncFileSystem — usable directly from asyncio for concurrent reads:
fs = fsspec.filesystem("lore", path="/path/to/clone", ref="main", asynchronous=True)
data = await fs._cat_file("Content/Config/Game.ini") # awaitable
many = await fs._cat(["Content/A.ini", "Content/B.ini"]) # runs concurrently
Writes go through a transaction that maps onto Lore's native stage→commit flow — all files in the block land as a single revision (or none, on error):
fs = fsspec.filesystem("lore", path="/path/to/clone", ref="main", writable=True)
with fs.transaction(message="Import baked lighting"):
fs.pipe_file("Content/Lighting/Baked.bin", data)
fs.pipe_file("Content/Config/Game.ini", ini_bytes)
Branch topology is exposed as explicit methods (not folded into the write
transaction), mirroring fetch(). A transaction can target a branch so the
revision lands there in isolation; merging back is a separate, explicit step
because it can conflict:
fs.branches() # ['main']
fs.create_branch("import-job", checkout=True) # like `git switch -c`
# Commit onto a branch in isolation, then restore the original branch on exit.
with fs.transaction(message="Import", branch="import-job", create=True):
fs.pipe_file("Content/Lighting/Baked.bin", data)
# Clean merges land as one revision; a conflicting merge is aborted and raises
# with the conflicting paths (auto-resolution is intentionally never performed).
fs.merge("import-job")
Examples
End-to-end usecases, distilled from the integration benchmark
(tests/test_benchmark_parquet.py). They show the library doing real
data-engineering work, not just listing files.
Import a dataset atomically, then query it over lore://
Upload a multi-file parquet dataset as one Lore revision (all files land
together, or none on error), then read it straight back with two engines —
DuckDB (SQL) and Polars (DataFrame) — through the lore:// protocol:
import duckdb
import polars as pl
from lore_fsspec import LoreFileSystem
fs = LoreFileSystem(path="/path/to/clone", writable=True)
# Atomic import: every shard becomes part of a single revision.
with fs.transaction(message="import events dataset"):
for shard in ("part-000.parquet", "part-001.parquet", "part-002.parquet"):
fs.put_file(f"/local/events/{shard}", f"warehouse/events/{shard}")
# Query with DuckDB by registering the filesystem under the 'lore' protocol.
con = duckdb.connect()
con.register_filesystem(fs)
rows, total = con.sql(
"SELECT count(*), sum(amount) "
"FROM read_parquet('lore://warehouse/events/*.parquet')",
).fetchone()
# Or read DataFrames directly via fs.open file objects (column projection works).
df = pl.concat(
pl.read_parquet(fs.open(p), columns=["region", "amount"])
for p in sorted(fs.glob("warehouse/events/*.parquet"))
)
by_region = df.group_by("region").agg(pl.len()).sort("region")
Write-audit-publish with a branch
Ingest a new partition on an isolation branch, audit it without exposing it on
main, then publish it atomically by merging — the classic
"write-audit-publish" pattern:
fs = LoreFileSystem(path="/path/to/clone", writable=True) # starts on 'main'
# WRITE: commit the new partition onto a fresh branch, not main.
with fs.transaction(message="ingest Feb partition", branch="ingest-2026-02", create=True):
fs.put_file("/local/part-new.parquet", "warehouse/events/part-new.parquet")
assert fs.ref == "main" # the transaction restored the original branch on exit
# AUDIT: main is untouched; read the new data back by targeting the branch ref.
fs.ls("warehouse/events") # main: existing partitions only
fs.ls("warehouse/events", ref="ingest-2026-02") # branch: includes part-new
audited = pl.read_parquet(
fs.open("warehouse/events/part-new.parquet", ref="ingest-2026-02"),
)
# PUBLISH: a clean merge lands as one revision; a conflicting one aborts and raises.
fs.merge("ingest-2026-02")
Development
uv sync # install deps (fsspec, lore-vcs)
uv run pytest # run tests
lore ships a platform-specific liblore shared library; tests skip when the
current platform's library isn't available.
License
MIT (matching Lore).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lore_fsspec-0.1.1.tar.gz.
File metadata
- Download URL: lore_fsspec-0.1.1.tar.gz
- Upload date:
- Size: 81.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74691839c4c5dcc348c4d7c7dc22d8f5c0234344143766d6848073d6b3bb8bff
|
|
| MD5 |
8062f4a3306597e93045e36a165f69a3
|
|
| BLAKE2b-256 |
b24ae0389acea41801b9c23dd737897aa76db3d69174d65f781131d78d3dd428
|
Provenance
The following attestation bundles were made for lore_fsspec-0.1.1.tar.gz:
Publisher:
release.yml on ggoggam/lore-fsspec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lore_fsspec-0.1.1.tar.gz -
Subject digest:
74691839c4c5dcc348c4d7c7dc22d8f5c0234344143766d6848073d6b3bb8bff - Sigstore transparency entry: 1926139892
- Sigstore integration time:
-
Permalink:
ggoggam/lore-fsspec@46f7899c578b49f31f9c4d373a55139b0c46e0d7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ggoggam
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@46f7899c578b49f31f9c4d373a55139b0c46e0d7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lore_fsspec-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lore_fsspec-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af9a97bdda95b25907ef9881972ca17680bf1ca1dbff2355f97c146437cddfb9
|
|
| MD5 |
5050938c58f94a6f0ce4e6300588078e
|
|
| BLAKE2b-256 |
e9b2da87033e44bdc79ede46e12e2bbe7c98c1f681ce29870eb0a31d4baed8aa
|
Provenance
The following attestation bundles were made for lore_fsspec-0.1.1-py3-none-any.whl:
Publisher:
release.yml on ggoggam/lore-fsspec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lore_fsspec-0.1.1-py3-none-any.whl -
Subject digest:
af9a97bdda95b25907ef9881972ca17680bf1ca1dbff2355f97c146437cddfb9 - Sigstore transparency entry: 1926140238
- Sigstore integration time:
-
Permalink:
ggoggam/lore-fsspec@46f7899c578b49f31f9c4d373a55139b0c46e0d7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ggoggam
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@46f7899c578b49f31f9c4d373a55139b0c46e0d7 -
Trigger Event:
push
-
Statement type: