<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2011 Citrix Systems
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#    @author: <NAME>, Cisco Systems

import httplib
import socket
import urllib
from quantum.common.wsgi import Serializer
from quantum.common import exceptions

EXCEPTIONS = {
    400: exceptions.BadInputError,
    401: exceptions.NotAuthorized,
    420: exceptions.NetworkNotFound,
    421: exceptions.NetworkInUse,
    422: exceptions.NetworkNameExists,
    430: exceptions.PortNotFound,
    431: exceptions.StateInvalid,
    432: exceptions.PortInUse,
    440: exceptions.AlreadyAttached,
    441: exceptions.AttachmentNotReady,
}


class ApiCall(object):
    """A Decorator to add support for format and tenant overriding"""
    def __init__(self, function):
        self.function = function

    def __get__(self, instance, owner):
        def with_params(*args, **kwargs):
            """
            Temporarily sets the format and tenant for this request
            """
            (format, tenant) = (instance.format, instance.tenant)

            if 'format' in kwargs:
                instance.format = kwargs['format']
            if 'tenant' in kwargs:
                instance.tenant = kwargs['tenant']

            ret = self.function(instance, *args)
            (instance.format, instance.tenant) = (format, tenant)
            return ret
        return with_params


class Client(object):

    """A base client class - derived from Glance.BaseClient"""

    action_prefix = '/v0.1/tenants/{tenant_id}'

    # Action query strings
    networks_path = "/networks"
    network_path = "/networks/%s"
    ports_path = "/networks/%s/ports"
    port_path = "/networks/%s/ports/%s"
    attachment_path = "/networks/%s/ports/%s/attachment"

    def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None,
                format="xml", testingStub=None, key_file=None, cert_file=None,
                logger=None):
        """
        Creates a new client to some service.

        :param host: The host where service resides
        :param port: The port where service resides
        :param use_ssl: True to use SSL, False to use HTTP
        :param tenant: The tenant ID to make requests with
        :param format: The format to query the server with
        :param testingStub: A class that stubs basic server methods for tests
        :param key_file: The SSL key file to use if use_ssl is true
        :param cert_file: The SSL cert file to use if use_ssl is true
        """
        self.host = host
        self.port = port
        self.use_ssl = use_ssl
        self.tenant = tenant
        self.format = format
        self.connection = None
        self.testingStub = testingStub
        self.key_file = key_file
        self.cert_file = cert_file
        self.logger = logger

    def get_connection_type(self):
        """
        Returns the proper connection type
        """
        if self.testingStub:
            return self.testingStub
        if self.use_ssl:
            return httplib.HTTPSConnection
        else:
            return httplib.HTTPConnection

    def do_request(self, method, action, body=None,
                   headers=None, params=None):
        """
        Connects to the server and issues a request.
        Returns the result data, or raises an appropriate exception if
        HTTP status code is not 2xx

        :param method: HTTP method ("GET", "POST", "PUT", etc...)
        :param body: string of data to send, or None (default)
        :param headers: mapping of key/value pairs to add as headers
        :param params: dictionary of key/value pairs to add to append
                             to action

        """

        # Ensure we have a tenant id
        if not self.tenant:
            raise Exception("Tenant ID not set")

        # Add format and tenant_id
        action += ".%s" % self.format
        action = Client.action_prefix + action
        action = action.replace('{tenant_id}', self.tenant)

        if type(params) is dict:
            action += '?' + urllib.urlencode(params)

        if body:
            body = self.serialize(body)

        try:
            connection_type = self.get_connection_type()
            headers = headers or {"Content-Type":
                                      "application/%s" % self.format}

            # Open connection and send request, handling SSL certs
            certs = {'key_file': self.key_file, 'cert_file': self.cert_file}
            certs = dict((x, certs[x]) for x in certs if certs[x] != None)

            if self.use_ssl and len(certs):
                conn = connection_type(self.host, self.port, **certs)
            else:
                conn = connection_type(self.host, self.port)

            if self.logger:
                self.logger.debug("Quantum Client Request:\n" \
                        + method + " " + action + "\n")
                if body:
                    self.logger.debug(body)

            conn.request(method, action, body, headers)
            res = c.getresponse()
            status_code = self.get_status_code(res)
            data = res.read()

            if self.logger:
                self.logger.debug("Quantum Client Reply (code = %s) :\n %s" \
                        % (str(status_code), data))

            if status_code in (httplib.OK,
                               httplib.CREATED,
                               httplib.ACCEPTED,
                               httplib.NO_CONTENT):
                return self.deserialize(data, status_code)
            else:
                if res.status in EXCEPTIONS:
                    raise EXCEPTIONS[res.status]()
                raise Exception("Server returned error: %s" % res.read())

        except (socket.error, IOError), e:
            raise Exception("Unable to connect to "
                            "server. Got error: %s" % e)

    def get_status_code(self, response):<commit_msg>Fixing typo<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2011 Citrix Systems
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#    @author: <NAME>, Cisco Systems

import httplib
import socket
import urllib
from quantum.common.wsgi import Serializer
from quantum.common import exceptions

EXCEPTIONS = {
    400: exceptions.BadInputError,
    401: exceptions.NotAuthorized,
    420: exceptions.NetworkNotFound,
    421: exceptions.NetworkInUse,
    422: exceptions.NetworkNameExists,
    430: exceptions.PortNotFound,
    431: exceptions.StateInvalid,
    432: exceptions.PortInUse,
    440: exceptions.AlreadyAttached,
    441: exceptions.AttachmentNotReady,
}


class ApiCall(object):
    """A Decorator to add support for format and tenant overriding"""
    def __init__(self, function):
        self.function = function

    def __get__(self, instance, owner):
        def with_params(*args, **kwargs):
            """
            Temporarily sets the format and tenant for this request
            """
            (format, tenant) = (instance.format, instance.tenant)

            if 'format' in kwargs:
                instance.format = kwargs['format']
            if 'tenant' in kwargs:
                instance.tenant = kwargs['tenant']

            ret = self.function(instance, *args)
            (instance.format, instance.tenant) = (format, tenant)
            return ret
        return with_params


class Client(object):

    """A base client class - derived from Glance.BaseClient"""

    action_prefix = '/v0.1/tenants/{tenant_id}'

    # Action query strings
    networks_path = "/networks"
    network_path = "/networks/%s"
    ports_path = "/networks/%s/ports"
    port_path = "/networks/%s/ports/%s"
    attachment_path = "/networks/%s/ports/%s/attachment"

    def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None,
                format="xml", testingStub=None, key_file=None, cert_file=None,
                logger=None):
        """
        Creates a new client to some service.

        :param host: The host where service resides
        :param port: The port where service resides
        :param use_ssl: True to use SSL, False to use HTTP
        :param tenant: The tenant ID to make requests with
        :param format: The format to query the server with
        :param testingStub: A class that stubs basic server methods for tests
        :param key_file: The SSL key file to use if use_ssl is true
        :param cert_file: The SSL cert file to use if use_ssl is true
        """
        self.host = host
        self.port = port
        self.use_ssl = use_ssl
        self.tenant = tenant
        self.format = format
        self.connection = None
        self.testingStub = testingStub
        self.key_file = key_file
        self.cert_file = cert_file
        self.logger = logger

    def get_connection_type(self):
        """
        Returns the proper connection type
        """
        if self.testingStub:
            return self.testingStub
        if self.use_ssl:
            return httplib.HTTPSConnection
        else:
            return httplib.HTTPConnection

    def do_request(self, method, action, body=None,
                   headers=None, params=None):
        """
        Connects to the server and issues a request.
        Returns the result data, or raises an appropriate exception if
        HTTP status code is not 2xx

        :param method: HTTP method ("GET", "POST", "PUT", etc...)
        :param body: string of data to send, or None (default)
        :param headers: mapping of key/value pairs to add as headers
        :param params: dictionary of key/value pairs to add to append
                             to action

        """

        # Ensure we have a tenant id
        if not self.tenant:
            raise Exception("Tenant ID not set")

        # Add format and tenant_id
        action += ".%s" % self.format
        action = Client.action_prefix + action
        action = action.replace('{tenant_id}', self.tenant)

        if type(params) is dict:
            action += '?' + urllib.urlencode(params)

        if body:
            body = self.serialize(body)

        try:
            connection_type = self.get_connection_type()
            headers = headers or {"Content-Type":
                                      "application/%s" % self.format}

            # Open connection and send request, handling SSL certs
            certs = {'key_file': self.key_file, 'cert_file': self.cert_file}
            certs = dict((x, certs[x]) for x in certs if certs[x] != None)

            if self.use_ssl and len(certs):
                conn = connection_type(self.host, self.port, **certs)
            else:
                conn = connection_type(self.host, self.port)

            if self.logger:
                self.logger.debug("Quantum Client Request:\n" \
                        + method + " " + action + "\n")
                if body:
                    self.logger.debug(body)

            conn.request(method, action, body, headers)
            res = conn.getresponse()
            status_code = self.get_status_code(res)
            data = res.read()

            if self.logger:
                self.logger.debug("Quantum Client Reply (code = %s) :\n %s" \
                        % (str(status_code), data))

            if status_code in (httplib.OK,
                               httplib.CREATED,
                               httplib.ACCEPTED,
                               httplib.NO_CONTENT):
                return self.deserialize(data, status_code)
            else:
                if res.status in EXCEPTIONS:
                    raise EXCEPTIONS[res.status]()
                raise Exception("Server returned error: %s" % res.read())

        except (socket.error, IOError), e:
            raise Exception("Unable to connect to "
                            "server. Got error: %s" % e)

    def get_status_code(self, response):
{'fraction_non_alphanumeric': 0.08925974125392329, 'fraction_numerical': 0.00826762611957437, 'mean_word_length': 1.969090909090909, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1500629', 'n_tokens_mistral': 3572, 'n_tokens_neox': 3453, 'n_words': 1140}