{"componentChunkName":"component---src-templates-default-template-tsx","path":"/tutorials/basic-graph-operations/","result":{"data":{"asciidoc":{"id":"d9772ea0-bee5-5730-9daa-d915c539ea4c","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=\"#_prerequisites\">Prerequisites</a></li>\n<li><a href=\"#_create_a_new_vertex\">Create a new vertex</a></li>\n<li><a href=\"#_update_an_existing_vertex\">Update an existing vertex</a></li>\n<li><a href=\"#_create_an_edge_between_two_vertices\">Create an edge between two vertices</a></li>\n<li><a href=\"#_get_related_vertices\">Get related vertices</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>HIRO&#8482;’s database (HIRO Graph) is a semantic graph database, which consists of vertices (containing attributes) and edges (that connect the vertices) as data items.</p>\n</div>\n<div class=\"paragraph\">\n<p>This tutorial will demonstrate the basic graph operations that enable you to write data to the HIRO graph database.</p>\n</div>\n<div class=\"dlist\">\n<dl>\n<dt class=\"hdlist1\">What we will do in this tutorial</dt>\n<dd>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Write a new vertex to the graph</p>\n</li>\n<li>\n<p>Read a vertex and understand the vertex metadata</p>\n</li>\n<li>\n<p>Update an existing vertex</p>\n</li>\n<li>\n<p>Create an edge between two vertices</p>\n</li>\n<li>\n<p>Get related vertices</p>\n</li>\n</ol>\n</div>\n</dd>\n</dl>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_prerequisites\">Prerequisites</h2>\n<div class=\"sectionbody\">\n<div class=\"ulist\">\n<ul>\n<li>\n<p>API access to a HIRO instance</p>\n</li>\n<li>\n<p>Authenticated HIRO session with valid access token</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>Please follow the tutorial <a href=\"/7.0/tutorials/tutorial-first-steps-with-hiro/\">First Steps with HIRO</a> to authenticate before proceeding to use HIRO’s Graph API.\nWe assume for this tutorial that you have created an authenticated hiro session, which is available as <code>hiro_session</code> object:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Initiate session\nhiro_session = initiate_hiro_session('./hiro_credentials.json')</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_create_a_new_vertex\">Create a new vertex</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>We will create an entity in HIRO’s database called Person, together with some attributes, and then retrieve this information. To do this, we will define a function to create and read a vertex. Functions reduces repetition and make the codes reusable. By utilizing functions, any changes can be implemented in one place, without going through the whole code.</p>\n</div>\n<div class=\"paragraph\">\n<p>We will define a helper function called <code>create_vertex</code>. This function will create a vertex of a specific type in HIRO with some attributes that are passed as argument.  The parameters to pass to HIRO will be:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p><code>entity_type:</code> The type of entity to be created which will be in OGIT form. Among the examples are person (<code>ogit/Person</code>), calendar (<code>ogit/Schedule/Calendar</code>), and event in a calendar (<code>ogit/Schedule/Event</code>).</p>\n</li>\n<li>\n<p><code>attributes:</code> The attributes attached to the entity which will be in OGIT form. Some examples are first name (<code>ogit/firstName</code>), last name (<code>ogit/lastName</code>) and email (<code>ogit/Email</code>).</p>\n</li>\n<li>\n<p><code>scope:</code> The HIRO scope that should contain the vertex. This value will be written to the <code>ogit/_scope</code> attribute.</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>Since the entity type name contains special characters, remember to escape these special characters in the query string before sending it as URL query parameter.</p>\n</div>\n<div class=\"paragraph\">\n<p>Ideally you have an id for the <em>'data-scope'</em> (environment) you want to interact with. If 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</div>\n<div class=\"paragraph\">\n<p>If the vertex is successfully created, the function will return the vertex id to the console, so that we can use it for the next steps. We also print the vertex id to the console for now, so that we can easily see what is happening. If the write operation fails, we will print an error message to the console.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">create_vertex()</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def create_vertex(entity_type, attributes):\n    if hiro_session['scope']:\n        attributes['ogit/_scope'] = hiro_session['scope']\n    escaped_type = entity_type.replace(':', '/').replace('/', '%2F')\n    response = hiro_session['session'].post(hiro_session['graph_api'] + 'new/' + escaped_type, data=json.dumps(attributes))\n\n    if response.ok:\n        print('Vertex successfully written:' + response.json()['ogit/_id'])\n        return response.json()['ogit/_id']\n    else:\n        print(str(response.status_code) + \" - \" + response.text)\n        print('Failed to write vertex.')</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The function above can be used to write any type of vertex to the HIRO graph database.\nNow we define a more specific helper function to create a <code>ogit/Person</code> entity in HIRO Graph. This helper function will call the function <code>create_vertex</code> which was created earlier. The parameters that are being passed are:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p><code>last_name</code> = last name of the person, to be written to the <code>ogit/lastName</code> attribute</p>\n</li>\n<li>\n<p><code>email_address</code> = email address of the person - this will be written as <code>ogit/email</code> attribute.</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>The entity type will be set to <code>ogit/Person</code> within the function.</p>\n</div>\n<div class=\"paragraph\">\n<p>This function will return the vertex id as received from calling the <code>create_vertex</code> function.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">create_person()</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def create_person(last_name, email_address):\n    person_attributes = {'ogit/lastName': last_name, 'ogit/email': email_address}\n    return create_vertex('ogit/Person', person_attributes)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>As next step, we can write the first person entity to the HIRO Graph by calling the <code>create_person()</code> function declared before. We will call the person 'Johnny' and give it the email address '<a href=\"mailto:Johnny@test.com\">Johnny@test.com</a>'.\nWhen the Person object is successfully written, it will return the vertex id of the object. The vertex id is a unique id generated by the graph database.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">johnny = create_person('Johnny', 'johnny@test.com')\nif johnny:\n\tprint('Johnny is now known in HIRO.')\nelse:\n\tprint('Could not add person vertex.')</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The result will be similar to below, which is the definition of the Person object that was created, together with its Vertex ID.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-console\" data-lang=\"console\">Vertex successfully written: ckd73u0ul04jo01100j5dppq7_ckeu05eeajdvt01781ax1e8v6\nJohnny is now known in HIRO.</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>If everything succeeded the variable `johnny now contains vertex id of our created vertex.</p>\n</div>\n<div class=\"paragraph\">\n<p>To retrieve the Person object definition, do a GET request by specifying the query string OGIT and printing the response code as well as the object definition in a JSON format.\nAfter creating a vertex in the previous step, we can read the vertex by using the GET request in order to retrieve the vertex.\nAgain, we define a helper function called <code>read_vertex</code>, so that we can read vertices more conveniently in the future.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">read_vertex()</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def read_vertex (vertex_id):\n    response = hiro_session['session'].get(hiro_session['graph_api'] + str(vertex_id))\n\n    if response.ok:\n        return response.json()\n    else:\n        print (str(response.status_code) + \" - \" + response.text)\n        print ('Failed to read vertex.')\n    return None</code></pre>\n</div>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">usage</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># read vertex with given id\nresult = read_vertex(johnny)\npp.pprint(result)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The response will be the object definition in JSON format, similar to below.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">{   'ogit/_created-on': 1599572471842,\n    'ogit/_creator': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n    'ogit/_creator-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n    'ogit/_graphtype': 'vertex',\n    'ogit/_id': 'ckd73u0ul04jo01100j5dppq7_ckeu05eeajdvt01781ax1e8v6',\n    'ogit/_is-deleted': False,\n    'ogit/_modified-by': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n    'ogit/_modified-by-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n    'ogit/_modified-on': 1599572471842,\n    'ogit/_organization': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nku1o70n01y50gw',\n    'ogit/_owner': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nks1o70ouhlsk6a',\n    'ogit/_scope': 'cjy5tvdfx0nkq1o7040e4mow0_ckd73u0ul04jo01100j5dppq7',\n    'ogit/_type': 'ogit/Person',\n    'ogit/_v': 1,\n    'ogit/_v-id': '1599572471842-OluI9M',\n    'ogit/email': 'johnny@test.com',\n    'ogit/lastName': 'Johnny'}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>The information above shows the metadata for the person vertex that we created previously. In Step 2, we have specified the type of vertex to be created to be ogit/Person.</p>\n</div>\n<div class=\"paragraph\">\n<p>Attributes that start with <code>ogit/_</code> are metadata attributes with a special meaning. Most of these metadata attributes are automatically generated by HIRO; some can be set or modified by the user. Timestamps in metadata attributes use the EPOCH or UNIX timestamp. Please refer to the list below for more information on other metadata for the vertex that we created.</p>\n</div>\n<div class=\"paragraph\">\n<p><code>ogit/_creator-app</code> and <code>ogit/_modified-by-app</code> : This is the ID that is referring to the Client ID when connecting to HIRO’s API. This is the same Client ID that we had read from the credentials JSON file for authentication. This attribute is also helpful when identifying which connector has created or modified an entity.</p>\n</div>\n<div class=\"paragraph\">\n<p><code>ogit/_v</code>, and <code>ogit/_v-id</code> : This is the indicator for version or history when the vertex is modified. One-time modification will cause the counter to increase by 1 and accompanied by its own <code>_v-id</code>.</p>\n</div>\n<div class=\"paragraph\">\n<p><code>ogit/_xid</code> : This ID acts like a ‘foreign key’ in HIRO database. It may contain the original ID made by an external app that has a different ID format than HIRO database, but still  incorporated in HIRO as it may be crucial for the external app to refer to this vertex by this exact ID.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_update_an_existing_vertex\">Update an existing vertex</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>To update an existing vertex with new or updated attributes, we need a separate function. Define a function <code>update_vertex</code>, that will update a vertex by doing a POST request to the server.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">update_vertex()</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def update_vertex (vertex_id, attributes):\n    response = hiro_session['session'].post(hiro_session['graph_api'] + str(vertex_id), data=json.dumps(attributes))\n    if response.ok:\n        print('Vertex successfully updated:')\n        pp.pprint(response.json())\n    else:\n        print(str(response.status_code) + \" - \" + response.text)\n        print('Failed to update vertex.')\n    return response.ok</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To update a particular object which is also called a vertex, call the <code>update_vertex</code> function and pass the parameters Vertex ID as well as the attributes to be updated or added together with their values. In the example below, the Vertex ID object to be updated is 'johnny@test.com', to which we will add the phone number as attribute <code>ogit/mobilePhone</code> with the value '+1 888 123456789'.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">new_attributes = {'ogit/mobilePhone': '+1 888 123456789'}\nupdate_vertex (johnny, new_attributes)\n\n# verify update\nresult = read_vertex(johnny)\n    print('updated vertex')\n    pp.pprint(result)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>When the Vertex is successfully updated, it will respond with imformation about the modification.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">Vertex successfully updated:\n{   'ogit/_graphtype': 'vertex',\n    'ogit/_id': 'ckd73u0ul04jo01100j5dppq7_ckeu05eeajdvt01781ax1e8v6',\n    'ogit/_is-deleted': False,\n    'ogit/_modified-by': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n    'ogit/_modified-by-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n    'ogit/_modified-on': 1599641083074,\n    'ogit/_v': 2,\n    'ogit/_v-id': '1599641083074-RZVqx4'}</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To verify our update we call read_vertex` to retrieve the object definition with the newly added attribute <code>ogit/mobilePhone: '+1 888 123456789'</code>. We print this to the console to verify that the phone number is now stored in the graph database.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">updated vertex\n{   'ogit/_created-on': 1599572471842,\n    'ogit/_creator': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n    'ogit/_creator-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n    'ogit/_graphtype': 'vertex',\n    'ogit/_id': 'ckd73u0ul04jo01100j5dppq7_ckeu05eeajdvt01781ax1e8v6',\n    'ogit/_is-deleted': False,\n    'ogit/_modified-by': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n    'ogit/_modified-by-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n    'ogit/_modified-on': 1599641570097,\n    'ogit/_organization': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nku1o70n01y50gw',\n    'ogit/_owner': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nks1o70ouhlsk6a',\n    'ogit/_scope': 'cjy5tvdfx0nkq1o7040e4mow0_ckd73u0ul04jo01100j5dppq7',\n    'ogit/_type': 'ogit/Person',\n    'ogit/_v': 5,\n    'ogit/_v-id': '1599641570097-C1Of6P',\n    'ogit/email': 'johnny@test.com',\n    'ogit/lastName': 'Johnny',\n    'ogit/mobilePhone': '+1 888 123456789'}</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_create_an_edge_between_two_vertices\">Create an edge between two vertices</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>To demonstrate how two vertices can be related to each other with the Edge function, create another Person as a Vertex. The code below will call the helper function <code>create_person</code>.</p>\n</div>\n<div class=\"paragraph\">\n<p>We define the function <code>create_edge</code> which will accept the two vertices and the edge_type as parameters. The first Vertex will have a ‘line’ going out of it and the second Vertex will have a ‘line’ going into it.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def create_edge(vertex_1, vertex_2, edge_type):\n    escaped_type = edge_type.replace(':','/').replace('/', '%2F')\n    body = {'out': vertex_1,\n            'in': vertex_2}\n    response = hiro_session['session'].post(hiro_session['graph_api'] + 'connect/' + escaped_type, json.dumps(body))\n    return response.ok</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>In the example below, the parameters being passed are:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>\tvertex_1 = johnny\n\tvertex_2 = smith\n\tedge_type = ogit:follows</pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Which means that Johnny ‘follows’ Smith. The Edge can be verbs, like contains or likes.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">smith = create_person('Smith', 'smith@test.com', scope)\n\nif johnny and smith:\n    result = create_edge(johnny, smith, 'ogit:follows')\n    if result:\n        print ('Successfully created edge')\n    else:\n        print('failed to create edge')</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>If the edge is successfully created, a response like below can be expected.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">`Successfully created edge`</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>To validate that the edge has been created, we will ask the graph database to give us a list of all persons that Johnny follows.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_get_related_vertices\">Get related vertices</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>To receive related entities we use a gremlin query. For details on how to use please see <a href=\"https://github.com/spmallette/GremlinDocs\">GremlinDocs</a>.\nThe following code retrieves all vertices that can be reached by a <code>ogit:follows</code> edge from our <code>johnny</code> entity.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">    gremlin = hiro_session['graph_api'] + '/query/gremlin'\n    query = 'query=out(\\'ogit%2Ffollows\\')'\n    followers = hiro_session['session'].get(f\"{gremlin}?root={johnny}&amp;{query}\")\n    pprint.pprint(followers.json())</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>You will receive a list of followers vertices with their attributes.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre>{'items': [{'ogit/_created-on': 1599724886126,\n            'ogit/_creator': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n            'ogit/_creator-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n            'ogit/_graphtype': 'vertex',\n            'ogit/_id': 'ckd73u0ul04jo01100j5dppq7_ckewiw60ebt7e0178xrb984oh',\n            'ogit/_is-deleted': False,\n            'ogit/_modified-by': 'cjy5tvdfx0nkq1o7040e4mow0_cjl7uv0h3325tc506i5rv4ft8',\n            'ogit/_modified-by-app': 'cju16o7cg0001mz775fnoq66i_ckdyfzx3e92sk012669wa256x',\n            'ogit/_modified-on': 1599724886126,\n            'ogit/_organization': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nku1o70n01y50gw',\n            'ogit/_owner': 'cjy5tvdfx0nkq1o7040e4mow0_cjy5tvdfx0nks1o70ouhlsk6a',\n            'ogit/_scope': 'cjy5tvdfx0nkq1o7040e4mow0_ckd73u0ul04jo01100j5dppq7',\n            'ogit/_type': 'ogit/Person',\n            'ogit/_v': 1,\n            'ogit/_v-id': '1599724886126-DWPGBh',\n            'ogit/email': 'smith@test.com',\n            'ogit/lastName': 'Smith'}]}</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 written data to HIRO, and are able to read it out.</p>\n</div>\n<div class=\"paragraph\">\n<p>In this tutorial, we have learned the basic operations to work with data through the HIRO API.\nIn the next tutorial, we will learn how to <a href=\"/7.0/tutorials/automation-tasks/\">create automation tasks through the API</a>.</p>\n</div>\n</div>\n</div>","document":{"main":"Tutorial","title":"Tutorial: Basic Data Operations in HIRO","subtitle":"Basic Data Operations in HIRO"},"fields":{"toc":true,"location":["tutorials","basic-graph-operations"]}},"sidebarYaml":{"id":"0acf6fc1-95eb-5854-8f81-d5561b07a582","showIndex":null}},"pageContext":{"id":"d9772ea0-bee5-5730-9daa-d915c539ea4c","parent":"tutorials"}},"staticQueryHashes":["1010459453","1010459453","2356112386","2356112386","2603905930","2603905930","3026652197","3026652197","3167850324","3167850324","63159454","63159454"]}