') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - ffbobservatory/pyorient: Orientdb driver for python that uses the binary protocol. · GitHub
Skip to content

Repository files navigation

pyorient

master
Build StatusCoverage Status

develop
Build StatusCoverage Status

Orientdb driver for python that uses the binary protocol.

Pyorient works with orientdb version 1.7 and later.

Warning Some issues are experimented with record_create/record_upload and OrientDB < 2.0. These command are strongly discouraged with these versions

NOTICE Prior to version 1.4.9 there was a potential SQL injection vulnerability that now is fixed. (see details , details )

Installation

pip install pyorient

How to contribute

  • Fork the project
  • work on develop branch
  • Make your changes
  • Add tests for it. This is important so I don't break it in a future version unintentionally
  • Send me a pull request (pull request to master will be rejected)
  • ???
  • PROFIT

How to run tests

  • ensure you have ant and nose installed properly
  • bootsrap orient by running ./ci/ci-start.sh from project directory
    it will download latest orient and make some change on config and database for the tests
  • run with nosetests

Usage

Proper documentation will be available soon, for now you have to read the tests.

PyOrient is composed of two layers. At its foundation is the python wrapper around OrientDB's binary protocol. Built upon that - and OrientDB's own SQL language - is the Object-Graph Mapper (or OGM). The OGM layer is documented separately.

Init the client

client=pyorient.OrientDB("localhost", 2424)
session_id=client.connect( "admin", "admin" )

Create a DB

client.db_create( db_name, pyorient.DB_TYPE_GRAPH, pyorient.STORAGE_TYPE_MEMORY )

Check if a DB exists

client.db_exists( db_name, pyorient.STORAGE_TYPE_MEMORY )

Open a DB

client.db_open( db_name, "admin", "admin" )

Close a DB and destroy the connection ( by OrientDB design )

client.db_close()

Get the the list of databases ( needs to be connected )

client.db_list()

Get the size of a database ( needs a DB opened )

client.db_size()

Get the number of records in a database in the OrientDB Server instance

client.db_count_records()

Send a command

cluster_id=client.command( "create class my_class extends V" )
client.command(
"insert into my_class ( 'accommodation', 'work', 'holiday' ) values( 'B&B', 'garage', 'mountain' )"
)

Create a record

Warning Some issues are experimented with record_create/record_upload and OrientDB < 2.0. These command are strongly discouraged with these versions

rec= { '@my_class': { 'accommodation': 'house', 'work': 'office', 'holiday': 'sea' } }
rec_position=client.record_create( cluster_id, rec )

Update a record

Warning Some issues are experimented with record_create/record_upload and OrientDB < 2.0. These command are strongly discouraged with these versions

rec3= { '@my_class': { 'accommodation': 'hotel', 'work': 'home', 'holiday': 'hills' } }
update_success=client.record_update( rec_position._rid, rec_position._rid, rec3, rec_position._version )

Load a record

client.record_load( rec_position._rid )

Load a record with cache

def_my_callback(for_every_record):
print(for_every_record)
client.record_load( rec_position._rid, "*:-1", _my_callback )

Make a query

result=client.query("select from my_class", 10, '*:0')

Make an Async query

def_my_callback(for_every_record):
print(for_every_record)
result=client.query_async("select from my_class", 10, '*:0', _my_callback)

Delete a record

client.record_delete( cluster_id, rec_position._rid )

Drop a DB

client.db_drop( db_name )

Create a new cluster

new_cluster_id=client.data_cluster_add(
'my_cluster_1234567', pyorient.CLUSTER_TYPE_PHYSICAL
)

Reload DB ( refresh clusters info )

client.db_reload()

Get the range of record ids for a cluster

client.data_cluster_data_range( new_cluster_id )

Get the number of records in one or more clusters

client.data_cluster_count( [ 1, 2, 3, 4, 11 ] )

Drop a data cluster

client.data_cluster_drop( new_cluster_id )

Shut down the server. Requires "shutdown" permission to be set in orientdb-server-config.xml file

client.shutdown( "root", "a_super_secret_password" )

Transactions

### use a clustercluster_id=3### execute real create to get some inforec= { 'accommodation': 'mountain hut', 'work': 'not!', 'holiday': 'lake' }
rec_position=client.record_create( cluster_id, rec )
tx=client.tx_commit()
tx.begin()
### create a new recordrec1= { 'accommodation': 'home', 'work': 'some work', 'holiday': 'surf' }
rec_position1=client.record_create( -1, rec1 )
### prepare for an updaterec2= { 'accommodation': 'hotel', 'work': 'office', 'holiday': 'mountain' }
update_record=client.record_update( cluster_id, rec_position._rid, rec2, rec_position._version )
tx.attach( rec_position1 )
tx.attach( rec_position1 )
tx.attach( update_record )
res=tx.commit()
assertres["#3:1"].holiday=='mountain'assertres["#3:2"].holiday=='surf'assertres["#3:3"].holiday=='surf'

Execute OrientDB SQL Batch

cmd= ("begin;""let a = create vertex set script = true;""let b = select from v limit 1;""let e = create edge from $a to $b;""commit retry 100;")
edge_result=self.client.batch(cmd)

Persistent Connections ( Session Token )

Since version 27 is introduced an extension to allow use a token based session. This functionality must be enabled on the server config.

  • In the first negotiation the client can ask for a token based authentication using the client.set_session_token method.
  • The server will reply with a token or with an empty string meaning that it not support token based session and is using an old style session.
  • For each request, the client will send the token and eventually it will get a new one if token lifetime ends.

When using the token based authentication, the connections can be shared between users of the same server.

client=pyorient.OrientDB("localhost", 2424)
client.set_session_token( True ) # set true to enable the token basedauthenticationclient.db_open( "GratefulDeadConcerts", "admin", "admin" )
### store this token somewheresessionToken=client.get_session_token()
### destroy the old client, equals to another user/socket/ip ecc.delclient### create a new clientclient=pyorient.OrientDB("localhost", 2424)
### set the previous obtained token to re-attach to the old sessionclient.set_session_token( sessionToken )
### now the dbOpen is not needed to perform database operationsrecord=client.query( 'select from V where @rid = #9:1' )
### set the flag again to true if you want to renew the tokenclient.set_session_token( True ) # set trueclient.db_open( "GratefulDeadConcerts", "admin", "admin" )
new_sessionToken=client.get_session_token()
assertsessionToken!=new_sessionToken

A GRAPH Example

The GRAPH representation of animals and its food

importpyorientclient=pyorient.OrientDB("localhost", 2424) # host, port### open a connection (username and password)client.connect("admin", "admin")
### create a databaseclient.db_create("animals", pyorient.DB_TYPE_GRAPH, pyorient.STORAGE_TYPE_MEMORY)
### select to use that databaseclient.db_open("animals", "admin", "admin")
### Create the Vertex Animalclient.command("create class Animal extends V")
### Insert a new valueclient.command("insert into Animal set name = 'rat', specie = 'rodent'")
### query the valuesclient.query("select * from Animal")
[<OrientRecordat0x7f>..., ...]
### Create the vertex and insert the food valuesclient.command('create class Food extends V')
client.command("insert into Food set name = 'pea', color = 'green'")
### Create the edge for the Eat actionclient.command('create class Eat extends E')
### Lets the rat likes to eat peaeat_edges=client.command(
"create edge Eat from (""select from Animal where name = 'rat'"") to (""select from Food where name = 'pea'"")"
)
### Who eats the peas?pea_eaters=client.command("select expand( in( Eat )) from Food where name = 'pea'")
foranimalinpea_eaters:
print(animal.name, animal.specie)
'rat rodent'
...
### What each animal eats?animal_foods=client.command("select expand( out( Eat )) from Animal")
forfoodinanimal_foods:
animal=client.query(
"select name from ( select expand( in('Eat') ) from Food where name = 'pea' )"
)[0]
print(food.name, food.color, animal.name)
'pea green rat'

Authors

Copyright

Copyright (c) 2014 Niko Usai, Domenico Lupinetti. See LICENSE for details.

About

Orientdb driver for python that uses the binary protocol.

Resources

Stars

0 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages