{"id":171,"date":"2016-08-18T11:03:29","date_gmt":"2016-08-18T15:03:29","guid":{"rendered":"http:\/\/provideotech.org\/?p=171"},"modified":"2016-08-18T14:21:23","modified_gmt":"2016-08-18T18:21:23","slug":"using-python-to-talk-to-archiware-p5s-cli-api","status":"publish","type":"post","link":"https:\/\/provideotech.org\/?p=171","title":{"rendered":"Using Python to talk to Archiware P5&#8217;s CLI API"},"content":{"rendered":"<p>I get asked all the time how the Archiware P5 CLI works.  It is actually a fairly intuitive CLI, the docs can be found at Archiware&#8217;s knowledgebase <a href=\"http:\/\/portal.archiware.com\/support\/index.php?\/Knowledgebase\/Article\/View\/12\/0\/access-the-cli\" target=\"_blank\">here<\/a>.  Below is a heavily commented python script for doing some of the basics with P5 archive via the CLI.  This code should work with Python 2.6 and greater.<\/p>\n<pre lang=\"python\">\r\nimport sys\r\nimport os\r\nimport time\r\nimport hashlib\r\nimport subprocess\r\n\r\n###########################\r\n# user configurable stuff #\r\n###########################\r\n\r\n#where is p5 installed?\r\np5_path = '\/usr\/local\/aw'\r\n\r\n#ip of p5 server\r\np5_ip = 'p5demo'\r\n\r\n#user of p5 server - should be root or user allowed to use P5.  More info here at the url below\r\n# http:\/\/portal.archiware.com\/support\/index.php?\/Knowledgebase\/Article\/View\/46\/0\/user-access-rights-in-presstore\r\np5_user = 'root'\r\n\r\n#p5 user password\r\np5_pass = 'password'\r\n\r\n#p5 server public port - note this is NOT the port of the local nsd instance, otherwise we could sniff it\r\np5_port = '8000'\r\n\r\n###########################\r\n# end configurable stuff  #\r\n###########################\r\n\r\n#derive the nsdchat path\r\nnsdchat = p5_path + '\/bin\/nsdchat'\r\n\r\n# derive the API port\r\napi_port = str(int(p5_port) + 1001)\r\n\r\n#generate a random session ID - only want to do this once per startup of your app\r\n#I used MD5 here and hashed the date the script started, but you could use whatever you want.  You could even\r\n#use a fixed value as only this application will use that session ID\r\n\r\nsession_id = (hashlib.sha224(str(time.time()))).hexdigest()\r\n\r\n#build our command prefix so we don't have to keep typing stuff\r\nsock = 'awsock:\/' + p5_user + \":\" + p5_pass + \":\" + session_id + \"@\" + p5_ip + \":\" + api_port\r\n\r\n#build a simple list we can pass our process interpreter to make life easier\r\n#we can just append our classes\/methods now to this\r\ncmd = [nsdchat,'-s',sock,'-c']\r\n\r\n#make calls easier to make - it will always return a list even if only one element is in there.\r\n#it will print out what it sent via the CLI and return the result. Pass it our cmd from above\r\n#as argument 1 and the class\/methods\/args we need as a list in arg 2 in a list\r\ndef p5_api_call(p5_command_prefix, p5_call):\r\n\t#build our call\r\n\tnew_command = p5_command_prefix + p5_call\r\n\t#just print it out so it is easy to see what is going on\r\n\tprint ' '.join(new_command) \r\n\t#run the call and wait until the process completes\r\n\tp = subprocess.Popen(new_command,stdout=subprocess.PIPE, stderr=subprocess.PIPE)\r\n\tp.wait()\r\n\t#grab stdout and stderr\r\n\toutput,error = p.communicate()\r\n\t#return stdout formatted as a list.  This isn't 100% perfect, some results are pure text so\r\n\treturn output\r\n\r\n# a few quick examples.  To run geterror, sniff your response for expected error based on API\r\n# normally this is an empty line that strips out to nothing in a list (assuming your are building\r\n# lists), but sometimes it isn't.  \r\n#\r\nprint p5_api_call(cmd,['ArchivePlan','names']).rstrip().split(' ')\r\n\r\n# if you know a result never will be more than a single element, you could get rid of the split\r\nprint p5_api_call(cmd,['srvinfo','port']).rstrip()\r\n\r\n# if you want to trap for an error, take a look at your output and filter for expected results\r\n# then you can get the error running the 'geterror' method immediately after an error condition\r\n\r\nif p5_api_call(cmd,['Volume','1234','mediatype']).rstrip().split(' ')[0] == '':\r\n\tprint p5_api_call(cmd,['geterror'])\r\nelse:\r\n\tprint\r\n\r\n# an example of a full archive job - you'll want to error trap all of this\r\n# but for examples we'll just assume everything works\r\n#\r\n# first we need to create an archive selection\r\nmy_selection = p5_api_call(cmd,['ArchiveSelection','create','localhost','10001']).rstrip()\r\nprint my_selection\r\n\r\n# then we need to add entries to the selection.  Normally this will be a list of files\r\n# it is important to note that this absolute path to the file on the P5 server, so if there is path\r\n# mapping that has to happen, you'll need to do that before passing the files\r\n# \r\n# you will also want to check if a file does not return a handle as that means it won't be archived\r\n\r\nmy_file_list = ['\/tmp\/AlTest1.err','\/tmp\/AlTest1.out'] #fill this in with real files\r\nmy_handles = []\r\nfor file in my_file_list:\r\n\tthis_handle = p5_api_call(cmd,['ArchiveSelection',my_selection,'addentry',file]).rstrip()\r\n\tmy_handles.append(this_handle)\r\n\r\nprint my_handles # these are all the unique ids of the items that P5 will use in its index\r\n\r\n\r\nmy_job = p5_api_call(cmd,['ArchiveSelection','submit','now']).rstrip()\r\nprint my_job # this is the job that was just submitted\r\n\r\nmy_status = p5_api_call(cmd,['Job',my_job,'status']\r\nprint my_status # get back running status of a submitted job\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I get asked all the time how the Archiware P5 CLI works. It is actually a fairly intuitive CLI, the docs can be found at Archiware&#8217;s knowledgebase here. Below is a heavily commented python script for doing some of the basics with P5 archive via the CLI. This code should work with Python 2.6 and &hellip; <a href=\"https:\/\/provideotech.org\/?p=171\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using Python to talk to Archiware P5&#8217;s CLI API&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[8],"tags":[],"class_list":["post-171","post","type-post","status-publish","format-standard","hentry","category-archiware-p5"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2bwLw-2L","_links":{"self":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts\/171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=171"}],"version-history":[{"count":0,"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts\/171\/revisions"}],"wp:attachment":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}