{"id":6944,"library":"vt-py","title":"VirusTotal Python Client Library","description":"vt-py is the official Python client library for the VirusTotal API v3. This library enables interaction with the VirusTotal REST API v3 to automate security workflows, including scanning files and URLs, retrieving comprehensive information about various entities (files, URLs, domains), managing VirusTotal Intelligence searches, LiveHunt rulesets, and launching Retrohunt jobs. It is actively maintained with regular releases.","status":"active","version":"0.22.0","language":"en","source_language":"en","source_url":"https://github.com/VirusTotal/vt-py","tags":["VirusTotal","API Client","security","threat intelligence","async"],"install":[{"cmd":"pip install vt-py","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core library for asynchronous HTTP requests.","package":"aiohttp","optional":false}],"imports":[{"note":"The common pattern shown in documentation is to import the top-level 'vt' module and access Client via 'vt.Client'.","wrong":"from vt.client import Client","symbol":"Client","correct":"import vt\nclient = vt.Client(api_key)"},{"note":"The 'url_id' utility function is exposed directly under the top-level 'vt' module.","wrong":"from vt.client import url_id","symbol":"url_id","correct":"import vt\nurl_identifier = vt.url_id(url)"}],"quickstart":{"code":"import os\nimport asyncio\nimport vt\n\nasync def get_file_info(api_key: str, file_hash: str):\n    \"\"\"Fetches information about a file hash from VirusTotal.\"\"\"\n    async with vt.Client(api_key) as client:\n        try:\n            file_obj = await client.get_object(f\"/files/{file_hash}\")\n            print(f\"File SHA256: {file_obj.sha256}\")\n            print(f\"File Size: {file_obj.size} bytes\")\n            print(f\"Detection Stats: {file_obj.last_analysis_stats}\")\n        except vt.APIError as e:\n            print(f\"VirusTotal API error: {e}\")\n        except Exception as e:\n            print(f\"An unexpected error occurred: {e}\")\n\nif __name__ == \"__main__\":\n    VIRUSTOTAL_API_KEY = os.environ.get('VIRUSTOTAL_API_KEY', '')\n    if not VIRUSTOTAL_API_KEY:\n        print(\"Please set the VIRUSTOTAL_API_KEY environment variable.\")\n    else:\n        # Example SHA256 hash of an EICAR test file\n        example_hash = \"275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f\"\n        asyncio.run(get_file_info(VIRUSTOTAL_API_KEY, example_hash))\n","lang":"python","description":"This quickstart demonstrates how to fetch information about a file using its SHA256 hash. It initializes an asynchronous `vt.Client` with an API key from an environment variable, retrieves a `vt.Object` representing the file, and prints some of its attributes. The client is automatically closed using `async with`."},"warnings":[{"fix":"Upgrade Python to 3.8 or newer, or downgrade `vt-py` to `<0.21.0`.","message":"Python 3.7 support was officially dropped in `vt-py` version 0.21.0. Users on Python 3.7 or older will need to upgrade their Python version or pin `vt-py` to a version prior to 0.21.0.","severity":"breaking","affected_versions":">=0.21.0"},{"fix":"Update code to treat `vt.Object` attributes as standard dictionaries. If on older versions, ensure attributes are explicitly converted or accessed as plain dicts before serialization.","message":"In `vt-py` v0.20.0, the `WhistleBlowerDict` (a subclass of `collections.UserDict`) used internally for `vt.Object` attributes was converted to a plain Python `dict`. Code relying on `UserDict` specific behaviors or encountering 'Object of type WhistleBlowerDict is not JSON serializable' errors in older versions should be updated.","severity":"breaking","affected_versions":">=0.20.0"},{"fix":"Ensure `vt-py` asynchronous calls are executed within an `asyncio` event loop. For standalone scripts, use `asyncio.run()`. For integration into existing sync applications, consider `nest_asyncio` or carefully manage event loop contexts.","message":"The `vt-py` library is built around `asyncio`. Running client methods in synchronous code or within existing event loops (e.g., in some web frameworks or cloud functions) without proper `asyncio` context can lead to `RuntimeError: There is no current event loop in thread...` errors.","severity":"gotcha","affected_versions":"All"},{"fix":"Always use the client within an `async with vt.Client(...)` block, which handles automatic closing, or explicitly call `await client.close()` after all operations are complete.","message":"It is crucial to explicitly close the `vt.Client` instance to release underlying network resources (like TCP connections) when it's no longer needed. Not doing so can lead to resource leaks and potential runtime warnings/errors.","severity":"gotcha","affected_versions":"All"},{"fix":"Familiarize yourself with the official VirusTotal API v3 documentation to understand endpoints, object structures, and request/response formats when using `vt-py`.","message":"The `vt-py` library is designed as a relatively low-level wrapper around the VirusTotal API v3. Users are expected to have a good understanding of the VirusTotal API v3 concepts and REST endpoint paths, as the library mirrors the API structure rather than providing a high level of abstraction.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}