11from __future__ import annotations
22
3+ import os
4+ import re
35from abc import ABC , abstractmethod
46from collections import deque
57from collections .abc import Iterator
68from concurrent .futures import ThreadPoolExecutor , as_completed
79from dataclasses import dataclass
810from datetime import datetime
9- import os
1011from pathlib import Path
11- import re
1212from threading import Lock
1313from typing import IO , Any , Generic
1414from xml .etree .ElementTree import fromstring
1515
1616import dandischema
17+ import requests
1718from dandischema .consts import DANDI_SCHEMA_VERSION
1819from dandischema .digests .dandietag import DandiETag
19- from dandischema .models import BareAsset , CommonModel
20+ from dandischema .models import BareAsset , CommonModel , get_schema_version
2021from dandischema .models import Dandiset as DandisetMeta
21- from dandischema .models import get_schema_version
2222from packaging .version import Version
2323from pydantic import ValidationError
2424from pydantic_core import ErrorDetails
25- import requests
2625
2726import dandi
2827from dandi .dandiapi import RemoteAsset , RemoteDandiset , RESTFullAPIClient
@@ -320,6 +319,7 @@ def iter_upload(
320319 metadata : dict [str , Any ],
321320 jobs : int | None = None ,
322321 replacing : RemoteAsset | None = None ,
322+ zarr_id : str = "" ,
323323 ) -> Iterator [dict ]:
324324 """
325325 Upload the file as an asset with the given metadata to the given
@@ -335,6 +335,9 @@ def iter_upload(
335335 :param RemoteAsset replacing:
336336 If set, replace the given asset, which must have the same path as
337337 the new asset
338+ :param str zarr_id:
339+ The zarr id being uploaded to, if applicable. If set, this will
340+ modify the request params to the archive.
338341 :returns:
339342 A generator of `dict`\\ s containing at least a ``"status"`` key.
340343 Upon successful upload, the last `dict` will have a status of
@@ -361,17 +364,23 @@ def iter_upload(
361364 lgr .debug ("%s: Beginning upload" , asset_path )
362365 total_size = pre_upload_size_check (self .filepath )
363366 try :
364- resp = client .post (
365- "/uploads/initialize/" ,
366- json = {
367- "contentSize" : total_size ,
368- "digest" : {
369- "algorithm" : "dandi:dandi-etag" ,
370- "value" : filetag ,
371- },
372- "dandiset" : dandiset .identifier ,
367+ body = {
368+ "contentSize" : total_size ,
369+ "digest" : {
370+ "algorithm" : "dandi:dandi-etag" ,
371+ "value" : filetag ,
373372 },
374- )
373+ }
374+
375+ if zarr_id :
376+ body ["zarr" ] = {
377+ "chunk_key" : asset_path ,
378+ "zarr_id" : zarr_id ,
379+ }
380+ else :
381+ body ["dandiset" ] = dandiset .identifier
382+
383+ resp = client .post ("/uploads/initialize/" , json = body )
375384 except requests .HTTPError as e :
376385 if e .response is not None and e .response .status_code == 409 :
377386 lgr .debug ("%s: Blob already exists on server" , asset_path )
@@ -583,8 +592,8 @@ def get_validation_errors(
583592 )
584593
585594 # Avoid circular imports by importing within function:
586- from .bids import NWBBIDSAsset
587595 from ..organize import validate_organized_path
596+ from .bids import NWBBIDSAsset
588597
589598 if not isinstance (self , NWBBIDSAsset ) and self .dandiset_path is not None :
590599 errors .extend (
0 commit comments