Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging validation functions #1154

Closed
wants to merge 95 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
e1809e3
Update pynwb_utils.py
CodyCBakerPhD Nov 1, 2022
921f67a
Update pynwb_utils.py
CodyCBakerPhD Nov 1, 2022
d7ab706
Update pynwb_utils.py
CodyCBakerPhD Nov 1, 2022
7261a91
Non-working draft
TheChymera Nov 9, 2022
242be00
Absolute instead of resolve to avoid symlink issues.
TheChymera Nov 11, 2022
26467d1
Update `test_validate_nwb_path_grouping` test
jwodder Nov 11, 2022
75da4bb
Merge pull request #1149 from catalystneuro/use_cached_namespace_vali…
yarikoptic Nov 11, 2022
46f7095
Fix typing error under mypy 0.990
jwodder Nov 11, 2022
588034c
Merge pull request #1157 from dandi/fix-grouping-test
yarikoptic Nov 12, 2022
15ea79f
Merge pull request #1156 from dandi/fix-typing
yarikoptic Nov 12, 2022
77a380e
No longer mark `test_rename_type_mismatch` as xfailing
jwodder Nov 16, 2022
b11835a
Merge pull request #1161 from dandi/rm-xfail
yarikoptic Nov 16, 2022
b97689e
Renamed failing test, added prospective use case for NWBI warning.
TheChymera Nov 21, 2022
a50c4fe
importance_threshold and debugging print calls
TheChymera Nov 21, 2022
ede4a20
Created and using new fixture for non-critical NWBI error
TheChymera Nov 22, 2022
b6ee44a
Indentation fix
TheChymera Nov 22, 2022
d0ef688
Imports at top of module
TheChymera Nov 22, 2022
0439caf
Merge pull request #1162 from dandi/error_fix
TheChymera Nov 24, 2022
1d59b33
Add CodeQL workflow for GitHub code scanning
lgtm-migrator Nov 25, 2022
61e9b80
Make CodeQL ignore the files that LGTM ignored
jwodder Nov 28, 2022
25b9d98
Address some CodeQL alerts
jwodder Nov 28, 2022
1137dbd
Eliminate use of tempfile.mktemp()
jwodder Nov 28, 2022
d2d6836
Corrected reporting function logic to complete group message variable
TheChymera Nov 28, 2022
0ad1346
Merge pull request #1166 from dandi/reporting
yarikoptic Nov 29, 2022
a0b0015
Merge pull request #1165 from lgtm-migrator/codeql
yarikoptic Nov 29, 2022
3d3bb9a
dandi-cli readme edit
melster1010 Dec 1, 2022
d3ec5f1
Unravelling `ls` issues
TheChymera Nov 23, 2022
dc34ab0
strange `Cannot creat weak reference to PosixPath object`
TheChymera Nov 23, 2022
8aef541
Fixed weakref issue
TheChymera Nov 28, 2022
b3a4b9a
Added readme listing and removed some diagnostic print calls
TheChymera Nov 28, 2022
3272c86
Removed more debugging print calls
TheChymera Nov 28, 2022
ba99146
Removed more debugging print calls
TheChymera Nov 28, 2022
64677c1
Creating and passing digests
TheChymera Nov 28, 2022
f8a0da8
Added validation bids schema version to result object metadata
TheChymera Nov 28, 2022
430fb06
Assigning bids schema version for validation to metadata dict
TheChymera Nov 28, 2022
279ecf9
Trying to insert bids_schema_version ... somewhere.
TheChymera Nov 29, 2022
60b2408
Added (get_validation)_bids_version to BIDS assets
TheChymera Nov 29, 2022
4a4530e
Creating ZARR digest for ZARR files
TheChymera Nov 30, 2022
9df52ad
Using correct ZARR digest class (still not working)
TheChymera Dec 1, 2022
0e0ff8e
More debugging print calls trying to track down digest error
TheChymera Dec 1, 2022
cc28fbb
Removed unneeded import
TheChymera Dec 1, 2022
5d59ae8
Using zarr extensions variable from constants module
TheChymera Dec 1, 2022
5d62fcc
Reinstated fake digest after introducing ZARR conditional
TheChymera Dec 1, 2022
f0de103
Attempting to fix digest type conflict (still not working)
TheChymera Dec 1, 2022
86ae9c0
Use Zarr checksum to set metadata contentSize
jwodder Dec 1, 2022
9866d0c
Removed debugging print calls
TheChymera Dec 2, 2022
785dec0
Not requiring bids_version for ValidatorOrigin
TheChymera Dec 2, 2022
2059dd7
Typing fixes and improved variable name
TheChymera Dec 2, 2022
a2119ec
Attemting type check fix for missing attribute
TheChymera Dec 2, 2022
722e804
Removed commented imports
TheChymera Dec 2, 2022
3649b5e
Actually fix typing
jwodder Dec 2, 2022
32d0379
Debugging upload tests
TheChymera Dec 2, 2022
ba7d60c
Reinstating test
TheChymera Dec 5, 2022
e8a64e1
Associate BIDS asset errors with the actual assets
jwodder Dec 5, 2022
ccda9ec
Fixed novel README validation error
TheChymera Dec 5, 2022
44a8ab4
Checking ls output subject identifier
TheChymera Dec 5, 2022
efab43e
Added ls command tests for zarrBIDS file
TheChymera Dec 5, 2022
79c829c
fix spelling
melster1010 Dec 6, 2022
1ed0f5f
ZARR-appropriate fake checksum
TheChymera Dec 6, 2022
9900841
More compact code
TheChymera Dec 6, 2022
3384ef5
Dot in extension
TheChymera Dec 6, 2022
d9ccf8b
Safer assert satatement
TheChymera Dec 6, 2022
375947d
Making sure the method which sets the attribute has been run
TheChymera Dec 6, 2022
87c37b0
Incorporate review feedback
melster1010 Dec 7, 2022
11c18f5
Updated logic to better accommodate future BIDS NWB examples
TheChymera Dec 7, 2022
97555c7
Update dandi and ls --help output
melster1010 Dec 9, 2022
923d7b0
Merge pull request #1164 from dandi/ls
yarikoptic Dec 12, 2022
4cbadb1
Merge pull request #1170 from dandi/readme-cli
yarikoptic Dec 12, 2022
03854a7
Add validation of filepaths for non-BIDS NWB assets
jwodder Dec 13, 2022
55df999
Adjust organized filename regex
jwodder Dec 14, 2022
101d6ed
Merge pull request #1173 from dandi/gh-1163
yarikoptic Dec 14, 2022
72258b1
BF: convert str errors from checking nwb version into proper Validati…
yarikoptic Dec 14, 2022
8e67482
Merge pull request #1174 from dandi/bf-errors
yarikoptic Dec 14, 2022
8847ee8
Starter to allow user to specify mandatory if not empty fields
yarikoptic Dec 8, 2022
899c2ca
Add `dandi organize` option and change "mandatory" to "required"
jwodder Dec 16, 2022
0a5f20c
Update docs
jwodder Dec 16, 2022
d593992
Fix typing
jwodder Dec 16, 2022
5686277
Add test
jwodder Dec 16, 2022
be00d45
Move `potential_fields` to consts.py and rename to `dandi_layout_fields`
jwodder Dec 19, 2022
b704bca
Merge pull request #1171 from dandi/enh--mandatory
yarikoptic Dec 19, 2022
48e8ccd
Update CHANGELOG.md [skip ci]
Dec 19, 2022
47c524c
Update client for change in Zarr entries API
jwodder Dec 15, 2022
bfb6362
Remove deleted classes from docs
jwodder Dec 15, 2022
1a06a17
Content URLs for Zarrs are no longer followable redirects.
jwodder Dec 19, 2022
c0f018d
Fix uploading of Zarr file entries over pre-existing directories
jwodder Dec 19, 2022
54e2a12
Merge pull request #1175 from dandi/archive-1394
yarikoptic Dec 19, 2022
0eaec43
Update CHANGELOG.md [skip ci]
Dec 19, 2022
1ad8c23
Upload test to check for metadata
TheChymera Dec 20, 2022
ddfe305
Retrieving metadata
TheChymera Dec 20, 2022
cc01263
Getting all relevant assets for testing
TheChymera Dec 20, 2022
288715e
Improving check to not pass if the identifier changes
TheChymera Dec 21, 2022
9aae3bf
Merge pull request #1180 from dandi/metadata
yarikoptic Dec 21, 2022
40d55f1
Non-working draft
TheChymera Nov 9, 2022
2befd3a
Absolute instead of resolve to avoid symlink issues.
TheChymera Nov 11, 2022
b4e2e59
Merge branch 'merge_validation' of github.com:dandi/dandi-cli into me…
TheChymera Dec 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: "CodeQL"

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: "31 5 * * 5"

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ python ]

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
config-file: codeql.yml

- name: Autobuild
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{ matrix.language }}"
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
# 0.48.0 (Mon Dec 19 2022)

#### 🚀 Enhancement

- Update client for change in Zarr entries API [#1175](https://github.com/dandi/dandi-cli/pull/1175) ([@jwodder](https://github.com/jwodder))

#### Authors: 1

- John T. Wodder II ([@jwodder](https://github.com/jwodder))

---

# 0.47.0 (Mon Dec 19 2022)

#### 🚀 Enhancement

- Add validation of filepaths for non-BIDS NWB assets [#1173](https://github.com/dandi/dandi-cli/pull/1173) ([@jwodder](https://github.com/jwodder))
- Exclude special dotfiles from Zarrs [#1147](https://github.com/dandi/dandi-cli/pull/1147) ([@jwodder](https://github.com/jwodder))
- Structured validation results [#1104](https://github.com/dandi/dandi-cli/pull/1104) ([@jwodder](https://github.com/jwodder) [@yarikoptic](https://github.com/yarikoptic) [@TheChymera](https://github.com/TheChymera))

#### 🐛 Bug Fix

- Allow user to specify mandatory (if not empty) fields in organize [#1171](https://github.com/dandi/dandi-cli/pull/1171) ([@yarikoptic](https://github.com/yarikoptic) [@jwodder](https://github.com/jwodder))
- BF: convert str errors from checking nwb version into proper ValidationResult [#1174](https://github.com/dandi/dandi-cli/pull/1174) ([@yarikoptic](https://github.com/yarikoptic))
- Tests for `ls` reinstated, underlying function fixed, support for ZARR-BIDS files added. [#1164](https://github.com/dandi/dandi-cli/pull/1164) ([@TheChymera](https://github.com/TheChymera) [@jwodder](https://github.com/jwodder))
- Add CodeQL workflow for GitHub code scanning and fix few bugs it detected [#1165](https://github.com/dandi/dandi-cli/pull/1165) ([@lgtm-migrator](https://github.com/lgtm-migrator) [@jwodder](https://github.com/jwodder) [@lgtm-com[bot]](https://github.com/lgtm-com[bot]))
- Corrected reporting function logic to complete group message variable [#1166](https://github.com/dandi/dandi-cli/pull/1166) ([@TheChymera](https://github.com/TheChymera))
- Renamed failing test, added prospective use case for NWBI warning. [#1162](https://github.com/dandi/dandi-cli/pull/1162) ([@TheChymera](https://github.com/TheChymera))
- Use cached namespace validation [#1149](https://github.com/dandi/dandi-cli/pull/1149) ([@CodyCBakerPhD](https://github.com/CodyCBakerPhD))

#### 🏠 Internal

- Make `list_paths()` include dotfiles [#1142](https://github.com/dandi/dandi-cli/pull/1142) ([@jwodder](https://github.com/jwodder))

#### 📝 Documentation

- dandi-cli readme edit [#1170](https://github.com/dandi/dandi-cli/pull/1170) ([@melster1010](https://github.com/melster1010))
- Remove Parameters description from docstring used by click [#1150](https://github.com/dandi/dandi-cli/pull/1150) ([@yarikoptic](https://github.com/yarikoptic))

#### 🧪 Tests

- No longer mark `test_rename_type_mismatch` as xfailing [#1161](https://github.com/dandi/dandi-cli/pull/1161) ([@jwodder](https://github.com/jwodder))
- Fix typing error under mypy 0.990 [#1156](https://github.com/dandi/dandi-cli/pull/1156) ([@jwodder](https://github.com/jwodder))
- Update `test_validate_nwb_path_grouping` test [#1157](https://github.com/dandi/dandi-cli/pull/1157) ([@jwodder](https://github.com/jwodder))
- Fixed logic and commented a temporarily broken BIDS (lacking README) dataset [#1148](https://github.com/dandi/dandi-cli/pull/1148) ([@TheChymera](https://github.com/TheChymera))
- Installing hdf5 for Python 3.10 is no longer needed [#1145](https://github.com/dandi/dandi-cli/pull/1145) ([@jwodder](https://github.com/jwodder))
- Fix a typing issue involving the outdated `tmpdir_factory` [#1144](https://github.com/dandi/dandi-cli/pull/1144) ([@jwodder](https://github.com/jwodder))

#### Authors: 7

- [@lgtm-com[bot]](https://github.com/lgtm-com[bot])
- Cody Baker ([@CodyCBakerPhD](https://github.com/CodyCBakerPhD))
- Horea Christian ([@TheChymera](https://github.com/TheChymera))
- John T. Wodder II ([@jwodder](https://github.com/jwodder))
- LGTM Migrator ([@lgtm-migrator](https://github.com/lgtm-migrator))
- Mary Elise Dedicke ([@melster1010](https://github.com/melster1010))
- Yaroslav Halchenko ([@yarikoptic](https://github.com/yarikoptic))

---

# 0.46.6 (Fri Oct 21 2022)

#### 🐛 Bug Fix
Expand Down
105 changes: 73 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,36 @@
[![PyPI version fury.io](https://badge.fury.io/py/dandi.svg)](https://pypi.python.org/pypi/dandi/)
[![Documentation Status](https://readthedocs.org/projects/dandi/badge/?version=latest)](https://dandi.readthedocs.io/en/latest/?badge=latest)

This project is under heavy development. Beware of [hidden](I-wish-we-knew) and
[disclosed](https://github.com/dandi/dandi-cli/issues) issues, or
The [DANDI Python client](https://pypi.org/project/dandi/) allows you to:

* Download `Dandisets` and individual subject folders or files
* Validate data to locally conform to standards
* Organize your data locally before upload
* Upload `Dandisets`
* Interact with the DANDI archive's web API from Python
* Delete data in the DANDI archive
* Perform other auxiliary operations with data or the DANDI archive

**Note**: This project is under heavy development. See [the issues log](https://github.com/dandi/dandi-cli/issues) or
[Work-in-Progress (WiP)](https://github.com/dandi/dandi-cli/pulls).

## Installation

At the moment DANDI client releases are [available from PyPI](https://pypi.org/project/dandi)
and [conda-forge](https://anaconda.org/conda-forge/dandi). You could
install them in your Python (native, virtualenv, or conda) environment via
DANDI Client releases are [available from PyPI](https://pypi.org/project/dandi)
and [conda-forge](https://anaconda.org/conda-forge/dandi). Install them in your Python (native, virtualenv, or
conda) environment via

pip install dandi

or

conda install -c conda-forge dandi

if you are in a conda environment.

## dandi tool
## CLI Tool

This package provides a `dandi` command line utility with a basic interface
which should assist you in preparing and uploading your data to and/or obtaining
data from the http://dandiarchive.org:
This package provides a command line utility with a basic interface
to help you prepare and upload your data to, or obtain data from, the [DANDI archive](http://dandiarchive.org):

```bash
$> dandi
Expand All @@ -45,51 +52,85 @@ Usage: dandi [OPTIONS] COMMAND [ARGS]...

Options:
--version
-l, --log-level [DEBUG|INFO|WARNING|ERROR|CRITICAL]
Log level name [default: INFO]
-l, --log-level [DEBUG|INFO|WARNING|ERROR|CRITICAL]
Log level (case insensitive). May be
specified as an integer. [default: INFO]
--pdb Fall into pdb if errors out
--help Show this message and exit.

Commands:
download Download a file or entire folder from DANDI
ls List .nwb files and dandisets metadata.
organize (Re)organize files according to the metadata.
register Register a new dandiset in the DANDI archive
upload Upload dandiset (files) to DANDI archive.
validate Validate files for NWB (and DANDI) compliance.
delete Delete dandisets and assets from the server.
digest Calculate file digests
download Download a file or entire folder from DANDI.
instances List known Dandi Archive instances that the CLI can...
ls List .nwb files and dandisets metadata.
move Move or rename assets in a local Dandiset and/or on...
organize (Re)organize files according to the metadata.
service-scripts Various utility operations
shell-completion Emit shell script for enabling command completion.
upload Upload Dandiset files to DANDI Archive.
validate Validate files for NWB and DANDI compliance.
validate-bids Validate BIDS paths.
```

Each of the commands has a set of options to alter their behavior. Please run
`dandi COMMAND --help` to get more information, e.g.
Each of the commands has a set of options to alter its behavior. Run
`dandi COMMAND --help` to get more information:

```
$> dandi ls --help
Usage: dandi ls [OPTIONS] [PATHS]...

List .nwb files metadata
Usage: dandi ls [OPTIONS] PATH|URL

List .nwb files and dandisets metadata.

The arguments may be either resource identifiers or paths to local
files/directories.

Accepted resource identifier patterns:
- DANDI:<dandiset id>[/<version>]
- https://dandiarchive.org/...
- https://identifiers.org/DANDI:<dandiset id>[/<version id>] (<version id> cannot be 'draft')
- https://<server>[/api]/[#/]dandiset/<dandiset id>[/<version>][/files[?location=<path>]]
- https://*dandiarchive-org.netflify.app/...
- https://<server>[/api]/dandisets/<dandiset id>[/versions[/<version>]]
- https://<server>[/api]/assets/<asset id>[/download]
- https://<server>[/api]/dandisets/<dandiset id>/versions/<version>/assets/<asset id>[/download]
- https://<server>[/api]/dandisets/<dandiset id>/versions/<version>/assets/?path=<path>
- dandi://<instance name>/<dandiset id>[@<version>][/<path>]
- https://<server>/...

Options:
-F, --fields TEXT Comma-separated list of fields to display.
An empty value to trigger a list of
available fields to be printed out
-f, --format [auto|pyout|json|json_pp|yaml]
-f, --format [auto|pyout|json|json_pp|json_lines|yaml]
Choose the format/frontend for output. If
'auto', 'pyout' will be used in case of
multiple files, and 'yaml' for a single
file.
-r, --recursive Recurse into content of
dandisets/directories. Only .nwb files will
be considered.
-J, --jobs INTEGER Number of parallel download jobs. [default:
6]
--metadata [api|all|assets]
--schema VERSION Convert metadata to new schema version
--help Show this message and exit.
```

See [DANDI Handbook](https://www.dandiarchive.org/handbook/10_using_dandi/)
for examples on how to use this client in various use cases.

## Development/contributing
## Third-party Components

Please see [DEVELOPMENT.md](./DEVELOPMENT.md) file.
**dandi/tests/skip.py** -- from https://github.com/ReproNim/reproman, as of v0.2.1-40-gf4f026d
Copyright (c) 2016-2020 ReproMan Team

## 3rd party components included
## Resources

### dandi/tests/skip.py
* To learn how to interact with the DANDI archive and for examples on how to use the DANDI Client in various use cases,
see [the handbook](https://www.dandiarchive.org/handbook/).

From https://github.com/ReproNim/reproman, as of v0.2.1-40-gf4f026d
Copyright (c) 2016-2020 ReproMan Team
* To get help:
- ask a question: https://github.com/dandi/helpdesk/discussions
- file a feature request or bug report: https://github.com/dandi/helpdesk/issues/new/choose
- contact the DANDI team: [email protected]

* To understand how to contribute to the dandi-cli repository, see the [DEVELOPMENT.md](./DEVELOPMENT.md) file.
4 changes: 4 additions & 0 deletions codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
paths-ignore:
- dandi/_version.py
- dandi/due.py
- versioneer.py
17 changes: 15 additions & 2 deletions dandi/cli/cmd_ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import click

from .base import devel_option, lgr, map_to_click_exceptions
from ..consts import ZARR_EXTENSIONS, metadata_all_fields
from ..dandiarchive import DandisetURL, _dandi_url_parser, parse_dandi_url
from ..misctypes import Digest
from ..utils import is_url
Expand Down Expand Up @@ -92,7 +93,6 @@ def ls(
PYOUTFormatter,
YAMLFormatter,
)
from ..consts import metadata_all_fields

# TODO: avoid
from ..support.pyout import PYOUT_SHORT_NAMES_rev
Expand Down Expand Up @@ -358,7 +358,20 @@ def fn():
digest=Digest.dandi_etag(digest),
).json_dict()
else:
rec = get_metadata(path)
if path.endswith(tuple(ZARR_EXTENSIONS)):
if use_fake_digest:
digest = "0" * 32 + "-0--0"
else:
lgr.info("Calculating digest for %s", path)
digest = get_digest(path, digest="zarr-checksum")
rec = get_metadata(path, Digest.dandi_zarr(digest))
else:
if use_fake_digest:
digest = "0" * 32 + "-1"
else:
lgr.info("Calculating digest for %s", path)
digest = get_digest(path, digest="dandi-etag")
rec = get_metadata(path, Digest.dandi_etag(digest))
except Exception as exc:
_add_exc_error(path, rec, errors, exc)
if flatten:
Expand Down
16 changes: 15 additions & 1 deletion dandi/cli/cmd_organize.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import click

from .base import dandiset_path_option, devel_debug_option, map_to_click_exceptions
from ..consts import file_operation_modes
from ..consts import dandi_layout_fields, file_operation_modes


@click.command()
Expand Down Expand Up @@ -46,11 +48,22 @@
default=None,
help="How to relocate video files referenced by NWB files",
)
@click.option(
"--required-field",
"required_fields",
type=click.Choice(list(dandi_layout_fields)),
multiple=True,
help=(
"Force a given field to be included in the organized filename of any"
" file for which it is nonempty. Can be specified multiple times."
),
)
@click.argument("paths", nargs=-1, type=click.Path(exists=True))
@devel_debug_option()
@map_to_click_exceptions
def organize(
paths,
required_fields,
dandiset_path=None,
invalid="fail",
files_mode="auto",
Expand Down Expand Up @@ -101,4 +114,5 @@ def organize(
devel_debug=devel_debug,
update_external_file_paths=update_external_file_paths,
media_files_mode=media_files_mode,
required_fields=required_fields,
)
Loading