Simple object I/O without replica

Code sample

This code sample shows basic usage of the SDK - ingest an object, retrieve its metadata, read and delete it. It also shows how to retrieve request timers and how to enable debug logging.

First, we import the needed packages and setup a few constants with the parameters needed to access HCP. We also make sure that this program only runs if called as such:



import sys
from os.path import normpath
from pprint import pprint
import hcpsdk

# HCP Connection details - you'll need to adopt this to your environment!
# -- primary HCP
P_FQDN = 'n1.m.hcp1.snomis.local'
P_USER = 'n'
P_PASS = 'n01'
P_PORT = 443
# -- file to be used for the test (read-only)
P_FILE = normpath('../testfiles/128kbfile')
# -- debug mode
P_DEBUG = True

if __name__ == '__main__':
    

We need to create an authorization object, which converts the user credentials into the authorization token needed for HCP access.


    # Setup an authorization object:
    auth = hcpsdk.NativeAuthorization(P_USER, P_PASS)
    print('*I_NATIVE* authorization initialized')
    print('')
    

Now, we initialize a Target object with the parameters and the authorization object created in the steps before. Notice that we do this within a try/except clause, as we need to be able to react on errors that might happen during initialization.


    # Setup an HCP Target object:
    try:
        t = hcpsdk.Target(P_FQDN, auth, port=P_PORT)
    except hcpsdk.HcpsdkError as e:
        sys.exit('init of *Target* failed - {}'.format(e))
    else:
        print('Target *t* was initialized with IP addresses: {}'
              .format(t.addresses))
    

At next, we initialize a Connection object, using the Target created before. Notice that there is no IP address assigned to the Connection at this time! This is because a connection will acquire an IP address not earlier than needed.


    # Setup a Connection object:
    try:
        c = hcpsdk.Connection(t)
    except hcpsdk.HcpsdkError as e:
        sys.exit('init of *Target* failed - {}'.format(e))
    else:
        print('Connection *c* uses IP address: {}'.format(c.address))
        print('')
        

Now that we have a Connection and its corresponding Target, let’s write an object (the 128kb file); we’ll also set some policies for it, using the params argument. Again, notice the exception handling! Now, we have an IP address assigned. If all’s well, print the hash value HCP calculated for our object:


        # Ingest an object:
        try:
            with open(P_FILE, 'r') as infile:
                r = c.PUT('/rest/hcpsdk/sample_primary_only.txt',
                          body=infile,
                          params={'index': 'true', 'shred': 'true'})
        except hcpsdk.HcpsdkTimeoutError as e:
            sys.exit('PUT timed out - {}'.format(e))
        except hcpsdk.HcpsdkError as e:
            sys.exit('PUT failed - {}'.format(e))
        except OSError as e:
            sys.exit('failure on {} - {}'.format(P_FILE, e))
        else:
            if c.response_status == 201:
                print('PUT Request was successful')
                print('used IP address: {}'.format(c.address))
                print('hash = {}'.format(c.getheader('X-HCP-Hash')))
                print('connect time:     {:0.12f} seconds'
                      .format(c.connect_time))
                print('Request duration: {:0.12f} seconds'
                      .format(c.service_time2))
                print('')
            else:
                sys.exit('PUT failed - {}-{}'.format(c.response_status,
                                                     c.response_reason))
        

OK, as all was well so far, let’s see if our object is really there - we’ll do an HEAD Request and if successful, print the returned headers, as they contain the objects metadata:


        # Check an object for existence and get its metadata:
        try:
            r = c.HEAD('/rest/hcpsdk/sample_primary_only.txt')
        except hcpsdk.HcpsdkTimeoutError as e:
            sys.exit('HEAD timed out - {}'.format(e))
        except hcpsdk.HcpsdkError as e:
            sys.exit('HEAD failed - {}'.format(e))
        else:
            if c.response_status == 200:
                print('HEAD Request was successful - one of the headers:')
                print('Server: {}'.format(c.getheader('Server')))
                print('used IP address: {}'.format(c.address))
                print('Request duration: {:0.12f} seconds'
                      .format(c.service_time2))
                print('')
            else:
                sys.exit('HEAD failed - {}-{}'.format(c.response_status,
                                                      c.response_reason))
        

We’ll read the object back and print the first few bytes of its content:


        # Read an object:
        try:
            r = c.GET('/rest/hcpsdk/sample_primary_only.txt')
        except hcpsdk.HcpsdkTimeoutError as e:
            sys.exit('GET timed out - {}'.format(e))
        except hcpsdk.HcpsdkError as e:
            sys.exit('GET failed - {}'.format(e))
        else:
            if c.response_status == 200:

                print('GET Request was successful - here\'s the content:')
                print('{}...'.format(c.read()[:40]))
                print('used IP address: {}'.format(c.address))
                print('Request duration: {:0.12f} seconds'
                      .format(c.service_time2))
                print('')
            else:
                sys.exit('GET failed - {}-{}'.format(c.response_status,
                                                     c.response_reason))
        

Clean up by deleting the object again:


        # Delete the object:
        try:
            r = c.DELETE('/rest/hcpsdk/sample_primary_only.txt')
        except hcpsdk.HcpsdkTimeoutError as e:
            sys.exit('DELETE timed out - {}'.format(e))
        except hcpsdk.HcpsdkError as e:
            sys.exit('DELETE failed - {}'.format(e))
        else:
            if c.response_status == 200:
                print('DELETE Request was successful')
                print('used IP address: {}'.format(c.address))
                print('Request duration: {:0.12f} seconds'
                      .format(c.service_time2))
                print('')
            else:
                sys.exit('DELETE failed - {}-{}'.format(c.response_status,
                                                        c.response_reason))
                

And finally, don’t forget to close the Connection! This will cleanly cancel the timer thread that keeps an idle connection open (persistent). Not doing so will lead to the program not finishing until the timer expires!


    # Close the Connection:
    finally:
        # noinspection PyUnboundLocalVariable
        c.close()
        

As the SDK is pre-configured for DEBUG logging using Pythons native logging facility, you simply enable it by activating a logger, set to level DEBUG. In this example, we simply set P_DEBUG to True, which will enable the logging facility:


    if P_DEBUG:
        import logging
        logging.basicConfig(level=logging.DEBUG,
                            style='{', format='{levelname:>5s} {msg}')
        # noinspection PyShadowingBuiltins
        print = pprint = logging.info
    

Sample code output

Without debug messages

running *simple_primary_only.py*
*I_NATIVE* authorization initialized

Target *t* was initialized with IP addresses: ['192.168.0.53',
                                               '192.168.0.54',
                                               '192.168.0.55',
                                               '192.168.0.52']
Connection *c* uses IP address: None

PUT Request was successful
used IP address: 192.168.0.54
hash = SHA-256
       A2706A20394E48179A86C71E82C360C2960D3652340F9B9FDB355A42E3AC7691
connect time:     0.001283884048 seconds
Request duration: 0.079370975494 seconds

HEAD Request was successful - one of the headers:
Server: HCP V7.1.0.10
used IP address: 192.168.0.54
Request duration: 0.000217914581 seconds

GET Request was successful - here's the content:
b'0123456789abcdef0123456789abcdef01234567'...
used IP address: 192.168.0.54
Request duration: 0.019832849503 seconds

DELETE Request was successful
used IP address: 192.168.0.54
Request duration: 0.000179052353 seconds

With debug messages

 INFO running *simple_primary_only.py*
DEBUG *I_NATIVE* authorization initialized for user: n
DEBUG pre version 6:     Cookie: hcp-ns-auth=bg==:1dc7fed37e11b35093d311...
DEBUG version 6+: Authorization: HCP bg==:1dc7fed37e11b35093d311ef66928...
 INFO *I_NATIVE* authorization initialized
 INFO
DEBUG (re-) loaded IP address cache: ['192.168.0.52', '192.168.0.53',
                                      '192.168.0.54', '192.168.0.55'],
                                      dnscache = False
DEBUG issued IP address: 192.168.0.52
DEBUG Target initialized: n1.m.hcp1.snomis.local:443 - SSL = True
 INFO Target *t* was initialized with IP addresses: ['192.168.0.52',
                                                     '192.168.0.53',
                                                     '192.168.0.54',
                                                     '192.168.0.55']
DEBUG Connection object initialized: IP None (n1.m.hcp1.snomis.local)
                                     - timeout: 30
                                     - idletime: 30.0 - retries: 3
 INFO Connection *c* uses IP address: None
 INFO
DEBUG tried to cancel a non-existing idletimer (pretty OK)
DEBUG URL = /rest/hcpsdk/sample_primary_only.txt
DEBUG Connection needs to be opened
DEBUG issued IP address: 192.168.0.53
DEBUG Connection open: IP 192.168.0.53 (n1.m.hcp1.snomis.local)
                       - connect_time: 0.0016319751739501953
DEBUG PUT Request for /rest/hcpsdk/sample_primary_only.txt
                       - service_time1 = 0.07865500450134277
DEBUG tried to cancel a non-existing idletimer (pretty OK)
DEBUG idletimer started: <Timer(Thread-1, started 4350545920)>
 INFO PUT Request was successful
 INFO used IP address: 192.168.0.53
 INFO hash = SHA-256
             A2706A20394E48179A86C71E82C360C2960D3652340F9B9FDB355A42E3AC7691
 INFO connect time:     0.001631975174 seconds
 INFO Request duration: 0.078655004501 seconds
 INFO
DEBUG idletimer canceled: <Timer(Thread-1, started 4350545920)>
DEBUG URL = /rest/hcpsdk/sample_primary_only.txt
DEBUG HEAD Request for /rest/hcpsdk/sample_primary_only.txt
                       - service_time1 = 0.0001850128173828125
DEBUG tried to cancel a non-existing idletimer (pretty OK)
DEBUG idletimer started: <Timer(Thread-2, started 4350545920)>
 INFO HEAD Request was successful - one of the headers:
 INFO Server: HCP V7.1.0.10
 INFO used IP address: 192.168.0.53
 INFO Request duration: 0.000185012817 seconds
 INFO
DEBUG idletimer canceled: <Timer(Thread-2, started 4350545920)>
DEBUG URL = /rest/hcpsdk/sample_primary_only.txt
DEBUG GET Request for /rest/hcpsdk/sample_primary_only.txt
                      - service_time1 = 0.000186920166015625
DEBUG tried to cancel a non-existing idletimer (pretty OK)
DEBUG idletimer started: <Timer(Thread-3, started 4350545920)>
 INFO GET Request was successful - here's the content:
DEBUG (partial?) read: service_time1 = 0.022004127502441406 secs
 INFO b'0123456789abcdef0123456789abcdef01234567'...
 INFO used IP address: 192.168.0.53
 INFO Request duration: 0.022191047668 seconds
 INFO
DEBUG idletimer canceled: <Timer(Thread-3, started 4350545920)>
DEBUG URL = /rest/hcpsdk/sample_primary_only.txt
DEBUG DELETE Request for /rest/hcpsdk/sample_primary_only.txt
                         - service_time1 = 0.0001800060272216797
DEBUG tried to cancel a non-existing idletimer (pretty OK)
DEBUG idletimer started: <Timer(Thread-4, started 4350545920)>
 INFO DELETE Request was successful
 INFO used IP address: 192.168.0.53
 INFO Request duration: 0.000180006027 seconds
 INFO
DEBUG idletimer canceled: <Timer(Thread-4, started 4350545920)>
DEBUG Connection object closed: IP 192.168.0.53 (n1.m.hcp1.snomis.local)