{ "cells": [ { "cell_type": "code", "execution_count": null, "source": [ "import json\r\n", "import os\r\n", "from collections import Counter\r\n", "from datetime import datetime, timedelta\r\n", "\r\n", "import matplotlib.pyplot as plt\r\n", "import numpy as np\r\n", "import pandas as pd\r\n", "from bokeh.plotting import show\r\n", "from whois import whois\r\n", "\r\n", "import msticnb as nb\r\n", "from msticpy.common.azure_auth import az_connect\r\n", "from msticpy.common.timespan import TimeSpan\r\n", "from msticpy.data.data_providers import QueryProvider\r\n", "from msticpy.nbtools.utility import md\r\n", "from msticpy.sectools.tilookup import TILookup\r\n", "\r\n", "try:\r\n", " os.environ.pop(\"AZURE_CLIENT_SECRET\")\r\n", "except:\r\n", " pass\r\n", "pd.options.mode.chained_assignment = None" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "def check_ent(items, entity):\r\n", " \"\"\"Check if entity is present\"\"\"\r\n", " for item in items:\r\n", " if entity in item:\r\n", " return True\r\n", " return False\r\n", "\r\n", "\r\n", "def are_equal(ent1, ent2):\r\n", " \"\"\"Checks properties to see if the entities are the same.\"\"\"\r\n", " result = True\r\n", " for prop in ent1.properties:\r\n", " result &= getattr(ent1, prop, None) == getattr(ent2, prop, None)\r\n", " return result\r\n", "\r\n", "\r\n", "def color_cells(val):\r\n", " \"\"\"Color cells of output dataframe based on severity\"\"\"\r\n", " color = \"none\"\r\n", " if isinstance(val, str):\r\n", " if val.casefold() == \"high\":\r\n", " color = \"Red\"\r\n", " elif val.casefold() == \"warning\" or val.casefold() == \"medium\":\r\n", " color = \"Orange\"\r\n", " elif val.casefold() == \"information\" or val.casefold() == \"low\":\r\n", " color = \"Green\"\r\n", " return f\"background-color: {color}\"\r\n", "\r\n", "\r\n", "def Entropy(data):\r\n", " \"\"\"Calculate entropy of string\"\"\"\r\n", " s, lens = Counter(data), np.float(len(data))\r\n", " return -sum(count / lens * np.log2(count / lens) for count in s.values())\r\n", "\r\n", "\r\n", "def color_cells(val):\r\n", " \"\"\"Color table cells based on values in the cells\"\"\"\r\n", " if isinstance(val, int):\r\n", " color = \"yellow\" if val < 3 else \"none\"\r\n", " elif isinstance(val, float):\r\n", " color = \"yellow\" if val > 4.30891 or val < 2.72120 else \"none\"\r\n", " else:\r\n", " color = \"none\"\r\n", " return \"background-color: %s\" % color" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [], "outputs": [], "metadata": { "tags": [ "parameters" ] } }, { "cell_type": "code", "execution_count": null, "source": [ "# Connect to Azure Sentinel\r\n", "%env KQLMAGIC_LOAD_MODE=silent\r\n", "qry_prov = QueryProvider(\"LogAnalytics\")\r\n", "creds = az_connect([\"cli\", \"msi\"])\r\n", "token = creds.modern.get_token(\"https://api.loganalytics.io/.default\")\r\n", "token_dict = {\r\n", " \"access_token\": token.token,\r\n", " \"token_type\": \"Bearer\",\r\n", " \"resource\": \"https://api.loganalytics.io/\",\r\n", "}\r\n", "qry_prov.connect(\r\n", " connection_str=f\"loganalytics://code().tenant('{ten_id}').workspace('{ws_id}')\",\r\n", " kqlmagic_args=f\"-try_token=token_dict\",\r\n", ")" ], "outputs": [], "metadata": { "tags": [] } }, { "cell_type": "code", "execution_count": null, "source": [ "# Establish threat intelligence provider\r\n", "ti = TILookup()" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Set up notebooklets\r\n", "nb.init(qry_prov)\r\n", "timespan = TimeSpan(start=datetime.now() - timedelta(days=7))" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Get details of the incident from the Securityincident table\r\n", "incidents = qry_prov.exec_query(\r\n", " f\"SecurityIncident | where IncidentName =~ '{incident_id}'\"\r\n", ")\r\n", "incident = incidents.iloc[0]" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Extract individual alerts from the incident\r\n", "alert_id_list = \", \".join(list({f'\"{id}\"' for id in incident.AlertIds}))\r\n", "query = f\"SecurityAlert | where SystemAlertId in ({alert_id_list})\"\r\n", "alert_df = qry_prov.exec_query(query)" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# For each alert in the incident extract the entities and build a unique list\r\n", "from collections import defaultdict\r\n", "\r\n", "alert_entities = {}\r\n", "unique_entities = defaultdict(list)\r\n", "for _, row in alert_df.iterrows():\r\n", " try:\r\n", " alert = SecurityAlert(row)\r\n", " alert_entities[alert.SystemAlertId] = alert.entities\r\n", " for ent in alert.entities:\r\n", " for current_ent in unique_entities.get(ent.Type, []):\r\n", " if are_equal(ent, current_ent):\r\n", " break\r\n", " else:\r\n", " unique_entities[ent.Type].append(ent)\r\n", " except:\r\n", " pass" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "sev = []\r\n", "resps = pd.DataFrame()\r\n", "\r\n", "# For each entity look it up in Threat Intelligence data\r\n", "for ent in unique_entities.items():\r\n", " if (ent[0]) == \"ip\":\r\n", " for ip in ent[1]:\r\n", " resp = ti.lookup_ioc(\r\n", " observable=ip[\"Address\"], ioc_type=\"ipv4\"\r\n", " )\r\n", " resps = resps.append(ti.result_to_df(resp), ignore_index=True)\r\n", " for response in resp[1]:\r\n", " sev.append(response[1].severity)\r\n", " if (ent[0]) == \"url\":\r\n", " for url in ent[1]:\r\n", " resp = ti.lookup_ioc(\r\n", " observable=url[\"Url\"], ioc_type=\"url\"\r\n", " )\r\n", " resps = resps.append(ti.result_to_df(resp), ignore_index=True)\r\n", " for response in resp[1]:\r\n", " sev.append(response[1].severity)\r\n", "\r\n", "# Take overall severity of the entities based on the highest score\r\n", "if \"high\" in sev:\r\n", " severity = \"High\"\r\n", "elif \"warning\" in sev:\r\n", " severity = \"Warning\"\r\n", "elif \"information\" in sev:\r\n", " severity = \"Information\"\r\n", "else:\r\n", " severity = \"None\"\r\n", "\r\n", "incident[\"TI Severity\"] = severity\r\n", "# Output TI hits of high or warning severity\r\n", "if incident[\"TI Severity\"] == \"High\" or incident[\"TI Severity\"] == \"Warning\":\r\n", " print(\"Incident:\")\r\n", " display(\r\n", " incident.to_frame()\r\n", " .T[\r\n", " [\r\n", " \"TimeGenerated\",\r\n", " \"IncidentNumber\",\r\n", " \"Title\",\r\n", " \"Status\",\r\n", " \"Severity\",\r\n", " \"TI Severity\",\r\n", " ]\r\n", " ]\r\n", " .style.applymap(color_cells)\r\n", " .hide_index()\r\n", " )\r\n", " print(\"TI Results:\")\r\n", " display(\r\n", " resps[[\"Ioc\", \"IocType\", \"Provider\", \"Severity\", \"Details\"]]\r\n", " .style.applymap(color_cells)\r\n", " .hide_index()\r\n", " )" ], "outputs": [], "metadata": { "tags": [ "output" ] } }, { "cell_type": "code", "execution_count": null, "source": [ "# Enrich IP entities using the IP Summary notebooklet\r\n", "ip_ent_nb = nb.nblts.azsent.network.IpAddressSummary()\r\n", "\r\n", "if not resps.empty and \"ipv4\" in resps[\"IocType\"].unique():\r\n", " for ip_addr in resps[resps[\"IocType\"] == \"ipv4\"][\"Ioc\"].unique():\r\n", " try:\r\n", " ip_ent_nb_out = ip_ent_nb.run(value=ip_addr, timespan=timespan, silent=True)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.whois, pd.DataFrame)\r\n", " and not ip_ent_nb_out.whois.empty\r\n", " ):\r\n", " md(f\"Whois information for {ip_addr}\")\r\n", " display(ip_ent_nb_out.whois)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.geoip, pd.DataFrame)\r\n", " and not ip_ent_nb_out.geoip.empty\r\n", " ):\r\n", " md(f\"Geo IP details for {ip_addr}\")\r\n", " display(ip_ent_nb_out.geoip)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.related_alerts, pd.DataFrame)\r\n", " and not ip_ent_nb_out.related_alerts.empty and ip_ent_nb_out.alert_timeline\r\n", " ):\r\n", " md(f\"Alerts for {ip_addr}\")\r\n", " show(ip_ent_nb_out.alert_timeline)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.ti_results, pd.DataFrame)\r\n", " and not ip_ent_nb_out.ti_results.empty\r\n", " ):\r\n", " md(f\"TI results for {ip_addr}\")\r\n", " display(ip_ent_nb_out.ti_results)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.passive_dns, pd.DataFrame)\r\n", " and not ip_ent_nb_out.passive_dns.empty\r\n", " ):\r\n", " md(f\"Passive DNS results for {ip_addr}\")\r\n", " display(ip_ent_nb_out.passive_dns)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.vps_network, pd.DataFrame)\r\n", " and not ip_ent_nb_out.vps_network.empty\r\n", " ):\r\n", " md(f\"{ip_addr} belongs to a known VPS provider\")\r\n", " display(ip_ent_out.vps_network)\r\n", " if (\r\n", " isinstance(ip_ent_nb_out.host_entity, pd.DataFrame)\r\n", " and not ip_ent_nb_out.host_entity.empty\r\n", " ):\r\n", " md(f\"{ip_addr} belongs to a known host\")\r\n", " display(ip_ent_out.host_entity)\r\n", " except:\r\n", " print(f\"Error processing {ip_addr}\")\r\n", "else:\r\n", " md(\"No IP entities present \")" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Enrich Domain entities\r\n", "domain_items = [\r\n", " \"name\",\r\n", " \"org\",\r\n", " \"city\",\r\n", " \"state\",\r\n", " \"country\",\r\n", " \"registrar\",\r\n", " \"status\",\r\n", " \"creation_date\",\r\n", " \"expiration_date\",\r\n", " \"updated_date\",\r\n", " \"name_servers\",\r\n", " \"dnssec\",\r\n", "]\r\n", "\r\n", "domain_records = pd.DataFrame()\r\n", "if not resps.empty and \"url\" in resps[\"IocType\"].unique():\r\n", " for url in resps[resps[\"IocType\"] == \"url\"][\"Ioc\"].unique():\r\n", " md(f\"Summary for {url}\", \"bold\")\r\n", " wis = whois(url)\r\n", " if wis.domain_name:\r\n", " if isinstance(wis[\"domain_name\"], list):\r\n", " domain = wis[\"domain_name\"][0]\r\n", " else:\r\n", " domain = wis[\"domain_name\"]\r\n", " # Create domain record from whois data\r\n", " dom_rec = {}\r\n", " for key in wis.keys():\r\n", " if key in domain_items:\r\n", " dom_rec[key] = [wis[key]]\r\n", " dom_rec[\"domain\"] = domain\r\n", " dom_record = pd.DataFrame(dom_rec)\r\n", " page_rank = ti.result_to_df(\r\n", " ti.lookup_ioc(observable=domain, providers=[\"OPR\"])\r\n", " )\r\n", " page_rank_score = page_rank[\"RawResult\"][0][\"response\"][0][\r\n", " \"page_rank_integer\"\r\n", " ]\r\n", " dom_record[\"Page Rank\"] = [page_rank_score]\r\n", " dom_ent = Entropy(domain)\r\n", " dom_record[\"Entropy\"] = [dom_ent]\r\n", " # Highlight page rank of entropy scores of note\r\n", " display(\r\n", " dom_record.T.style.applymap(\r\n", " color_cells, subset=pd.IndexSlice[[\"Page Rank\", \"Entropy\"], 0]\r\n", " )\r\n", " )\r\n", " md(\r\n", " \"If Page Rank or Domain Entropy are highlighted this indicates that their values are outside the expected values of a legitimate website\"\r\n", " )\r\n", " md(f\"The average entropy for the 1M most popular domains is 3.2675\")\r\n", "else:\r\n", " md(\"No Domain entities present \")" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Enrich Account entities using the AccountSummary notebooklet\r\n", "timespan = TimeSpan(start=datetime.now() - timedelta(days=2))\r\n", "account_nb = nb.nblts.azsent.account.AccountSummary()\r\n", "user = None\r\n", "uent = None\r\n", "\r\n", "if check_ent(unique_entities.items(), \"account\"):\r\n", " for ent in unique_entities.items():\r\n", " if ent[0] == \"account\":\r\n", " if \"AadUserId\" in str(ent[1][0]):\r\n", " try:\r\n", " uent = ent[1][1]\r\n", " except IndexError:\r\n", " pass\r\n", " else:\r\n", " uent = ent[1][0]\r\n", " if uent:\r\n", " try:\r\n", " user = uent[\"Name\"] + \"@\" + uent[\"UPNSuffix\"]\r\n", " except TypeError:\r\n", " user = uent[\"Name\"]\r\n", " if user:\r\n", " try:\r\n", " ac_nb = account_nb.run(\r\n", " timespan=timespan, value=user.casefold(), silent=True\r\n", " )\r\n", " ac_nb.get_additional_data()\r\n", " md(f\"Account summary for {user}\", \"bold\")\r\n", " if (\r\n", " isinstance(ac_nb.account_activity, pd.DataFrame)\r\n", " and not ac_nb.account_activity.empty\r\n", " ):\r\n", " md(\"Recent activity\")\r\n", " display(ac_nb.account_activity)\r\n", " if (\r\n", " isinstance(ac_nb.related_alerts, pd.DataFrame)\r\n", " and not ac_nb.related_alerts.empty\r\n", " ):\r\n", " show(ac_nb.alert_timeline)\r\n", " if (\r\n", " isinstance(ac_nb.host_logon_summary, pd.DataFrame)\r\n", " and not ac_nb.host_logon_summary.empty\r\n", " ):\r\n", " md(f\"Host logons by {user}\")\r\n", " display(ac_nb.host_logon_summary)\r\n", " if (\r\n", " isinstance(ac_nb.azure_activity_summary, pd.DataFrame)\r\n", " and not ac_nb.azure_activity_summary.empty\r\n", " ):\r\n", " md(f\"Azure activity by {user}\")\r\n", " display(ac_nb.azure_activity_summary)\r\n", " show(ac_nb.azure_timeline_by_provider)\r\n", " except:\r\n", " print(f\"Error processing {user}\")\r\n", "else:\r\n", " md(\"No Account entities present \")" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Enrich Host entities using the HostSummary notebooklet\r\n", "timespan = TimeSpan(start=datetime.now() - timedelta(days=2))\r\n", "host_nb = nb.nblts.azsent.host.HostSummary()\r\n", "\r\n", "if check_ent(unique_entities.items(), \"host\"):\r\n", " for ent in unique_entities.items():\r\n", " if ent[0] == \"host\":\r\n", " for host in ent[1]:\r\n", " if host[\"DnsDomain\"]:\r\n", " host_name = host[\"HostName\"] + \".\" + host[\"DnsDomain\"], \"\"\r\n", " else:\r\n", " host_name = host[\"HostName\"]\r\n", " md(f\"Host summary for {host_name}\", \"bold\")\r\n", " try:\r\n", " host_sum_out = host_nb.run(value=host_name, timespan=timespan)\r\n", " except:\r\n", " print(f\"Error processing {host_name}\")\r\n", "else:\r\n", " md(\"No Host entities present\")" ], "outputs": [], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [], "outputs": [], "metadata": {} } ], "metadata": { "kernelspec": { "display_name": "papermill", "language": "python", "name": "papermill" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.12" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "0040cad1767f4b95a00aefbc70d06bc1": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "01069a28b66840f5908dbf5167e08482": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "14eaa102acb64e0b8073da21f45e83b5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_e28b52485fcb486c91ec902f5b7c61db", "IPY_MODEL_db98f91c5e394abeb6b76ed5fb4284ad", "IPY_MODEL_6125ee42c10541e3bca956f190da4496" ], "layout": "IPY_MODEL_47880b93603046cea618b9d10a7f192c" } }, "195c48cd5c414746b418dac44c964c18": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "100px" } }, "2483892439044ba69f374f2c0bb01c72": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "2b5f387ba79b44b9a764af8c44827521": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "LabelModel", "state": { "layout": "IPY_MODEL_af3398b31ebc4934a2dc1ed71efeb55c", "style": "IPY_MODEL_01069a28b66840f5908dbf5167e08482" } }, "3338fc72841a43b983a7a5d7ab114635": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "34aa9860ecc94a71b4ec1920d9554694": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "70%" } }, "3c3908a4efe34c62a0a008f31eefd1c8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_d8ba0aa2aad54cd0aa69760a5354b452", "IPY_MODEL_94d2f3d7a77d475fa56029c6c1b102a2" ], "layout": "IPY_MODEL_b108e5c7f71d41aa896d812172987157" } }, "3c990d1c0dac4fac9be32569b11c773a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "3de1a85313a54edab63eab8a97d013cd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "41ce3c950bf641e982dd88dc1439cc85": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_6d846f2a40af446183bbc9999494c25c", "IPY_MODEL_db4165bc3d9e4a3182d06b7fca3178e4", "IPY_MODEL_aad0360f0cb94309b96360ef49ef7474" ], "layout": "IPY_MODEL_7601235d1fbb40478da390e5c635bde4" } }, "424d17d0ee4b4d929ea90e253f069ed7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntRangeSliderModel", "state": { "_model_name": "IntRangeSliderModel", "_view_name": "IntRangeSliderView", "description": "Time Range", "layout": "IPY_MODEL_847bf20ca3504a108341090f44a5d399", "max": 28, "min": -28, "style": "IPY_MODEL_ecd5058213f7439db39bd205512843e5", "value": [ -1, 1 ] } }, "442fd1263e334d45ad7d171c3457d7cd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Time (24hr)", "layout": "IPY_MODEL_d1f7f46ac3b64c818536834c60392fea", "style": "IPY_MODEL_3de1a85313a54edab63eab8a97d013cd", "value": "22:38:45.575783" } }, "47880b93603046cea618b9d10a7f192c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "4bf47ca149934c799ae842ef53122f0d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "511af61975284928bb839f6a946ae2b6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "56dbb96a024b4062bb16295c93bb8386": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "5d170286dedd41889a7345023f650a33": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "6125ee42c10541e3bca956f190da4496": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query end time (UTC) : ", "layout": "IPY_MODEL_4bf47ca149934c799ae842ef53122f0d", "style": "IPY_MODEL_c8d4203d9a214a2faf7c33159211f3ad", "value": "2021-07-03 22:38:35.047441" } }, "621702c9f018481183b96930e706cc54": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "6d846f2a40af446183bbc9999494c25c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_af92228a3694413aacca38bdf0d6db3a", "style": "IPY_MODEL_ff485c7bb935466a8425b6a4ae8f8da9", "value": "

Set time range for pivot functions.

" } }, "722e044af71d41c6b6a82690cd8a577c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "minute", "hour", "day", "week" ], "index": 2, "layout": "IPY_MODEL_96fa332bb44f43b19d7a373d509f7afb", "style": "IPY_MODEL_2483892439044ba69f374f2c0bb01c72" } }, "7601235d1fbb40478da390e5c635bde4": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "777e16e2c58745df8e5d76524f5a1433": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "7a9485f145724c38b81876500dbb43f2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "layout": "IPY_MODEL_fa1b0cab6957493e935f4e9a8d428cb2", "style": "IPY_MODEL_94439f6f9f9b400496af079cd6e37604", "value": "

Set query time boundaries

" } }, "81676b130d4a4af3a1b88a9a378dd60d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "82a64b7fb54640eda6c0c87406c628d2": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "847bf20ca3504a108341090f44a5d399": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "70%" } }, "8c8eab82b42945dc89a91bbb570eb170": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "8f45b292a74043d0a1cee653bc57689a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "8f4f079d2f044d36a7adfaf4efdd27cc": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "95%" } }, "927b173de2034b0dbe37d9e1ae388c9a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_7a9485f145724c38b81876500dbb43f2", "IPY_MODEL_d1fa63f01abb4c59a0158af8c3af9d8d", "IPY_MODEL_14eaa102acb64e0b8073da21f45e83b5" ], "layout": "IPY_MODEL_8f45b292a74043d0a1cee653bc57689a" } }, "94439f6f9f9b400496af079cd6e37604": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } }, "949f237e510542789ff9e149560d5181": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DatePickerModel", "state": { "description": "Origin Date", "disabled": false, "layout": "IPY_MODEL_dcd9308cd0474c24827bcc6cec31e96d", "style": "IPY_MODEL_81676b130d4a4af3a1b88a9a378dd60d", "value": { "date": 2, "month": 6, "year": 2021 } } }, "94d2f3d7a77d475fa56029c6c1b102a2": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DropdownModel", "state": { "_options_labels": [ "minute", "hour", "day", "week" ], "index": 2, "layout": "IPY_MODEL_195c48cd5c414746b418dac44c964c18", "style": "IPY_MODEL_8c8eab82b42945dc89a91bbb570eb170" } }, "96fa332bb44f43b19d7a373d509f7afb": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "100px" } }, "a445ee0e426c4f13af21b260b700e05f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "99%" } }, "a4d3df3b4447488f93e32ac4b3ada8c9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "initial" } }, "aad0360f0cb94309b96360ef49ef7474": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "children": [ "IPY_MODEL_3c3908a4efe34c62a0a008f31eefd1c8", "IPY_MODEL_f5fe70128cdf4eadaf8455cdbbd719cb", "IPY_MODEL_ae8c36ba95ab4ffb883b6cef6ffa6ac7" ], "layout": "IPY_MODEL_777e16e2c58745df8e5d76524f5a1433" } }, "ae8c36ba95ab4ffb883b6cef6ffa6ac7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query end time (UTC) : ", "layout": "IPY_MODEL_82a64b7fb54640eda6c0c87406c628d2", "style": "IPY_MODEL_f85fee408dda49ffadbae38d3f49eab9", "value": "2021-07-02 22:38:45.575783" } }, "af3398b31ebc4934a2dc1ed71efeb55c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "99%" } }, "af92228a3694413aacca38bdf0d6db3a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b108e5c7f71d41aa896d812172987157": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "b7cffa19b0144d8eb66f2c87e47282f6": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "50%" } }, "c8d4203d9a214a2faf7c33159211f3ad": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "d1f7f46ac3b64c818536834c60392fea": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d1fa63f01abb4c59a0158af8c3af9d8d": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_949f237e510542789ff9e149560d5181", "IPY_MODEL_e0f304182b2543cc88d79e19c5bae2c6" ], "layout": "IPY_MODEL_621702c9f018481183b96930e706cc54" } }, "d43e2535709949c7bbe3b426483ff4ae": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "70%" } }, "d6fa1751257f48c5a6161393ac096efc": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "d8ba0aa2aad54cd0aa69760a5354b452": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntRangeSliderModel", "state": { "_model_name": "IntRangeSliderModel", "_view_name": "IntRangeSliderView", "description": "Time Range", "layout": "IPY_MODEL_d43e2535709949c7bbe3b426483ff4ae", "max": 28, "min": -28, "style": "IPY_MODEL_a4d3df3b4447488f93e32ac4b3ada8c9", "value": [ -1, 0 ] } }, "db4165bc3d9e4a3182d06b7fca3178e4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_ed5543a1b31c4370ab95fdb59cf1453e", "IPY_MODEL_442fd1263e334d45ad7d171c3457d7cd" ], "layout": "IPY_MODEL_f3278667c52b4c6986fe59f6854be181" } }, "db98f91c5e394abeb6b76ed5fb4284ad": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query start time (UTC):", "layout": "IPY_MODEL_5d170286dedd41889a7345023f650a33", "style": "IPY_MODEL_3c990d1c0dac4fac9be32569b11c773a", "value": "2021-07-01 22:38:35.047441" } }, "dcd9308cd0474c24827bcc6cec31e96d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "debbd947449c4860aef557d0d8c54d08": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "70%" } }, "e0f304182b2543cc88d79e19c5bae2c6": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Time (24hr)", "layout": "IPY_MODEL_d6fa1751257f48c5a6161393ac096efc", "style": "IPY_MODEL_56dbb96a024b4062bb16295c93bb8386", "value": "22:38:35.047441" } }, "e28b52485fcb486c91ec902f5b7c61db": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "children": [ "IPY_MODEL_424d17d0ee4b4d929ea90e253f069ed7", "IPY_MODEL_722e044af71d41c6b6a82690cd8a577c" ], "layout": "IPY_MODEL_0040cad1767f4b95a00aefbc70d06bc1" } }, "e41efc3621cc45e399078cf24332bf67": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "height": "150px", "width": "300px" } }, "ec9a50e5fb5646669c679ce5dcf6f26a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "ecd5058213f7439db39bd205512843e5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "description_width": "initial" } }, "ed5543a1b31c4370ab95fdb59cf1453e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DatePickerModel", "state": { "description": "Origin Date", "disabled": false, "layout": "IPY_MODEL_ec9a50e5fb5646669c679ce5dcf6f26a", "style": "IPY_MODEL_511af61975284928bb839f6a946ae2b6", "value": { "date": 2, "month": 6, "year": 2021 } } }, "f3278667c52b4c6986fe59f6854be181": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "f5fe70128cdf4eadaf8455cdbbd719cb": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "TextModel", "state": { "description": "Query start time (UTC):", "layout": "IPY_MODEL_b7cffa19b0144d8eb66f2c87e47282f6", "style": "IPY_MODEL_3338fc72841a43b983a7a5d7ab114635", "value": "2021-07-01 22:38:45.575783" } }, "f662b92adde64b5da4e13750c0fa88c0": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "width": "70%" } }, "f85fee408dda49ffadbae38d3f49eab9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "initial" } }, "f90cc4c565664db79c4aa5220fe7f94c": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "height": "150px", "width": "300px" } }, "fa1b0cab6957493e935f4e9a8d428cb2": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {} }, "ff485c7bb935466a8425b6a4ae8f8da9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "description_width": "" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }