mstransfer
Transfer mass spectrometry files (mzML / MSZ) between machines over HTTP. Files are always transported in compressed MSZ format using mscompress — mzML sources are compressed on-the-fly without temp files, and the receiving end can optionally decompress back to mzML.
Install
# Recommended — installs as an isolated CLI tool
uv tool install mstransfer
# Or with pipx
pipx install mstransfer
# Or as a project dependency
uv pip install mstransfer
pip install mstransfer
Quick start
Start a server on the receiving machine:
mstransfer serve --port 1319 --store-as msz
Upload files from the source machine:
mstransfer upload /data/experiment1.mzML /data/batch/ remote-host:1319
Usage
mstransfer serve
Start the receiver server.
mstransfer serve [--host 0.0.0.0] [--port 1319] [--output-dir ./received] [--store-as msz|mzml]
| Flag | Default | Description |
|---|---|---|
--host |
0.0.0.0 |
Bind address |
--port |
1319 |
Listen port |
--output-dir |
./received |
Where received files are written |
--store-as |
msz |
Store as msz (compressed) or mzml (decompress on arrival) |
mstransfer upload
Upload files to a server. Accepts any mix of files and directories. The last positional argument is the target.
mstransfer upload <paths...> <host[:port]> [--recursive] [--parallel 4]
| Flag | Default | Description |
|---|---|---|
--recursive, -r |
off | Recurse into directories |
--parallel, -p |
4 |
Number of concurrent uploads |
Supported file types: .mzML, .msz, .mszx.
- mzML files are compressed to MSZ on-the-fly via
compress_stream()and streamed directly into the HTTP request — no temp files on the sender. - MSZ / MSZX files are streamed as-is.
Programmatic access
You can use mstransfer as a library to send files from your own Python code:
from pathlib import Path
from mstransfer.client import send_file, send_batch
# Send a single file (Path)
result = send_file(Path("experiment.mzML"), "http://remote-host:1319")
# Send an already-opened mscompress object
from mscompress import MZMLFile, MSZFile
from mscompress.mszx import MSZXFile
mzml = MZMLFile(b"/data/experiment.mzML")
send_file(mzml, "http://remote-host:1319")
msz = MSZFile(b"/data/experiment.msz")
send_file(msz, "http://remote-host:1319")
mszx = MSZXFile.open("/data/experiment.mszx")
send_file(mszx, "http://remote-host:1319")
# Send multiple files in parallel
send_batch(
[Path("a.mzML"), Path("b.msz"), mszx],
"http://remote-host:1319",
parallel=4,
)
send_file and send_batch accept any mix of Path, MZMLFile, MSZFile, and MSZXFile inputs.
API
The server exposes a REST API under /v1/:
| Endpoint | Method | Description |
|---|---|---|
/v1/health |
GET | Server status, version, storage mode |
/v1/upload |
POST | Upload a file (streamed MSZ body) |
/v1/transfer/{id}/status |
GET | Poll transfer state |
Embedding in another app
The server is built as a FastAPI app factory:
from mstransfer import create_app
# Standalone
app = create_app(output_dir="/data/ms", store_as="mzml")
# Mount in an existing FastAPI app
from fastapi import FastAPI
main_app = FastAPI()
main_app.mount("/transfer", create_app())
How it works
flowchart LR
subgraph Sender
mzML[".mzML"] --> compress["compress_stream()"]
msz[".msz / .mszx"] --> read["read file"]
end
compress --> upload["POST /v1/upload\n(MSZ bytes)"]
read --> upload
subgraph Server
upload --> mode{store-as?}
mode -- msz --> write["write to disk"]
mode -- mzml --> temp["write temp .msz"]
temp --> decompress["decompress"]
decompress --> cleanup["cleanup temp"]
end
Development
uv sync --dev
uv run pytest
uv run ruff check src/ tests/
Pre-commit hooks
Install the pre-commit hooks to automatically run linting, type checking, and tests before each commit:
uv run pre-commit install
Metadata
Release files for mstransfer 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mstransfer-0.2.3.tar.gz | 2.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mstransfer-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.1 MB
Release files / mstransfer-0.2.3.tar.gz
| Download URL | mstransfer-0.2.3.tar.gz |
|---|---|
| Size | 2.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d499684eab6105cd118b481c42d474af91d1fe733aace8814175de082001cef2
|
|
BLAKE2b-256 checksum How to use checksums |
44921fdaf4e7fb3351eadbefabd5f14a3cc1054ae55e27235e6a2ff0cdca3462
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 15, 2026.
Transparency logRelease files / mstransfer-0.2.3-py3-none-any.whl
| Download URL | mstransfer-0.2.3-py3-none-any.whl |
|---|---|
| Size | 25.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ef76ffa860ef2a15c0a4682d3306cc9f874777f0eaa0b91bcf657f6acb94ca9
|
|
BLAKE2b-256 checksum How to use checksums |
fcf70ef84347bcef2adbbd258a0936b8031af28812a54df8445e7642299ded3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 15, 2026.
Transparency log