Skip to content

Commit

Permalink
Merge pull request #1414 from dandi/gh-1413
Browse files Browse the repository at this point in the history
Add arguments for API query parameters when fetching all Dandisets; support creating embargoed Dandisets
  • Loading branch information
yarikoptic authored Feb 29, 2024
2 parents c99385d + 1ed5a55 commit 2cafb50
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 9 deletions.
76 changes: 70 additions & 6 deletions dandi/dandiapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,19 +554,83 @@ def get_dandiset(
return d.for_version(version_id)
return d

def get_dandisets(self) -> Iterator[RemoteDandiset]:
def get_dandisets(
self,
*,
draft: bool | None = None,
embargoed: bool | None = None,
empty: bool | None = None,
mine: bool | None = None,
order: str | None = None,
search: str | None = None,
) -> Iterator[RemoteDandiset]:
"""
Returns a generator of all Dandisets on the server. For each Dandiset,
the `RemoteDandiset`'s version is set to the most recent published
version if there is one, otherwise to the draft version.
"""
for data in self.paginate("/dandisets/"):
.. versionchanged:: 0.61.0
``draft``, ``embargoed``, ``empty``, ``mine``, ``order``, and
``search`` parameters added
:param draft:
If true, Dandisets that have only draft versions (i.e., that
haven't yet been published) will be included in the results
(default true)
:param embargoed:
If true, embargoed Dandisets will be included in the results
(default false)
:param empty:
If true, empty Dandisets will be included in the results (default
true)
:param mine:
If true, only Dandisets owned by the authenticated user will be
retrieved (default false)
:param order:
The field to sort the results by. The accepted field names are
``"id"``, ``"name"``, ``"modified"``, and ``"size"``. Prepend a
hyphen to the field name to reverse the sort order.
:param search:
A search string to filter the returned Dandisets by. The string is
searched for in the metadata of Dandiset versions.
"""
for data in self.paginate(
"/dandisets/",
params={
"draft": draft,
"embargoed": embargoed,
"empty": empty,
"ordering": order,
"search": search,
"user": "me" if mine else None,
},
):
yield RemoteDandiset.from_data(self, data)

def create_dandiset(self, name: str, metadata: dict[str, Any]) -> RemoteDandiset:
"""Creates a Dandiset with the given name & metadata"""
def create_dandiset(
self, name: str, metadata: dict[str, Any], *, embargo: bool = False
) -> RemoteDandiset:
"""
Creates a Dandiset with the given name & metadata. If ``embargo`` is
`True`, the resulting Dandiset will be embargoed.
.. versionchanged:: 0.61.0
``embargo`` argument added
"""
return RemoteDandiset.from_data(
self, self.post("/dandisets/", json={"name": name, "metadata": metadata})
self,
self.post(
"/dandisets/",
json={"name": name, "metadata": metadata},
params={"embargo": "true" if embargo else "false"},
),
)

def check_schema_version(self, schema_version: str | None = None) -> None:
Expand Down
3 changes: 2 additions & 1 deletion dandi/tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ class SampleDandisetFactory:
local_dandi_api: DandiAPI
tmp_path_factory: pytest.TempPathFactory

def mkdandiset(self, name: str) -> SampleDandiset:
def mkdandiset(self, name: str, embargo: bool = False) -> SampleDandiset:
d = self.local_dandi_api.client.create_dandiset(
name,
# Minimal metadata needed to create a publishable Dandiset:
Expand All @@ -539,6 +539,7 @@ def mkdandiset(self, name: str) -> SampleDandiset:
}
],
},
embargo=embargo,
)
dspath = self.tmp_path_factory.mktemp("dandiset")
(dspath / dandiset_metadata_file).write_text(f"identifier: '{d.identifier}'\n")
Expand Down
44 changes: 42 additions & 2 deletions dandi/tests/test_dandiapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import requests
import responses

from .fixtures import DandiAPI, SampleDandiset
from .fixtures import DandiAPI, SampleDandiset, SampleDandisetFactory
from .skip import mark
from .. import dandiapi
from ..consts import (
Expand Down Expand Up @@ -329,7 +329,47 @@ def test_check_schema_version_mismatch() -> None:

def test_get_dandisets(text_dandiset: SampleDandiset) -> None:
dandisets = list(text_dandiset.client.get_dandisets())
assert sum(1 for d in dandisets if d.identifier == text_dandiset.dandiset_id) == 1
assert text_dandiset.dandiset_id in [d.identifier for d in dandisets]


def test_get_embargoed_dandisets(
sample_dandiset_factory: SampleDandisetFactory,
) -> None:
ds = sample_dandiset_factory.mkdandiset("Embargoed Dandiset", embargo=True)
dandisets = list(ds.client.get_dandisets(embargoed=True))
assert ds.dandiset_id in [d.identifier for d in dandisets]
dandisets = list(ds.client.get_dandisets(embargoed=False))
assert ds.dandiset_id not in [d.identifier for d in dandisets]
dandisets = list(ds.client.get_dandisets(embargoed=None))
assert ds.dandiset_id not in [d.identifier for d in dandisets]


def test_get_draft_dandisets(new_dandiset: SampleDandiset) -> None:
dandisets = list(new_dandiset.client.get_dandisets(draft=True))
assert new_dandiset.dandiset_id in [d.identifier for d in dandisets]
dandisets = list(new_dandiset.client.get_dandisets(draft=False))
assert new_dandiset.dandiset_id not in [d.identifier for d in dandisets]
dandisets = list(new_dandiset.client.get_dandisets(draft=None))
assert new_dandiset.dandiset_id in [d.identifier for d in dandisets]


def test_get_empty_dandisets(new_dandiset: SampleDandiset) -> None:
dandisets = list(new_dandiset.client.get_dandisets(empty=True))
assert new_dandiset.dandiset_id in [d.identifier for d in dandisets]
dandisets = list(new_dandiset.client.get_dandisets(empty=False))
assert new_dandiset.dandiset_id not in [d.identifier for d in dandisets]
dandisets = list(new_dandiset.client.get_dandisets(empty=None))
assert new_dandiset.dandiset_id in [d.identifier for d in dandisets]


def test_search_get_dandisets(
sample_dandiset_factory: SampleDandisetFactory,
) -> None:
ds = sample_dandiset_factory.mkdandiset("Unicorn Dandiset")
dandisets = list(ds.client.get_dandisets(search="Unicorn"))
assert ds.dandiset_id in [d.identifier for d in dandisets]
dandisets = list(ds.client.get_dandisets(search="Dragon"))
assert ds.dandiset_id not in [d.identifier for d in dandisets]


def test_get_dandiset_lazy(
Expand Down

0 comments on commit 2cafb50

Please sign in to comment.