Knowledge Base

Find answers to common questions about Cloudmersive products and services.



Scan Files in Folder for Viruses with Python and Cloudmersive Advanced Scan Sample
12/22/2025 - Cloudmersive Suport


In this sample, we will use the Python SDK for Cloudmersive Advanced Virus Scanning API to scan all the files in a local disk folder and tally up the results.

First, we need to install the Cloudmersive Python SDK:

pip install cloudmersive_virus_api_client

Now, we can setup and run our Python script. Fill in the variables BASE_PATH with the folder that you would like to scan (all child files will be scanned). Set API_KEY to your API key. For Managed Instance and Private Cloud be sure to set API_HOST to your API host, e.g. https://my-host-name.azurewebsites.net.

import json
import sys
from pathlib import Path

import cloudmersive_virus_api_client
from cloudmersive_virus_api_client.rest import ApiException



# =========================
# CONFIG (edit these)
# =========================
BASE_PATH = r"C:\\input"
API_KEY = "YOUR-API-KEY-HERE"

# Optional knobs
RECURSIVE = True  # True = include subfolders, False = only files directly in BASE_PATH
API_HOST = "https://api.cloudmersive.com"  # change only if using a private/managed instance
# =========================


def iter_files(base_dir: Path, recursive: bool):
    if recursive:
        for p in base_dir.rglob("*"):
            if p.is_file():
                yield p
    else:
        for p in base_dir.iterdir():
            if p.is_file():
                yield p


def pretty_json(obj) -> str:
    return json.dumps(obj, indent=2, sort_keys=True, ensure_ascii=False, default=str)


def main() -> int:
    base_dir = Path(BASE_PATH)

    if not base_dir.exists():
        print(f"ERROR: BASE_PATH does not exist: {base_dir}", file=sys.stderr)
        return 2
    if not base_dir.is_dir():
        print(f"ERROR: BASE_PATH is not a directory: {base_dir}", file=sys.stderr)
        return 2

    # Configure Cloudmersive API client
    configuration = cloudmersive_virus_api_client.Configuration()
    configuration.api_key["Apikey"] = API_KEY
    configuration.host = API_HOST

    api_client = cloudmersive_virus_api_client.ApiClient(configuration)
    scan_api = cloudmersive_virus_api_client.ScanApi(api_client)

    clean_count = 0
    infected_count = 0
    error_count = 0
    total_files = 0

    files = list(iter_files(base_dir, RECURSIVE))
    total_files = len(files)

    if total_files == 0:
        print(f"No files found in: {base_dir}")
        print("\nSUMMARY")
        print(f"Total files found: {total_files}")
        print(f"Clean files: {clean_count}")
        print(f"Infected/Not-clean files: {infected_count}")
        return 0

    for file_path in files:
        # Display a nice relative file name if possible
        try:
            display_name = str(file_path.relative_to(base_dir))
        except Exception:
            display_name = str(file_path)

        print("\n" + "=" * 80)
        print(f"File: {display_name}")

        try:
            # Advanced Scan a file for viruses
            result_obj = scan_api.scan_file_advanced(str(file_path))

            # Convert SDK model -> JSON-serializable dict using swagger client's sanitizer
            result_json = api_client.sanitize_for_serialization(result_obj)

            print(pretty_json(result_json))

            # Determine clean vs infected/not-clean
            # Prefer the model attribute if available, else fall back to JSON
            is_clean = getattr(result_obj, "clean_result", None)
            if is_clean is None:
                is_clean = result_json.get("CleanResult", result_json.get("clean_result"))

            if is_clean is True:
                clean_count += 1
            else:
                infected_count += 1

        except ApiException as e:
            error_count += 1
            # Try to show any JSON error body if provided
            error_payload = {
                "error": "ApiException",
                "status": getattr(e, "status", None),
                "reason": getattr(e, "reason", None),
                "body": getattr(e, "body", None),
            }
            print(pretty_json(error_payload))
        except Exception as e:
            error_count += 1
            error_payload = {"error": "Exception", "message": str(e)}
            print(pretty_json(error_payload))

    print("\n" + "=" * 80)
    print("SUMMARY")
    print(f"Total files found: {total_files}")
    print(f"Clean files: {clean_count}")
    print(f"Infected/Not-clean files: {infected_count}")
    if error_count:
        print(f"Errors (scan failed): {error_count}")

    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Sample Output

================================================================================
File: Antlr3.Runtime.dll
{
  "CleanResult": false,
  "ContainsExecutable": true,
  "ContainsHtml": false,
  "ContainsInsecureDeserialization": false,
  "ContainsInvalidFile": false,
  "ContainsMacros": false,
  "ContainsOleEmbeddedObject": false,
  "ContainsPasswordProtectedFile": false,
  "ContainsRestrictedFileFormat": false,
  "ContainsScript": false,
  "ContainsUnsafeArchive": false,
  "ContainsXmlExternalEntities": false,
  "ContentInformation": {
    "ContainsImage": false,
    "ContainsJSON": false,
    "ContainsXML": false
  },
  "VerifiedFileFormat": ""
}

================================================================================
File: Cloudmersive Subscription Levels.pdf
{
  "CleanResult": true,
  "ContainsExecutable": false,
  "ContainsHtml": false,
  "ContainsInsecureDeserialization": false,
  "ContainsInvalidFile": false,
  "ContainsMacros": false,
  "ContainsOleEmbeddedObject": false,
  "ContainsPasswordProtectedFile": false,
  "ContainsRestrictedFileFormat": false,
  "ContainsScript": false,
  "ContainsUnsafeArchive": false,
  "ContainsXmlExternalEntities": false,
  "ContentInformation": {
    "ContainsImage": true,
    "ContainsJSON": false,
    "ContainsXML": false
  },
  "VerifiedFileFormat": ".pdf"
}

================================================================================
File: jsinjection.pdf
{
  "CleanResult": false,
  "ContainsExecutable": false,
  "ContainsHtml": false,
  "ContainsInsecureDeserialization": false,
  "ContainsInvalidFile": false,
  "ContainsMacros": false,
  "ContainsOleEmbeddedObject": false,
  "ContainsPasswordProtectedFile": false,
  "ContainsRestrictedFileFormat": false,
  "ContainsScript": true,
  "ContainsUnsafeArchive": false,
  "ContainsXmlExternalEntities": false,
  "ContentInformation": {
    "ContainsImage": false,
    "ContainsJSON": false,
    "ContainsXML": false
  },
  "VerifiedFileFormat": ".pdf"
}

================================================================================
SUMMARY
Total files found: 3
Clean files: 1
Infected/Not-clean files: 2

600 free API calls/month, with no expiration

Sign Up Now or Sign in with Google    Sign in with Microsoft

Questions? We'll be your guide.

Contact Sales