{"id":6328,"library":"clamd","title":"Clamd Python Interface","description":"Clamd is a Python interface library for communicating with the ClamAV daemon (`clamd`). It allows Python applications to send files or streams to `clamd` for virus scanning. The current stable version is 1.0.2, with a low release cadence indicating maturity and stability, focusing on Python 3.7+.","status":"active","version":"1.0.2","language":"python","source_language":"en","source_url":"https://github.com/graingert/python-clamd","tags":["antivirus","clamav","security","daemon","virus-scanner"],"install":[{"cmd":"pip install clamd","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"clamd","correct":"import clamd"},{"note":"The primary way to connect using a Unix domain socket.","symbol":"ClamdUnixSocket","correct":"import clamd\ncd = clamd.ClamdUnixSocket()"},{"note":"Used to connect to clamd over TCP/IP.","symbol":"ClamdNetworkSocket","correct":"import clamd\ncd = clamd.ClamdNetworkSocket(host='127.0.0.1', port=3310)"}],"quickstart":{"code":"import clamd\nimport os\n\n# Assuming clamd is running and accessible via its default Unix socket\n# You might need to adjust the socket path or use ClamdNetworkSocket\n# if clamd is running on a network port.\n\ndef scan_string(text_to_scan: str):\n    try:\n        # Common Unix socket paths for clamd:\n        # /var/run/clamav/clamd.ctl (Ubuntu/Debian)\n        # /run/clamd.ctl (Arch Linux)\n        # /var/lib/clamav/clamd.sock\n        \n        # Use environment variable for socket path or default\n        clamd_socket_path = os.environ.get('CLAMD_UNIX_SOCKET', '/var/run/clamav/clamd.ctl')\n        cd = clamd.ClamdUnixSocket(path=clamd_socket_path)\n        \n        # Test connection\n        cd.ping()\n        print(f\"Successfully connected to clamd at {clamd_socket_path}\")\n        \n        # Scan the string. The 'stream' key is arbitrary for stream scans.\n        # 'EICAR_Test_File' is a safe test virus string.\n        result = cd.scan(b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*')\n        \n        print(f\"Scan result for string: {result}\")\n        \n        # Interpret result\n        if 'stream' in result and result['stream'][0] == 'FOUND':\n            print(f\"!!! VIRUS DETECTED: {result['stream'][1]} !!!\")\n        elif 'stream' in result and result['stream'][0] == 'OK':\n            print(\"No virus detected.\")\n        else:\n            print(\"Unexpected scan result format.\")\n            \n    except clamd.ClamdError as e:\n        print(f\"Error connecting to or communicating with clamd: {e}\")\n        print(\"Please ensure the clamd daemon is running and accessible at the specified socket path/address, and that your user has permissions.\")\n    except FileNotFoundError:\n        print(f\"Error: Clamd Unix socket not found at {clamd_socket_path}. Please check the path and clamd status.\")\n    except Exception as e:\n        print(f\"An unexpected error occurred: {e}\")\n\nif __name__ == \"__main__\":\n    # Example usage with the EICAR test string\n    scan_string(\"This is a test file for antivirus scanning.\")\n","lang":"python","description":"This quickstart demonstrates how to connect to the ClamAV daemon using a Unix domain socket, send a test string for scanning, and interpret the results. It includes basic error handling for common connection issues."},"warnings":[{"fix":"Ensure the ClamAV daemon (`clamd`) is installed, started, and configured to listen on the specified Unix socket path or network address. Check system logs (e.g., `journalctl -u clamd.service`) for daemon status.","message":"Clamd daemon must be running and accessible. The `clamd` library is merely a client; it does not start or manage the ClamAV daemon. Connection attempts will fail with `clamd.ClamdError` or `FileNotFoundError` if the daemon isn't running or the socket/network address is incorrect.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Adjust file permissions for the clamd socket or ensure the Python process is running as a user or group that has access (e.g., `clamav` group). Alternatively, consider using `ClamdNetworkSocket` if network access is configured and appropriate for your security model.","message":"Unix socket permissions can cause 'Permission denied' errors. When using `ClamdUnixSocket`, the user running the Python script needs appropriate read/write permissions for the socket file (e.g., `/var/run/clamav/clamd.ctl`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always check the dictionary structure. For stream scans, the key is typically 'stream'. The value is `('OK', None)` for clean files, or `('FOUND', 'VIRUS_NAME')` if a virus is detected. Example: `result = cd.scan(b'...')`; then access `result['stream'][0]` for status and `result['stream'][1]` for virus name.","message":"The `scan()` and `multiscan()` methods return a dictionary where keys are stream names/file paths and values are tuples `(status, virus_name)`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always provide byte strings (e.g., `b'my data'`) when scanning data directly. If you have a Python string, convert it using `.encode('utf-8')` or another appropriate encoding.","message":"The library primarily uses bytes for scanning inputs, not strings. While Python 3 handles string-to-bytes implicitly in some I/O operations, explicitly encoding input strings to bytes (`my_string.encode()`) is best practice.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.0.2':36 '3.7':49 'allow':18 'antivirus':50 'applic':20 'cadenc':41 'clamav':14,51 'clamd':1,4,16,27 'communic':11 'current':32 'daemon':15,53 'file':23 'focus':46 'indic':42 'interfac':3,8 'librari':9 'low':39 'matur':43 'python':2,7,19,48 'releas':40 'scan':30 'scanner':56 'secur':52 'send':22 'stabil':45 'stabl':33 'stream':25 'version':34 'virus':29,55 'virus-scann':54","created_at":"2026-04-15T05:32:32.248329+00:00","updated_at":"2026-04-16T02:14:13.759742+00:00","problems":[{"fix":"Ensure the `clamd` service is running (`sudo systemctl start clamav-daemon` or `sudo service clamav-daemon start`). Verify `clamd.conf` for correct `LocalSocket` or `TCPAddr`/`TCPSocket` settings and check firewall rules to allow connections to the daemon's port (default 3310) or socket.","cause":"The `clamd` daemon is not running, is configured to listen on a different address/port, or a firewall is blocking the connection.","error":"clamd.ClamdError: Error 111 connecting 127.0.0.1:3310. Connection refused."},{"fix":"Install the `clamd` library using pip: `pip install clamd`","cause":"The `clamd` Python library has not been installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'clamd'"},{"fix":"Grant read permissions to the user under which `clamd` runs for the target files/directories. If AppArmor or SELinux is active, review and adjust their profiles to allow `clamd` access to the relevant paths.","cause":"The `clamd` daemon, running as a specific user (e.g., 'clamav'), lacks the necessary read permissions for the file or directory attempting to be scanned, or a security module like AppArmor/SELinux is preventing access.","error":"{'file_path': ('ERROR', \"Can't open file or directory\")}"},{"fix":"Edit the `clamd.conf` file (typically `/etc/clamav/clamd.conf`) to increase the `StreamMaxLength` value to accommodate larger streams, then restart the `clamd` service. Alternatively, ensure the data stream being sent is within the configured limit.","cause":"The data stream sent to `clamd` for scanning exceeds the maximum size allowed by the `StreamMaxLength` directive in the `clamd` configuration file.","error":"clamd.ClamdError: BufferTooLongError: Buffer length (X) is greater than StreamMaxLength (Y) in /etc/clamav/clamd.conf"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.0.2","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/graingert/python-clamd","docs":null,"changelog":null,"pypi":"https://pypi.org/project/clamd/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}