Skip to content

Commit

Permalink
Convert dandiarchive URL classes from pydantic models to dataclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
jwodder committed Nov 9, 2023
1 parent cb86c9c commit 34ff697
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
5 changes: 1 addition & 4 deletions dandi/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from dataclasses import dataclass
from enum import Enum
import os
from typing import Union

#: A list of metadata fields which dandi extracts from .nwb files.
#: Additional fields (such as ``number_of_*``) might be added by
Expand Down Expand Up @@ -99,9 +98,7 @@ class EmbargoStatus(Enum):
@dataclass(frozen=True)
class DandiInstance:
name: str
# This class is used as an attribute of ParsedDandiURL, a Pydantic class,
# and thus we need non-future annotations:
gui: Union[str, None]
gui: str | None
api: str

@property
Expand Down
23 changes: 18 additions & 5 deletions dandi/dandiarchive.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@
from abc import ABC, abstractmethod
from collections.abc import Iterable, Iterator
from contextlib import contextmanager
from dataclasses import dataclass, field
import posixpath
import re
from time import sleep
from typing import Any, Union
from typing import Any
from urllib.parse import unquote as urlunquote

from pydantic import AnyHttpUrl, BaseModel, parse_obj_as
from pydantic import AnyHttpUrl, parse_obj_as
import requests

from . import get_logger
Expand All @@ -55,7 +56,8 @@
lgr = get_logger()


class ParsedDandiURL(ABC, BaseModel):
@dataclass
class ParsedDandiURL(ABC):
"""
Parsed representation of a URL pointing to a Dandi Archive resource
(Dandiset or asset(s)). Subclasses must implement `get_assets()`.
Expand All @@ -70,11 +72,11 @@ class ParsedDandiURL(ABC, BaseModel):
#: The Dandi Archive instance that the URL points to
instance: DandiInstance
#: The ID of the Dandiset given in the URL
dandiset_id: Union[str, None]
dandiset_id: str | None
#: The version of the Dandiset, if specified. If this is not set, the
#: version will be defaulted using the rules described under
#: `DandiAPIClient.get_dandiset()`.
version_id: Union[str, None] = None
version_id: str | None

@property
def api_url(self) -> AnyHttpUrl:
Expand Down Expand Up @@ -215,6 +217,7 @@ def is_under_download_path(self, path: str) -> bool:
...


@dataclass
class DandisetURL(ParsedDandiURL):
"""
Parsed from a URL that only refers to a Dandiset (possibly with a version)
Expand All @@ -236,6 +239,7 @@ def is_under_download_path(self, path: str) -> bool:
return True


@dataclass
class SingleAssetURL(ParsedDandiURL):
"""Superclass for parsed URLs that refer to a single asset"""

Expand All @@ -248,6 +252,7 @@ def is_under_download_path(self, path: str) -> bool:
)


@dataclass
class MultiAssetURL(ParsedDandiURL):
"""Superclass for parsed URLs that refer to multiple assets"""

Expand All @@ -264,12 +269,15 @@ def is_under_download_path(self, path: str) -> bool:
return path.startswith(self.path)


@dataclass
class BaseAssetIDURL(SingleAssetURL):
"""
Parsed from a URL that refers to an asset by ID and does not include the
Dandiset ID
"""

dandiset_id: None = field(init=False, default=None)
version_id: None = field(init=False, default=None)
asset_id: str

def get_assets(
Expand Down Expand Up @@ -313,6 +321,7 @@ def navigate(
yield (client, dandiset, assets)


@dataclass
class AssetIDURL(SingleAssetURL):
"""
Parsed from a URL that refers to an asset by ID and includes the Dandiset ID
Expand All @@ -338,6 +347,7 @@ def get_asset_ids(self, client: DandiAPIClient) -> Iterator[str]:
yield self.asset_id


@dataclass
class AssetPathPrefixURL(MultiAssetURL):
"""
Parsed from a URL that refers to a collection of assets by path prefix
Expand Down Expand Up @@ -366,6 +376,7 @@ def get_assets(
raise NotFoundError(f"No assets found with path prefix {self.path!r}")


@dataclass
class AssetItemURL(SingleAssetURL):
"""Parsed from a URL that refers to a specific asset by path"""

Expand Down Expand Up @@ -414,6 +425,7 @@ def get_assets(
)


@dataclass
class AssetFolderURL(MultiAssetURL):
"""
Parsed from a URL that refers to a collection of assets by folder path
Expand Down Expand Up @@ -446,6 +458,7 @@ def get_assets(
raise NotFoundError(f"No assets found under folder {path!r}")


@dataclass
class AssetGlobURL(MultiAssetURL):
"""
.. versionadded:: 0.54.0
Expand Down

0 comments on commit 34ff697

Please sign in to comment.