Skip to content

Download files

As noted in Download files (Public API), the sandbox has restrictions on downloading files from a task.

To work around this limitation, download files using the UI API.

Code example
import asyncio

import aiofiles

from ptsandbox import Sandbox
from ptsandbox.models import SandboxKey, StorageItem


async def main():
    async with Sandbox(SandboxKey(...)) as sandbox:
        await sandbox.ui.authorize()

        items: list[StorageItem] = [
            {"sha256": "..."},
            {"sha256": "...", "name": "..."}
        ]

        async with aiofiles.open("./artifacts.zip", "wb") as fd:
            async for chunk in sandbox.ui.get_files(items):
                await fd.write(chunk)

Note

The response is a zip archive protected with the password "infected". You need to extract it yourself.

For example, using pyzipper.

ptsandbox.sandbox.ui._artifacts.ArtifactsMixin.get_files async

get_files(items: list[StorageItem]) -> AsyncIterator[bytes]

Download file via UI API

Parameters:

  • items (list[StorageItem]) –

    the list of files to download

Returns:

  • AsyncIterator[bytes] –

    ZIP archive with "infected" password

  • AsyncIterator[bytes] –

    Please note that if one of the hashes doesn't exist, and the others do,

  • AsyncIterator[bytes] –

    then the archive will be only with existing hashes.

Raises:

  • SandboxException –

    if not authorized or token refresh fails

  • ClientResponseError –

    if the server returns an error status (404 if none of the files are found)

  • ClientError –

    on connection or transport errors

Download logs from recent tasks

import asyncio
from pathlib import Path

import aiofiles

from ptsandbox import Sandbox, SandboxKey
from ptsandbox.models import StorageItem, ScanArtifactType


async def main():
    sandbox = Sandbox(SandboxKey(...))

    await sandbox.ui.authorize()

    tasks = await sandbox.ui.get_tasks()
    for task in tasks.tasks:
        summary = await sandbox.ui.get_task_tree(task.id)

        items: list[StorageItem] = []

        for children in summary.children:
            if not children.scan_artifacts:
                continue

            for artifact in children.scan_artifacts:
                if artifact.type in {
                    ScanArtifactType.CORRELATED,
                    ScanArtifactType.NORMALIZED,
                    ScanArtifactType.DEBUG,
                    ScanArtifactType.VIDEO,
                }:
                    items.append({"sha256": artifact.sha256, "name": artifact.name})

        path = Path("./tasks") / str(task.id)
        path.mkdir(parents=True, exist_ok=True)

        async with aiofiles.open(path / "logs.zip", "wb") as fd:
            async for chunk in sandbox.ui.get_files(items):
                await fd.write(chunk)


asyncio.run(main())