hcpsdk — object access

hcpsdk provides access to HCP through http[s]/reST dialects.

Setup is easy (see example below):

  1. Instantiate an Authorization object with the required credentials.

    This class will be queried by Target objects for authorization tokens.

  2. Optional: create an SSL context if you want to have certificates presented by HCP validated.

  3. Instantiate a Target class with HCPs Full Qualified Domain Name, the port to be used, the Authorization object, optionally the SSL context created in 2. and -eventually- the FQDN of a replica HCP.

  4. Instantiate one or more Connection objects.

    These objects are the workhorses of the hcpsdk - they are providing the access methods needed. You’ll need to consult the respective HCP manuals to find out how to frame the required requests.

    Connection objects will open a session to HCP as soon as needed, but not before. After use, they keep the session open for an adjustable amount of time, helping to speed up things for an subsequent request.

    Don’t forget to close Connection objects when finished with them!

Functions

version

hcpsdk.version()

Return the full version of the HCPsdk (0.9.5-1).

checkport

hcpsdk.checkport(target, port)[source]

Check if an hcpsdk.Target() object is initialized with the correct port.

Parameters:
  • target – the hcpsdk.Target() object to check
  • port – the needed port
Returns:

nothing

Raises:

hcpsdk.HcpsdkPortError in case the port is invalid

Constants

Ports

hcpsdk.P_HTTP

Port 80 - insecure Namespace access

hcpsdk.P_HTTPS

Port 443 - secure Namespace access

Port 8888 - search facility

hcpsdk.P_MAPI

Port 9090 - Management API access

Interfaces

hcpsdk.I_NATIVE

HCP’s http/REST dialect for access to HCPs authenticated namespaces.

hcpsdk.I_HSWIFT

HCP’s http dialect for access to HCPs HSwift gateway.

hcpsdk.I_DUMMY

HCP’s http dialect for access to HCPs Default Namespace.

Classes

NativeAuthorization

class hcpsdk.NativeAuthorization(user, password)[source]

Authorization for native http/REST access to HCP.

Parameters:
  • user – the data access user
  • password – his password

NativeADAuthorization

class hcpsdk.NativeADAuthorization(user, password)[source]

Authorization for native http/REST access to HCP using an Active Directory user.

Supported with HCP 7.2.0 and later. The user needs to be a member of the Active Directory domain in which HCP is joined.

Parameters:
  • user – an Active Directory user
  • password – his password

New in version 0.9.4.0.

LocalSwiftAuthorization

class hcpsdk.LocalSwiftAuthorization(user, password)[source]

Authorization for local HSwift access to HCP (w/o Keystone).

Parameters:
  • user – the data access user
  • password – his password

New in version 0.9.3.10.

DummyAuthorization

class hcpsdk.DummyAuthorization[source]

Dummy authorization for the Default Namespace.

Target

class hcpsdk.Target(fqdn, authorization, port=443, dnscache=False, sslcontext=<ssl.SSLContext object>, interface='I_NATIVE', replica_fqdn=None, replica_strategy=None)[source]

This is the a central access point to an HCP target (and its replica, eventually). It caches the FQDN and the port and queries the provided Authorization object for the required authorization token.

Parameters:
  • fqdn – ([namespace.]tenant.hcp.loc)
  • authorization – an instance of one of BaseAuthorization’s subclasses
  • port – one of the port constants (hcpsdk.P_*)
  • dnscache – if True, use the system resolver (which might do local caching), else use an internal resolver, bypassing any cache available
  • sslcontext – the context used to handle https requests; defaults to no certificate verification
  • interface – the HCP interface to use (I_NATIVE)
  • replica_fqdn – the replica HCP’s FQDN
  • replica_strategy – OR’ed combination of the RS_* modes
Raises:

ips.IpsError if DNS query fails, HcpsdkError in all other fault cases

getaddr()[source]

Convenience method to get an IP address out of the pool.

Returns:an IP address (as string)
fqdn

The FQDN for which this object was initialized (r/o)

interface

The HCP interface used (r/o)

port

The target port in use (r/o)

ssl

Indicates if SSL is used (r/o)

sslcontext

The assigned SSL context (r/o)

addresses

The list of resolved IP addresses for this target (r/o)

headers

The calculated authorization headers (r/o)

replica

The target object for the HCP replica, if set (r/o)

replica_strategy

The replica strategy selected (r/o)

Connection

class hcpsdk.Connection(target, timeout=30, idletime=30, retries=0, debuglevel=0, sock_keepalive=False, tcp_keepalive=60, tcp_keepintvl=60, tcp_keepcnt=3)[source]

This class represents a Connection to HCP, caching the related parameters.

Parameters:
  • target – an initialized Target object
  • timeout – the timeout for this Connection (secs)
  • idletime – the time the Connection shall stay persistence when idle (secs)
  • retries – the number of retries until giving up on a Request
  • debuglevel – 0..9 -see-> http.client.HTTPconnection
  • sock_keepalive – enable TCP keepalive, if True
  • tcp_keepalive – idle time used when SO_KEEPALIVE is enable
  • tcp_keepintvl – interval between keepalives
  • tcp_keepcnt – number of keepalives before close
Connection() retries request()s if:
  1. the underlying connection has been closed by HCP before idletime has passed (the request will be retried using the existing connection context) or
  2. a timeout emerges during an active request, in which case the connection is closed, Target() is urged to refresh its cache of IP addresses, a fresh IP address is acquired from the cache and the connection is setup from scratch.

You should rarely need this, but if you have a device in the data path that limits the time an idle connection can be open, this might be of help:

Setting sock_keepalive to True enables TCP keep-alive for this connection. tcp_keepalive defines the idle time before a keep-alive packet is first sent, tcp_keepintvl is the time between keep-alive packets and tcp_keepcnt is the number of keep-alive packets to be sent before failing the connection in case the remote end doesn’t answer. See man tcp for the details.

New in version 0.9.4.3.

request(method, url, body=None, params=None, headers=None)[source]

Wraps the http.client.HTTP[s]Connection.Request() method to be able to catch any exception that might happen plus to be able to trigger hcpsdk.Target to do a new DNS query.

Url and params will be urlencoded, by default.

Beside of *method*, all arguments are valid for the convenience methods, too.

Parameters:
  • method – any valid http method (GET,HEAD,PUT,POST,DELETE)
  • url – the url to access w/o the server part (i.e: /rest/path/object); url quoting will be done if necessary, but existing quoting will not be touched
  • body – the payload to send (see http.client documentation for details)
  • params

    a dictionary with parameters to be added to the Request:

    {'verbose': 'true', 'retention': 'A+10y', ...}

    or a list of 2-tuples:

    [('verbose', 'true'), ('retention', 'A+10y'), ...]

  • headers – a dictionary holding additional key/value pairs to add to the auto-prepared header
Returns:

the original Response object received from http.client.HTTP[S]Connection.requests().

Raises:

one of the hcpsdk.Hcpsdk[..]Errors or hcpsdk.ips.IpsError in case an IP address cache refresh failed

getheader(*args, **kwargs)[source]

Used to get a single Response header. Wraps http.client.Response.getheader(). Arguments are simply passed through.

getheaders()[source]

Used to get a the Response headers. Wraps http.client.Response.getheaders().

PUT(url, body=None, params=None, headers=None)[source]

Convenience method for Request() - PUT an object. Cleans up and leaves the Connection ready for the next Request. For parameter description see Request().

GET(url, params=None, headers=None)[source]

Convenience method for Request() - GET an object. You need to fully .read() the requested content from the Connection before it can be used for another Request. For parameter description see Request().

HEAD(url, params=None, headers=None)[source]

Convenience method for Request() - HEAD - get metadata of an object. Cleans up and leaves the Connection ready for the next Request. For parameter description see Request().

POST(url, body=None, params=None, headers=None)[source]

Convenience method for Request() - POST metadata. Does no clean-up, as a POST can have a response body! For parameter description see Request().

DELETE(url, params=None, headers=None)[source]

Convenience method for Request() - DELETE an object. Cleans up and leaves the Connection ready for the next Request. For parameter description see Request().

read(amt=None)[source]

Read amt # of bytes (or all, if amt isn’t given) from a Response.

Parameters:amt – number of bytes to read
Returns:the requested number of bytes; fewer (or zero) bytes signal end of transfer, which means that the Connection is ready for another Request.
Raises:HcpsdkTimeoutError in case a socket.timeout was catched, HcpsdkError in all other cases.
close()[source]

Close the Connection.

Warning

It is essential to close the Connection, as open connections might keep the program from terminating for at max timeout seconds, due to the fact that the timer used to keep the Connection persistent runs in a separate thread, which will be canceled on close().

address

The IP address for which this object was initialized (r/o)

con

The internal connection object (r/o)

Response

Deprecated since version 0.9.4.2.

Use response instead!

response

Exposition of the http.client.Response object for the last Request (r/o)

New in version 0.9.4.2.

response_status

The HTTP status code of the last Request (r/o)

response_reason

The corresponding HTTP status message (r/o)

connect_time

The time in seconds the last connect took (r/o)

service_time1

The time in seconds the last action on a Request took. This can be the initial part of PUT/GET/etc., or a single (possibly incomplete) read from a Response (r/o)

service_time2

Duration in secods of the complete Request up to now. Sum of all service_time1 during handling a Request (r/o)

Exceptions

exception hcpsdk.HcpsdkError(reason)[source]

Raised on generic errors in hcpsdk.

Parameters:reason – an error description
exception hcpsdk.HcpsdkCantConnectError(reason)[source]

Raised if a connection couldn’t be established.

Parameters:reason – an error description
exception hcpsdk.HcpsdkTimeoutError(reason)[source]

Raised if a Connection timed out.

Parameters:reason – an error description
exception hcpsdk.HcpsdkCertificateError(reason)[source]

Raised if the SSL context doesn’t verify a certificate presented by HCP.

Parameters:reason – an error description
exception hcpsdk.HcpsdkPortError(reason)[source]

Raised if the Target is initialized with an invalid port.

Parameters:reason – an error description
exception hcpsdk.HcpsdkReplicaInitError(reason)[source]

Raised if the setup of the internal Target for the replica HCP failed (typically, this is a name resolution problem). If this exception is raised, the primary Target’s init failed, too. You’ll need to retry!

Parameters:reason – an error description

Example

>>> import hcpsdk
>>> hcpsdk.version()
'0.9.0-2'
>>> auth = hcpsdk.NativeAuthorization('n', 'n01')
>>> t = hcpsdk.Target('n1.m.hcp1.snomis.local', auth, port=443)
>>> c = hcpsdk.Connection(t)
>>> c.connect_time
'0.000000000010'
>>>
>>> r = c.PUT('/rest/hcpsdk/test1.txt', body='This is an example',
              params={'index': 'true'})
>>> c.response_status, c.response_reason
(201, 'Created')
>>>
>>> r = c.HEAD('/rest/hcpsdk/test1.txt')
>>> c.response_status, c.response_reason
(200, 'OK')
>>> c.getheaders()
[('Date', 'Sat, 31 Jan 2015 20:34:53 GMT'),
 ('Server', 'HCP V7.1.0.10'),
 ('X-RequestId', '38AD86EF250DEB35'),
 ('X-HCP-ServicedBySystem', 'hcp1.snomis.local'),
 ('X-HCP-Time', '1422736493'),
 ('X-HCP-SoftwareVersion', '7.1.0.10'),
 ('ETag', '"68791e1b03badd5e4eb9287660f67745"'),
 ('Cache-Control', 'no-cache,no-store'),
 ('Pragma', 'no-cache'),
 ('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT'),
 ('Content-Type', 'text/plain'),
 ('Content-Length', '18'),
 ('X-HCP-Type', 'object'),
 ('X-HCP-Size', '18'),
 ('X-HCP-Hash', 'SHA-256 47FB563CC8F86DC37C86D08BC542968F7986ACD81C97B'
                'F76DB7AD744407FE117'),
 ('X-HCP-VersionId', '91055133849537'),
 ('X-HCP-IngestTime', '1422736466'),
 ('X-HCP-RetentionClass', ''),
 ('X-HCP-RetentionString', 'Deletion Allowed'),
 ('X-HCP-Retention', '0'),
 ('X-HCP-IngestProtocol', 'HTTP'),
 ('X-HCP-RetentionHold', 'false'),
 ('X-HCP-Shred', 'false'),
 ('X-HCP-DPL', '2'),
 ('X-HCP-Index', 'true'),
 ('X-HCP-Custom-Metadata', 'false'),
 ('X-HCP-ACL', 'false'),
 ('X-HCP-Owner', 'n'),
 ('X-HCP-Domain', ''),
 ('X-HCP-UID', ''),
 ('X-HCP-GID', ''),
 ('X-HCP-CustomMetadataAnnotations', ''),
 ('X-HCP-Replicated', 'false'),
 ('X-HCP-ReplicationCollision', 'false'),
 ('X-HCP-ChangeTimeMilliseconds', '1422736466446.00'),
 ('X-HCP-ChangeTimeString', '2015-01-31T21:34:26+0100'),
 ('Last-Modified', 'Sat, 31 Jan 2015 20:34:26 GMT')
]
>>>
>>> r = c.GET('/rest/hcpsdk/test1.txt')
>>> c.response_status, c.response_reason
(200, 'OK')
>>> c.read()
b'This is an example'
>>> c.service_time2
0.0005471706390380859
>>>
>>> r = c.DELETE('/rest/hcpsdk/test1.txt')
>>> c.response_status, c.response_reason
(200, 'OK')
>>> c.service_time2
0.0002570152282714844
>>>
>>> c.close()
>>>