Unified File Explorer

IT EngineersDevelopers

Getting Started

Core Concepts

View files from multiple systems in one place

Unified file exploration connects multiple systems so their files and folders can be viewed from a single exploration screen.

Users can select a connected system and browse its folders to find the files they need, then continue using files from multiple systems within a single work environment.

For example, you can view documents on a work PC, data on a server, and result files on storage from one exploration environment and select the files you need.

Exploration Flow

Continue from system selection through file discovery and transfer

Unified file exploration lets users find required files on connected systems and transfer selected files to the next work environment.

① Select System

② Browse Folders

③ Review Files

④ Select Required Files

⑤ Select Destination

⑥ Transfer Files

⑦ Check Results

This flow connects everything from finding files to transferring them to the required work location and confirming the result.

Business Impact

Connect file exploration and transfer into a single workflow

When work requires files across multiple systems, users first identify where the required files are, find them on that system, and prepare them for the next work environment.

With unified file exploration, users can find required files on connected systems and transfer selected files directly to a designated system or workspace.

CategorySystem-by-System File ManagementUnified File Explorer
Work StartIdentify the system containing the required filesSelect directly from the connected system list
File ExplorationReview files and folders in each system's environmentExplore systems and files from a single view
File PreparationPrepare files for the next work location after reviewing themTransfer selected files directly to the destination system
Workflow ConnectionContinue to the next task after preparing filesUse files immediately for the next task after transfer

By configuring file exploration and transfer as a single flow, files across multiple work environments can be used immediately where they are needed.

IT Engineers

Build and manage a file exploration environment across multiple systems

System Connection

Connect the systems to explore and extend the environment as needed

To configure unified file exploration, first connect the systems used in the work environment, such as PCs, servers, and storage systems, whose files need to be reviewed.

By configuring connection information for each system, its files and folders can be viewed from the unified exploration screen.

As the work environment expands, new servers or storage systems can be added in the same way. After configuring their connection information, include them in the existing exploration environment.

System TypeFiles Used
Work PCPersonal and team work files
Windows ServerBusiness documents and operational files
Linux ServerData and processing files
StorageShared files and result files

Adding systems extends the exploration scope to the systems required for work while preserving the existing file exploration environment.

Access Scope

Set the file and folder scope each user and system can access

After connecting the systems, configure the systems and file paths each user can view according to their role and responsibilities.

Specify the systems each user or user group can explore and configure the folder scope available on each system.

For example, configure the operations team to view designated folders on operational servers, while the data team can view work paths on analysis servers and data storage.

User GroupSystems to ExploreFile Scope
Operations TeamOperations ServerOperational file paths
Data TeamAnalysis ServerData folders
Business TeamShared StorageBusiness document folders

Configuring exploration scope by user lets you operate the unified file exploration environment around the systems and files each role requires.

File Exploration

Find required files across connected systems

Once systems and access scopes are configured, users can select a system in the unified exploration screen and browse its folders and files.

Selecting a system from the system list displays its folder structure and file list, allowing users to find required files by name and path.

The file exploration screen provides the following information.

Review ItemDetails
DeviceSystem containing the file
PathCurrent file path
File NameFile name
SizeFile size
ModifiedLast modified time

When the required file is found, select it to continue directly to the next transfer task.

File Transfer

Transfer selected files to the required systems and workspaces

After selecting the required files in the exploration screen, specify the destination system and path.

Selected files are transferred from their current location to the designated destination system or workspace, where they can be reviewed and used for the next task.

The transfer flow is configured as follows.

text
Device A
   │
   │ File Exploration
   ▼
Select Files
   │
   │ Select Destination
   ▼
Device B
   │
   ▼
Workspace

Finding files and specifying the destination in a single exploration screen connects file exploration and transfer into one workflow.

Verify Results

Check transfer status and file processing results

When a file transfer runs, review task progress and processing results in Runs.

Each task shows the Source and Target of the transferred files, file count and transfer volume, progress, execution time, and current status.

Review ItemDetails
SourceSystem and path from which the files were selected
TargetSystem or workspace receiving the files
FilesNumber of files processed
SizeTotal transfer volume
ProgressTransfer progress
StatusCurrent task status
TimeExecution and completion time

Operators can use execution results to review file transfer flows between systems and manage how files were applied to each work environment.

Developers

Execute transfers between systems by retrieving remote file lists and search results through APIs

Integration Preparation

Prepare shared request code and status values

import os
import requests

BASE_URL = os.getenv("INNORIX_BASE_URL", "https://app.innorix.com").rstrip("/")
TOKEN = os.environ["INNORIX_ACCESS_TOKEN"]
WORKSPACE_ID = os.getenv("INNORIX_WORKSPACE_ID")   # optional; falls back to the current workspace

STATUS_COMPLETE = 2
TERMINAL = {2, 4, 5, 9, 99}          # complete / error / cancelled / partial / failed
NOT_SUCCEEDED = {4, 5, 9, 99}


def api(method, path, body=None, params=None):
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {TOKEN}",
    }

    if WORKSPACE_ID:
        headers["x-workspace-id"] = WORKSPACE_ID

    response = requests.request(
        method, BASE_URL + path,
        headers=headers, json=body, params=params, timeout=30,
    )

    payload = response.json() if response.content else {}

    if not response.ok:
        raise RuntimeError(payload.get("message") or f"HTTP {response.status_code}")

    return payload.get("data")


def is_terminal(detail):
    return detail.get("isTerminal", detail.get("status") in TERMINAL)

Determine the transfer status using the values below. There are five terminal states, and the successful state is Complete (2).

Status ValueMeaningTerminal
2CompleteYes
4ErrorYes
5CancelledYes
9Partially CompleteYes
99FailedYes
1 · 6 · 12 · 13Started · Transferring · Synchronizing · ReceivingNo

List Folders

Retrieve the file list for each system and display it on screen

Specify the system identifier and path to retrieve files and subfolders. The value passed to --device becomes a path parameter, so it must be the device ID.

result = api("GET", f"/api/devices/{device_id}/files", params={
    "path": "/data/reports",
    "page": 1,
    "size": 50,
    "sort": "name:asc",
    "type": "all",
})

for item in result["items"]:
    kind = "DIR " if item["isDir"] else "FILE"
    print(kind, item["name"], item["size"], item.get("modifiedAt"))
Response ItemDetails
itemsList of files and folders
total · lastPageTotal count and last page
truncatedWhether some items were omitted because the item count exceeded the limit
isDirWhether the item is a folder

Retrieve the device ID through the device list endpoint.

result = api("GET", "/api/devices", params={"page": 1, "size": 200})

for device in result["devices"]:
    print(device["deviceId"], device["name"], device.get("os"),
          device.get("ipAddress"))

The device list is returned in the data.devices array.

Recursively search subfolders to find files

Folder listing shows only the specified folder. To search through subfolders, start a search and continue retrieving results with the cursor.

RESTART_CODES = {"INVALID_CURSOR", "CURSOR_OUT_OF_SEQUENCE", "SEARCH_EXPIRED"}


def start_search(device_id, path, page_size=500):
    return api("POST", f"/api/devices/{device_id}/files/search",
               {"path": path, "pageSize": page_size})


def iter_search(device_id, path, max_pages=200):
    page = start_search(device_id, path)
    search_id = page.get("searchId")

    for _ in range(max_pages):
        for item in page.get("items") or []:
            yield search_id, item

        if not page.get("hasMore"):
            return

        try:
            page = api("GET", f"/api/devices/{device_id}/files/search",
                       params={"cursor": page["nextCursor"]})
        except RuntimeError:
            # restart the scan when the cursor expires or falls out of sequence
            page = start_search(device_id, path)
            search_id = page.get("searchId")

The search request accepts only the base path and page size. Name and extension conditions are evaluated against the returned results, so narrowing the base path reduces the search scope.

Response ItemDetails
searchIdSearch identifier passed to a stop request
items[].typefile or directory
hasMore · nextCursorWhether another page exists and the cursor to use for the next request

Stop Search

Stop an in-progress search

Search requires the system to actually scan its disk. Stop the search when the user leaves the screen so system load does not continue to accumulate.

def cancel_search(device_id, search_id):
    api("POST", f"/api/devices/{device_id}/files/search/cancel",
        {"uuid": search_id})       # pass the searchId returned when the search started


search_id = None

try:
    for search_id, item in iter_search(device_id, "/data"):
        if item["type"] == "file" and item["name"].endswith(".csv"):
            print(item["path"], item["size"])
finally:
    if search_id:
        cancel_search(device_id, search_id)

Use the same cleanup code both when starting a new search and when closing the screen.

File Transfer

Transfer selected files to another system

Immediate transfers can identify the system by name, IP address, or identifier, and the path is passed as a plain-text string. This differs from the exploration API, which accepts only a device ID.

When sending a file list, explicitly set isDir: false in sourceItem rather than using sourcePaths. sourcePaths treats every path as a folder, so supplying files can cause the server to scan each file as a folder, resulting in slowdowns or timeouts.

def send_files(source, target, target_path, paths, action="numbering"):
    transfer = api("POST", "/api/transfers/manual", {
        "sourceDevice": source,
        "targetDevice": target,
        "targetPath": target_path,
        "sourceItem": [{"path": p, "isDir": False} for p in paths],
        "sendAllFolder": False,
        "transferOptions": {"target-action": action},
    })

    return transfer["monitorId"]


monitor_id = send_files("device-a", "device-b", "/data/collected",
                        ["/data/reports/2026-08.csv"])

When sending folders, use sourcePaths with sendAllFolder: True.

api("POST", "/api/transfers/manual", {
    "sourceDevice": "device-a",
    "targetDevice": "device-b",
    "targetPath": "/data/collected",
    "sourcePaths": ["/data/reports"],
    "sendAllFolder": True,
    "transferOptions": {"target-action": "numbering"},
})

If the file size is already known, provide fileSize as well so the server can skip retrieving each item's size.

"sourceItem": [
  { "path": "/data/a.csv", "isDir": false, "fileSize": 1200 }
]

Verify Results

Check transfer status and file-level processing results

import time


def wait(monitor_id, timeout=1800, interval=3):
    deadline = time.time() + timeout

    while time.time() < deadline:
        detail = api("GET", f"/api/transfers/{monitor_id}")

        if is_terminal(detail):
            return detail

        time.sleep(interval)

    raise TimeoutError(monitor_id)


detail = wait(monitor_id)
succeeded = detail["status"] == STATUS_COMPLETE

Total failure and partial failure should be displayed differently on the screen. Retrieve file-level status and retransmit only the failed files.

def failed_files(monitor_id):
    result = api("GET", f"/api/transfers/{monitor_id}/files", params={
        "state": "any", "size": 500,
    }) or {}

    return [r for r in (result.get("children") or [])
            if r.get("status") in NOT_SUCCEEDED]


def retry_failed(monitor_id):
    rows = failed_files(monitor_id)

    if not rows:
        return 0

    api("POST", f"/api/transfers/{monitor_id}/retry", {
        "filesRetry": [
            {"filePath": r["sourceFilePath"], "isDir": bool(r.get("isFolder"))}
            for r in rows
        ]
    })

    return len(rows)

Retransmission can be called only after the transfer has ended. It is rejected while the transfer is in progress, so check the status first.

Review ItemDetails
statusTransfer status value
statusLabelStatus text displayed on screen
percentProgress
fileCount · totalSizeProcessed file count and total size
children[].errorCodeFailure reason for each file