orrisroot 0cac30ccf8 fix(auth): serialise the token refresh across processes
The login cache is shared by every mdrs process, but the refresh was
guarded by a lock that only reaches inside one. Concurrent runs each
sent the same refresh token, and a provider that rotates them accepts
the first and refuses the rest.

- hold a lock that spans processes across the whole read-refresh-
  write, checking cheaply first so ordinary requests never take it
- write the cache through a temporary file: opening it for writing
  truncates it, and a reader landing in that window found it empty
  and threw the session away
- take the lock for every write, not just the refresh, so a login
  running beside one cannot be silently reverted
- wait for a busy lock on Windows rather than giving up after the ten
  attempts msvcrt allows, and retry the rename it refuses while a
  reader still holds the file open
- bound the refresh request on its own, so a provider that goes quiet
  cannot hold the lock indefinitely
- accept bare hostnames such as localhost, store URLs without the
  trailing slash, and join download paths through one helper
2026-08-14 16:36:50 +09:00
2024-07-04 12:33:57 +09:00

mdrs-client-python

The mdrs-client-python is python library and a command-line client for up- and downloading files to and from MDRS based repository.

Installation (Production)

It is recommended to use a virtual environment (venv) to keep your Python environment isolated.

Option 1: Using standard venv + pip

python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install .

Option 2: Using uv

uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uv pip install .

Development Setup

To set up a local development environment with development tools (testing, formatting, linting):

Option 1: Using standard venv + pip

python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -e ".[dev]"
uv sync

CLI Usage

config create

Create remote host configuration

mdrs config create neurodata https://neurodata.riken.jp/api

config update

Update the URL of a registered remote host.

mdrs config update neurodata https://neurodata.riken.jp/api

config list

List registered remote hosts.

mdrs config list
mdrs config ls

config delete

Remove a registered remote host.

mdrs config delete neurodata
mdrs config rm neurodata

login

Login to remote host

mdrs login neurodata:
Username: (enter your login name)
Password: (enter your password)

mdrs login -u USERNAME -p PASSWORD neurodata:

logout

Logout from remote host

mdrs logout neurodata:

whoami

Print current user name

mdrs whoami neurodata:

labs

List all laboratories

mdrs labs neurodata:

ls

List the folder contents. You can also specify a DOI path in the form remote:10.xxxx/yyy.ID[/optional/subpath].

mdrs ls neurodata:/NIU/Repository/
mdrs ls -p SHARING_PASSWORD neurodata:/NIU/Repository/PW_Open/
mdrs ls -r neurodata:/NIU/Repository/Dataset1/
mdrs ls -J -r neurodata:/NIU/Repository/Dataset1/

# DOI access examples:
mdrs ls neurodata:10.60178/cbs.20260429-001
mdrs ls "neurodata:10.60178/cbs.20260429-001/Figure 1"

mkdir

Create a new folder

mdrs mkdir neurodata:/NIU/Repository/TEST

upload

Upload the file or directory

mdrs upload ./sample.dat neurodata:/NIU/Repository/TEST/
mdrs upload -r ./dataset neurodata:/NIU/Repository/TEST/
mdrs upload -r --skip-if-exists ./dataset neurodata:/NIU/Repository/TEST/

download

Download the file or folder. You can also specify a DOI path.

mdrs download neurodata:/NIU/Repository/TEST/sample.dat ./
mdrs download -r neurodata:/NIU/Repository/TEST/dataset/ ./
mdrs download -p SHARING_PASSWORD neurodata:/NIU/Repository/PW_Open/Readme.dat ./
mdrs download -r --exclude /NIU/Repository/TEST/dataset/skip neurodata:/NIU/Repository/TEST/dataset/ ./
mdrs download -r --skip-if-exists neurodata:/NIU/Repository/TEST/dataset/ ./

# DOI access examples:
mdrs download neurodata:10.60178/cbs.20260429-001/README_NeuroData.md ./
mdrs download -r "neurodata:10.60178/cbs.20260429-001/Figure 1" ./

mv

Move or rename the file or folder

mdrs mv neurodata:/NIU/Repository/TEST/sample.dat neurodata:/NIU/Repository/TEST2/sample2.dat
mdrs mv neurodata:/NIU/Repository/TEST/dataset neurodata:/NIU/Repository/TEST2/

cp

Copy the file and folder

mdrs cp neurodata:/NIU/Repository/TEST/sample.dat neurodata:/NIU/Repository/TEST2/sample2.dat
mdrs cp -r neurodata:/NIU/Repository/TEST/dataset neurodata:/NIU/Repository/TEST2/

rm

Remove the file or folder

mdrs rm neurodata:/NIU/Repository/TEST/sample.dat
mdrs rm -r neurodata:/NIU/Repository/TEST/dataset

chacl

Change the folder access level

mdrs chacl private neurodata:/NIU/Repository/Private
mdrs chacl cbs_open -r neurodata:/NIU/Repository/CBS_Open
mdrs chacl pw_open -r -p SHARING_PASSWORD neurodata:/NIU/Repository/PW_Open

metadata

Get a folder metadata. You can also specify a DOI path.

mdrs metadata neurodata:/NIU/Repository/TEST/
mdrs metadata -p SHARING_PASSWORD neurodata:/NIU/Repository/PW_Open/

# DOI access examples:
mdrs metadata neurodata:10.60178/cbs.20260429-001

file-metadata

Get the file metadata. You can also specify a DOI path.

mdrs file-metadata neurodata:/NIU/Repository/TEST/dataset/sample.dat
mdrs file-metadata -p SHARING_PASSWORD neurodata:/NIU/Repository/PW_Open/Readme.txt

# DOI access examples:
mdrs file-metadata "neurodata:10.60178/cbs.20260429-001/Figure 1/Figure1v3.pdf"

version

Show the tool name and version number

mdrs version

help

Show the help message and exit

mdrs -h

Python API Usage

You can also use this package as a Python library to programmatically interact with MDRS repositories.

from mdrsclient.client import MdrsClient
from mdrsclient.cache import InMemoryCache
from mdrsclient.config import InMemoryConfig

# 1. Setup in-memory configuration and cache to avoid local state files (e.g., config.ini, cache/*.json)
config = InMemoryConfig("neurodata")
config.url = "https://neurodata.riken.jp/api"

cache = InMemoryCache()

# 2. Initialize client with custom configuration and cache
client = MdrsClient.from_remote("neurodata", cache=cache, config=config)

# 3. Login to the remote server
client.login("username", "password")

# 4. Use service methods
labs = client.get_laboratories()
metadata = client.metadata("neurodata:/NIU/Repository/")

# Transfer files programmatically
client.upload("/path/to/local/data", "neurodata:/NIU/Repository/TEST/", is_recursive=True)
client.download("neurodata:/NIU/Repository/TEST/data", "/path/to/local", is_recursive=True)

Testing

You can run the unit test suite using the standard library unittest discover runner:

.venv/bin/python -m unittest discover tests

Changelog

See CHANGELOG.md for the full change history.

S
Description
A command line client for MDRS (Multiomics Data Repository System)
Readme
259 KiB
Languages
Python 100%