def download(auth, label, scan_ids=None, project=None, aid=None,<EOL>out_dir='<STR_LIT:.>', in_mem=True, progress=False, attempts=<NUM_LIT:1>):
if not scan_ids:<EOL><INDENT>scan_ids = ['<STR_LIT>']<EOL><DEDENT>if not aid:<EOL><INDENT>aid = accession(auth, label, project)<EOL><DEDENT>url = "<STR_LIT>" % (auth.url.rstrip('<STR_LIT:/>'), <EOL>aid, '<STR_LIT:U+002C>'.join([str(x) for x in scan_ids]))<EOL>backoff = <NUM_LIT:10><EOL>for _ in range(attempts): <EOL><INDENT>logger.debug("<STR_LIT>", url)<EOL>r = requests.get(url, stream=True, auth=(auth.username, auth.password), verify=CHECK_CERTIFICATE)<EOL>logger.debug("<STR_LIT>", r.headers)<EOL>if r.status_code == requests.codes.ok:<EOL><INDENT>break<EOL><DEDENT>fuzz = random.randint(<NUM_LIT:0>, <NUM_LIT:10>)<EOL>logger.warn("<STR_LIT>", r.status_code, <EOL>backoff + fuzz)<EOL>time.sleep(backoff + fuzz)<EOL>backoff *= <NUM_LIT:2><EOL><DEDENT>if r.status_code != requests.codes.ok:<EOL><INDENT>raise DownloadError("<STR_LIT>" % (r.status_code, r.url))<EOL><DEDENT>if not os.path.exists(out_dir):<EOL><INDENT>os.makedirs(out_dir)<EOL><DEDENT>if in_mem:<EOL><INDENT>content = io.BytesIO()<EOL>logger.debug("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>content = tf.NamedTemporaryFile(dir=out_dir, prefix="<STR_LIT>", suffix="<STR_LIT>")<EOL>logger.debug("<STR_LIT>", content.name)<EOL><DEDENT>if progress:<EOL><INDENT>sys.stdout.write("<STR_LIT>")<EOL>sys.stdout.flush()<EOL><DEDENT>meter = <NUM_LIT:0><EOL>chunk_size = <NUM_LIT><EOL>for chunk in r.iter_content(chunk_size=chunk_size):<EOL><INDENT>if progress and meter >= progress:<EOL><INDENT>sys.stdout.write(next(commons.spinner)); sys.stdout.flush()<EOL>sys.stdout.write('<STR_LIT>')<EOL>meter = <NUM_LIT:0><EOL><DEDENT>content.write(chunk)<EOL>meter += chunk_size<EOL><DEDENT>if progress:<EOL><INDENT>sys.stdout.write('<STR_LIT>'); sys.stdout.flush()<EOL><DEDENT>try:<EOL><INDENT>zf = zipfile.ZipFile(content, allowZip64=True)<EOL><DEDENT>except zipfile.BadZipfile:<EOL><INDENT>with tf.NamedTemporaryFile(dir=out_dir, prefix="<STR_LIT>",<EOL>suffix="<STR_LIT>", delete=False) as fo:<EOL><INDENT>content.seek(<NUM_LIT:0>)<EOL>fo.write(content.read())<EOL><DEDENT>raise DownloadError("<STR_LIT>" % fo.name)<EOL><DEDENT>logger.debug("<STR_LIT>", out_dir)<EOL>extract(zf, content, out_dir)<EOL>
Download scan data from XNAT.

Example:
    >>> import yaxil
    >>> auth = yaxil.XnatAuth(url='...', username='...', password='...')
    >>> yaxil.download(auth, 'AB1234C', ['1', '2'], out_dir='./data')

:param auth: XNAT authentication object
:type auth: :mod:`yaxil.XnatAuth`
:param label: XNAT MR Session label
:type label: str
:param scan_ids: Scan numbers to return; use None for all
:type scan_ids: list
:param project: XNAT MR Session project
:type project: str
:param aid: XNAT Accession ID
:type aid: str
:param out_dir: Output directory
:type out_dir: str
:param in_mem: Keep download content in memory; faster but uses more memory
:type in_mem: bool
:param progress: Show download progress every N bytes
:type progress: int
:param attempts: Number of download attempts
:type attempts: int