{"componentChunkName":"component---src-templates-default-template-tsx","path":"/tutorials/tutorial-first-steps-with-hiro/","result":{"data":{"asciidoc":{"id":"8e8a24bb-3f13-5757-ad0d-bb3ad27e7101","html":"<div id=\"toc\" class=\"toc\">\n<div id=\"toctitle\">Table of Contents</div>\n<ul class=\"sectlevel1\">\n<li><a href=\"#_overview\">Overview</a></li>\n<li><a href=\"#_prepare_prerequisites_to_connect_with_hiro\">Prepare prerequisites to connect with HIRO</a></li>\n<li><a href=\"#_authenticate_and_retrieve_an_auth_token\">Authenticate and retrieve an auth token</a></li>\n<li><a href=\"#_refactoring_the_session_initiation\">Refactoring the session initiation</a></li>\n<li><a href=\"#_call_the_hiro_api_to_retrieve_data\">Call the HIRO API to retrieve data</a></li>\n<li><a href=\"#_summary\">Summary</a></li>\n</ul>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_overview\">Overview</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In this tutorial, we make first contact with the HIRO API. We will understand which prerequisites are required to use the API, authenticate with our credentials, and the make first calls to the HIRO API.</p>\n</div>\n<div class=\"paragraph\">\n<p>We will perform the following steps to implement the connector:</p>\n</div>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Prepare prerequisites to connect with HIRO</p>\n</li>\n<li>\n<p>Authenticate and retrieve an auth token</p>\n</li>\n<li>\n<p>Call the HIRO API to retrieve data</p>\n</li>\n</ol>\n</div>\n<div class=\"paragraph\">\n<p>The sample code in this tutorial is written in Python programming language. However, the HIRO API follows web standards and therefore is language agnostic. You may use any programming language of your choice to interact with the HIRO API.\nWe are using Jupyter to write the sample code to facilitate iterating and testing the code snippets (see screenshot below).</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/jupyter-notebook-1.png\" alt=\"Jupyter notebook\">\n</div>\n<div class=\"title\">Figure 1. A Jupyter notebook to quickly iterate code samples</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_prepare_prerequisites_to_connect_with_hiro\">Prepare prerequisites to connect with HIRO</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Before we can start, there are a few prerequisites we need to prepare:</p>\n</div>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Make sure that you have access to a HIRO instance. The HIRO URL should be <strong><a href=\"https://core.engine.datagroup.de/api/\" class=\"bare\">https://core.engine.datagroup.de/api/</a></strong></p>\n</li>\n<li>\n<p>Make sure that you have a valid user account and password with sufficient access permissions.</p>\n</li>\n<li>\n<p>Make sure that you have received a registered application key (pair of client_id and client_secret)</p>\n</li>\n<li>\n<p>Ideally you have an id for the <em>'data-scope'</em> (environment) you want to interact with.\nIf omitted the default scope of your account will be used. Please be aware, that this may lead to confusion if your account has access to multiple scopes. Therefore, it&#8217;s highly recommended defining your desired scope.</p>\n</li>\n</ol>\n</div>\n<div class=\"paragraph\">\n<p>Connectors typically use service accounts to connect with HIRO. However, you may work with your personal HIRO user account during development.</p>\n</div>\n<div class=\"paragraph\">\n<p>To connect and authenticate ourselves with the HIRO system, we need to provide a few  parameters, i.e. server URL, user credentials and application credentials. For convenience and to keep credentials out of our code, we put them into a configuration file 'hiro_credentials.json', so that we can read the configuration from file later.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">hiro_credentials.json</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-json\" data-lang=\"json\">{\n  \"api_url\": \"https://core.engine.datagroup.de/api/\",\n  \"scope\" : \"--INSERT SCOPE ID HERE--\",\n  \"client_id\": \"--INSERT CLIENT ID HERE--\",\n  \"client_secret\": \"--INSERT CLIENT SECRET HERE--\",\n  \"username\": \"--INSERT YOUR USER NAME HERE--\",\n  \"password\": \"--INSERT YOUR PASSWORD HERE--\"\n}</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_authenticate_and_retrieve_an_auth_token\">Authenticate and retrieve an auth token</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Now we can import the credentials file, so that server URL and user credentials are available as variables. For convenience, we construct additional specific URLs for the Auth API (hiro_auth_api) and Graph API (hiro_auth_api).</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Imports\nimport requests\nimport json\nimport pprint\npp = pprint.PrettyPrinter(indent=4)\n\n# Create HIRO Session\nhiro_credentials_file = \"./hiro_credentials.json\" #\nwith open(hiro_credentials_file) as json_file:\n    hiro_credentials = json.load(json_file)\nhiro_api_base = hiro_credentials['api_url']\nhiro_auth_api = hiro_api_base + 'auth/6/'\nhiro_graph_api = hiro_api_base + 'graph/7/'</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>As next step, we need to authenticate with the HIRO server. This is done by sending a POST request to the Auth API, and sending the auth data as payload attributes. We must provide our user name, password, client id and client secret to successfully authenticate. The generated user token is then bound to the provided user account in combination with the specific application (client_id).</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Authenticate\nprint('Authenticating with HIRO Auth Service to receive an auth token ...')\nauth_data = {'client_id': hiro_credentials['client_id'], 'client_secret': hiro_credentials['client_secret'], 'username': hiro_credentials['username'], 'password': hiro_credentials['password']}\nresponse = requests.post(hiro_auth_api+'app', data=json.dumps(auth_data))</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>After we have sent the authentication request, we want to know whether the authentication has succeeded, and react accordingly. In our sample code, we will print out the authentication status to the console.</p>\n</div>\n<div class=\"paragraph\">\n<p>For further API use, we always need to pass on our auth token as header attribute in all HTTPS requests. We will prepare for that by creating a session object and add the header attribute to it. From now on, all requests in this session will automatically send the auth token.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Inspect response\nprint('Response code: ' + str(response))\nif response.ok:\n    hiro_user_token = response.json()['_TOKEN']\n    s = requests.Session()\n    s.headers.update({'Authorization': 'Bearer ' + hiro_user_token})\n    print ('You have successfully created a HIRO access token and can start using the HIRO API.')\nelse:\n    print ('Authentication error: '+ str(response.status_code) + ' - ' + response.reason)\n    print ('Error message: ' + response.text)\n    print ('Please check your credentials and try again.')</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The console output should look like this:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-console\" data-lang=\"console\">Authenticating with HIRO Auth Service to receive an auth token ...\nResponse code: &lt;Response [200]&gt;\nYou have successfully created a HIRO access token and can start using the HIRO API.</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>If everything went well, we have a valid authentication token, created an HTTPS session, and are ready to work with the HIRO API. If not, there was probably something wrong with your credentials. Go back, check the credentials, and retry.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_refactoring_the_session_initiation\">Refactoring the session initiation</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Before we continue, let&#8217;s refactor the authentication code, so that it will be reusable for further examples. We define a function for session initiation, which takes the file name of the credentials file as input parameter. The returned session object will contain the HTTPS session, the HIRO URLs and the scope.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Define authentication function\ndef initiate_hiro_session(credentials_file_name):\n    with open(credentials_file_name) as json_file:\n        hiro_credentials = json.load(json_file)\n    hiro_session_context = dict()\n    hiro_api_base = hiro_credentials['api_url']\n    hiro_session_context['scope'] = hiro_credentials['scope']\n    hiro_session_context['auth_api'] = hiro_api_base + 'auth/6/'\n    hiro_session_context['graph_api'] = hiro_api_base + 'graph/7/'\n\n    # authenticate\n    print('Authenticating with HIRO Auth Service to receive an auth token ...')\n    auth_data = {'client_id': hiro_credentials['client_id'], 'client_secret': hiro_credentials['client_secret'],\n                 'username': hiro_credentials['username'], 'password': hiro_credentials['password']}\n    hiro_auth_api = str(hiro_session_context['auth_api'])\n    print(hiro_auth_api)\n    response = requests.post(hiro_auth_api + 'app', data=json.dumps(auth_data))\n\n    print('Response code: ' + str(response))\n    if response.ok:\n        print('You have successfully created a HIRO access token and can start using the HIRO API.')\n        hiro_user_token = response.json()['_TOKEN']\n        hiro_session_context['session'] = requests.Session()\n        hiro_session_context['session'].headers.update({'Authorization': 'Bearer ' + hiro_user_token})\n        hiro_session_context['active'] = True\n    else:\n        print('Authentication error: ' + str(response.status_code) + ' - ' + response.reason)\n        print('Error message: ' + response.text)\n        print('Please check your credentials and try again.')\n        hiro_session_context['active'] = False\n\n    return hiro_session_context\n\n\nhiro_session = initiate_hiro_session('./hiro_credentials.json')\nif hiro_session['active'] == True:\n    print('continue using the API ...')</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_call_the_hiro_api_to_retrieve_data\">Call the HIRO API to retrieve data</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>With this active HIRO session, we can now work with the HIRO API. As an example, we will try to submit a simple query to the HIRO Graph.</p>\n</div>\n<div class=\"paragraph\">\n<p>The HIRO Graph supports different query modes. We use the <em>vertices</em> query mode to search for items of type <em>ogit/Automation/AutomationIssue</em>. Don&#8217;t worry, we will explain this data type later in details.</p>\n</div>\n<div class=\"paragraph\">\n<p>As you may have noticed, we need to escape a few special characters in the query string before sending it as URL query parameter.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">vertex_query_url = hiro_session['graph_api'] + 'query/vertices?query='\nquery_string = '+ogit/_type:ogit/Automation/AutomationIssue AND ogit/_scope:'+hiro_session['scope']\nescaped_query_string = query_string\\\n    .replace('/', '%5C%2F')\\\n    .replace(' ', '%20')\\\n    .replace('\\\\', '%5C')\\\n    .replace(':','%3A')\\\n    .replace( '+', '%2B')\n\nquery_response = hiro_session['session'].get(vertex_query_url + escaped_query_string)\nprint(query_response)\npp.pprint(query_response.json())</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>This query has either returned a list of AutomationIssue vertices - if you already have some in your HIRO instance - or alternatively an empty list. In case your Graph is still empty: we will soon learn how to populate it with data.</p>\n</div>\n<div class=\"paragraph\">\n<p>The result data might look like this:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-json\" data-lang=\"json\">{\n  \"items\": [\n    {\n      \"/DatePrintOutput\": \"2020-08-18 13:23:30\",\n      \"ogit/Automation/deployStatus\": \"deployed\",\n      \"ogit/Automation/issueType\": \"unknown\",\n      \"ogit/Automation/originNode\": \"ckd73u0ul04jo01100j5dppq7_ckdzyc2kftth40126ws47ktio\",\n      \"ogit/Automation/processingTimestamp\": \"1597757010332\",\n      \"ogit/_created-on\": 1597757000390,\n      \"ogit/_creator\": \"cjy5tvdfx0nkq1o7040e4mow0_cjl7za8hs3csfl1756lo90sen\",\n      \"ogit/_creator-app\": \"cju16o7cg0001mz775fnoq66i_cjix82rxi000gu473w5kvkpqv\",\n      \"ogit/_graphtype\": \"vertex\",\n      \"ogit/_id\": \"ckd73u0ul04jo01100j5dppq7_ckdzz9jnqxrya0185e1e4zijb\",\n      \"ogit/_is-deleted\": false,\n      \"ogit/_modified-by\": \"cjy5tvdfx0nkq1o7040e4mow0_ckd73u30p04k00110vtx04pgg\",\n      \"ogit/_modified-by-app\": \"cju16o7cf0000mz77pbwbhl3q_cjix82tev000ou473gko8jgey\",\n      \"ogit/_modified-on\": 1597757011631,\n      \"ogit/_organization\": \"cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nku1o70n01y50gw\",\n      \"ogit/_owner\": \"cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nks1o70ouhlsk6a\",\n      \"ogit/_scope\": \"cjy5tvdfx0nkq1o7040e4mow0_ckd73u0ul04jo01100j5dppq7\",\n      \"ogit/_type\": \"ogit/Automation/AutomationIssue\",\n      \"ogit/_v\": 4,\n      \"ogit/_v-id\": \"1597757011631-SwG5pa\",\n      \"ogit/status\": \"RESOLVED\",\n      \"ogit/subject\": \"Test\"\n    },\n    {\n      \"/ProcessIssue\": \"todo\",\n      \"ogit/Automation/deployStatus\": \"ExecIdle threshold (900) exceeded: more knowledge required?\",\n      \"ogit/Automation/issueType\": \"unknown\",\n      \"ogit/Automation/originNode\": \"ckd73u0ul04jo01100j5dppq7_ckdzyc2kftth40126ws47ktio\",\n      \"ogit/Automation/processingTimestamp\": \"1597756624025\",\n      \"ogit/_created-on\": 1597755613445,\n      \"ogit/_creator\": \"cjy5tvdfx0nkq1o7040e4mow0_cjl7za8hs3csfl1756lo90sen\",\n      \"ogit/_creator-app\": \"cju16o7cg0001mz775fnoq66i_cjix82rxi000gu473w5kvkpqv\",\n      \"ogit/_graphtype\": \"vertex\",\n      \"ogit/_id\": \"ckd73u0ul04jo01100j5dppq7_ckdzyfthhtuci01263h47hpo9\",\n      \"ogit/_is-deleted\": false,\n      \"ogit/_modified-by\": \"cjy5tvdfx0nkq1o7040e4mow0_ckd73u30p04k00110vtx04pgg\",\n      \"ogit/_modified-by-app\": \"cju16o7cf0000mz77pbwbhl3q_cjix82tev000ou473gko8jgey\",\n      \"ogit/_modified-on\": 1597756624107,\n      \"ogit/_organization\": \"cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nku1o70n01y50gw\",\n      \"ogit/_owner\": \"cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nks1o70ouhlsk6a\",\n      \"ogit/_scope\": \"cjy5tvdfx0nkq1o7040e4mow0_ckd73u0ul04jo01100j5dppq7\",\n      \"ogit/_type\": \"ogit/Automation/AutomationIssue\",\n      \"ogit/_v\": 5,\n      \"ogit/_v-id\": \"1597756624107-zXxQk6\",\n      \"ogit/status\": \"STOPPED\",\n      \"ogit/subject\": \"Test\"\n    }\n  ]\n}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>or an empty list:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-json\" data-lang=\"json\">{\n    \"items\": []\n}</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_summary\">Summary</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Congratulations! You have successfully connected to HIRO and run the first query against the graph database.</p>\n</div>\n<div class=\"paragraph\">\n<p>In this tutorial, we have prepared the prerequisites to work with the HIRO API, authenticated with the Auth API, and then used the auth token to submit a query to the HIRO Graph.</p>\n</div>\n<div class=\"paragraph\">\n<p>In the next tutorial, we will learn how to <a href=\"/7.0/tutorials/basic-graph-operations/\">Write and read data to the HIRO Graph</a>.</p>\n</div>\n</div>\n</div>","document":{"main":"Tutorial","title":"Tutorial: First Steps With HIRO","subtitle":"First Steps With HIRO"},"fields":{"toc":true,"location":["tutorials","tutorial-first-steps-with-hiro"]}},"sidebarYaml":{"id":"0acf6fc1-95eb-5854-8f81-d5561b07a582","showIndex":null}},"pageContext":{"id":"8e8a24bb-3f13-5757-ad0d-bb3ad27e7101","parent":"tutorials"}},"staticQueryHashes":["1010459453","1010459453","2356112386","2356112386","2603905930","2603905930","3026652197","3026652197","3167850324","3167850324","63159454","63159454"]}