{"id":20658082,"url":"https://github.com/deepfence/threatmapper-python-client","last_synced_at":"2025-04-19T13:19:54.898Z","repository":{"id":190004833,"uuid":"647650946","full_name":"deepfence/threatmapper-python-client","owner":"deepfence","description":"ThreatMapper python client","archived":false,"fork":false,"pushed_at":"2024-11-21T18:22:40.000Z","size":661,"stargazers_count":3,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T08:11:41.271Z","etag":null,"topics":["cloudsecurity","cnap","cspm","cwpp","devsecops","secops","security-tools","threatmapper"],"latest_commit_sha":null,"homepage":"https://github.com/deepfence/ThreatMapper","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deepfence.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-31T08:31:43.000Z","updated_at":"2024-11-21T18:20:46.000Z","dependencies_parsed_at":"2024-01-03T19:25:41.047Z","dependency_job_id":"882aa2cc-6bc0-4e9e-a7de-f27d84615f25","html_url":"https://github.com/deepfence/threatmapper-python-client","commit_stats":null,"previous_names":["deepfence/threatmapper-python-client"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepfence%2Fthreatmapper-python-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepfence%2Fthreatmapper-python-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepfence%2Fthreatmapper-python-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepfence%2Fthreatmapper-python-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deepfence","download_url":"https://codeload.github.com/deepfence/threatmapper-python-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249702811,"owners_count":21312762,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudsecurity","cnap","cspm","cwpp","devsecops","secops","security-tools","threatmapper"],"created_at":"2024-11-16T18:24:43.205Z","updated_at":"2025-04-19T13:19:54.867Z","avatar_url":"https://github.com/deepfence.png","language":"Python","readme":"# threatmapper\nA client library for accessing Deepfence ThreatMapper\n\n## How to Install \n\n```shell\npip install git+https://github.com/deepfence/threatmapper-python-client.git\n```\n\n## Usage\nFirst, create a client:\n\n```python\nfrom threatmapper import Client\n\nclient = Client(base_url=\"YOUR_CONSOLE_URL\")\n```\n\nIf the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead:\n### Api Key\nAfter Login Go to Settings -\u003e User Management -\u003e Api key\n\n```python\nfrom threatmapper import AuthenticatedClient\n\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"Api Key\")\n```\n\nBy default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle.\n\n```python\nfrom threatmapper import AuthenticatedClient\n\nclient = AuthenticatedClient(\n    base_url=\"YOUR_CONSOLE_URL\", \n    token=\"Api Key\",\n    verify_ssl=\"/path/to/certificate_bundle.pem\",\n)\n```\n\nYou can also disable certificate validation altogether, but beware that **this is a security risk**.\n\n```python\n\nfrom threatmapper import AuthenticatedClient\n\nclient = AuthenticatedClient(\n    base_url=\"YOUR_CONSOLE_URL\", \n    token=\"Api Key\", \n    verify_ssl=False\n)\n```\n\nThings to know:\n1. Every path/method combo becomes a Python module with four functions:\n    1. `sync`: Blocking request that returns parsed data (if successful) or `None`\n    2. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.\n    3. `asyncio`: Like `sync` but async instead of blocking\n    4. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking\n\n2. All path/query params, and bodies become method arguments.\n3. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)\n4. Any endpoint which did not have a tag will be in `threatmapper.api.default`\n\n## Advanced customizations\n\nThere are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):\n\n```python\nfrom threatmapper import Client\n\ndef log_request(request):\n    print(f\"Request event hook: {request.method} {request.url} - Waiting for response\")\n\ndef log_response(response):\n    request = response.request\n    print(f\"Response event hook: {request.method} {request.url} - Status {response.status_code}\")\n\nclient = Client(\n    base_url=\"YOUR_CONSOLE_URL\",\n    httpx_args={\"event_hooks\": {\"request\": [log_request], \"response\": [log_response]}},\n)\n\n# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client()\n```\n\nYou can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url):\n\n```python\nimport httpx\nfrom threatmapper import Client\n\nclient = Client(\n    base_url=\"YOUR_CONSOLE_URL\",\n)\n# Note that base_url needs to be re-set, as would any shared cookies, headers, etc.\nclient.set_httpx_client(httpx.Client(base_url=\"YOUR_CONSOLE_URL\", proxies=\"YOUR_PROXY_URL\"))\n```\n\n### Get Access \u0026 Refresh Token With Regular Client\n\n```python\nimport json\nfrom threatmapper import Client\nfrom threatmapper.models import ModelApiAuthRequest\nfrom threatmapper.api.authentication import auth_token\nfrom threatmapper.errors import UnexpectedStatus\n\n# Regular Client SSL Disabled\nclient = Client(base_url=\"YOUR_CONSOLE_URL\", verify_ssl=False)\n#OR\n# Regular Client SSL Enabled\nclient = Client(base_url=\"YOUR_CONSOLE_URL\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\ndef get_access_refresh_token_sync():\n    try:\n        body = ModelApiAuthRequest(\n            api_token=\"YOUR_API_KEY\"\n        )\n        #  If we want minified response\n        api_response = auth_token.sync(client=client, body=json_body)\n        print(api_response.access_token, api_response.refresh_token)\n        #  If we want detailed response\n        api_response = auth_token.sync_detailed(client=client, body=json_body)\n        if api_response.status_code == 200:\n           json_response =  json.loads(api_response.content.decode(\"utf-8\"))\n           print(json_response[\"access_token\"], json_response[\"refresh_token\"])\n        else:\n           raise Exception(\"\")\n    except UnexpectedStatus as e:\n        print(\"Exception when calling get_access_refresh_token_sync-\u003e: %s\\n\" % e)\n```\n\nOr do the same thing with an async version:\n\n```python\nimport json\nfrom threatmapper import Client\nfrom threatmapper.models import ModelApiAuthRequest\nfrom threatmapper.api.authentication import auth_token\nfrom threatmapper.errors import UnexpectedStatus\n\n\n# SSL Disabled\nclient = Client(base_url=\"YOUR_CONSOLE_URL\", verify_ssl=False)\n# OR\n# SSL Enabled\nclient = Client(base_url=\"YOUR_CONSOLE_URL\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\nasync def get_access_refresh_token_async():\n    try:\n        body = ModelApiAuthRequest(\n            api_token=\"YOUR_API_KEY\"\n        )\n        #  If we want minified response\n        api_response = await auth_token.asyncio(client=client, body=json_body)\n        print(api_response.access_token, api_response.refresh_token)\n        #  If we want detailed response\n        api_response = await auth_token.asyncio_detailed(client=client, body=json_body)\n        if api_response.status_code == 200:\n           json_response = json.loads(api_response.content.decode(\"utf-8\"))\n           print(json_response[\"access_token\"], json_response[\"refresh_token\"])\n        else:\n           raise Exception(\"\")\n    except UnexpectedStatus as e:\n        print(\"Exception when calling get_access_refresh_token_async-\u003e %s\\n\" % e)\n```\n\n### Get Token Refresh With Authenticated Client SYNC\n\n```python\nimport json\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.api.authentication import auth_token_refresh\nfrom threatmapper.errors import UnexpectedStatus\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n# OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\",\n                             verify_ssl=\"/path/to/certificate_bundle.pem\")\n\n\ndef refresh_token_sync():\n   try:\n      #  If we want minified response\n      res = auth_token_refresh.sync(client=client)\n      print(res.access_token, res.refresh_token)\n      #  If we want Detailed response\n      res = auth_token_refresh.sync_detailed(client=client)\n      if res.status_code == 200:\n         json_response = json.loads(res.content.decode(\"utf-8\"))\n         print(json_response[\"access-token\"], json_response[\"refresh-token\"])\n      else:\n         raise Exception(\"\")\n   except UnexpectedStatus as e:\n      print(\"Exception when calling refresh_token_sync-\u003e %s\\n\" % e)\n```\n\nOr do the same thing with an async version:\n\n```python\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.api.authentication import auth_token_refresh\nfrom threatmapper.errors import UnexpectedStatus\nimport json\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n#OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\nasync def refresh_token_async():\n    try:\n        #  If we want minified response\n        res = await auth_token_refresh.asyncio(client=client)\n        print(res.access_token, res.refresh_token)\n        #  If we want Detailed response\n        res = await auth_token_refresh.asyncio_detailed(client=client)\n        if res.status_code == 200:\n           json_response = json.loads(res.content.decode(\"utf-8\"))\n           print(json_response[\"access-token\"], json_response[\"refresh-token\"])\n        else:\n            raise Exception(\"\")\n    except UnexpectedStatus as e:\n        print(\"Exception when calling refresh_token_async-\u003e %s\\n\" % e)\n```\n\n### Add Gcr Registry\n\n```python\nfrom threatmapper.types import File\nfrom threatmapper.api.registry import add_registry_gcr\nfrom threatmapper.models import FormDataModelRegistryGCRAddReq\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.errors import UnexpectedStatus\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n#OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\ndef add_gcr_registry():\n    try:\n       name = 'Google Registry'\n       registry_url = 'YOUR_REGISTRY_URL'\n       service_account_json = File(payload=open('/path/to/json','rb'), mime_type=\"application/json\", file_name=\"service.json\")\n       multipart_data=FormDataModelRegistryGCRAddReq(name=name, registry_url=registry_url, service_account_json=service_account_json)\n       response = add_registry_gcr.sync(client=client, multipart_data=multipart_data)\n       print(response.message)\n    except UnexpectedStatus as e:\n        print(\"Exception when calling refresh_token_async-\u003e %s\\n\" % e)\n      \n```\n\n### List Hosts\n\n```python\nfrom threatmapper.api.search import search_hosts\nfrom threatmapper.models import SearchSearchNodeReq\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.errors import UnexpectedStatus\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n#OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\ndef list_hosts():\n    try:\n       payload_dict = {\n                       \"node_filter\": {\n                         \"filters\": {\n                           \"compare_filter\": None,\n                           \"contains_filter\": {\n                             \"filter_in\": {\n                               \"active\": [\n                                 True\n                               ]\n                             }\n                           },\n                           \"match_filter\": {\n                             \"filter_in\": None\n                           },\n                           \"not_contains_filter\": {\n                             \"filter_in\": {}\n                           },\n                           \"order_filter\": {\n                             \"order_fields\": []\n                           }\n                         },\n                         \"in_field_filter\": None,\n                         \"window\": {\n                           \"offset\": 0,\n                           \"size\": 0\n                         }\n                       },\n                       \"window\": {\n                         \"offset\": 0,\n                         \"size\": 100\n                       }\n                     }\n       body = SearchSearchNodeReq.from_dict(payload_dict)\n       hosts = search_hosts.sync(client=client,body=json_body)\n       agent_host_list = []\n       discovered_host_list = []\n       for host in hosts:\n           # If agent is running inside hosts\n           if host.agent_running:\n               agent_host_list.append(host.node_id)\n           else:\n              discovered_host_list.append(host.node_id)\n       print(agent_host_list, discovered_host_list)\n    except UnexpectedStatus as e:\n        print(\"Exception when calling list_hosts-\u003e %s\\n\" % e)\n      \n```\n### List Containers ASYNC\n\n```python\nfrom threatmapper.api.search import search_containers\nfrom threatmapper.models import SearchSearchNodeReq\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.errors import UnexpectedStatus\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n#OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\nasync def list_containers():\n    try:\n       payload_dict = {\n                       \"node_filter\": {\n                         \"filters\": {\n                           \"compare_filter\": None,\n                           \"contains_filter\": {\n                             \"filter_in\": {\n                               \"active\": [\n                                 True\n                               ]\n                             }\n                           },\n                           \"match_filter\": {\n                             \"filter_in\": None\n                           },\n                           \"not_contains_filter\": {\n                             \"filter_in\": {}\n                           },\n                           \"order_filter\": {\n                             \"order_fields\": []\n                           }\n                         },\n                         \"in_field_filter\": None,\n                         \"window\": {\n                           \"offset\": 0,\n                           \"size\": 0\n                         }\n                       },\n                       \"window\": {\n                         \"offset\": 0,\n                         \"size\": 100\n                       }\n                     }\n       body = SearchSearchNodeReq.from_dict(payload_dict)\n       containers = await search_containers.asyncio(client=client,body=json_body)\n       for container in containers:\n          print(container.node_id, container.node_name)\n    except UnexpectedStatus as e:\n        print(\"Exception when calling list_containers-\u003e %s\\n\" % e)\n```\n\n### Start Vulnerability Scan ASYNC\n\n```python\nfrom threatmapper.api.vulnerability import start_vulnerability_scan\nfrom threatmapper.api.search import search_hosts\nfrom threatmapper.models import ModelVulnerabilityScanTriggerReq, SearchSearchNodeReq, ModelScanTriggerResp\nfrom threatmapper import AuthenticatedClient\nfrom threatmapper.errors import UnexpectedStatus\nfrom typing import List\n\n#  Authenticated Client SSL Disabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=False)\n#OR\n# Authenticated Client SSL Enabled\nclient = AuthenticatedClient(base_url=\"YOUR_CONSOLE_URL\", token=\"YOUR_REFRESH_TOKEN\", verify_ssl=\"/path/to/certificate_bundle.pem\")\n\n\ndef node_config() -\u003e List:\n    try:\n       payload_dict = {\n                       \"node_filter\": {\n                         \"filters\": {\n                           \"compare_filter\": None,\n                           \"contains_filter\": {\n                             \"filter_in\": {\n                               \"active\": [\n                                 True\n                               ]\n                             }\n                           },\n                           \"match_filter\": {\n                             \"filter_in\": None\n                           },\n                           \"not_contains_filter\": {\n                             \"filter_in\": {}\n                           },\n                           \"order_filter\": {\n                             \"order_fields\": []\n                           }\n                         },\n                         \"in_field_filter\": None,\n                         \"window\": {\n                           \"offset\": 0,\n                           \"size\": 0\n                         }\n                       },\n                       \"window\": {\n                         \"offset\": 0,\n                         \"size\": 100\n                       }\n                     }\n       body = SearchSearchNodeReq.from_dict(payload_dict)\n       hosts = search_hosts.sync(client=client,body=json_body)\n       host_list = []\n       for host in hosts:\n          host_list.append({\"node_id\":host.node_id, \"node_type\": \"host\"})\n       return host_list\n    except UnexpectedStatus as e:\n        print(\"Exception when calling node_config-\u003e %s\\n\" % e)\n\nasync def start_vulnerability_scan_on_hosts():\n    try:\n       node_ids = node_config()\n       payload_dict = {\n                       \"filters\": {\n                         \"cloud_account_scan_filter\": {\n                           \"filter_in\": None\n                         },\n                         \"container_scan_filter\": {\n                           \"filter_in\": None\n                         },\n                         \"host_scan_filter\": {\n                           \"filter_in\": None\n                         },\n                         \"image_scan_filter\": {\n                           \"filter_in\": None\n                         },\n                         \"kubernetes_cluster_scan_filter\": {\n                           \"filter_in\": None\n                         }\n                       },\n                       \"node_ids\": node_ids,\n                       \"scan_config\": [\n                         {\n                           \"language\": \"base\"\n                         },\n                         {\n                           \"language\": \"java\"\n                         },\n                         {\n                           \"language\": \"javascript\"\n                         },\n                         {\n                           \"language\": \"rust\"\n                         },\n                         {\n                           \"language\": \"golang\"\n                         },\n                         {\n                           \"language\": \"ruby\"\n                         },\n                         {\n                           \"language\": \"python\"\n                         },\n                         {\n                           \"language\": \"php\"\n                         },\n                         {\n                           \"language\": \"dotnet\"\n                         }\n                       ]\n                     }\n       body = ModelVulnerabilityScanTriggerReq.from_dict(payload_dict)\n       response: ModelScanTriggerResp = await start_vulnerability_scan.asyncio(client=client,body=json_body)\n       print(response.scan_ids, response.bulk_scan_id)\n    except UnexpectedStatus as e:\n        print(\"Exception when calling start_vulnerability_scan_on_hosts-\u003e %s\\n\" % e)\n```\n\n\n\n## Building / publishing this package\nThis project uses [Poetry](https://python-poetry.org/) to manage dependencies  and packaging.  Here are the basics:\n1. Update the metadata in pyproject.toml (e.g. authors, version)\n2. If you're using a private repository, configure it with Poetry\n    1. `poetry config repositories.\u003cyour-repository-name\u003e \u003curl-to-your-repository\u003e`\n    2. `poetry config http-basic.\u003cyour-repository-name\u003e \u003cusername\u003e \u003cpassword\u003e`\n3. Publish the client with `poetry publish --build -r \u003cyour-repository-name\u003e` or, if for public PyPI, just `poetry publish --build`\n\nIf you want to install this client into another project without publishing it (e.g. for development) then:\n1. If that project **is using Poetry**, you can simply do `poetry add \u003cpath-to-this-client\u003e` from that project\n2. If that project is not using Poetry:\n    1. Build a wheel with `poetry build -f wheel`\n    2. Install that wheel from the other project `pip install \u003cpath-to-wheel\u003e`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeepfence%2Fthreatmapper-python-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeepfence%2Fthreatmapper-python-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeepfence%2Fthreatmapper-python-client/lists"}