dandi.move¶
Move and rename assets in DANDI Archive.
This module provides functionality for moving and renaming assets both locally and remotely in DANDI Archive instances. Features include: - Local file reorganization - Remote asset path changes - Combined local and remote moves - Conflict resolution (skip, overwrite, error) - Validation of move operations
Module Attributes
A /-separated path to an asset, relative to the root of the Dandiset |
Functions
Find the Dandiset rooted at |
|
|
Classes
|
|
|
|
|
A |
|
A |
A |
|
|
An enumeration. |
|
An enumeration. |
|
A movement/renaming of an asset |
|
An abstract base class for calculating and performing asset moves/renames |
|
A |
Exceptions
|
- class dandi.move.AssetPath¶
A /-separated path to an asset, relative to the root of the Dandiset
alias of
str
- class dandi.move.Folder(path: 'str', relcontents: 'list[str]')[source]¶
- path: str¶
A /-separated path to an asset folder, relative to the root of the Dandiset
- relcontents: list[str]¶
All file paths under the folder recursively, as /-separated paths relative to the folder path
- class dandi.move.LocalMover(dandiset_path: Path, subpath: Path)[source]¶
A
Moverfor moving only the assets in a local Dandiset- dandiset_path: Path¶
The path to the root of the Dandiset
- get_assets(subpath_only: bool = False) Iterator[tuple[AssetPath, str]][source]¶
Yield all available assets as
(asset_path, relpath)pairs, whereasset_pathis a/-separated path relative to the root of the Dandiset andrelpathis a/-separated path to that asset, relative tosubpath(For assets outside ofsubpath,relpathstarts with"../"). Ifsubpath_onlyis true, only assets underneathsubpathare returned.
- get_path(path: str, is_src: bool = True) File | Folder[source]¶
Return the asset or folder of assets at
path(relative tosubpath) as aFileorFolderinstance. If there is nothing at the given path, raisesNotFoundError.If the path points to a folder, its
relcontentsattribute will be populated iffis_srcis given.
- move(src: AssetPath, dest: AssetPath) None[source]¶
Move the asset at path
srcto pathdest(which can be assumed to not exist)
- property placename: str¶
A description of the mover to show in messages
- property status_field: str¶
Name of the pyout status column
- subpath: Path¶
A relative path denoting the subdirectory of the Dandiset in which we are operating
- class dandi.move.LocalRemoteMover(local: LocalMover, remote: RemoteMover)[source]¶
A
Moverfor moving the assets in a local Dandiset and the corresponding remote Dandiset simultaneously. It cannot be reused after performing a set of moves.- calculate_moves(*srcs: str, dest: str, existing: MoveExisting) list[Movement][source]¶
Given a sequence of input source paths and a destination path, return a sorted list of all assets that will be moved/renamed
- calculate_moves_by_regex(find: str, replace: str, existing: MoveExisting) list[Movement][source]¶
Given a regular expression and a replacement string, return a sorted list of all assets that will be moved/renamed
- compare_moves(local_moves: list[Movement], remote_moves: list[Movement]) None[source]¶
Given a list of
Movementinstances calculated by the local and remoteMovers, compare them and raiseAssetMismatchErrorif there are any differences.
- local: LocalMover¶
The local
Mover
- process_movement(m: Movement, dry_run: bool = False) Iterator[dict[str, str]][source]¶
Perform the
Movementand yield adictfor each step
- remote: RemoteMover¶
The remote
Mover
- property status_field: str¶
Name of the pyout status column.
This specific property should never be used.
- property updating_fields: tuple[str, ...]¶
Names of the pyout fields that are updated as things progress
- class dandi.move.LocalizedMover[source]¶
A
Moverfor moving only the assets in one location (i.e., either local or remote)- calculate_moves(*srcs: str, dest: str, existing: MoveExisting) list[Movement][source]¶
Given a sequence of input source paths and a destination path, return a sorted list of all assets that will be moved/renamed
- calculate_moves_by_regex(find: str, replace: str, existing: MoveExisting) list[Movement][source]¶
Given a regular expression and a replacement string, return a sorted list of all assets that will be moved/renamed
- compile_moves(moves: dict[AssetPath, AssetPath], existing: MoveExisting) list[Movement][source]¶
Given a
dictmapping source paths to destination paths, produce a sorted list ofMovementinstances.
- abstract get_assets(subpath_only: bool = False) Iterator[tuple[AssetPath, str]][source]¶
Yield all available assets as
(asset_path, relpath)pairs, whereasset_pathis a/-separated path relative to the root of the Dandiset andrelpathis a/-separated path to that asset, relative tosubpath(For assets outside ofsubpath,relpathstarts with"../"). Ifsubpath_onlyis true, only assets underneathsubpathare returned.
- abstract get_path(path: str, is_src: bool = True) File | Folder[source]¶
Return the asset or folder of assets at
path(relative tosubpath) as aFileorFolderinstance. If there is nothing at the given path, raisesNotFoundError.If the path points to a folder, its
relcontentsattribute will be populated iffis_srcis given.
- abstract move(src: AssetPath, dest: AssetPath) None[source]¶
Move the asset at path
srcto pathdest(which can be assumed to not exist)
- abstract property placename: str¶
A description of the mover to show in messages (either
"local"or"remote")
- process_movement(m: Movement, dry_run: bool = False) Iterator[dict[str, str]][source]¶
Perform the
Movementand yield adictfor each step
- resolve(path: str) tuple[AssetPath, bool][source]¶
Convert an input path (relative to
subpath, possibly starting with../) to a /-separated path relative to the root of the Dandiset, plus a boolean that is true iffpathended with a slash
- subpath: Path¶
A relative path denoting the subdirectory of the Dandiset in which we are operating
- class dandi.move.MoveExisting(value)[source]¶
An enumeration.
- ERROR = 'error'¶
- OVERWRITE = 'overwrite'¶
- SKIP = 'skip'¶
- class dandi.move.MoveWorkOn(value)[source]¶
An enumeration.
- AUTO = 'auto'¶
- BOTH = 'both'¶
- LOCAL = 'local'¶
- REMOTE = 'remote'¶
- class dandi.move.Movement(src: AssetPath, dest: AssetPath, skip: bool = False, delete: bool = False)[source]¶
A movement/renaming of an asset
- delete: bool = False¶
Whether to delete the asset at the destination before moving
- property dest_exists: bool¶
True iff an asset already exists at the destination
- skip: bool = False¶
Whether to skip this operation because an asset already exists at the destination
- class dandi.move.Mover[source]¶
An abstract base class for calculating and performing asset moves/renames
- abstract calculate_moves(*srcs: str, dest: str, existing: MoveExisting) list[Movement][source]¶
Given a sequence of input source paths and a destination path, return a sorted list of all assets that will be moved/renamed
- abstract calculate_moves_by_regex(find: str, replace: str, existing: MoveExisting) list[Movement][source]¶
Given a regular expression and a replacement string, return a sorted list of all assets that will be moved/renamed
- property columns: tuple[str, ...]¶
Names of the columns in the pyout display
- abstract process_movement(m: Movement, dry_run: bool = False) Iterator[dict[str, str]][source]¶
Perform the
Movementand yield adictfor each step
- process_moves_debug(plan: list[Movement], dry_run: bool = False) Iterator[Iterator[dict]][source]¶
For each
Movementinplan, yield an iterator ofdicts to print for each step of the movement operation.
- process_moves_pyout(plan: list[Movement], dry_run: bool = False) Iterator[dict][source]¶
Yield a
dictto pass to pyout for eachMovementinplan
- abstract property status_field: str¶
Name of the pyout status column (either
"local"or"remote")
- property updating_fields: tuple[str, ...]¶
Names of the pyout fields that are updated as things progress
- class dandi.move.RemoteMover(dandiset: RemoteDandiset, subpath: Path, local_dandiset_path: Path | None = None)[source]¶
A
Moverfor moving only the assets in a remote Dandiset. It cannot be reused after performing a set of moves.- assets: dict[AssetPath, RemoteAsset]¶
A collection of all assets in the Dandiset, keyed by their paths
- dandiset: RemoteDandiset¶
The client object for the remote Dandiset being operated on
- get_assets(subpath_only: bool = False) Iterator[tuple[AssetPath, str]][source]¶
Yield all available assets as
(asset_path, relpath)pairs, whereasset_pathis a/-separated path relative to the root of the Dandiset andrelpathis a/-separated path to that asset, relative tosubpath(For assets outside ofsubpath,relpathstarts with"../"). Ifsubpath_onlyis true, only assets underneathsubpathare returned.
- get_path(path: str, is_src: bool = True) File | Folder[source]¶
Return the asset or folder of assets at
path(relative tosubpath) as aFileorFolderinstance. If there is nothing at the given path, raisesNotFoundError.If the path points to a folder, its
relcontentsattribute will be populated iffis_srcis given.
- local_dandiset_path: Path | None = None¶
The
dandiset_pathof the correspondingLocalMoverwhen inside aLocalRemoteMover
- move(src: AssetPath, dest: AssetPath) None[source]¶
Move the asset at path
srcto pathdest(which can be assumed to not exist)
- property placename: str¶
A description of the mover to show in messages
- property status_field: str¶
Name of the pyout status column
- subpath: Path¶
A relative path denoting the subdirectory of the Dandiset in which we are operating
- dandi.move.find_dandiset_and_subpath(path: Path) tuple[Dandiset, Path][source]¶
Find the Dandiset rooted at
pathor one of its parents, and return the Dandiset along withpathmade relative to the Dandiset root
- dandi.move.move(*srcs: str, dest: str, regex: bool = False, existing: MoveExisting = MoveExisting.ERROR, dandi_instance: str | DandiInstance = 'dandi', dandiset: str | Path | None = None, work_on: MoveWorkOn = MoveWorkOn.AUTO, devel_debug: bool = False, jobs: int | None = None, dry_run: bool = False) None[source]¶