<jupyter_start><jupyter_text>Using the OTX-Python-SDK  API Key Configuration<jupyter_code>from OTXv2 import OTXv2, IndicatorTypes
from pandas.io.json import json_normalize
from datetime import datetime, timedelta
otx = OTXv2("458044df4b3238308723bc3df5b8bdea1504e5d0e19ac9e2c4f505fd6ffec067")
hello<jupyter_output><empty_output><jupyter_text>Replace YOUR_KEY with your OTX API key. You can find it on your settings page https://otx.alienvault.com/settings.  Subscriptions The getall() method accesses your subscriptions.  It downloads all the OTX pulses and their assocciated indicators of compromise (IOCs) from your account. This includes:  - All pulses you subscribe to directly- All pulses by users you subscribe to- OTX pulses you created (including private pulses)If this is the first time you are using your account, the download includes all pulses created by AlienVault. All users are subscribed to the AlienVault user by default.<jupyter_code>pulses = otx.getall()
len(pulses)<jupyter_output><empty_output><jupyter_text>Let's list a few pulses:<jupyter_code>pulses
json_normalize(pulses)[0:5]
json_normalize(pulses)[0:5]['indicators'][0]<jupyter_output><empty_output><jupyter_text>- author_name: The username of the OTX User that created the pulse- created: Date when the pulse was created in the system- description: Describes the pulse in terms of the type of threat it poses, and any other facts that may link it to other threat indicators.- id: Unique identifier of the pulse- indicators: Collection of Indicators Of Compromise - modified: Date when the pulse was last modified- name: Name of the pulse- references: List of references to papers, websites or blogs related to the threat described in the pulse- revision: Revision number that increments each time pulse contents change- tags: List of tags that provide information about pulse content, for example, Phshing, malware, C&C, and apt. Let's explore the indicators object:<jupyter_code>json_normalize(pulses[1]["indicators"])<jupyter_output><empty_output><jupyter_text>- _id: Unique identifier of the IOC- created: Date IOC was added to the pulse- description: Describe the Indicator Of Compromise- indicator: The IOC- indicator_type: Type of indicatorThe following Indicator Types are supported (also defined in IndicatorTypes.py):<jupyter_code>indicator_types = [
			{
			    "name": "IPv4", 
			    "description": "An IPv4 address indicating the online location of a server or other computer."
			}, 
			{
			    "name": "IPv6", 
			    "description": "An IPv6 address indicating the online location of a server or other computer."
			}, 
			{
			    "name": "domain", 
			    "description": "A domain name for a website or server. Domains encompass a series of hostnames."
			}, 
			{
			    "name": "hostname", 
			    "description": "The hostname for a server located within a domain."
			}, 
			{
			     
			    "name": "email", 
			    "description": "An email associated with suspicious activity."
			}, 
			{
			    "name": "URL", 
			    "description": " Uniform Resource Location (URL) summarizing the online location of a file or resource."
			}, 
			{
			     
			    "name": "URI", 
			    "description": "Uniform Resource Indicator (URI) describing the explicit path to a file hosted online."
			}, 
			{
			    "name": "FileHash-MD5", 
			    "description": "A MD5-format hash that summarizes the architecture and content of a file."
			}, 
			{
			    "name": "FileHash-SHA1", 
			    "description": "A SHA-format hash that summarizes the architecture and content of a file."
			}, 
			{
			    "name": "FileHash-SHA256", 
			    "description": "A SHA-256-format hash that summarizes the architecture and content of a file."
			}, 
			{
			     
			    "name": "FileHash-PEHASH", 
			    "description": "A PEPHASH-format hash that summarizes the architecture and content of a file."
			}, 
			{
			     
			    "name": "FileHash-IMPHASH", 
			    "description": "An IMPHASH-format hash that summarizes the architecture and content of a file."
			}, 
			{
			    "name": "CIDR", 
			    "description": "Classless Inter-Domain Routing (CIDR) address, which describes both a server's IP address and the network architecture (routing path) surrounding that server."
			}, 
			{
			     
			    "name": "FilePath", 
			    "description": "A unique location in a file system."
			}, 
			{
			     
			    "name": "Mutex", 
			    "description": "The name of a mutex resource describing the execution architecture of a file."
			}, 
			{
			    "name": "CVE", 
			    "description": "Common Vulnerability and Exposure (CVE) entry describing a software vulnerability that can be exploited to engage in malicious activity."
			}]
json_normalize(indicator_types)
mtime = (datetime.now() - timedelta(days=1)).isoformat()
mtime<jupyter_output><empty_output><jupyter_text>Events Besides receiving the pulse information, there is another function that can retrieve different events that are ocurring in the OTX system and affect your account.<jupyter_code>events = otx.getevents_since(mtime)
json_normalize(events)<jupyter_output><empty_output><jupyter_text>- id: object id of this event.  Unique reference identifier- action : "[subscribe | unsubscribe | delete]", Currently supports subscribe / unsubscribe events for users and pulses and delete events for pulses- object_type : "[pulse | user]", // Currently supports events for pulse and user objects- object_id : "[pulse id | author id]", // Unique id can be used to lookup pulses and users (e.g. to remove them from  system, they would remove all pulses by author_id or an individual pulse by pulse "id"."created" :  When developing an application, you must decide how you want to handle different types of events. For instance, if one OTX user unsubscribes from another user, do you want to delete the IOCs the second user contributed from your application? How do you plan to reconcile the data on the server versus the data in your application?The same question comes up when users delete a pulse.  Using Search and get Pulse by ID The OTX API allows you to search for pulses and users by keyword.  This allows you to obtain pulses that you're not (yet) subscribed to.<jupyter_code>pulses = otx.search_pulses("Russian")
json_normalize(pulses["results"])<jupyter_output><empty_output><jupyter_text>Let's say we're interested in viewing the full details (including indicators) from one of our search results.  For example maybe we're interested in the Enigma Ransomware:<jupyter_code>pulse_id = pulses["results"][0]["id"]
pulse_id = '2118732129'
pulse_details = otx.get_pulse_details(pulse_id)
json_normalize(pulse_details)<jupyter_output><empty_output><jupyter_text>Indicator details Let's investigate an indicator included in the Enigma Ransomware pulse.<jupyter_code>indicator = pulse_details["indicators"][4]["indicator"]
indicator_details = otx.get_indicator_details_full(IndicatorTypes.IPv4, indicator)<jupyter_output><empty_output><jupyter_text>Indicator details are divided into sections for convenience:<jupyter_code>indicator_details.keys()
json_normalize(indicator_details["url_list"])
json_normalize(indicator_details["passive_dns"].get('passive_dns'))<jupyter_output><empty_output><jupyter_text>Indicator details are not available for all supported indicator types.  IndicatorTypes.supported_api_types contains a list of the indicator types you can use with get_indicator_details_by_section and get_indicator_details_full.   Create pulse You can create new pulses using the create_pulse function.  A name string is required.  Public boolean is also required but will be set True if not provided:<jupyter_code>indicators = [{"indicator": "192.168.127.12", "description":"", "type": "IPv4"}, {"indicator": "172.16.58.3", "description":"", "type": "IPv4"}]
new_pulse = otx.create_pulse(name="IPy Notebook Test", indicators=indicators, public=False)
json_normalize(new_pulse)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0871807774562838, 'fraction_numerical': 0.011951188828783495, 'mean_word_length': 4.513176144244105, 'pattern_counts': {'":': 38, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '179593', 'license': 'Apache-2.0', 'n_tokens_mistral': 2533, 'n_tokens_neox': 2238, 'n_words': 853, 'path': 'howto_use_python_otx_api.ipynb', 'repo_name': 'Vgrob/OTX-Python-SDK', 'size': '7950'}