def subscribe_to_candles(self, pair, timeframe=None, **kwargs):
        """Subscribe to the passed pair's OHLC data channel.

        :param pair: str, Symbol pair to request data for
        :param timeframe: str, {1m, 5m, 15m, 30m, 1h, 3h, 6h, 12h,
                                1D, 7D, 14D, 1M}
        :param kwargs:
        :return:
        """

        valid_tfs = ['1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D',
                     '7D', '14D', '1M']
        if timeframe:
            if timeframe not in valid_tfs:
                raise ValueError("timeframe must be any of %s" % valid_tfs)
        else:
            timeframe = '1m'
        identifier = ('candles', pair, timeframe)
        pair = 't' + pair if not pair.startswith('t') else pair
        key = 'trade:' + timeframe + ':' + pair
        self._subscribe('candles', identifier, key=key, **kwargs)

def
subscribe_to_candles
(
self
,
pair
,
timeframe
=
,
*
*
kwargs
)
:
valid_tfs
=
[
'1m'
,
'5m'
,
'15m'
,
'30m'
,
'1h'
,
'3h'
,
'6h'
,
'12h'
,
'1D'
,
'7D'
,
'14D'
,
'1M'
]
if
timeframe
:
if
timeframe
not
in
valid_tfs
:
raise
ValueError
(
"timeframe must be any of %s"
%
valid_tfs
)
else
:
timeframe
=
'1m'
identifier
=
(
'candles'
,
pair
,
timeframe
)
pair
=
't'
+
pair
if
not
pair
.
startswith
(
't'
)
else
pair
key
=
'trade:'
+
timeframe
+
':'
+
pair
self
.
_subscribe
(
'candles'
,
identifier
,
key
=
key
,
*
*
kwargs
)

Subscribe to the passed pair s OHLC data channel .


def unsubscribe_from_candles(self, pair, timeframe=None, **kwargs):
        """Unsubscribe to the passed pair's OHLC data channel.

        :param timeframe: str, {1m, 5m, 15m, 30m, 1h, 3h, 6h, 12h,
                                1D, 7D, 14D, 1M}
        :param kwargs:
        :return:
        """

        valid_tfs = ['1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D',
                     '7D', '14D', '1M']
        if timeframe:
            if timeframe not in valid_tfs:
                raise ValueError("timeframe must be any of %s" % valid_tfs)
        else:
            timeframe = '1m'
        identifier = ('candles', pair, timeframe)
        pair = 't' + pair if not pair.startswith('t') else pair
        key = 'trade:' + timeframe + ':' + pair

        self._unsubscribe('candles', identifier, key=key, **kwargs)

def
unsubscribe_from_candles
(
self
,
pair
,
timeframe
=
,
*
*
kwargs
)
:
valid_tfs
=
[
'1m'
,
'5m'
,
'15m'
,
'30m'
,
'1h'
,
'3h'
,
'6h'
,
'12h'
,
'1D'
,
'7D'
,
'14D'
,
'1M'
]
if
timeframe
:
if
timeframe
not
in
valid_tfs
:
raise
ValueError
(
"timeframe must be any of %s"
%
valid_tfs
)
else
:
timeframe
=
'1m'
identifier
=
(
'candles'
,
pair
,
timeframe
)
pair
=
't'
+
pair
if
not
pair
.
startswith
(
't'
)
else
pair
key
=
'trade:'
+
timeframe
+
':'
+
pair
self
.
_unsubscribe
(
'candles'
,
identifier
,
key
=
key
,
*
*
kwargs
)

Unsubscribe to the passed pair s OHLC data channel .


def authenticate(self):
        """Authenticate with the Bitfinex API.

        :return:
        """
        if not self.key and not self.secret:
            raise ValueError("Must supply both key and secret key for API!")
        self.channel_configs['auth'] = {'api_key': self.key, 'secret': self.secret}
        self.conn.send(api_key=self.key, secret=self.secret, auth=True)


def cancel_order(self, multi=False, **order_identifiers):
        """Cancel one or multiple orders via Websocket.

        :param multi: bool, whether order_settings contains settings for one, or
                      multiples orders
        :param order_identifiers: Identifiers for the order(s) you with to cancel
        :return:
        """
        if multi:
            self._send_auth_command('oc_multi', order_identifiers)
        else:
            self._send_auth_command('oc', order_identifiers)

def cancel_order ( self , multi = False , * * order_identifiers ) : if multi : self . _send_auth_command ( 'oc_multi' , order_identifiers ) else : self . _send_auth_command ( 'oc' , order_identifiers )

Cancel one or multiple orders via Websocket .


def _onCommand(self, client, userdata, pahoMessage):
        """
        Internal callback for device command messages, parses source device from topic string and
        passes the information on to the registered device command callback
        """
        try:
            command = Command(pahoMessage, self._messageCodecs)
        except InvalidEventException as e:
            self.logger.critical(str(e))
        else:
            self.logger.debug("Received device command '%s'" % (command.command))
            if self.commandCallback:
                self.commandCallback(command)

def
_onCommand
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
command
=
Command
(
pahoMessage
,
self
.
_messageCodecs
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)
else
:
self
.
logger
.
debug
(
"Received device command '%s'"
%
(
command
.
command
)
)
if
self
.
commandCallback
:
self
.
commandCallback
(
command
)

Internal callback for device command messages parses source device from topic string and passes the information on to the registered device command callback


def _onDeviceCommand(self, client, userdata, pahoMessage):
        """
        Internal callback for gateway command messages, parses source device from topic string and
        passes the information on to the registered device command callback
        """
        try:
            command = Command(pahoMessage, self._messageCodecs)
        except InvalidEventException as e:
            self.logger.critical(str(e))
        else:
            self.logger.debug("Received gateway command '%s'" % (command.command))
            if self.deviceCommandCallback:
                self.deviceCommandCallback(command)

def
_onDeviceCommand
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
command
=
Command
(
pahoMessage
,
self
.
_messageCodecs
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)
else
:
self
.
logger
.
debug
(
"Received gateway command '%s'"
%
(
command
.
command
)
)
if
self
.
deviceCommandCallback
:
self
.
deviceCommandCallback
(
command
)

Internal callback for gateway command messages parses source device from topic string and passes the information on to the registered device command callback


def _onMessageNotification(self, client, userdata, pahoMessage):
        """
        Internal callback for gateway notification messages, parses source device from topic string and
        passes the information on to the registered device command callback
        """
        try:
            note = Notification(pahoMessage, self._messageCodecs)
        except InvalidEventException as e:
            self.logger.critical(str(e))
        else:
            self.logger.debug("Received Notification")
            if self.notificationCallback:
                self.notificationCallback(note)

def
_onMessageNotification
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
note
=
Notification
(
pahoMessage
,
self
.
_messageCodecs
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)
else
:
self
.
logger
.
debug
(
"Received Notification"
)
if
self
.
notificationCallback
:
self
.
notificationCallback
(
note
)

Internal callback for gateway notification messages parses source device from topic string and passes the information on to the registered device command callback


def create(self, deviceType):
        """
        Register one or more new device types, each request can contain a maximum of 512KB.
        """

        r = self._apiClient.post("api/v0002/device/types", deviceType)

        if r.status_code == 201:
            return DeviceType(apiClient=self._apiClient, **r.json())
        else:
            raise ApiException(r)

def create ( self , deviceType ) : r = self . _apiClient . post ( "api/v0002/device/types" , deviceType ) if r . status_code == 201 : return DeviceType ( apiClient = self . _apiClient , * * r . json ( ) ) else : raise ApiException ( r )

Register one or more new device types each request can contain a maximum of 512KB .


def publishEvent(self, event, msgFormat, data, qos=0, on_publish=None):
        """
        Publish an event to Watson IoT Platform.

        # Parameters
        event (string): Name of this event
        msgFormat (string): Format of the data for this event
        data (dict): Data for this event
        qos (int): MQTT quality of service level to use (`0`, `1`, or `2`)
        on_publish(function): A function that will be called when receipt
           of the publication is confirmed.

        # Callback and QoS
        The use of the optional #on_publish function has different implications depending
        on the level of qos used to publish the event:

        - qos 0: the client has asynchronously begun to send the event
        - qos 1 and 2: the client has confirmation of delivery from the platform
        """
        topic = "iot-2/evt/{event}/fmt/{msg_format}".format(event=event, msg_format=msgFormat)
        return self._publishEvent(topic, event, msgFormat, data, qos, on_publish)

def publishEvent ( self , event , msgFormat , data , qos = 0 , on_publish = None ) : topic = "iot-2/evt/{event}/fmt/{msg_format}" . format ( event = event , msg_format = msgFormat ) return self . _publishEvent ( topic , event , msgFormat , data , qos , on_publish )

Publish an event to Watson IoT Platform .


def update(self, deviceUid, metadata=None, deviceInfo=None, status=None):
        """
        Update an existing device
        """

        if not isinstance(deviceUid, DeviceUid) and isinstance(deviceUid, dict):
            deviceUid = DeviceUid(**deviceUid)

        deviceUrl = "api/v0002/device/types/%s/devices/%s" % (deviceUid.typeId, deviceUid.deviceId)

        data = {"status": status, "deviceInfo": deviceInfo, "metadata": metadata}

        r = self._apiClient.put(deviceUrl, data)
        if r.status_code == 200:
            return Device(apiClient=self._apiClient, **r.json())
        else:
            raise ApiException(r)

def update ( self , deviceUid , metadata = None , deviceInfo = None , status = None ) : if not isinstance ( deviceUid , DeviceUid ) and isinstance ( deviceUid , dict ) : deviceUid = DeviceUid ( * * deviceUid ) deviceUrl = "api/v0002/device/types/%s/devices/%s" % ( deviceUid . typeId , deviceUid . deviceId ) data = { "status" : status , "deviceInfo" : deviceInfo , "metadata" : metadata } r = self . _apiClient . put ( deviceUrl , data ) if r . status_code == 200 : return Device ( apiClient = self . _apiClient , * * r . json ( ) ) else : raise ApiException ( r )


def find(self, status=None, connectedAfter=None):
        """
        Iterate through all Connectors
        """
        queryParms = {}
        if status:
            queryParms["status"] = status
        if connectedAfter:
            queryParms["connectedAfter"] = connectedAfter

        return IterableClientStatusList(self._apiClient, filters=queryParms)

def find ( self , status = None , connectedAfter = None ) : queryParms = { } if status : queryParms [ "status" ] = status if connectedAfter : queryParms [ "connectedAfter" ] = connectedAfter return IterableClientStatusList ( self . _apiClient , filters = queryParms )


def list(self):
        """
        List all device management extension packages
        """
        url = "api/v0002/mgmt/custom/bundle"
        r = self._apiClient.get(url)

        if r.status_code == 200:
            return r.json()
        else:
            raise ApiException(r)

def list ( self ) : url = "api/v0002/mgmt/custom/bundle" r = self . _apiClient . get ( url ) if r . status_code == 200 : return r . json ( ) else : raise ApiException ( r )


def create(self, dmeData):
        """
        Create a new device management extension package
        In case of failure it throws APIException
        """
        url = "api/v0002/mgmt/custom/bundle"
        r = self._apiClient.post(url, dmeData)

        if r.status_code == 201:
            return r.json()
        else:
            raise ApiException(r)

def create ( self , dmeData ) : url = "api/v0002/mgmt/custom/bundle" r = self . _apiClient . post ( url , dmeData ) if r . status_code == 201 : return r . json ( ) else : raise ApiException ( r )


def updateSchema(self, schemaId, schemaDefinition):
        """
        Update a schema. Throws APIException on failure.
        """
        req = ApiClient.oneSchemaUrl % (self.host, "/draft", schemaId)
        body = {"schemaDefinition": schemaDefinition}
        resp = requests.put(req, auth=self.credentials, headers={"Content-Type":"application/json"},
                           data=json.dumps(body),  verify=self.verify)
        if resp.status_code == 200:
            self.logger.debug("Schema updated")
        else:
            raise ibmiotf.APIException(resp.status_code, "HTTP error updating schema", resp)
        return resp.json()

def
updateSchema
(
self
,
schemaId
,
schemaDefinition
)
:
req
=
ApiClient
.
oneSchemaUrl
%
(
self
.
host
,
"/draft"
,
schemaId
)
body
=
{
"schemaDefinition"
:
schemaDefinition
}
resp
=
requests
.
put
(
req
,
auth
=
self
.
credentials
,
headers
=
{
"Content-Type"
:
"application/json"
}
,
data
=
json
.
dumps
(
body
)
,
verify
=
self
.
verify
)
if
resp
.
status_code
==
200
:
self
.
logger
.
debug
(
"Schema updated"
)
else
:
raise
ibmiotf
.
APIException
(
resp
.
status_code
,
"HTTP error updating schema"
,
resp
)
return
resp
.
json
(
)

Update a schema . Throws APIException on failure .


def disconnect(self):
        """
        Disconnect the client from IBM Watson IoT Platform
        """
        # self.logger.info("Closing connection to the IBM Watson IoT Platform")
        self.client.disconnect()
        # If we don't call loop_stop() it appears we end up with a zombie thread which continues to process
        # network traffic, preventing any subsequent attempt to reconnect using connect()
        self.client.loop_stop()
        self.logger.info("Closed connection to the IBM Watson IoT Platform")


def _onConnect(self, mqttc, userdata, flags, rc):
        """
        Called when the broker responds to our connection request.

        The value of rc determines success or not:
            0: Connection successful
            1: Connection refused - incorrect protocol version
            2: Connection refused - invalid client identifier
            3: Connection refused - server unavailable
            4: Connection refused - bad username or password
            5: Connection refused - not authorised
            6-255: Currently unused.
        """
        if rc == 0:
            self.connectEvent.set()
            self.logger.info("Connected successfully: %s" % (self.clientId))

            # Restoring previous subscriptions
            with self._subLock:
                if len(self._subscriptions) > 0:
                    for subscription in self._subscriptions:
                        # We use the underlying mqttclient subscribe method rather than _subscribe because we are
                        # claiming a lock on the subscriptions list and do not want anything else to modify it,
                        # which that method does
                        (result, mid) = self.client.subscribe(subscription, qos=self._subscriptions[subscription])
                        if result != paho.MQTT_ERR_SUCCESS:
                            self._logAndRaiseException(ConnectionException("Unable to subscribe to %s" % subscription))
                    self.logger.debug("Restored %s previous subscriptions" % len(self._subscriptions))
        elif rc == 1:
            self._logAndRaiseException(ConnectionException("Incorrect protocol version"))
        elif rc == 2:
            self._logAndRaiseException(ConnectionException("Invalid client identifier"))
        elif rc == 3:
            self._logAndRaiseException(ConnectionException("Server unavailable"))
        elif rc == 4:
            self._logAndRaiseException(
                ConnectionException("Bad username or password: (%s, %s)" % (self.username, self.password))
            )
        elif rc == 5:
            self._logAndRaiseException(
                ConnectionException("Not authorized: s (%s, %s, %s)" % (self.clientId, self.username, self.password))
            )
        else:
            self._logAndRaiseException(ConnectionException("Unexpected connection failure: %s" % (rc)))

Called when the broker responds to our connection request .


def subscribeToDeviceEvents(self, typeId="+", deviceId="+", eventId="+", msgFormat="+", qos=0):
        """
        Subscribe to device event messages

        # Parameters
        typeId (string): typeId for the subscription, optional.  Defaults to all device types (MQTT `+` wildcard)
        deviceId (string): deviceId for the subscription, optional.  Defaults to all devices (MQTT `+` wildcard)
        eventId (string): eventId for the subscription, optional.  Defaults to all events (MQTT `+` wildcard)
        msgFormat (string): msgFormat for the subscription, optional.  Defaults to all formats (MQTT `+` wildcard)
        qos (int): MQTT quality of service level to use (`0`, `1`, or `2`)

        # Returns
        int: If the subscription was successful then the return Message ID (mid) for the subscribe request
            will be returned. The mid value can be used to track the subscribe request by checking against
            the mid argument if you register a subscriptionCallback method.
            If the subscription fails then the return value will be `0`
        """
        if self._config.isQuickstart() and deviceId == "+":
            self.logger.warning(
                "QuickStart applications do not support wildcard subscription to events from all devices"
            )
            return 0

        topic = "iot-2/type/%s/id/%s/evt/%s/fmt/%s" % (typeId, deviceId, eventId, msgFormat)
        return self._subscribe(topic, qos)


def subscribeToDeviceStatus(self, typeId="+", deviceId="+"):
        """
        Subscribe to device status messages

        # Parameters
        typeId (string): typeId for the subscription, optional.  Defaults to all device types (MQTT `+` wildcard)
        deviceId (string): deviceId for the subscription, optional.  Defaults to all devices (MQTT `+` wildcard)

        # Returns
        int: If the subscription was successful then the return Message ID (mid) for the subscribe request
            will be returned. The mid value can be used to track the subscribe request by checking against
            the mid argument if you register a subscriptionCallback method.
            If the subscription fails then the return value will be `0`
        """
        if self._config.isQuickstart() and deviceId == "+":
            self.logger.warning("QuickStart applications do not support wildcard subscription to device status")
            return 0

        topic = "iot-2/type/%s/id/%s/mon" % (typeId, deviceId)
        return self._subscribe(topic, 0)


def subscribeToDeviceCommands(self, typeId="+", deviceId="+", commandId="+", msgFormat="+"):
        """
        Subscribe to device command messages

        # Parameters
        typeId (string): typeId for the subscription, optional.  Defaults to all device types (MQTT `+` wildcard)
        deviceId (string): deviceId for the subscription, optional.  Defaults to all devices (MQTT `+` wildcard)
        commandId (string): commandId for the subscription, optional.  Defaults to all commands (MQTT `+` wildcard)
        msgFormat (string): msgFormat for the subscription, optional.  Defaults to all formats (MQTT `+` wildcard)
        qos (int): MQTT quality of service level to use (`0`, `1`, or `2`)

        # Returns
        int: If the subscription was successful then the return Message ID (mid) for the subscribe request
            will be returned. The mid value can be used to track the subscribe request by checking against
            the mid argument if you register a subscriptionCallback method.
            If the subscription fails then the return value will be `0`
        """
        if self._config.isQuickstart():
            self.logger.warning("QuickStart applications do not support commands")
            return 0

        topic = "iot-2/type/%s/id/%s/cmd/%s/fmt/%s" % (typeId, deviceId, commandId, msgFormat)
        return self._subscribe(topic, 0)


def publishCommand(self, typeId, deviceId, commandId, msgFormat, data=None, qos=0, on_publish=None):
        """
        Publish a command to a device

        # Parameters
        typeId (string) : The type of the device this command is to be published to
        deviceId (string): The id of the device this command is to be published to
        command (string) : The name of the command
        msgFormat (string) : The format of the command payload
        data (dict) : The command data
        qos (int) : The equivalent MQTT semantics of quality of service using the same constants (optional, defaults to `0`)
        on_publish (function) : A function that will be called when receipt of the publication is confirmed.  This has
            different implications depending on the qos:
            - qos 0 : the client has asynchronously begun to send the event
            - qos 1 and 2 : the client has confirmation of delivery from WIoTP
        """
        if self._config.isQuickstart():
            self.logger.warning("QuickStart applications do not support sending commands")
            return False
        if not self.connectEvent.wait(timeout=10):
            return False
        else:
            topic = "iot-2/type/%s/id/%s/cmd/%s/fmt/%s" % (typeId, deviceId, commandId, msgFormat)

            # Raise an exception if there is no codec for this msgFormat
            if self.getMessageCodec(msgFormat) is None:
                raise MissingMessageEncoderException(msgFormat)

            payload = self.getMessageCodec(msgFormat).encode(data, datetime.now())
            result = self.client.publish(topic, payload=payload, qos=qos, retain=False)
            if result[0] == paho.MQTT_ERR_SUCCESS:
                # Because we are dealing with aync pub/sub model and callbacks it is possible that
                # the _onPublish() callback for this mid is called before we obtain the lock to place
                # the mid into the _onPublishCallbacks list.
                #
                # _onPublish knows how to handle a scenario where the mid is not present (no nothing)
                # in this scenario we will need to invoke the callback directly here, because at the time
                # the callback was invoked the mid was not yet in the list.
                with self._messagesLock:
                    if result[1] in self._onPublishCallbacks:
                        # paho callback beat this thread so call callback inline now
                        del self._onPublishCallbacks[result[1]]
                        if on_publish is not None:
                            on_publish()
                    else:
                        # this thread beat paho callback so set up for call later
                        self._onPublishCallbacks[result[1]] = on_publish
                return True
            else:
                return False


def _onUnsupportedMessage(self, client, userdata, message):
        """
        Internal callback for messages that have not been handled by any of the specific internal callbacks, these
        messages are not passed on to any user provided callback
        """
        self.logger.warning(
            "Received messaging on unsupported topic '%s' on topic '%s'" % (message.payload, message.topic)
        )

Internal callback for messages that have not been handled by any of the specific internal callbacks these messages are not passed on to any user provided callback


def _onDeviceEvent(self, client, userdata, pahoMessage):
        """
        Internal callback for device event messages, parses source device from topic string and
        passes the information on to the registerd device event callback
        """
        try:
            event = Event(pahoMessage, self._messageCodecs)
            self.logger.debug("Received event '%s' from %s:%s" % (event.eventId, event.typeId, event.deviceId))
            if self.deviceEventCallback:
                self.deviceEventCallback(event)
        except InvalidEventException as e:
            self.logger.critical(str(e))

def
_onDeviceEvent
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
event
=
Event
(
pahoMessage
,
self
.
_messageCodecs
)
self
.
logger
.
debug
(
"Received event '%s' from %s:%s"
%
(
event
.
eventId
,
event
.
typeId
,
event
.
deviceId
)
)
if
self
.
deviceEventCallback
:
self
.
deviceEventCallback
(
event
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)

Internal callback for device event messages parses source device from topic string and passes the information on to the registerd device event callback


def _onDeviceStatus(self, client, userdata, pahoMessage):
        """
        Internal callback for device status messages, parses source device from topic string and
        passes the information on to the registerd device status callback
        """
        try:
            status = Status(pahoMessage)
            self.logger.debug("Received %s action from %s" % (status.action, status.clientId))
            if self.deviceStatusCallback:
                self.deviceStatusCallback(status)
        except InvalidEventException as e:
            self.logger.critical(str(e))

def
_onDeviceStatus
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
status
=
Status
(
pahoMessage
)
self
.
logger
.
debug
(
"Received %s action from %s"
%
(
status
.
action
,
status
.
clientId
)
)
if
self
.
deviceStatusCallback
:
self
.
deviceStatusCallback
(
status
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)

Internal callback for device status messages parses source device from topic string and passes the information on to the registerd device status callback


def _onAppStatus(self, client, userdata, pahoMessage):
        """
        Internal callback for application command messages, parses source application from topic string and
        passes the information on to the registerd applicaion status callback
        """
        try:
            status = Status(pahoMessage)
            self.logger.debug("Received %s action from %s" % (status.action, status.clientId))
            if self.appStatusCallback:
                self.appStatusCallback(status)
        except InvalidEventException as e:
            self.logger.critical(str(e))

def
_onAppStatus
(
self
,
client
,
userdata
,
pahoMessage
)
:
try
:
status
=
Status
(
pahoMessage
)
self
.
logger
.
debug
(
"Received %s action from %s"
%
(
status
.
action
,
status
.
clientId
)
)
if
self
.
appStatusCallback
:
self
.
appStatusCallback
(
status
)
except
InvalidEventException
as
e
:
self
.
logger
.
critical
(
str
(
e
)
)

Internal callback for application command messages parses source application from topic string and passes the information on to the registerd applicaion status callback


def get(self, deviceUid, eventId):
        """
        Retrieves the last cached message for specified event from a specific device.
        """

        if not isinstance(deviceUid, DeviceUid) and isinstance(deviceUid, dict):
            deviceUid = DeviceUid(**deviceUid)

        url = "api/v0002/device/types/%s/devices/%s/events/%s" % (deviceUid.typeId, deviceUid.deviceId, eventId)
        r = self._apiClient.get(url)

        if r.status_code == 200:
            return LastEvent(**r.json())
        else:
            raise ApiException(r)

Retrieves the last cached message for specified event from a specific device .


def getAll(self, deviceUid):
        """
        Retrieves a list of the last cached message for all events from a specific device.
        """

        if not isinstance(deviceUid, DeviceUid) and isinstance(deviceUid, dict):
            deviceUid = DeviceUid(**deviceUid)

        url = "api/v0002/device/types/%s/devices/%s/events" % (deviceUid.typeId, deviceUid.deviceId)
        r = self._apiClient.get(url)

        if r.status_code == 200:
            events = []
            for event in r.json():
                events.append(LastEvent(**event))
            return events
        else:
            raise ApiException(r)

Retrieves a list of the last cached message for all events from a specific device .


def _makeApiCall(self, parameters=None):
        """
        Retrieve bulk devices
        It accepts accepts a list of parameters
        In case of failure it throws Exception
        """
        r = self._apiClient.get(self._url, parameters)
        if r.status_code == 200:
            return r.json()
        else:
            raise Exception("HTTP %s %s" % (r.status_code, r.text))

def
_makeApiCall
(
self
,
parameters
=
)
:
r
=
self
.
_apiClient
.
get
(
self
.
_url
,
parameters
)
if
r
.
status_code
==
200
:
return
r
.
json
(
)
else
:
raise
Exception
(
"HTTP %s %s"
%
(
r
.
status_code
,
r
.
text
)
)


def initiate(self, request):
        """
        Initiates a device management request, such as reboot.
        In case of failure it throws APIException
        """
        url = MgmtRequests.mgmtRequests
        r = self._apiClient.post(url, request)

        if r.status_code == 202:
            return r.json()
        else:
            raise ApiException(r)

def initiate ( self , request ) : url = MgmtRequests . mgmtRequests r = self . _apiClient . post ( url , request ) if r . status_code == 202 : return r . json ( ) else : raise ApiException ( r )

Initiates a device management request such as reboot . In case of failure it throws APIException


def getStatus(self, requestId, typeId=None, deviceId=None):
        """
        Get a list of device management request device statuses.
        Get an individual device mangaement request device status.
        """
        if typeId is None or deviceId is None:
            url = MgmtRequests.mgmtRequestStatus % (requestId)
            r = self._apiClient.get(url)

            if r.status_code == 200:
                return r.json()
            else:
                raise ApiException(r)
        else:
            url = MgmtRequests.mgmtRequestSingleDeviceStatus % (requestId, typeId, deviceId)
            r = self._apiClient.get(url)

            if r.status_code == 200:
                return r.json()
            else:
                raise ApiException(r)

def getStatus ( self , requestId , typeId = None , deviceId = None ) : if typeId is None or deviceId is None : url = MgmtRequests . mgmtRequestStatus % ( requestId ) r = self . _apiClient . get ( url ) if r . status_code == 200 : return r . json ( ) else : raise ApiException ( r ) else : url = MgmtRequests . mgmtRequestSingleDeviceStatus % ( requestId , typeId , deviceId ) r = self . _apiClient . get ( url ) if r . status_code == 200 : return r . json ( ) else : raise ApiException ( r )

Get a list of device management request device statuses . Get an individual device mangaement request device status .


def close(self):
        """Force a flush of the index to storage. Renders index
        inaccessible."""
        if self.handle:
            self.handle.destroy()
            self.handle = None
        else:
            raise IOError("Unclosable index")

def
close
(
self
)
:
if
self
.
handle
:
self
.
handle
.
destroy
(
)
self
.
handle
=
else
:
raise
IOError
(
"Unclosable index"
)

Force a flush of the index to storage . Renders index inaccessible .


def count(self, coordinates):
        """Return number of objects that intersect the given coordinates.

        :param coordinates: sequence or array
            This may be an object that satisfies the numpy array
            protocol, providing the index's dimension * 2 coordinate
            pairs representing the `mink` and `maxk` coordinates in
            each dimension defining the bounds of the query window.

        The following example queries the index for any objects any objects
        that were stored in the index intersect the bounds given in the
        coordinates::

            >>> from rtree import index
            >>> idx = index.Index()
            >>> idx.insert(4321,
            ...            (34.3776829412, 26.7375853734, 49.3776829412,
            ...             41.7375853734),
            ...            obj=42)

            >>> print(idx.count((0, 0, 60, 60)))
            1

        """
        p_mins, p_maxs = self.get_coordinate_pointers(coordinates)

        p_num_results = ctypes.c_uint64(0)

        core.rt.Index_Intersects_count(self.handle,
                                       p_mins,
                                       p_maxs,
                                       self.properties.dimension,
                                       ctypes.byref(p_num_results))

        return p_num_results.value

def count ( self , coordinates ) : p_mins , p_maxs = self . get_coordinate_pointers ( coordinates ) p_num_results = ctypes . c_uint64 ( 0 ) core . rt . Index_Intersects_count ( self . handle , p_mins , p_maxs , self . properties . dimension , ctypes . byref ( p_num_results ) ) return p_num_results . value

Return number of objects that intersect the given coordinates .


def nearest(self, coordinates, num_results=1, objects=False):
        """Returns the ``k``-nearest objects to the given coordinates.

        :param coordinates: sequence or array
            This may be an object that satisfies the numpy array
            protocol, providing the index's dimension * 2 coordinate
            pairs representing the `mink` and `maxk` coordinates in
            each dimension defining the bounds of the query window.

        :param num_results: integer
            The number of results to return nearest to the given coordinates.
            If two index entries are equidistant, *both* are returned.
            This property means that :attr:`num_results` may return more
            items than specified

        :param objects: True / False / 'raw'
            If True, the nearest method will return index objects that
            were pickled when they were stored with each index entry, as
            well as the id and bounds of the index entries.
            If 'raw', it will return the object as entered into the database
            without the :class:`rtree.index.Item` wrapper.

        Example of finding the three items nearest to this one::

            >>> from rtree import index
            >>> idx = index.Index()
            >>> idx.insert(4321, (34.37, 26.73, 49.37, 41.73), obj=42)
            >>> hits = idx.nearest((0, 0, 10, 10), 3, objects=True)
        """
        if objects:
            return self._nearest_obj(coordinates, num_results, objects)
        p_mins, p_maxs = self.get_coordinate_pointers(coordinates)

        p_num_results = ctypes.pointer(ctypes.c_uint64(num_results))

        it = ctypes.pointer(ctypes.c_int64())

        core.rt.Index_NearestNeighbors_id(self.handle,
                                          p_mins,
                                          p_maxs,
                                          self.properties.dimension,
                                          ctypes.byref(it),
                                          p_num_results)

        return self._get_ids(it, p_num_results.contents.value)

def nearest ( self , coordinates , num_results = 1 , objects = False ) : if objects : return self . _nearest_obj ( coordinates , num_results , objects ) p_mins , p_maxs = self . get_coordinate_pointers ( coordinates ) p_num_results = ctypes . pointer ( ctypes . c_uint64 ( num_results ) ) it = ctypes . pointer ( ctypes . c_int64 ( ) ) core . rt . Index_NearestNeighbors_id ( self . handle , p_mins , p_maxs , self . properties . dimension , ctypes . byref ( it ) , p_num_results ) return self . _get_ids ( it , p_num_results . contents . value )

Returns the k - nearest objects to the given coordinates .


def get_bounds(self, coordinate_interleaved=None):
        """Returns the bounds of the index

        :param coordinate_interleaved: If True, the coordinates are turned
            in the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax],
            otherwise they are returned as
            [xmin, xmax, ymin, ymax, ..., ..., kmin, kmax].  If not specified,
            the :attr:`interleaved` member of the index is used, which
            defaults to True.
        """
        if coordinate_interleaved is None:
            coordinate_interleaved = self.interleaved
        return _get_bounds(
            self.handle, core.rt.Index_GetBounds, coordinate_interleaved)

def get_bounds ( self , coordinate_interleaved = None ) : if coordinate_interleaved is None : coordinate_interleaved = self . interleaved return _get_bounds ( self . handle , core . rt . Index_GetBounds , coordinate_interleaved )


def delete(self, id, coordinates):
        """Deletes items from the index with the given ``'id'`` within the
        specified coordinates.

        :param id: long integer
            A long integer that is the identifier for this index entry.  IDs
            need not be unique to be inserted into the index, and it is up
            to the user to ensure they are unique if this is a requirement.

        :param coordinates: sequence or array
            Dimension * 2 coordinate pairs, representing the min
            and max coordinates in each dimension of the item to be
            deleted from the index. Their ordering will depend on the
            index's :attr:`interleaved` data member.
            These are not the coordinates of a space containing the
            item, but those of the item itself. Together with the
            id parameter, they determine which item will be deleted.
            This may be an object that satisfies the numpy array protocol.

        Example::

            >>> from rtree import index
            >>> idx = index.Index()
            >>> idx.delete(4321,
            ...            (34.3776829412, 26.7375853734, 49.3776829412,
            ...             41.7375853734))

        """
        p_mins, p_maxs = self.get_coordinate_pointers(coordinates)
        core.rt.Index_DeleteData(
            self.handle, id, p_mins, p_maxs, self.properties.dimension)

def delete ( self , id , coordinates ) : p_mins , p_maxs = self . get_coordinate_pointers ( coordinates ) core . rt . Index_DeleteData ( self . handle , id , p_mins , p_maxs , self . properties . dimension )

Deletes items from the index with the given id within the specified coordinates .


def _create_idx_from_stream(self, stream):
        """This function is used to instantiate the index given an
        iterable stream of data."""

        stream_iter = iter(stream)
        dimension = self.properties.dimension
        darray = ctypes.c_double * dimension
        mins = darray()
        maxs = darray()
        no_data = ctypes.cast(ctypes.pointer(ctypes.c_ubyte(0)),
                              ctypes.POINTER(ctypes.c_ubyte))

        def py_next_item(p_id, p_mins, p_maxs, p_dimension, p_data, p_length):
            """This function must fill pointers to individual entries that will
            be added to the index.  The C API will actually call this function
            to fill out the pointers.  If this function returns anything other
            than 0, it is assumed that the stream of data is done."""

            try:
                p_id[0], coordinates, obj = next(stream_iter)
            except StopIteration:
                # we're done
                return -1
            except Exception as exc:
                self._exception = exc
                return -1

            if self.interleaved:
                coordinates = Index.deinterleave(coordinates)

            # this code assumes the coords are not interleaved.
            # xmin, xmax, ymin, ymax, zmin, zmax
            for i in range(dimension):
                mins[i] = coordinates[i*2]
                maxs[i] = coordinates[(i*2)+1]

            p_mins[0] = ctypes.cast(mins, ctypes.POINTER(ctypes.c_double))
            p_maxs[0] = ctypes.cast(maxs, ctypes.POINTER(ctypes.c_double))

            # set the dimension
            p_dimension[0] = dimension
            if obj is None:
                p_data[0] = no_data
                p_length[0] = 0
            else:
                p_length[0], data, _ = self._serialize(obj)
                p_data[0] = ctypes.cast(data, ctypes.POINTER(ctypes.c_ubyte))

            return 0

        stream = core.NEXTFUNC(py_next_item)
        return IndexStreamHandle(self.properties.handle, stream)

This function is used to instantiate the index given an iterable stream of data .


def loadByteArray(self, page, returnError):
        """Must be overridden. Must return a string with the loaded data."""
        returnError.contents.value = self.IllegalStateError
        raise NotImplementedError("You must override this method.")
        return ''

def
loadByteArray
(
self
,
page
,
returnError
)
:
returnError
.
contents
.
value
=
self
.
IllegalStateError
raise
NotImplementedError
(
"You must override this method."
)
return
''

Must be overridden . Must return a string with the loaded data .


def delete(self, obj, coordinates):
        """Deletes the item from the container within the specified
        coordinates.

        :param obj: object
            Any object.

        :param coordinates: sequence or array
            Dimension * 2 coordinate pairs, representing the min
            and max coordinates in each dimension of the item to be
            deleted from the index. Their ordering will depend on the
            index's :attr:`interleaved` data member.
            These are not the coordinates of a space containing the
            item, but those of the item itself. Together with the
            id parameter, they determine which item will be deleted.
            This may be an object that satisfies the numpy array protocol.

        Example::

            >>> from rtree import index
            >>> idx = index.RtreeContainer()
            >>> idx.delete(object(),
            ...            (34.3776829412, 26.7375853734, 49.3776829412,
            ...             41.7375853734))
            Traceback (most recent call last):
             ...
            IndexError: object is not in the index

        """
        try:
            count = self._objects[id(obj)] - 1
        except KeyError:
            raise IndexError('object is not in the index')
        if count == 0:
            del self._objects[obj]
        else:
            self._objects[id(obj)] = (count, obj)
        return super(RtreeContainer, self).delete(id, coordinates)

def
delete
(
self
,
obj
,
coordinates
)
:
try
:
count
=
self
.
_objects
[
id
(
obj
)
]
1
except
KeyError
:
raise
IndexError
(
'object is not in the index'
)
if
count
==
0
:
del
self
.
_objects
[
obj
]
else
:
self
.
_objects
[
id
(
obj
)
]
=
(
count
,
obj
)
return
super
(
RtreeContainer
,
self
)
.
delete
(
id
,
coordinates
)

Deletes the item from the container within the specified coordinates .


def check_return(result, func, cargs):
    "Error checking for Error calls"
    if result != 0:
        s = rt.Error_GetLastErrorMsg().decode()
        msg = 'LASError in "%s": %s' % \
            (func.__name__, s)
        rt.Error_Reset()
        raise RTreeError(msg)
    return True

def
check_return
(
result
,
func
,
cargs
)
:
if
result
!=
0
:
s
=
rt
.
Error_GetLastErrorMsg
(
)
.
decode
(
)
msg
=
'LASError in "%s": %s'
%
(
func
.
__name__
,
s
)
rt
.
Error_Reset
(
)
raise
RTreeError
(
msg
)
return
True


def load(self):
        """ Attempt an import of the specified application """

        if isinstance(self.application, str):
            return util.import_app(self.application)
        else:
            return self.application

def load ( self ) : if isinstance ( self . application , str ) : return util . import_app ( self . application ) else : return self . application


def init_app(self, app):
        """Initializes the Flask application with Common."""
        if not hasattr(app, 'extensions'):
            app.extensions = {}

        if 'common' in app.extensions:
            raise RuntimeError("Flask-Common extension already initialized")

        app.extensions['common'] = self
        self.app = app

        if 'COMMON_FILESERVER_DISABLED' not in app.config:
            with app.test_request_context():

                # Configure WhiteNoise.
                app.wsgi_app = WhiteNoise(app.wsgi_app, root=url_for('static', filename='')[1:])

        self.cache = Cache(app, config={'CACHE_TYPE': app.config.get("COMMON_CACHE_TYPE", 'simple')})

        @app.before_request
        def before_request_callback():
            request.start_time = maya.now()

        @app.after_request
        def after_request_callback(response):
            if 'COMMON_POWERED_BY_DISABLED' not in current_app.config:
                response.headers['X-Powered-By'] = 'Flask'
            if 'COMMON_PROCESSED_TIME_DISABLED' not in current_app.config:
                response.headers['X-Processed-Time'] = maya.now().epoch - request.start_time.epoch
            return response

        @app.route('/favicon.ico')
        def favicon():
            return redirect(url_for('static', filename='favicon.ico'), code=301)

Initializes the Flask application with Common .


def serve(self, workers=None, **kwargs):
        """Serves the Flask application."""
        if self.app.debug:
            print(crayons.yellow('Booting Flask development server...'))
            self.app.run()

        else:
            print(crayons.yellow('Booting Gunicorn...'))

            # Start the web server.
            server = GunicornServer(
                self.app, workers=workers or number_of_gunicorn_workers(),
                worker_class='egg:meinheld#gunicorn_worker', **kwargs)
            server.run()

def
serve
(
self
,
workers
=
,
*
*
kwargs
)
:
if
self
.
app
.
debug
:
print
(
crayons
.
yellow
(
'Booting Flask development server...'
)
)
self
.
app
.
run
(
)
else
:
print
(
crayons
.
yellow
(
'Booting Gunicorn...'
)
)
# Start the web server.
server
=
GunicornServer
(
self
.
app
,
workers
=
workers
or
number_of_gunicorn_workers
(
)
,
worker_class
=
'egg:meinheld#gunicorn_worker'
,
*
*
kwargs
)
server
.
run
(
)


def to_native(self, value):
        """For djangorestframework <=2.3.14"""
        context_request = None
        if self.context:
            context_request = self.context.get('request', None)
        return build_versatileimagefield_url_set(
            value,
            self.sizes,
            request=context_request
        )

def to_native ( self , value ) : context_request = None if self . context : context_request = self . context . get ( 'request' , None ) return build_versatileimagefield_url_set ( value , self . sizes , request = context_request )


def crop_on_centerpoint(self, image, width, height, ppoi=(0.5, 0.5)):
        """
        Return a PIL Image instance cropped from `image`.

        Image has an aspect ratio provided by dividing `width` / `height`),
        sized down to `width`x`height`. Any 'excess pixels' are trimmed away
        in respect to the pixel of `image` that corresponds to `ppoi` (Primary
        Point of Interest).

        `image`: A PIL Image instance
        `width`: Integer, width of the image to return (in pixels)
        `height`: Integer, height of the image to return (in pixels)
        `ppoi`: A 2-tuple of floats with values greater than 0 and less than 1
                These values are converted into a cartesian coordinate that
                signifies the 'center pixel' which the crop will center on
                (to trim the excess from the 'long side').

        Determines whether to trim away pixels from either the left/right or
        top/bottom sides by comparing the aspect ratio of `image` vs the
        aspect ratio of `width`x`height`.

        Will trim from the left/right sides if the aspect ratio of `image`
        is greater-than-or-equal-to the aspect ratio of `width`x`height`.

        Will trim from the top/bottom sides if the aspect ration of `image`
        is less-than the aspect ratio or `width`x`height`.

        Similar to Kevin Cazabon's ImageOps.fit method but uses the
        ppoi value as an absolute centerpoint (as opposed as a
        percentage to trim off the 'long sides').
        """
        ppoi_x_axis = int(image.size[0] * ppoi[0])
        ppoi_y_axis = int(image.size[1] * ppoi[1])
        center_pixel_coord = (ppoi_x_axis, ppoi_y_axis)
        # Calculate the aspect ratio of `image`
        orig_aspect_ratio = float(
            image.size[0]
        ) / float(
            image.size[1]
        )
        crop_aspect_ratio = float(width) / float(height)

        # Figure out if we're trimming from the left/right or top/bottom
        if orig_aspect_ratio >= crop_aspect_ratio:
            # `image` is wider than what's needed,
            # crop from left/right sides
            orig_crop_width = int(
                (crop_aspect_ratio * float(image.size[1])) + 0.5
            )
            orig_crop_height = image.size[1]
            crop_boundary_top = 0
            crop_boundary_bottom = orig_crop_height
            crop_boundary_left = center_pixel_coord[0] - (orig_crop_width // 2)
            crop_boundary_right = crop_boundary_left + orig_crop_width
            if crop_boundary_left < 0:
                crop_boundary_left = 0
                crop_boundary_right = crop_boundary_left + orig_crop_width
            elif crop_boundary_right > image.size[0]:
                crop_boundary_right = image.size[0]
                crop_boundary_left = image.size[0] - orig_crop_width

        else:
            # `image` is taller than what's needed,
            # crop from top/bottom sides
            orig_crop_width = image.size[0]
            orig_crop_height = int(
                (float(image.size[0]) / crop_aspect_ratio) + 0.5
            )
            crop_boundary_left = 0
            crop_boundary_right = orig_crop_width
            crop_boundary_top = center_pixel_coord[1] - (orig_crop_height // 2)
            crop_boundary_bottom = crop_boundary_top + orig_crop_height
            if crop_boundary_top < 0:
                crop_boundary_top = 0
                crop_boundary_bottom = crop_boundary_top + orig_crop_height
            elif crop_boundary_bottom > image.size[1]:
                crop_boundary_bottom = image.size[1]
                crop_boundary_top = image.size[1] - orig_crop_height
        # Cropping the image from the original image
        cropped_image = image.crop(
            (
                crop_boundary_left,
                crop_boundary_top,
                crop_boundary_right,
                crop_boundary_bottom
            )
        )
        # Resizing the newly cropped image to the size specified
        # (as determined by `width`x`height`)
        return cropped_image.resize(
            (width, height),
            Image.ANTIALIAS
        )

Return a PIL Image instance cropped from image .


def process_image(self, image, image_format, save_kwargs,
                      width, height):
        """
        Return a BytesIO instance of `image` cropped to `width` and `height`.

        Cropping will first reduce an image down to its longest side
        and then crop inwards centered on the Primary Point of Interest
        (as specified by `self.ppoi`)
        """
        imagefile = BytesIO()
        palette = image.getpalette()
        cropped_image = self.crop_on_centerpoint(
            image,
            width,
            height,
            self.ppoi
        )

        # Using ImageOps.fit on GIFs can introduce issues with their palette
        # Solution derived from: http://stackoverflow.com/a/4905209/1149774
        if image_format == 'GIF':
            cropped_image.putpalette(palette)

        cropped_image.save(
            imagefile,
            **save_kwargs
        )

        return imagefile

Return a BytesIO instance of image cropped to width and height .


def process_image(self, image, image_format, save_kwargs,
                      width, height):
        """
        Return a BytesIO instance of `image` that fits in a bounding box.

        Bounding box dimensions are `width`x`height`.
        """
        imagefile = BytesIO()
        image.thumbnail(
            (width, height),
            Image.ANTIALIAS
        )
        image.save(
            imagefile,
            **save_kwargs
        )
        return imagefile

def process_image ( self , image , image_format , save_kwargs , width , height ) : imagefile = BytesIO ( ) image . thumbnail ( ( width , height ) , Image . ANTIALIAS ) image . save ( imagefile , * * save_kwargs ) return imagefile

Return a BytesIO instance of image that fits in a bounding box .


def process_image(self, image, image_format, save_kwargs={}):
        """Return a BytesIO instance of `image` with inverted colors."""
        imagefile = BytesIO()
        inv_image = ImageOps.invert(image)
        inv_image.save(
            imagefile,
            **save_kwargs
        )
        return imagefile

def process_image ( self , image , image_format , save_kwargs = { } ) : imagefile = BytesIO ( ) inv_image = ImageOps . invert ( image ) inv_image . save ( imagefile , * * save_kwargs ) return imagefile

Return a BytesIO instance of image with inverted colors .


def to_python(self, data):
        """Ensure data is prepped properly before handing off to ImageField."""
        if data is not None:
            if hasattr(data, 'open'):
                data.open()
            return super(VersatileImageFormField, self).to_python(data)

def to_python ( self , data ) : if data is not None : if hasattr ( data , 'open' ) : data . open ( ) return super ( VersatileImageFormField , self ) . to_python ( data )

Ensure data is prepped properly before handing off to ImageField .


def process_placeholder_image(self):
        """
        Process the field's placeholder image.

        Ensures the placeholder image has been saved to the same storage class
        as the field in a top level folder with a name specified by
        settings.VERSATILEIMAGEFIELD_SETTINGS['placeholder_directory_name']

        This should be called by the VersatileImageFileDescriptor __get__.
        If self.placeholder_image_name is already set it just returns right away.
        """
        if self.placeholder_image_name:
            return

        placeholder_image_name = None
        placeholder_image = self.placeholder_image
        if placeholder_image:
            if isinstance(placeholder_image, OnStoragePlaceholderImage):
                name = placeholder_image.path
            else:
                name = placeholder_image.image_data.name
            placeholder_image_name = os.path.join(
                VERSATILEIMAGEFIELD_PLACEHOLDER_DIRNAME, name
            )
            if not self.storage.exists(placeholder_image_name):
                self.storage.save(
                    placeholder_image_name,
                    placeholder_image.image_data
                )
        self.placeholder_image_name = placeholder_image_name

def process_placeholder_image ( self ) : if self . placeholder_image_name : return placeholder_image_name = None placeholder_image = self . placeholder_image if placeholder_image : if isinstance ( placeholder_image , OnStoragePlaceholderImage ) : name = placeholder_image . path else : name = placeholder_image . image_data . name placeholder_image_name = os . path . join ( VERSATILEIMAGEFIELD_PLACEHOLDER_DIRNAME , name ) if not self . storage . exists ( placeholder_image_name ) : self . storage . save ( placeholder_image_name , placeholder_image . image_data ) self . placeholder_image_name = placeholder_image_name


def pre_save(self, model_instance, add):
        """Return field's value just before saving."""
        file = super(VersatileImageField, self).pre_save(model_instance, add)
        self.update_ppoi_field(model_instance)
        return file

def pre_save ( self , model_instance , add ) : file = super ( VersatileImageField , self ) . pre_save ( model_instance , add ) self . update_ppoi_field ( model_instance ) return file

Return field s value just before saving .


def update_ppoi_field(self, instance, *args, **kwargs):
        """
        Update field's ppoi field, if defined.

        This method is hooked up this field's pre_save method to update
        the ppoi immediately before the model instance (`instance`)
        it is associated with is saved.

        This field's ppoi can be forced to update with force=True,
        which is how VersatileImageField.pre_save calls this method.
        """
        # Nothing to update if the field doesn't have have a ppoi
        # dimension field.
        if not self.ppoi_field:
            return

        # getattr will call the VersatileImageFileDescriptor's __get__ method,
        # which coerces the assigned value into an instance of
        # self.attr_class(VersatileImageFieldFile in this case).
        file = getattr(instance, self.attname)

        # file should be an instance of VersatileImageFieldFile or should be
        # None.
        ppoi = None
        if file and not isinstance(file, tuple):
            if hasattr(file, 'ppoi'):
                ppoi = file.ppoi

        # Update the ppoi field.
        if self.ppoi_field:
            setattr(instance, self.ppoi_field, ppoi)


def save_form_data(self, instance, data):
        """
        Handle data sent from MultiValueField forms that set ppoi values.

        `instance`: The model instance that is being altered via a form
        `data`: The data sent from the form to this field which can be either:
        * `None`: This is unset data from an optional field
        * A two-position tuple: (image_form_data, ppoi_data)
            * `image_form-data` options:
                * `None` the file for this field is unchanged
                * `False` unassign the file form the field
            * `ppoi_data` data structure:
                * `%(x_coordinate)sx%(y_coordinate)s': The ppoi data to
                  assign to the unchanged file

        """
        to_assign = data
        if data and isinstance(data, tuple):
            # This value is coming from a MultiValueField
            if data[0] is None:
                # This means the file hasn't changed but we need to
                # update the ppoi
                current_field = getattr(instance, self.name)
                if data[1]:
                    current_field.ppoi = data[1]
                to_assign = current_field
            elif data[0] is False:
                # This means the 'Clear' checkbox was checked so we
                # need to empty the field
                to_assign = ''
            else:
                # This means there is a new upload so we need to unpack
                # the tuple and assign the first position to the field
                # attribute
                to_assign = data[0]
        super(VersatileImageField, self).save_form_data(instance, to_assign)

Handle data sent from MultiValueField forms that set ppoi values .


def formfield(self, **kwargs):
        """Return a formfield."""
        # This is a fairly standard way to set up some defaults
        # while letting the caller override them.
        defaults = {}
        if self.ppoi_field:
            defaults['form_class'] = SizedImageCenterpointClickDjangoAdminField
        if kwargs.get('widget') is AdminFileWidget:
            # Ensuring default admin widget is skipped (in favor of using
            # SizedImageCenterpointClickDjangoAdminField's default widget as
            # the default widget choice for use in the admin).
            # This is for two reasons:
            # 1. To prevent 'typical' admin users (those who want to use
            #    the PPOI 'click' widget by default) from having to
            #    specify a formfield_overrides for each ModelAdmin class
            #    used by each model that has a VersatileImageField.
            # 2. If a VersatileImageField does not have a ppoi_field specified
            #    it will 'fall back' to a ClearableFileInput anyways.
            # If admin users do, in fact, want to force use of the
            # AdminFileWidget they can simply subclass AdminFileWidget and
            # specify it in their ModelAdmin.formfield_overrides (though,
            # if that's the case, why are they using VersatileImageField in
            # the first place?)
            del kwargs['widget']
        defaults.update(kwargs)
        return super(VersatileImageField, self).formfield(**defaults)


def value_to_string(self, obj):
        """Prepare field for serialization."""
        if DJANGO_VERSION > (1, 9):
            value = self.value_from_object(obj)
        else:
            value = self._get_val_from_obj(obj)
        return self.get_prep_value(value)

def value_to_string ( self , obj ) : if DJANGO_VERSION > ( 1 , 9 ) : value = self . value_from_object ( obj ) else : value = self . _get_val_from_obj ( obj ) return self . get_prep_value ( value )


def autodiscover():
    """
    Discover versatileimagefield.py modules.

    Iterate over django.apps.get_app_configs() and discover
    versatileimagefield.py modules.
    """
    from importlib import import_module
    from django.apps import apps
    from django.utils.module_loading import module_has_submodule

    for app_config in apps.get_app_configs():
        # Attempt to import the app's module.

        try:
            before_import_sizedimage_registry = copy.copy(
                versatileimagefield_registry._sizedimage_registry
            )
            before_import_filter_registry = copy.copy(
                versatileimagefield_registry._filter_registry
            )
            import_module('%s.versatileimagefield' % app_config.name)
        except Exception:
            # Reset the versatileimagefield_registry to the state before the
            # last import as this import will have to reoccur on the next
            # request and this could raise NotRegistered and AlreadyRegistered
            # exceptions (see django ticket #8245).
            versatileimagefield_registry._sizedimage_registry = \
                before_import_sizedimage_registry
            versatileimagefield_registry._filter_registry = \
                before_import_filter_registry

            # Decide whether to bubble up this error. If the app just
            # doesn't have the module in question, we can ignore the error
            # attempting to import it, otherwise we want it to bubble up.
            if module_has_submodule(app_config.module, 'versatileimagefield'):
                raise

Discover versatileimagefield . py modules .


def unregister_sizer(self, attr_name):
        """
        Unregister the SizedImage subclass currently assigned to `attr_name`.

        If a SizedImage subclass isn't already registered to `attr_name`
        NotRegistered will raise.
        """
        if attr_name not in self._sizedimage_registry:
            raise NotRegistered(
                'No SizedImage subclass is registered to %s' % attr_name
            )
        else:
            del self._sizedimage_registry[attr_name]

Unregister the SizedImage subclass currently assigned to attr_name .


def unregister_filter(self, attr_name):
        """
        Unregister the FilteredImage subclass currently assigned to attr_name.

        If a FilteredImage subclass isn't already registered to filters.
        `attr_name` NotRegistered will raise.
        """
        if attr_name not in self._filter_registry:
            raise NotRegistered(
                'No FilteredImage subclass is registered to %s' % attr_name
            )
        else:
            del self._filter_registry[attr_name]

Unregister the FilteredImage subclass currently assigned to attr_name .


def url(self):
        """
        Return the appropriate URL.

        URL is constructed based on these field conditions:
            * If empty (not `self.name`) and a placeholder is defined, the
              URL to the placeholder is returned.
            * Otherwise, defaults to vanilla ImageFieldFile behavior.
        """
        if not self.name and self.field.placeholder_image_name:
            return self.storage.url(self.field.placeholder_image_name)

        return super(VersatileImageMixIn, self).url

def url ( self ) : if not self . name and self . field . placeholder_image_name : return self . storage . url ( self . field . placeholder_image_name ) return super ( VersatileImageMixIn , self ) . url


def build_filters_and_sizers(self, ppoi_value, create_on_demand):
        """Build the filters and sizers for a field."""
        name = self.name
        if not name and self.field.placeholder_image_name:
            name = self.field.placeholder_image_name
        self.filters = FilterLibrary(
            name,
            self.storage,
            versatileimagefield_registry,
            ppoi_value,
            create_on_demand
        )
        for (
            attr_name,
            sizedimage_cls
        ) in iteritems(versatileimagefield_registry._sizedimage_registry):
            setattr(
                self,
                attr_name,
                sizedimage_cls(
                    path_to_image=name,
                    storage=self.storage,
                    create_on_demand=create_on_demand,
                    ppoi=ppoi_value
                )
            )

def build_filters_and_sizers ( self , ppoi_value , create_on_demand ) : name = self . name if not name and self . field . placeholder_image_name : name = self . field . placeholder_image_name self . filters = FilterLibrary ( name , self . storage , versatileimagefield_registry , ppoi_value , create_on_demand ) for ( attr_name , sizedimage_cls ) in iteritems ( versatileimagefield_registry . _sizedimage_registry ) : setattr ( self , attr_name , sizedimage_cls ( path_to_image = name , storage = self . storage , create_on_demand = create_on_demand , ppoi = ppoi_value ) )

Build the filters and sizers for a field .


def get_filtered_root_folder(self):
        """Return the location where filtered images are stored."""
        folder, filename = os.path.split(self.name)
        return os.path.join(folder, VERSATILEIMAGEFIELD_FILTERED_DIRNAME, '')

def get_filtered_root_folder ( self ) : folder , filename = os . path . split ( self . name ) return os . path . join ( folder , VERSATILEIMAGEFIELD_FILTERED_DIRNAME , '' )

Return the location where filtered images are stored .


def get_sized_root_folder(self):
        """Return the location where sized images are stored."""
        folder, filename = os.path.split(self.name)
        return os.path.join(VERSATILEIMAGEFIELD_SIZED_DIRNAME, folder, '')

def get_sized_root_folder ( self ) : folder , filename = os . path . split ( self . name ) return os . path . join ( VERSATILEIMAGEFIELD_SIZED_DIRNAME , folder , '' )

Return the location where sized images are stored .


def get_filtered_sized_root_folder(self):
        """Return the location where filtered + sized images are stored."""
        sized_root_folder = self.get_sized_root_folder()
        return os.path.join(
            sized_root_folder,
            VERSATILEIMAGEFIELD_FILTERED_DIRNAME
        )

def get_filtered_sized_root_folder ( self ) : sized_root_folder = self . get_sized_root_folder ( ) return os . path . join ( sized_root_folder , VERSATILEIMAGEFIELD_FILTERED_DIRNAME )

Return the location where filtered + sized images are stored .


def delete_matching_files_from_storage(self, root_folder, regex):
        """
        Delete files in `root_folder` which match `regex` before file ext.

        Example values:
            * root_folder = 'foo/'
            * self.name = 'bar.jpg'
            * regex = re.compile('-baz')

            Result:
                * foo/bar-baz.jpg <- Deleted
                * foo/bar-biz.jpg <- Not deleted
        """
        if not self.name:   # pragma: no cover
            return
        try:
            directory_list, file_list = self.storage.listdir(root_folder)
        except OSError:   # pragma: no cover
            pass
        else:
            folder, filename = os.path.split(self.name)
            basename, ext = os.path.splitext(filename)
            for f in file_list:
                if not f.startswith(basename) or not f.endswith(ext):   # pragma: no cover
                    continue
                tag = f[len(basename):-len(ext)]
                assert f == basename + tag + ext
                if regex.match(tag) is not None:
                    file_location = os.path.join(root_folder, f)
                    self.storage.delete(file_location)
                    cache.delete(
                        self.storage.url(file_location)
                    )
                    print(
                        "Deleted {file} (created from: {original})".format(
                            file=os.path.join(root_folder, f),
                            original=self.name
                        )
                    )

Delete files in root_folder which match regex before file ext .


def preprocess(self, image, image_format):
        """
        Preprocess an image.

        An API hook for image pre-processing. Calls any image format specific
        pre-processors (if defined). I.E. If `image_format` is 'JPEG', this
        method will look for a method named `preprocess_JPEG`, if found
        `image` will be passed to it.

        Arguments:
            * `image`: a PIL Image instance
            * `image_format`: str, a valid PIL format (i.e. 'JPEG' or 'GIF')

        Subclasses should return a 2-tuple:
            * [0]: A PIL Image instance.
            * [1]: A dictionary of additional keyword arguments to be used
                   when the instance is saved. If no additional keyword
                   arguments, return an empty dict ({}).
        """
        save_kwargs = {'format': image_format}

        # Ensuring image is properly rotated
        if hasattr(image, '_getexif'):
            exif_datadict = image._getexif()  # returns None if no EXIF data
            if exif_datadict is not None:
                exif = dict(exif_datadict.items())
                orientation = exif.get(EXIF_ORIENTATION_KEY, None)
                if orientation == 3:
                    image = image.transpose(Image.ROTATE_180)
                elif orientation == 6:
                    image = image.transpose(Image.ROTATE_270)
                elif orientation == 8:
                    image = image.transpose(Image.ROTATE_90)

        # Ensure any embedded ICC profile is preserved
        save_kwargs['icc_profile'] = image.info.get('icc_profile')

        if hasattr(self, 'preprocess_%s' % image_format):
            image, addl_save_kwargs = getattr(
                self,
                'preprocess_%s' % image_format
            )(image=image)
            save_kwargs.update(addl_save_kwargs)

        return image, save_kwargs


def preprocess_GIF(self, image, **kwargs):
        """
        Receive a PIL Image instance of a GIF and return 2-tuple.

        Args:
            * [0]: Original Image instance (passed to `image`)
            * [1]: Dict with a transparency key (to GIF transparency layer)
        """
        if 'transparency' in image.info:
            save_kwargs = {'transparency': image.info['transparency']}
        else:
            save_kwargs = {}
        return (image, save_kwargs)

def preprocess_GIF ( self , image , * * kwargs ) : if 'transparency' in image . info : save_kwargs = { 'transparency' : image . info [ 'transparency' ] } else : save_kwargs = { } return ( image , save_kwargs )

Receive a PIL Image instance of a GIF and return 2 - tuple .


def preprocess_JPEG(self, image, **kwargs):
        """
        Receive a PIL Image instance of a JPEG and returns 2-tuple.

        Args:
            * [0]: Image instance, converted to RGB
            * [1]: Dict with a quality key (mapped to the value of `QUAL` as
                   defined by the `VERSATILEIMAGEFIELD_JPEG_RESIZE_QUALITY`
                   setting)
        """
        save_kwargs = {
            'progressive': VERSATILEIMAGEFIELD_PROGRESSIVE_JPEG,
            'quality': QUAL
        }
        if image.mode != 'RGB':
            image = image.convert('RGB')
        return (image, save_kwargs)

def preprocess_JPEG ( self , image , * * kwargs ) : save_kwargs = { 'progressive' : VERSATILEIMAGEFIELD_PROGRESSIVE_JPEG , 'quality' : QUAL } if image . mode != 'RGB' : image = image . convert ( 'RGB' ) return ( image , save_kwargs )

Receive a PIL Image instance of a JPEG and returns 2 - tuple .


def retrieve_image(self, path_to_image):
        """Return a PIL Image instance stored at `path_to_image`."""
        image = self.storage.open(path_to_image, 'rb')
        file_ext = path_to_image.rsplit('.')[-1]
        image_format, mime_type = get_image_metadata_from_file_ext(file_ext)

        return (
            Image.open(image),
            file_ext,
            image_format,
            mime_type
        )

def retrieve_image ( self , path_to_image ) : image = self . storage . open ( path_to_image , 'rb' ) file_ext = path_to_image . rsplit ( '.' ) [ - 1 ] image_format , mime_type = get_image_metadata_from_file_ext ( file_ext ) return ( Image . open ( image ) , file_ext , image_format , mime_type )

Return a PIL Image instance stored at path_to_image .


def save_image(self, imagefile, save_path, file_ext, mime_type):
        """
        Save an image to self.storage at `save_path`.

        Arguments:
            `imagefile`: Raw image data, typically a BytesIO instance.
            `save_path`: The path within self.storage where the image should
                         be saved.
            `file_ext`: The file extension of the image-to-be-saved.
            `mime_type`: A valid image mime type (as found in
                         versatileimagefield.utils)
        """
        file_to_save = InMemoryUploadedFile(
            imagefile,
            None,
            'foo.%s' % file_ext,
            mime_type,
            imagefile.tell(),
            None
        )
        file_to_save.seek(0)
        self.storage.save(save_path, file_to_save)

def save_image ( self , imagefile , save_path , file_ext , mime_type ) : file_to_save = InMemoryUploadedFile ( imagefile , None , 'foo.%s' % file_ext , mime_type , imagefile . tell ( ) , None ) file_to_save . seek ( 0 ) self . storage . save ( save_path , file_to_save )

Save an image to self . storage at save_path .


def ppoi_as_str(self):
        """Return PPOI value as a string."""
        return "%s__%s" % (
            str(self.ppoi[0]).replace('.', '-'),
            str(self.ppoi[1]).replace('.', '-')
        )

def ppoi_as_str ( self ) : return "%s__%s" % ( str ( self . ppoi [ 0 ] ) . replace ( '.' , '-' ) , str ( self . ppoi [ 1 ] ) . replace ( '.' , '-' ) )


def create_resized_image(self, path_to_image, save_path_on_storage,
                             width, height):
        """
        Create a resized image.

        `path_to_image`: The path to the image with the media directory to
                         resize. If `None`, the
                         VERSATILEIMAGEFIELD_PLACEHOLDER_IMAGE will be used.
        `save_path_on_storage`: Where on self.storage to save the resized image
        `width`: Width of resized image (int)
        `height`: Desired height of resized image (int)
        `filename_key`: A string that will be used in the sized image filename
                        to signify what operation was done to it.
                        Examples: 'crop' or 'scale'
        """
        image, file_ext, image_format, mime_type = self.retrieve_image(
            path_to_image
        )

        image, save_kwargs = self.preprocess(image, image_format)

        imagefile = self.process_image(
            image=image,
            image_format=image_format,
            save_kwargs=save_kwargs,
            width=width,
            height=height
        )
        self.save_image(imagefile, save_path_on_storage, file_ext, mime_type)

def create_resized_image ( self , path_to_image , save_path_on_storage , width , height ) : image , file_ext , image_format , mime_type = self . retrieve_image ( path_to_image ) image , save_kwargs = self . preprocess ( image , image_format ) imagefile = self . process_image ( image = image , image_format = image_format , save_kwargs = save_kwargs , width = width , height = height ) self . save_image ( imagefile , save_path_on_storage , file_ext , mime_type )


def render(self, name, value, attrs=None, renderer=None):
        """
        Render the widget as an HTML string.

        Overridden here to support Django < 1.11.
        """
        if self.has_template_widget_rendering:
            return super(ClearableFileInputWithImagePreview, self).render(
                name, value, attrs=attrs, renderer=renderer
            )
        else:
            context = self.get_context(name, value, attrs)
            return render_to_string(self.template_name, context)

def render ( self , name , value , attrs = None , renderer = None ) : if self . has_template_widget_rendering : return super ( ClearableFileInputWithImagePreview , self ) . render ( name , value , attrs = attrs , renderer = renderer ) else : context = self . get_context ( name , value , attrs ) return render_to_string ( self . template_name , context )


def get_context(self, name, value, attrs):
        """Get the context to render this widget with."""
        if self.has_template_widget_rendering:
            context = super(ClearableFileInputWithImagePreview, self).get_context(name, value, attrs)
        else:
            # Build the context manually.
            context = {}
            context['widget'] = {
                'name': name,
                'is_hidden': self.is_hidden,
                'required': self.is_required,
                'value': self._format_value(value),
                'attrs': self.build_attrs(self.attrs, attrs),
                'template_name': self.template_name,
                'type': self.input_type,
            }

        # It seems Django 1.11's ClearableFileInput doesn't add everything to the 'widget' key, so we can't use it
        # in MultiWidget. Add it manually here.
        checkbox_name = self.clear_checkbox_name(name)
        checkbox_id = self.clear_checkbox_id(checkbox_name)

        context['widget'].update({
            'checkbox_name': checkbox_name,
            'checkbox_id': checkbox_id,
            'is_initial': self.is_initial(value),
            'input_text': self.input_text,
            'initial_text': self.initial_text,
            'clear_checkbox_label': self.clear_checkbox_label,
        })

        if value and hasattr(value, "url"):
            context['widget'].update({
                'hidden_field_id': self.get_hidden_field_id(name),
                'point_stage_id': self.get_point_stage_id(name),
                'ppoi_id': self.get_ppoi_id(name),
                'sized_url': self.get_sized_url(value),
                'image_preview_id': self.image_preview_id(name),
            })

        return context

Get the context to render this widget with .


def build_attrs(self, base_attrs, extra_attrs=None):
        """Build an attribute dictionary."""
        attrs = base_attrs.copy()
        if extra_attrs is not None:
            attrs.update(extra_attrs)
        return attrs

def build_attrs ( self , base_attrs , extra_attrs = None ) : attrs = base_attrs . copy ( ) if extra_attrs is not None : attrs . update ( extra_attrs ) return attrs


def get_resized_path(path_to_image, width, height,
                     filename_key, storage):
    """
    Return a `path_to_image` location on `storage` as dictated by `width`, `height`
    and `filename_key`
    """
    containing_folder, filename = os.path.split(path_to_image)

    resized_filename = get_resized_filename(
        filename,
        width,
        height,
        filename_key
    )

    joined_path = os.path.join(*[
        VERSATILEIMAGEFIELD_SIZED_DIRNAME,
        containing_folder,
        resized_filename
    ]).replace(' ', '')  # Removing spaces so this path is memcached friendly

    return joined_path

Return a path_to_image location on storage as dictated by width height and filename_key


def get_filtered_path(path_to_image, filename_key, storage):
    """
    Return the 'filtered path'
    """
    containing_folder, filename = os.path.split(path_to_image)

    filtered_filename = get_filtered_filename(filename, filename_key)
    path_to_return = os.path.join(*[
        containing_folder,
        VERSATILEIMAGEFIELD_FILTERED_DIRNAME,
        filtered_filename
    ])
    # Removing spaces so this path is memcached key friendly
    path_to_return = path_to_return.replace(' ', '')
    return path_to_return


def validate_versatileimagefield_sizekey_list(sizes):
    """
    Validate a list of size keys.

    `sizes`: An iterable of 2-tuples, both strings. Example:
    [
        ('large', 'url'),
        ('medium', 'crop__400x400'),
        ('small', 'thumbnail__100x100')
    ]
    """
    try:
        for key, size_key in sizes:
            size_key_split = size_key.split('__')
            if size_key_split[-1] != 'url' and (
                'x' not in size_key_split[-1]
            ):
                raise InvalidSizeKey(
                    "{0} is an invalid size. All sizes must be either "
                    "'url' or made up of at least two segments separated "
                    "by double underscores. Examples: 'crop__400x400', "
                    "filters__invert__url".format(size_key)
                )
    except ValueError:
        raise InvalidSizeKeySet(
            '{} is an invalid size key set. Size key sets must be an '
            'iterable of 2-tuples'.format(str(sizes))
        )
    return list(set(sizes))


def get_url_from_image_key(image_instance, image_key):
    """Build a URL from `image_key`."""
    img_key_split = image_key.split('__')
    if 'x' in img_key_split[-1]:
        size_key = img_key_split.pop(-1)
    else:
        size_key = None
    img_url = reduce(getattr, img_key_split, image_instance)
    if size_key:
        img_url = img_url[size_key].url
    return img_url


def get_rendition_key_set(key):
    """
    Retrieve a validated and prepped Rendition Key Set from
    settings.VERSATILEIMAGEFIELD_RENDITION_KEY_SETS
    """
    try:
        rendition_key_set = IMAGE_SETS[key]
    except KeyError:
        raise ImproperlyConfigured(
            "No Rendition Key Set exists at "
            "settings.VERSATILEIMAGEFIELD_RENDITION_KEY_SETS['{}']".format(key)
        )
    else:
        return validate_versatileimagefield_sizekey_list(rendition_key_set)

Retrieve a validated and prepped Rendition Key Set from settings . VERSATILEIMAGEFIELD_RENDITION_KEY_SETS


def format_instruction(insn):
    """
    Takes a raw `Instruction` and translates it into a human readable text
    representation. As of writing, the text representation for WASM is not yet
    standardized, so we just emit some generic format.
    """
    text = insn.op.mnemonic

    if not insn.imm:
        return text

    return text + ' ' + ', '.join([
        getattr(insn.op.imm_struct, x.name).to_string(
            getattr(insn.imm, x.name)
        )
        for x in insn.op.imm_struct._meta.fields
    ])

def
format_instruction
(
insn
)
:
text
=
insn
.
op
.
mnemonic
if
not
insn
.
imm
:
return
text
return
text
+
' '
+
', '
.
join
(
[
getattr
(
insn
.
op
.
imm_struct
,
x
.
name
)
.
to_string
(
getattr
(
insn
.
imm
,
x
.
name
)
)
for
x
in
insn
.
op
.
imm_struct
.
_meta
.
fields
]
)

Takes a raw Instruction and translates it into a human readable text representation . As of writing the text representation for WASM is not yet standardized so we just emit some generic format .


def format_function(
    func_body,
    func_type=None,
    indent=2,
    format_locals=True,
):
    """
    Takes a `FunctionBody` and optionally a `FunctionType`, yielding the string
    representation of the function line by line. The function type is required
    for formatting function parameter and return value information.
    """
    if func_type is None:
        yield 'func'
    else:
        param_section = ' (param {})'.format(' '.join(
            map(format_lang_type, func_type.param_types)
        )) if func_type.param_types else ''
        result_section = ' (result {})'.format(
            format_lang_type(func_type.return_type)
        ) if func_type.return_type else ''
        yield 'func' + param_section + result_section

    if format_locals and func_body.locals:
        yield '(locals {})'.format(' '.join(itertools.chain.from_iterable(
            itertools.repeat(format_lang_type(x.type), x.count)
            for x in func_body.locals
        )))

    level = 1
    for cur_insn in decode_bytecode(func_body.code):
        if cur_insn.op.flags & INSN_LEAVE_BLOCK:
            level -= 1
        yield ' ' * (level * indent) + format_instruction(cur_insn)
        if cur_insn.op.flags & INSN_ENTER_BLOCK:
            level += 1

def
format_function
(
func_body
,
func_type
=
,
indent
=
2
,
format_locals
=
True
,
)
:
if
func_type
is
:
yield
'func'
else
:
param_section
=
' (param {})'
.
format
(
' '
.
join
(
map
(
format_lang_type
,
func_type
.
param_types
)
)
)
if
func_type
.
param_types
else
''
result_section
=
' (result {})'
.
format
(
format_lang_type
(
func_type
.
return_type
)
)
if
func_type
.
return_type
else
''
yield
'func'
+
param_section
+
result_section
if
format_locals
and
func_body
.
locals
:
yield
'(locals {})'
.
format
(
' '
.
join
(
itertools
.
chain
.
from_iterable
(
itertools
.
repeat
(
format_lang_type
(
x
.
type
)
,
x
.
count
)
for
x
in
func_body
.
locals
)
)
)
level
=
1
for
cur_insn
in
decode_bytecode
(
func_body
.
code
)
:
if
cur_insn
.
op
.
flags
&
INSN_LEAVE_BLOCK
:
level
-=
1
yield
' '
*
(
level
*
indent
)
+
format_instruction
(
cur_insn
)
if
cur_insn
.
op
.
flags
&
INSN_ENTER_BLOCK
:
level
+=
1

Takes a FunctionBody and optionally a FunctionType yielding the string representation of the function line by line . The function type is required for formatting function parameter and return value information .


def decode_bytecode(bytecode):
    """Decodes raw bytecode, yielding `Instruction`s."""
    bytecode_wnd = memoryview(bytecode)
    while bytecode_wnd:
        opcode_id = byte2int(bytecode_wnd[0])
        opcode = OPCODE_MAP[opcode_id]

        if opcode.imm_struct is not None:
            offs, imm, _ = opcode.imm_struct.from_raw(None, bytecode_wnd[1:])
        else:
            imm = None
            offs = 0

        insn_len = 1 + offs
        yield Instruction(opcode, imm, insn_len)
        bytecode_wnd = bytecode_wnd[insn_len:]

def decode_bytecode ( bytecode ) : bytecode_wnd = memoryview ( bytecode ) while bytecode_wnd : opcode_id = byte2int ( bytecode_wnd [ 0 ] ) opcode = OPCODE_MAP [ opcode_id ] if opcode . imm_struct is not None : offs , imm , _ = opcode . imm_struct . from_raw ( None , bytecode_wnd [ 1 : ] ) else : imm = None offs = 0 insn_len = 1 + offs yield Instruction ( opcode , imm , insn_len ) bytecode_wnd = bytecode_wnd [ insn_len : ]

Decodes raw bytecode yielding Instruction s .


def decode_module(module, decode_name_subsections=False):
    """Decodes raw WASM modules, yielding `ModuleFragment`s."""
    module_wnd = memoryview(module)

    # Read & yield module header.
    hdr = ModuleHeader()
    hdr_len, hdr_data, _ = hdr.from_raw(None, module_wnd)
    yield ModuleFragment(hdr, hdr_data)
    module_wnd = module_wnd[hdr_len:]

    # Read & yield sections.
    while module_wnd:
        sec = Section()
        sec_len, sec_data, _ = sec.from_raw(None, module_wnd)

        # If requested, decode name subsections when encountered.
        if (
            decode_name_subsections and
            sec_data.id == SEC_UNK and
            sec_data.name == SEC_NAME
        ):
            sec_wnd = sec_data.payload
            while sec_wnd:
                subsec = NameSubSection()
                subsec_len, subsec_data, _ = subsec.from_raw(None, sec_wnd)
                yield ModuleFragment(subsec, subsec_data)
                sec_wnd = sec_wnd[subsec_len:]
        else:
            yield ModuleFragment(sec, sec_data)

        module_wnd = module_wnd[sec_len:]

Decodes raw WASM modules yielding ModuleFragment s .


def deprecated_func(func):
    """Deprecates a function, printing a warning on the first usage."""

    # We use a mutable container here to work around Py2's lack of
    # the `nonlocal` keyword.
    first_usage = [True]

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if first_usage[0]:
            warnings.warn(
                "Call to deprecated function {}.".format(func.__name__),
                DeprecationWarning,
            )
            first_usage[0] = False
        return func(*args, **kwargs)

    return wrapper

Deprecates a function printing a warning on the first usage .


def connect(self):
        """connect to the server"""
        if self.loop is None:  # pragma: no cover
            self.loop = asyncio.get_event_loop()
        t = asyncio.Task(
            self.loop.create_connection(
                self.config['protocol_factory'],
                self.config['host'], self.config['port'],
                ssl=self.config['ssl']),
            loop=self.loop)
        t.add_done_callback(self.connection_made)
        return t

def
connect
(
self
)
:
if
self
.
loop
is
:
# pragma: no cover
self
.
loop
=
asyncio
.
get_event_loop
(
)
t
=
asyncio
.
Task
(
self
.
loop
.
create_connection
(
self
.
config
[
'protocol_factory'
]
,
self
.
config
[
'host'
]
,
self
.
config
[
'port'
]
,
ssl
=
self
.
config
[
'ssl'
]
)
,
loop
=
self
.
loop
)
t
.
add_done_callback
(
self
.
connection_made
)
return
t


def close(self):
        """Close the connection"""
        if self.pinger:
            self.pinger.cancel()
            self.pinger = None
        if getattr(self, 'protocol', None):
            self.protocol.close()

def close ( self ) : if self . pinger : self . pinger . cancel ( ) self . pinger = None if getattr ( self , 'protocol' , None ) : self . protocol . close ( )


def _read_result(self):
        """Parse read a response from the AGI and parse it.

        :return dict: The AGI response parsed into a dict.
        """
        response = yield from self.reader.readline()
        return parse_agi_result(response.decode(self.encoding)[:-1])

def _read_result ( self ) : response = yield from self . reader . readline ( ) return parse_agi_result ( response . decode ( self . encoding ) [ : - 1 ] )

Parse read a response from the AGI and parse it .


def handler(self, reader, writer):
        """AsyncIO coroutine handler to launch socket listening.

        :Example:

        ::

            @asyncio.coroutine
            def start(request):
                print('Receive a FastAGI request')
                print(['AGI variables:', request.headers])

            fa_app = Application()
            fa_app.add_route('calls/start', start)
            coro = asyncio.start_server(fa_app.handler, '0.0.0.0', 4574)
            server = loop.run_until_complete(coro)

        See https://docs.python.org/3/library/asyncio-stream.html
        """
        buffer = b''
        while b'\n\n' not in buffer:
            buffer += yield from reader.read(self.buf_size)
        lines = buffer[:-2].decode(self.default_encoding).split('\n')
        headers = OrderedDict([
            line.split(': ', 1) for line in lines if ': ' in line
        ])

        agi_network_script = headers.get('agi_network_script')
        log.info('Received FastAGI request from %r for "%s" route',
                 writer.get_extra_info('peername'), agi_network_script)
        log.debug("Asterisk Headers: %r", headers)

        if agi_network_script is not None:
            route = self._route.get(agi_network_script)
            if route is not None:
                request = Request(app=self,
                                  headers=headers,
                                  reader=reader, writer=writer,
                                  encoding=self.default_encoding)
                try:
                    yield from route(request)
                except BaseException:
                    log.exception(
                        'An exception has been raised for the request "%s"',
                        agi_network_script
                    )
            else:
                log.error('No route for the request "%s"', agi_network_script)
        else:
            log.error('No agi_network_script header for the request')
        log.debug("Closing client socket")
        writer.close()

AsyncIO coroutine handler to launch socket listening .


def parse_agi_result(line):
    """Parse AGI results using Regular expression.

    AGI Result examples::

        100 result=0 Trying...

        200 result=0

        200 result=-1

        200 result=132456

        200 result= (timeout)

        510 Invalid or unknown command

        520-Invalid command syntax. Proper usage follows:
        int() argument must be a string, a bytes-like object or a number, not
        'NoneType'

        HANGUP

    """
    # print("--------------\n", line)
    if line == 'HANGUP':
        return {'error': 'AGIResultHangup',
                'msg': 'User hungup during execution'}

    kwargs = dict(code=0, response="", line=line)
    m = re_code.search(line)
    try:
        kwargs.update(m.groupdict())
    except AttributeError:
        # None has no attribute groupdict
        pass
    return agi_code_check(**kwargs)

def
parse_agi_result
(
line
)
:
# print("--------------\n", line)
if
line
==
'HANGUP'
:
return
{
'error'
:
'AGIResultHangup'
,
'msg'
:
'User hungup during execution'
}
kwargs
=
dict
(
code
=
0
,
response
=
""
,
line
=
line
)
m
=
re_code
.
search
(
line
)
try
:
kwargs
.
update
(
m
.
groupdict
(
)
)
except
AttributeError
:
# None has no attribute groupdict
pass
return
agi_code_check
(
*
*
kwargs
)

Parse AGI results using Regular expression .


def agi_code_check(code=None, response=None, line=None):
    """
    Check the AGI code and return a dict to help on error handling.
    """
    code = int(code)
    response = response or ""
    result = {'status_code': code, 'result': ('', ''), 'msg': ''}
    if code == 100:
        result['msg'] = line
    elif code == 200:
        for key, value, data in re_kv.findall(response):
            result[key] = (value, data)
            # If user hangs up... we get 'hangup' in the data
            if data == 'hangup':
                return {
                    'error': 'AGIResultHangup',
                    'msg': 'User hungup during execution'}
            elif key == 'result' and value == '-1':
                return {
                    'error': 'AGIAppError',
                    'msg': 'Error executing application, or hangup'}
    elif code == 510:
        result['error'] = 'AGIInvalidCommand'
    elif code == 520:
        # AGI Usage error
        result['error'] = 'AGIUsageError'
        result['msg'] = line
    else:
        # Unhandled code or undefined response
        result['error'] = 'AGIUnknownError'
        result['msg'] = line
    return result

Check the AGI code and return a dict to help on error handling .


def reset(cls, uid=None):
        """Mostly used for unit testing. Allow to use a static uuid and reset
        all counter"""
        for instance in cls.instances:
            if uid:
                instance.uid = uid
            instance.generator = instance.get_generator()

def reset ( cls , uid = None ) : for instance in cls . instances : if uid : instance . uid = uid instance . generator = instance . get_generator ( )

Mostly used for unit testing . Allow to use a static uuid and reset all counter


def get_instances(self):
        """Mostly used for debugging"""
        return ["<%s prefix:%s (uid:%s)>" % (self.__class__.__name__,
                                             i.prefix, self.uid)
                for i in self.instances]

def
get_instances
(
self
)
:
return
[
"<%s prefix:%s (uid:%s)>"
%
(
self
.
__class__
.
__name__
,
i
.
prefix
,
self
.
uid
)
for
i
in
self
.
instances
]


def get_data(path):
    """
    Returns data from a package directory.
    'path' should be an absolute path.
    """
    # Run the imported setup to get the metadata.
    with FakeContext(path):
        with SetupMonkey() as sm:
            try:
                distro = run_setup('setup.py', stop_after='config')

                metadata = {'_setuptools': sm.used_setuptools}

                for k, v in distro.metadata.__dict__.items():
                    if k[0] == '_' or not v:
                        continue
                    if all(not x for x in v):
                        continue
                    metadata[k] = v

                if sm.used_setuptools:
                    for extras in ['cmdclass', 'zip_safe', 'test_suite']:
                        v = getattr(distro, extras, None)
                        if v is not None and v not in ([], {}):
                            metadata[extras] = v

            except ImportError as e:
                # Either there is no setup py, or it's broken.
                logging.exception(e)
                metadata = {}

    return metadata

Returns data from a package directory . path should be an absolute path .


def get_primary_keys(model):
    """Get primary key properties for a SQLAlchemy model.

    :param model: SQLAlchemy model class
    """
    mapper = model.__mapper__
    return [mapper.get_property_by_column(column) for column in mapper.primary_key]

def get_primary_keys ( model ) : mapper = model . __mapper__ return [ mapper . get_property_by_column ( column ) for column in mapper . primary_key ]

Get primary key properties for a SQLAlchemy model .


def _deserialize(self, value, *args, **kwargs):
        """Deserialize a serialized value to a model instance.

        If the parent schema is transient, create a new (transient) instance.
        Otherwise, attempt to find an existing instance in the database.
        :param value: The value to deserialize.
        """
        if not isinstance(value, dict):
            if len(self.related_keys) != 1:
                self.fail(
                    "invalid",
                    value=value,
                    keys=[prop.key for prop in self.related_keys],
                )
            value = {self.related_keys[0].key: value}
        if self.transient:
            return self.related_model(**value)
        try:
            result = self._get_existing_instance(
                self.session.query(self.related_model), value
            )
        except NoResultFound:
            # The related-object DNE in the DB, but we still want to deserialize it
            # ...perhaps we want to add it to the DB later
            return self.related_model(**value)
        return result

Deserialize a serialized value to a model instance .