-
Is it possible to download schedule reports through an api call? I am currently using falconpy and I am having trouble finding which api call would work. I tried using the falcon.get_download() call from the report execution section of the api call; however, when I feed in the report id it says the report entity couldn't be found. I also tried finding the report execution id mentioned in the docs, but couldn't find it . I only have one scheduled report and I got the report ID from the url when you review the report history. There is a trace ID but I removed from the response for the post. Here's the link I am looking at: https://www.falconpy.io/Service-Collections/Report-Executions.html#report_executions_download_get Example of the code use: Service class example (PEP8 syntax) from falconpy import ReportExecutions
# Do not hardcode API credentials!
falcon = ReportExecutions(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET
)
id_list = 'ID HERE'
save_file = "some_file.ext"
response = falcon.get_download(ids=id_list)
open(save_file, 'wb').write(response) code: from pprint import pp
import os
import json
from falconpy import SpotlightVulnerabilities
from falconpy import ScheduledReports
from falconpy import ReportExecutions
from falconpy import OAuth2
import pandas as pd
if '__name__' == '__main__':
falcon_client_id = os.environ.get("CLIENT_ID")
falcon_client_secret = os.environ.get("SECRET")
authorization = OAuth2(creds={
'client_id': CLIENT_ID,
'client_secret': SECRET
}, base_url="https://api.crowdstrike.com")
try:
# calls the token method which generates a dictionary containing the body and the access token
token = authorization.token()['body']['access_token']
except:
token = False
response = authorization.oAuth2AccessToken()
If token:
falcon = ReportExecutions(
access_token=token, base_url="https://api.crowdstrike.com")
id = "2fff3b432e12934085ebc2sd"
response = falcon.get_download(id)
pd.set_option('display.max_rows', 1000)
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 10000)
# DISPLAYS THE ENTIRETY OF THE COLUMN
pd.set_option('display.max_colwidth', None)
#loads the response into a json file
with open("resp.json", "w") as f:
json.dump(response, f, ensure_ascii=False, indent=4)
with open("resp.json") as myFile:
fileData = json.load(myFile)
dataFrame = pd.DataFrame.from_dict(fileData)
pp(dataFrame) Here's the response I get: {
"status_code": 404,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 13:43:00 GMT",
"Content-Type": "application/json",
"Content-Length": "179",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5998"
},
"body": {
"meta": {
"query_time": 0.02317307,
"powered_by": "reports",
"trace_id": ""
},
"errors": [
{
"code": 404,
"message": "Not found."
}
]
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 10 comments 17 replies
-
I found something that may help: scheduled_reports_launch But im not sure how this would get the download |
Beta Was this translation helpful? Give feedback.
-
Hi @arahman63 - I'll put some code together to better describe the process and post it to our samples library, but to get you started now, here's a high level summary:
from falconpy import ScheduledReports, ReportExecutions
sched = ScheduledReports(client_id="KEY", client_secret="SECRET")
reps = ReportExecutions(auth_object=sched)
Let us know if you have any questions! 😄 |
Beta Was this translation helpful? Give feedback.
-
I made the code more readable, building off what you wrote. scheduledreports = ScheduledReports(
access_token=token, base_url="https://api.crowdstrike.com")
report_executions = ReportExecutions(
access_token=token, base_url="https://api.crowdstrike.com")
report_execution_ids = scheduledreports.query_reports(filter="scheduled_report_id:'2fff3b432e12934085ebc2sd'")
specified_exec_status = report_executions.get_reports(report_execution_ids)
getReportDownloads = report_executions.get_download(report_execution_ids)
with open("resp.json", "w") as f:
json.dump(specified_exec_status, f, ensure_ascii=False, indent=4)
with open("resp.json") as myFile:
fileData = json.load(myFile)
dataFrame = pd.DataFrame.from_dict(fileData)
pp(dataFrame) in the json.dump() I would specify what response variable I would like to print out in a json file. the query reports works I get a 200: {
"status_code": 200,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 17:17:19 GMT",
"Content-Type": "application/json",
"Content-Length": "195",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5998"
},
"body": {
"meta": {
"query_time": 0.019471532,
"pagination": {
"offset": 0,
"limit": 100,
"total": 0
},
"powered_by": "reports",
"trace_id": ""
},
"resources": [],
"errors": []
}
} But once I feed in the report_execution_ids into report_executions get method and call it into the json dump thing, it doesn't work and it gives me this response: {
"status_code": 404,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 17:18:59 GMT",
"Content-Type": "application/json",
"Content-Length": "225",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5996"
},
"body": {
"meta": {
"query_time": 0.105971571,
"powered_by": "reports",
"trace_id": ""
},
"resources": [],
"errors": [
{
"code": 404,
"message": "report_execution not found",
"id": "status_code"
},
{
"code": 404,
"message": "report_execution not found",
"id": "headers"
},
{
"code": 404,
"message": "report_execution not found",
"id": "body"
}
]
}
} |
Beta Was this translation helpful? Give feedback.
-
Try this variation, we need to grab the execution IDs from the resources array in the scheduledreports = ScheduledReports(
access_token=token, base_url="https://api.crowdstrike.com")
report_executions = ReportExecutions(
access_token=token, base_url="https://api.crowdstrike.com")
report_execution_ids = scheduledreports.query_reports(
filter="scheduled_report_id:'2fff3b432e12934085ebc2sd'"
)["body"].get("resources", [])
specified_exec_status = report_executions.get_reports(report_execution_ids)
getReportDownloads = report_executions.get_download(report_execution_ids)
with open("resp.json", "w") as f:
json.dump(specified_exec_status, f, ensure_ascii=False, indent=4)
with open("resp.json") as myFile:
fileData = json.load(myFile)
dataFrame = pd.DataFrame.from_dict(fileData)
pp(dataFrame) |
Beta Was this translation helpful? Give feedback.
-
scheduledreports.query_reports(filter="scheduled_report_id:'2fff3b432e12934085ebc2sd'")["body"].get("resources", {}) fixes the exec status call, but for the last getReportDownloads call, it gives me a 400 saying no ids were given: {
"status_code": 400,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 17:21:11 GMT",
"Content-Type": "application/json",
"Content-Length": "182",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5992"
},
"body": {
"meta": {
"query_time": 0.015345274,
"powered_by": "reports",
"trace_id": ""
},
"errors": [
{
"code": 400,
"message": "No ids given."
}
]
}
} |
Beta Was this translation helpful? Give feedback.
-
when i used list instead it gave me empty dataframe report_execution_ids = scheduledreports.query_reports(filter="scheduled_report_id:'2fff3b432e12934085ebc2sd'")["body"].get("resources", []) this is what report_execution_ids gives Empty DataFrame
Columns: []
Index: [] exec status worked with this query {
"status_code": 200,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 17:28:59 GMT",
"Content-Type": "application/json",
"Content-Length": "156",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "c5388dbb-7f25-4c2c-bf3f-b38093fe5c52",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5997"
},
"body": {
"meta": {
"query_time": 0.018988878,
"powered_by": "reports",
"trace_id": ""
},
"resources": [],
"errors": []
}
} and then for the last call with getReportDownloads it gave me this {
"status_code": 400,
"headers": {
"Server": "nginx",
"Date": "Wed, 26 Oct 2022 17:29:53 GMT",
"Content-Type": "application/json",
"Content-Length": "183",
"Connection": "keep-alive",
"Content-Encoding": "gzip",
"Strict-Transport-Security": "max-age=15724800; includeSubDomains, max-age=31536000; includeSubDomains",
"X-Cs-Region": "us-1",
"X-Cs-Traceid": "240d74ff-77f4-4806-8c89-9b622b4dbcfa",
"X-Ratelimit-Limit": "6000",
"X-Ratelimit-Remaining": "5995"
},
"body": {
"meta": {
"query_time": 0.014649593,
"powered_by": "reports",
"trace_id": ""
},
"errors": [{
"code": 400,
"message": "No ids given."
}]
}
} |
Beta Was this translation helpful? Give feedback.
-
report_execution_ids = scheduledreports.query_reports(filter={'scheduled_report_id':'2fff3b432e12934085ebc2sd'})["body"].get("resources", {}) I thought using a dict instead would work, but the same behavior happens |
Beta Was this translation helpful? Give feedback.
-
Hi @arahman63 - Try this code. You should be able to provide it your scheduled report ID and it will download all successful executions of the report in JSON format. (Named after the execution ID.) This is working in my environment.
"""Retrieve the contents of a scheduled report and save it to a file."""
import os
import json
from argparse import ArgumentParser, RawTextHelpFormatter
from falconpy import ReportExecutions
parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter)
parser.add_argument("-r", "--report", help="ID of the report to retrieve", required=True)
report_id = parser.parse_args().report
falcon = ReportExecutions(client_id=os.getenv("FALCON_CLIENT_ID"),
client_secret=os.getenv("FALCON_CLIENT_SECRET")
)
print(f"Searching for {report_id}")
# Get execution IDs
execution_id_lookup = falcon.reports_executions_query(filter=f"scheduled_report_id:'{report_id}'")
if not execution_id_lookup["status_code"] == 200:
raise SystemExit("Unable to retrieve report executions from the CrowdStrike API.")
execution_ids = execution_id_lookup["body"]["resources"]
print(f"Found {len(execution_ids)} executions of this report available.")
# Check status of these IDs
exec_status_lookup = falcon.report_executions_get(execution_ids)
if not exec_status_lookup["status_code"] == 200:
raise SystemExit("Unable to retrieve execution statuses from the CrowdStrike API.")
SAVED = 0
for exec_status in exec_status_lookup["body"]["resources"]:
status = exec_status["status"]
exec_id = exec_status["id"]
print(f"{exec_id} is {status}")
if status.upper() == "DONE":
report_detail = falcon.get_download(exec_id)
if report_detail:
SAVED += 1
with open(f"{exec_id}.rpt", "w", encoding="utf-8") as json_output:
json.dump(report_detail, json_output)
else:
print(f"Unable to retrieve report for execution {exec_id}.")
print(f"Retrieval complete, {SAVED} reports were downloaded.") |
Beta Was this translation helpful? Give feedback.
-
Thank you for your help. Works as intended! |
Beta Was this translation helpful? Give feedback.
-
Pls show an example
בתאריך יום ד׳, 16 בנוב׳ 2022, 0:56, מאת Arifur ***@***.***>:
… Hey were you able to format the csv generated after downloading it? I was
thinking the csv generated is a deserialized json, and I may need
unserialize it to reformat it and convert back to csv to have a working
table.
—
Reply to this email directly, view it on GitHub
<#809 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABNBJWJ6FL4P5YZYP2LRDQ3WIQIK5ANCNFSM6AAAAAARPCNCQA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***
com>
|
Beta Was this translation helpful? Give feedback.
Hi @arahman63 -
Try this code. You should be able to provide it your scheduled report ID and it will download all successful executions of the report in JSON format. (Named after the execution ID.) This is working in my environment.