<commit_before>from swiftclient import client
from ThuCloudDisk.settings import *
import os
import requests
import magic
import json

SH2_API_ADDR=u"59.66.137.32:9144"
def read_in_chunks(file_object, chunk_size=1024):
    """Lazy function (generator) to read a file piece by piece.
    Default chunk size: 1k."""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data
class Swift:
    def __init__(self):
        self.host = SWIFT_HOST
        self.user_name = SWIFT_USER
        self.user_pass = SWIFT_SECRET
        self.authurl ='http://'+ self.host +'/v2.0'
        self.tenant = SWIFT_TENANT

    def connect(self):
        auth = client.get_auth(self.authurl,self.user_name,self.user_pass,tenant_name=self.tenant,auth_version='2')
        self.storage_url = auth[0]
        self.http_conn = client.http_connection(self.storage_url)
        self.token = auth[1]

    # If the container does not exist, return None: however, the function will almost never returns None [l TODO]
    # otherwise, return Tuple: (httpHeader, [object List]); and the header is currently nothing
        # the returned obj list will have the folder itself in it.
        # all the file names are their full path
    # if the path (not the container) does not exist, returns an empty list

    def list_container(self,container_name,prefix=None,delimiter=None):
        print (container_name,prefix,delimiter)
        PREFIX=u"fmap-file-"
        try:
            if (prefix==None):
                prefix=u""
            r=requests.get(u"http://"+SH2_API_ADDR+u"/fs/"+container_name+u"/"+prefix)
            forRet=[]
            if (r.status_code!=200):
                return (r.headers, forRet)
            result=r.json()
            try:
                for obj in result:
                    objVal=json.loads(obj["Val"])
                    if (objVal["type"]=="dir"):
                        forRet.append({"subdir": prefix+obj["Key"]+u"/"})
                    else:
                        i4Maniputate={}
                        for k in objVal:
                            if (k.startswith(PREFIX)):
                                i4Maniputate[(k[len(PREFIX):]).replace(u"-", u"_")]=objVal[k]
                        i4Maniputate["bytes"]=int(i4Maniputate["content_length"])
                        i4Maniputate["name"]=prefix+obj["Key"]
                        forRet.append(i4Maniputate)
                forRet.append({"name":prefix, "bytes": 0})
                print forRet
                return (r.headers, forRet)
            except Exception as e:
                print forRet, e
                return (r.headers, [])
        except:
            return None

    def put_container(self,container_name):
        r=requests.post(u"http://"+SH2_API_ADDR+u"/cn/"+container_name)
        if (r.status_code==201):
            return True
        return False

    # [l TODO] Implement it.
    def get_object(self,container,object):
        raise Exception("NOT IMPLEMENTED")

    def delete_folder(self,container,prefix):
        r=requests.delete(u"http://"+SH2_API_ADDR+u"/fs/"+container+u"/"+prefix)
        return False

    def get_object_to_file(self,container,userpath,filename):
        filepath = os.path.join(LOCAL_BUFFER_PATH,userpath)
        filepath = filepath + filename
        prefix = userpath
        objectName = prefix + filename
        try:
            r=requests.get(u"http://"+SH2_API_ADDR+u"/io/"+container+u"/"+objectName, stream=True)
            if (r.status_code!=200):
                return False
            header=r.headers
            fileSize = header['ori-content-length']
            fileDate = header['ori-last-modified']
            chunk_size=1*1024*1024  # 1MB
            with open(filepath, 'wb') as fd:
                for chunk in r.iter_content(chunk_size):
                    fd.write(chunk)
                fd.close()

            return fileSize, fileDate, filepath, filename
        except:
            return False

    def put_object_of_foler(self,container,prefix,folder):
        r=requests.post(u"http://"+SH2_API_ADDR+u"/fs/"+container+u"/"+prefix+folder)
        if (r.status_code==201 or r.status_code==202):
            return True
        return False

    def put_object_from_file(self,container,prefix,filepath):
        try:
            content_type = magic.from_file(filepath,mime=True);
            fp = open(filepath,'rb')
            filename=prefix+(filepath.split("/"))[-1]
            r=requests.put(u"http://"+SH2_API_ADDR+u"/io/"+container+u"/"+filename, data=read_in_chunks(fp), headers={"content-type": content_type})
            return True
            fp.close()
        except Exception as e:
            print "Exception @ put_object_from_file:", e
            return False

    def delete_object(self, container, prefix, name):
        try:
            r=requests.delete(u"http://"+SH2_API_ADDR+u"/fs/"+container_name+u"/"+prefix+name)
	        return True
        except:
            return False

if __name__ == '__main__':
    #def get_new_file_path(container,object):
    swift = Swift();
    swift.connect();
    print swift.list_container('test@thucloud.com');
    #swift.put_container('demo-container1');
    # print swift.list_container('xiaoh16@gmail.com');
    #print swift.put_container('ThuCloudDisk-container');
    #swift.put_object_from_file('ThuCloudDisk-container',prefix='',filepath='/home/chengls10/Desktop/2')
    #print swift.get_object_to_file('ThuCloudDisk-container','1.py')
    #print swift.delete_object('ThuCloudDisk-container','1.py')
<commit_msg>eliminating tab indenting<commit_after>from swiftclient import client
from ThuCloudDisk.settings import *
import os
import requests
import magic
import json

SH2_API_ADDR=u"59.66.137.32:9144"
def read_in_chunks(file_object, chunk_size=1024):
    """Lazy function (generator) to read a file piece by piece.
    Default chunk size: 1k."""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data
class Swift:
    def __init__(self):
        self.host = SWIFT_HOST
        self.user_name = SWIFT_USER
        self.user_pass = SWIFT_SECRET
        self.authurl ='http://'+ self.host +'/v2.0'
        self.tenant = SWIFT_TENANT

    def connect(self):
        auth = client.get_auth(self.authurl,self.user_name,self.user_pass,tenant_name=self.tenant,auth_version='2')
        self.storage_url = auth[0]
        self.http_conn = client.http_connection(self.storage_url)
        self.token = auth[1]

    # If the container does not exist, return None: however, the function will almost never returns None [l TODO]
    # otherwise, return Tuple: (httpHeader, [object List]); and the header is currently nothing
        # the returned obj list will have the folder itself in it.
        # all the file names are their full path
    # if the path (not the container) does not exist, returns an empty list

    def list_container(self,container_name,prefix=None,delimiter=None):
        print (container_name,prefix,delimiter)
        PREFIX=u"fmap-file-"
        try:
            if (prefix==None):
                prefix=u""
            r=requests.get(u"http://"+SH2_API_ADDR+u"/fs/"+container_name+u"/"+prefix)
            forRet=[]
            if (r.status_code!=200):
                return (r.headers, forRet)
            result=r.json()
            try:
                for obj in result:
                    objVal=json.loads(obj["Val"])
                    if (objVal["type"]=="dir"):
                        forRet.append({"subdir": prefix+obj["Key"]+u"/"})
                    else:
                        i4Maniputate={}
                        for k in objVal:
                            if (k.startswith(PREFIX)):
                                i4Maniputate[(k[len(PREFIX):]).replace(u"-", u"_")]=objVal[k]
                        i4Maniputate["bytes"]=int(i4Maniputate["content_length"])
                        i4Maniputate["name"]=prefix+obj["Key"]
                        forRet.append(i4Maniputate)
                forRet.append({"name":prefix, "bytes": 0})
                print forRet
                return (r.headers, forRet)
            except Exception as e:
                print forRet, e
                return (r.headers, [])
        except:
            return None

    def put_container(self,container_name):
        r=requests.post(u"http://"+SH2_API_ADDR+u"/cn/"+container_name)
        if (r.status_code==201):
            return True
        return False

    # [l TODO] Implement it.
    def get_object(self,container,object):
        raise Exception("NOT IMPLEMENTED")

    def delete_folder(self,container,prefix):
        r=requests.delete(u"http://"+SH2_API_ADDR+u"/fs/"+container+u"/"+prefix)
        return False

    def get_object_to_file(self,container,userpath,filename):
        filepath = os.path.join(LOCAL_BUFFER_PATH,userpath)
        filepath = filepath + filename
        prefix = userpath
        objectName = prefix + filename
        try:
            r=requests.get(u"http://"+SH2_API_ADDR+u"/io/"+container+u"/"+objectName, stream=True)
            if (r.status_code!=200):
                return False
            header=r.headers
            fileSize = header['ori-content-length']
            fileDate = header['ori-last-modified']
            chunk_size=1*1024*1024  # 1MB
            with open(filepath, 'wb') as fd:
                for chunk in r.iter_content(chunk_size):
                    fd.write(chunk)
                fd.close()

            return fileSize, fileDate, filepath, filename
        except:
            return False

    def put_object_of_foler(self,container,prefix,folder):
        r=requests.post(u"http://"+SH2_API_ADDR+u"/fs/"+container+u"/"+prefix+folder)
        if (r.status_code==201 or r.status_code==202):
            return True
        return False

    def put_object_from_file(self,container,prefix,filepath):
        try:
            content_type = magic.from_file(filepath,mime=True);
            fp = open(filepath,'rb')
            filename=prefix+(filepath.split("/"))[-1]
            r=requests.put(u"http://"+SH2_API_ADDR+u"/io/"+container+u"/"+filename, data=read_in_chunks(fp), headers={"content-type": content_type})
            return True
            fp.close()
        except Exception as e:
            print "Exception @ put_object_from_file:", e
            return False

    def delete_object(self, container, prefix, name):
        try:
            r=requests.delete(u"http://"+SH2_API_ADDR+u"/fs/"+container_name+u"/"+prefix+name)
            return True
        except:
            return False

if __name__ == '__main__':
    #def get_new_file_path(container,object):
    swift = Swift();
    swift.connect();
    print swift.list_container('test@thucloud.com');
    #swift.put_container('demo-container1');
    # print swift.list_container('xiaoh16@gmail.com');
    #print swift.put_container('ThuCloudDisk-container');
    #swift.put_object_from_file('ThuCloudDisk-container',prefix='',filepath='/home/chengls10/Desktop/2')
    #print swift.get_object_to_file('ThuCloudDisk-container','1.py')
    #print swift.delete_object('ThuCloudDisk-container','1.py')
<|endoftext|>


<commit_before>from shapely.geometry import Polygon, Point

from geopandas import GeoSeries, GeoDataFrame, base, read_file
from geopandas.tests.util import unittest, download_nybb

@unittest.skipIf(not base.HAS_SINDEX, 'Rtree absent, skipping')
class TestSeriesSindex(unittest.TestCase):

    def test_empty_index(self):
        self.assert_(GeoSeries().sindex is None)

    def test_point(self):
        s = GeoSeries([Point(0, 0)])
        self.assertEqual(s.sindex.size, 1)
        hits = s.sindex.intersection((-1, -1, 1, 1))
        self.assertEqual(len(list(hits)), 1)
        hits = s.sindex.intersection((-2, -2, -1, -1))
        self.assertEqual(len(list(hits)), 0)

    def test_empty_point(self):
        s = GeoSeries([Point()])
        self.assert_(GeoSeries().sindex is None)

    def test_polygons(self):
        t1 = Polygon([(0, 0), (1, 0), (1, 1)])
        t2 = Polygon([(0, 0), (1, 1), (0, 1)])
        sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
        s = GeoSeries([t1, t2, sq])
        self.assertEqual(s.sindex.size, 3)

    def test_polygons_append(self):
        t1 = Polygon([(0, 0), (1, 0), (1, 1)])
        t2 = Polygon([(0, 0), (1, 1), (0, 1)])
        sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
        s = GeoSeries([t1, t2, sq])
        t = GeoSeries([t1, t2, sq], [3,4,5])
        s = s.append(t)
        self.assertEqual(len(s), 6)
        self.assertEqual(s.sindex.size, 6)

    def test_lazy_build(self):
        s = GeoSeries([Point(0, 0)])
        self.assert_(s._sindex is None)
        self.assertEqual(s.sindex.size, 1)
        self.assert_(s._sindex is not None)

@unittest.skipIf(not base.HAS_SINDEX, 'Rtree absent, skipping')
class TestFrameSindex(unittest.TestCase):
    def setUp(self):
        data = {"A": range(5), "B": range(-5, 0),
                "location": [Point(x, y) for x, y in zip(range(5), range(5))]}
        self.df = GeoDataFrame(data, geometry='location')

    def test_sindex(self):
        self.df.crs = {'init': 'epsg:4326'}
        self.assertEqual(self.df.sindex.size, 5)
        hits = list(self.df.sindex.intersection((2.5, 2.5, 4, 4), objects=True))
        self.assertEqual(len(hits), 2)
        self.assertEqual(hits[0].object, 3)

    def test_lazy_build(self):
        self.assert_(self.df._sindex is None)
        self.assertEqual(self.df.sindex.size, 5)
        self.assert_(self.df._sindex is not None)

    def test_sindex_rebuild_on_set_geometry(self):
        # First build the sindex
        self.assert_(self.df.sindex is not None)
        self.df.set_geometry(
            [Point(x, y) for x, y in zip(range(5, 10), range(5, 10))],
            inplace=True)
        self.assert_(self.df._sindex_valid == False)

# Skip to accommodate Shapely geometries being unhashable
@unittest.skip
class TestJoinSindex(unittest.TestCase):

    def setUp(self):
        nybb_filename, nybb_zip_path = download_nybb()
        self.boros = read_file(nybb_zip_path, vfs='zip://' + nybb_filename)

    def test_merge_geo(self):
        # First check that we gets hits from the boros frame.
        tree = self.boros.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [self.boros.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx', 'Queens'])

        # Check that we only get the Bronx from this view.
        first = self.boros[self.boros['BoroCode'] < 3]
        tree = first.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [first.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx'])

        # Check that we only get Queens from this view.
        second = self.boros[self.boros['BoroCode'] >= 3]
        tree = second.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [second.ix[hit.object]['BoroName'] for hit in hits],
            ['Queens'])

        # Get both the Bronx and Queens again.
        merged = first.merge(second, how='outer')
        self.assertEqual(len(merged), 5)
        self.assertEqual(merged.sindex.size, 5)
        tree = merged.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [merged.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx', 'Queens'])
<commit_msg>TST: skip sindex tests on appveyor for now<commit_after>import sys

from shapely.geometry import Polygon, Point

from geopandas import GeoSeries, GeoDataFrame, base, read_file
from geopandas.tests.util import unittest, download_nybb

@unittest.skipIf(sys.platform.startswith("win"), "fails on AppVeyor")
@unittest.skipIf(not base.HAS_SINDEX, 'Rtree absent, skipping')
class TestSeriesSindex(unittest.TestCase):

    def test_empty_index(self):
        self.assert_(GeoSeries().sindex is None)

    def test_point(self):
        s = GeoSeries([Point(0, 0)])
        self.assertEqual(s.sindex.size, 1)
        hits = s.sindex.intersection((-1, -1, 1, 1))
        self.assertEqual(len(list(hits)), 1)
        hits = s.sindex.intersection((-2, -2, -1, -1))
        self.assertEqual(len(list(hits)), 0)

    def test_empty_point(self):
        s = GeoSeries([Point()])
        self.assert_(GeoSeries().sindex is None)

    def test_polygons(self):
        t1 = Polygon([(0, 0), (1, 0), (1, 1)])
        t2 = Polygon([(0, 0), (1, 1), (0, 1)])
        sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
        s = GeoSeries([t1, t2, sq])
        self.assertEqual(s.sindex.size, 3)

    def test_polygons_append(self):
        t1 = Polygon([(0, 0), (1, 0), (1, 1)])
        t2 = Polygon([(0, 0), (1, 1), (0, 1)])
        sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
        s = GeoSeries([t1, t2, sq])
        t = GeoSeries([t1, t2, sq], [3,4,5])
        s = s.append(t)
        self.assertEqual(len(s), 6)
        self.assertEqual(s.sindex.size, 6)

    def test_lazy_build(self):
        s = GeoSeries([Point(0, 0)])
        self.assert_(s._sindex is None)
        self.assertEqual(s.sindex.size, 1)
        self.assert_(s._sindex is not None)

@unittest.skipIf(sys.platform.startswith("win"), "fails on AppVeyor")
@unittest.skipIf(not base.HAS_SINDEX, 'Rtree absent, skipping')
class TestFrameSindex(unittest.TestCase):
    def setUp(self):
        data = {"A": range(5), "B": range(-5, 0),
                "location": [Point(x, y) for x, y in zip(range(5), range(5))]}
        self.df = GeoDataFrame(data, geometry='location')

    def test_sindex(self):
        self.df.crs = {'init': 'epsg:4326'}
        self.assertEqual(self.df.sindex.size, 5)
        hits = list(self.df.sindex.intersection((2.5, 2.5, 4, 4), objects=True))
        self.assertEqual(len(hits), 2)
        self.assertEqual(hits[0].object, 3)

    def test_lazy_build(self):
        self.assert_(self.df._sindex is None)
        self.assertEqual(self.df.sindex.size, 5)
        self.assert_(self.df._sindex is not None)

    def test_sindex_rebuild_on_set_geometry(self):
        # First build the sindex
        self.assert_(self.df.sindex is not None)
        self.df.set_geometry(
            [Point(x, y) for x, y in zip(range(5, 10), range(5, 10))],
            inplace=True)
        self.assert_(self.df._sindex_valid == False)

# Skip to accommodate Shapely geometries being unhashable
@unittest.skip
class TestJoinSindex(unittest.TestCase):

    def setUp(self):
        nybb_filename, nybb_zip_path = download_nybb()
        self.boros = read_file(nybb_zip_path, vfs='zip://' + nybb_filename)

    def test_merge_geo(self):
        # First check that we gets hits from the boros frame.
        tree = self.boros.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [self.boros.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx', 'Queens'])

        # Check that we only get the Bronx from this view.
        first = self.boros[self.boros['BoroCode'] < 3]
        tree = first.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [first.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx'])

        # Check that we only get Queens from this view.
        second = self.boros[self.boros['BoroCode'] >= 3]
        tree = second.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [second.ix[hit.object]['BoroName'] for hit in hits],
            ['Queens'])

        # Get both the Bronx and Queens again.
        merged = first.merge(second, how='outer')
        self.assertEqual(len(merged), 5)
        self.assertEqual(merged.sindex.size, 5)
        tree = merged.sindex
        hits = tree.intersection((1012821.80, 229228.26), objects=True)
        self.assertEqual(
            [merged.ix[hit.object]['BoroName'] for hit in hits],
            ['Bronx', 'Queens'])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Implement graph products

G graph is the undirected base graph

>>> G = nx.Graph()

H graph is the "pop design" graph

Each node u in the graph G has a property "H" which specifies the H graph to use

>>> G.add_nodes_from([ ('a', dict(H='style_a')), ('b', dict(H='style_b')), ('c', dict(H='style_b'))])

The 'H' attribute of a node in G refers to the key in the 'H_graphs' dictionary:

>>> H_graphs = {}
>>> H_graphs['style_a'] = nx.cycle_graph(1)
>>> H_graphs['style_b'] = nx.cycle_graph(2)

Edges in the graph G specify edges between pops, and have an operator which specifies the interconnection method (covered below).

Valid operators are cartesian, rooted, strong, or tensor.

>>> G.add_edges_from([('a','b', dict(operator = 'cartesian')), ('a','c', dict(operator = 'cartesian')),  ('b','c', dict(operator = 'cartesian'))])

Nodes in output graph are the tuple (u,v) for u in G for v in G[u]['H']

>>> sorted(node_list(G, H_graphs))

Intra PoP links:

"""
__author__ = "\n".join(['Simon Knight'])
#    Copyright (C) 2009-2012 by Simon Knight, Hung Nguyen, Eric Parsonage

import networkx as nx
import logging
import itertools

LOG = logging.getLogger("ANK")

__all__ = ['graph_product']

def node_list(G, H_graphs):
    # TODO: work out how to retain node properties
    retval = []
    for u in G:
        H_label = G.node[u]['H']
        H = H_graphs[H_label]
        retval += [(u,v) for v in H for u in G]

    return list(retval)

def graph_product(G, H_graphs):
    """

    """
    pass

<commit_msg>more graph products<commit_after># -*- coding: utf-8 -*-
"""
Implement graph products

G graph is the undirected base graph

>>> G = nx.Graph()

H graph is the "pop design" graph

Each node u in the graph G has a property "H" which specifies the H graph to use

>>> G.add_nodes_from([ ('a', dict(H='style_a')), ('b', dict(H='style_b')), ('c', dict(H='style_c'))])

The 'H' attribute of a node in G refers to the key in the 'H_graphs' dictionary:

>>> H_graphs = {}
>>> H_graphs['style_a'] = nx.trivial_graph()
>>> H_graphs['style_b'] = nx.cycle_graph(2)
>>> H_graphs['style_c'] = nx.cycle_graph(3)

Edges in the graph G specify edges between pops, and have an operator which specifies the interconnection method (covered below).

Valid operators are cartesian, rooted, strong, or tensor.

>>> G.add_edges_from([('a','b', dict(operator = 'cartesian')), ('a','c', dict(operator = 'rooted')),  ('b','c', dict(operator = 'tensor'))])

Nodes in output graph are the tuple (u,v) for u in G for v in G[u]['H']

>>> sorted(node_list(G, H_graphs))
[('a', 0), ('b', 0), ('b', 1), ('c', 0), ('c', 1), ('c', 2)]

Intra PoP links are from the relevant H graph

>>> sorted(intra_pop_links(G, H_graphs))
[(('b', 0), ('b', 1)), (('c', 0), ('c', 1)), (('c', 0), ('c', 2)), (('c', 1), ('c', 2))]

>>> sorted(inter_pop_links(G, H_graphs))

"""
__author__ = "\n".join(['Simon Knight'])
#    Copyright (C) 2009-2012 by Simon Knight, Hung Nguyen, Eric Parsonage

import networkx as nx
import logging
import itertools

LOG = logging.getLogger("ANK")

__all__ = ['graph_product']

def node_list(G, H_graphs):
    # TODO: work out how to retain node properties
    return [ (u,v) for u in G for v in H_graphs[G.node[u]['H']] ]

def intra_pop_links(G, H_graphs):
    return [ ((u,v1), (u,v2)) for u in G for (v1, v2) in H_graphs[G.node[u]['H']].edges() ]

def inter_pop_links(G, H_graphs):
    #TODO:: list any edges without operator marked on them
    edges = []
    cartesian_operators = set(["cartesian", "strong"])
    tensor_operators = set(["tensor", "strong"])
    for (u1, u2) in G.edges():
        operator = G[u1][u2]['operator']
        H1 = H_graphs[G.node[u1]['H']]
        H2 = H_graphs[G.node[u2]['H']]
        if operator in cartesian_operators:
            edges += [((u1, v1), (u2, v2)) for v1 in H1 for v2 in H2 if v1 == v2]
        if operator in tensor_operators:
            edges += [((u1, v1), (u2, v2)) for v1 in H1 for v2 in H2
                    if ( (v1, v2) in H1.edges() or (v1,v2) in H2.edges())]
        if operator in tensor_operators:
            edges += [((u1, v1), (u2, v2)) for v1 in H1 for v2 in H2
                    if H1.node[v1].get("root") == H2.node[v2].get("root") == True ]

    return edges

<|endoftext|>


<commit_before>"""Sphinx bootstrap theme."""
import os

VERSION = (0, 1, 8)

__version__ = ".".join(str(v) for v in VERSION)
__version_full__ = __version__

def get_html_theme_path():
    """Return list of HTML theme paths."""
    cur_dir = os.path.abspath(os.path.dirname(__file__))
    return [cur_dir]
<commit_msg>version bump<commit_after>"""Sphinx bootstrap theme."""
import os

VERSION = (0, 2, 0)

__version__ = ".".join(str(v) for v in VERSION)
__version_full__ = __version__

def get_html_theme_path():
    """Return list of HTML theme paths."""
    cur_dir = os.path.abspath(os.path.dirname(__file__))
    return [cur_dir]
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Null was adapted (and bugfixed) from the python cookbook
"""
monitors: callable class instances that record data

Monitors
========

Montors provide the ability to monitor progress as the optimization
is underway. Monitors also can be used to extract and prepare information
for mystic's analysis viewers. Each of mystic's monitors are customizable,
and provide the user with a different type of output. The following
monitors are available::
    - Monitor        -- the basic monitor; only writes to internal state
    - VerboseMonitor -- a verbose monitor; also writes to stdout/stderr
    - LoggingMonitor -- a logging monitor; also writes to a logfile
    - CustomMonitor  -- a customizable 'n-variable' version of Monitor
    - Null           -- a null object, which reliably does nothing

Usage
=====

Typically monitors are either bound to a model function by a modelFactory,
or bound to a cost function by a Solver.  The typical usage pattern is::

    >>> # get and configure monitors
    >>> from mystic.monitors import Monitor, VerboseMonitor
    >>> evalmon = Monitor()
    >>> stepmon = VerboseMonitor(5)
    >>>
    >>> # instantiate and configure the solver
    >>> from mystic.solvers import NelderMeadSimplexSolver
    >>> from mystic.termination import CandidateRelativeTolerance as CRT
    >>> solver = NelderMeadSimplexSolver(len(x0))
    >>> solver.SetInitialPoints(x0)
    >>>
    >>> # associate the monitor with a solver, then solve
    >>> solver.SetEvaluationMonitor(evalmon)
    >>> solver.SetGenerationMonitor(stepmon)
    >>> solver.Solve(rosen, CRT())
    >>>
    >>> # access the 'iteration' history
    >>> stepmon.x     # parameters after each iteration
    >>> stepmon.y     # cost after each iteration
    >>>
    >>> # access the 'evaluation' history
    >>> evalmon.x     # parameters after each evaluation
    >>> evalmon.y     # cost after each evaluation

"""

class Null(object):
    """A Null object

Null objects always and reliably "do nothing." """
    # optional optimization: ensure only one instance per subclass
    # (essentially just to save memory, no functional difference)
    #
    # from the Python cookbook, but type.__new__ replaced by object.__new__
    #
    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls):
            cls._inst = object.__new__(cls) #, *args, **kwargs)
        return cls._inst
    def __init__(self, *args, **kwargs): pass
    def __call__(self, *args, **kwargs): return self
    def __repr__(self): return "Null( )"
    def __nonzero__(self): return False
    def __getattr__(self, name): return self
    def __setattr__(self, name, value): return self
    def __delattr__(self, name): return self

class Monitor(object):
    """
Instances of objects that can be passed as monitors.
Typically, a Monitor logs a list of parameters and the
corresponding costs, retrievable by accessing the Monitor's
member variables.

example usage...
    >>> sow = Monitor()
    >>> sow([1,2],3)
    >>> sow([4,5],6)
    >>> sow.x
    [[1, 2], [4, 5]]
    >>> sow.y
    [3, 6]

    """
    def __init__(self, **kwds):#, all=True):
        self._x = []
        self._y = []
        self._id = []
       #self._all = all

    def __call__(self, x, y, id=None, **kwds):#, best=0):
        from mystic.tools import listify
        self._x.append(listify(x)) #XXX: better to save as-is?
        self._y.append(listify(y)) #XXX: better to save as-is?
        self._id.append(id)
       #if not self._all and list_or_tuple_or_ndarray(x):
       #    self._x[-1] = self._x[-1][best]
       #if not self._all and list_or_tuple_or_ndarray(y):
       #    self._y[-1] = self._y[-1][best]

    def get_x(self):
        return self._x

    def get_y(self):
        return self._y

    def get_id(self):
        return self._id

    x = property(get_x, doc = "Params")
    y = property(get_y, doc = "Costs")
    id = property(get_id, doc = "Id")
    pass

class VerboseMonitor(Monitor):
    """A verbose version of the basic Monitor.

Prints ChiSq every 'interval', and optionally prints
current parameters every 'xinterval'.
    """
    import numpy
    def __init__(self, interval = 10, xinterval = numpy.inf, all=True):
        super(VerboseMonitor,self).__init__()
        self._step = 0
        self._yinterval = interval
        self._xinterval = xinterval
        self._all = all
        return
    def __call__(self, x, y, id=None, best=0):
        from mystic.tools import list_or_tuple_or_ndarray
        super(VerboseMonitor,self).__call__(x, y, id)
        if int(self._step % self._yinterval) == 0:
            if not list_or_tuple_or_ndarray(y):
                who = ''
                y = " %f" % self._y[-1]
            elif self._all:
                who = ''
                y = " %s" % self._y[-1]
            else:
                who = ' best'
                y = " %f" % self._y[-1][best]
            msg = "Generation %d has%s Chi-Squared:%s" % (self._step, who, y)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        if int(self._step % self._xinterval) == 0:
            if not list_or_tuple_or_ndarray(x):
                who = ''
                x = " %f" % self._x[-1]
            elif self._all:
                who = ''
                x = "\n %s" % self._x[-1]
            else:
                who = ' best'
                x = "\n %s" % self._x[-1][best]
            msg = "Generation %d has%s fit parameters:%s" % (self._step, who, x)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        self._step += 1
        return
    pass

class LoggingMonitor(Monitor):
    """A basic Monitor that writes to a file at specified intervals.

Logs ChiSq and parameters to a file every 'interval'
    """
    import numpy
    def __init__(self, interval=1, filename='log.txt', new=False, all=True):
        import datetime
        super(LoggingMonitor,self).__init__()
        self._filename = filename
        self._step = 0
        self._yinterval = interval
        self._xinterval = interval
        if new: ind = 'w'
        else: ind = 'a'
        self._file = open(self._filename,ind)
        self._file.write("# %s\n" % datetime.datetime.now().ctime() )
        self._file.write("# ___#___  __ChiSq__  __params__\n")
        self._file.close()
        self._all = all
        return
    def __call__(self, x, y, id=None, best=0):
        from mystic.tools import list_or_tuple_or_ndarray
        self._file = open(self._filename,'a')
        super(LoggingMonitor,self).__call__(x, y, id)
        if int(self._step % self._yinterval) == 0:
            if not list_or_tuple_or_ndarray(y):
                y = "%f" % self._y[-1]
            elif self._all:
                y = "%s" % self._y[-1]
            else:
                y = "%f" % self._y[-1][best]
            if not list_or_tuple_or_ndarray(x):
                x = "[%f]" % self._x[-1]
            elif self._all:
                xa = self._x[-1]
                if not list_or_tuple_or_ndarray(xa):
                  x = "[%f]" % xa
                else:
                  x = "%s" % xa
            else:
                xb = self._x[-1][best]
                if not list_or_tuple_or_ndarray(xb):
                  x = "[%f]" % xb
                else:
                  x = "%s" % xb
            step = [self._step]
            if id != None: step.append(id)
            self._file.write("  %s     %s   %s\n" % (tuple(step), y, x))
        self._step += 1
        self._file.close()
        return
    pass

def CustomMonitor(*args,**kwds):
    """
generate a custom Monitor

takes *args & **kwds, where args will be required inputs for the Monitor::
    - args: property name strings (i.e. 'x')
    - kwds: must be in the form: property="doc" (i.e. x='Params')

example usage...
    >>> sow = CustomMonitor('x','y',x="Params",y="Costs",e="Error",d="Deriv")
    >>> sow(1,1)
    >>> sow(2,4,e=0)
    >>> sow.x
    [1,2]
    >>> sow.y
    [1,4]
    >>> sow.e
    [0]
    >>> sow.d
    []
    """
    from _genSow import genSow
    return genSow(**kwds)(*args)

# end of file
<commit_msg>added VerboseLoggingMonitor<commit_after>#!/usr/bin/env python
#
# Null was adapted (and bugfixed) from the python cookbook
"""
monitors: callable class instances that record data

Monitors
========

Montors provide the ability to monitor progress as the optimization
is underway. Monitors also can be used to extract and prepare information
for mystic's analysis viewers. Each of mystic's monitors are customizable,
and provide the user with a different type of output. The following
monitors are available::
    - Monitor        -- the basic monitor; only writes to internal state
    - LoggingMonitor -- a logging monitor; also writes to a logfile
    - VerboseMonitor -- a verbose monitor; also writes to stdout/stderr
    - VerboseLoggingMonitor -- a verbose logging monitor; best of both worlds
    - CustomMonitor  -- a customizable 'n-variable' version of Monitor
    - Null           -- a null object, which reliably does nothing

Usage
=====

Typically monitors are either bound to a model function by a modelFactory,
or bound to a cost function by a Solver.  The typical usage pattern is::

    >>> # get and configure monitors
    >>> from mystic.monitors import Monitor, VerboseMonitor
    >>> evalmon = Monitor()
    >>> stepmon = VerboseMonitor(5)
    >>>
    >>> # instantiate and configure the solver
    >>> from mystic.solvers import NelderMeadSimplexSolver
    >>> from mystic.termination import CandidateRelativeTolerance as CRT
    >>> solver = NelderMeadSimplexSolver(len(x0))
    >>> solver.SetInitialPoints(x0)
    >>>
    >>> # associate the monitor with a solver, then solve
    >>> solver.SetEvaluationMonitor(evalmon)
    >>> solver.SetGenerationMonitor(stepmon)
    >>> solver.Solve(rosen, CRT())
    >>>
    >>> # access the 'iteration' history
    >>> stepmon.x     # parameters after each iteration
    >>> stepmon.y     # cost after each iteration
    >>>
    >>> # access the 'evaluation' history
    >>> evalmon.x     # parameters after each evaluation
    >>> evalmon.y     # cost after each evaluation

"""

class Null(object):
    """A Null object

Null objects always and reliably "do nothing." """
    # optional optimization: ensure only one instance per subclass
    # (essentially just to save memory, no functional difference)
    #
    # from the Python cookbook, but type.__new__ replaced by object.__new__
    #
    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls):
            cls._inst = object.__new__(cls) #, *args, **kwargs)
        return cls._inst
    def __init__(self, *args, **kwargs): pass
    def __call__(self, *args, **kwargs): return self
    def __repr__(self): return "Null( )"
    def __nonzero__(self): return False
    def __getattr__(self, name): return self
    def __setattr__(self, name, value): return self
    def __delattr__(self, name): return self

class Monitor(object):
    """
Instances of objects that can be passed as monitors.
Typically, a Monitor logs a list of parameters and the
corresponding costs, retrievable by accessing the Monitor's
member variables.

example usage...
    >>> sow = Monitor()
    >>> sow([1,2],3)
    >>> sow([4,5],6)
    >>> sow.x
    [[1, 2], [4, 5]]
    >>> sow.y
    [3, 6]

    """
    def __init__(self, **kwds):#, all=True):
        self._x = []
        self._y = []
        self._id = []
       #self._all = all

    def __call__(self, x, y, id=None, **kwds):#, best=0):
        from mystic.tools import listify
        self._x.append(listify(x)) #XXX: better to save as-is?
        self._y.append(listify(y)) #XXX: better to save as-is?
        self._id.append(id)
       #if not self._all and list_or_tuple_or_ndarray(x):
       #    self._x[-1] = self._x[-1][best]
       #if not self._all and list_or_tuple_or_ndarray(y):
       #    self._y[-1] = self._y[-1][best]

    def get_x(self):
        return self._x

    def get_y(self):
        return self._y

    def get_id(self):
        return self._id

    x = property(get_x, doc = "Params")
    y = property(get_y, doc = "Costs")
    id = property(get_id, doc = "Id")
    pass

class VerboseMonitor(Monitor):
    """A verbose version of the basic Monitor.

Prints ChiSq every 'interval', and optionally prints
current parameters every 'xinterval'.
    """
    import numpy
    def __init__(self, interval = 10, xinterval = numpy.inf, all=True):
        super(VerboseMonitor,self).__init__()
        self._step = 0
        self._yinterval = interval
        self._xinterval = xinterval
        self._all = all
        return
    def __call__(self, x, y, id=None, best=0):
        from mystic.tools import list_or_tuple_or_ndarray
        super(VerboseMonitor,self).__call__(x, y, id)
        if int(self._step % self._yinterval) == 0:
            if not list_or_tuple_or_ndarray(y):
                who = ''
                y = " %f" % self._y[-1]
            elif self._all:
                who = ''
                y = " %s" % self._y[-1]
            else:
                who = ' best'
                y = " %f" % self._y[-1][best]
            msg = "Generation %d has%s Chi-Squared:%s" % (self._step, who, y)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        if int(self._step % self._xinterval) == 0:
            if not list_or_tuple_or_ndarray(x):
                who = ''
                x = " %f" % self._x[-1]
            elif self._all:
                who = ''
                x = "\n %s" % self._x[-1]
            else:
                who = ' best'
                x = "\n %s" % self._x[-1][best]
            msg = "Generation %d has%s fit parameters:%s" % (self._step, who, x)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        self._step += 1
        return
    pass

class LoggingMonitor(Monitor):
    """A basic Monitor that writes to a file at specified intervals.

Logs ChiSq and parameters to a file every 'interval'
    """
    import numpy
    def __init__(self, interval=1, filename='log.txt', new=False, all=True):
        import datetime
        super(LoggingMonitor,self).__init__()
        self._filename = filename
        self._step = 0
        self._yinterval = interval
        self._xinterval = interval
        if new: ind = 'w'
        else: ind = 'a'
        self._file = open(self._filename,ind)
        self._file.write("# %s\n" % datetime.datetime.now().ctime() )
        self._file.write("# ___#___  __ChiSq__  __params__\n")
        self._file.close()
        self._all = all
        return
    def __call__(self, x, y, id=None, best=0):
        from mystic.tools import list_or_tuple_or_ndarray
        self._file = open(self._filename,'a')
        super(LoggingMonitor,self).__call__(x, y, id)
        if int(self._step % self._yinterval) == 0:
            if not list_or_tuple_or_ndarray(y):
                y = "%f" % self._y[-1]
            elif self._all:
                y = "%s" % self._y[-1]
            else:
                y = "%f" % self._y[-1][best]
            if not list_or_tuple_or_ndarray(x):
                x = "[%f]" % self._x[-1]
            elif self._all:
                xa = self._x[-1]
                if not list_or_tuple_or_ndarray(xa):
                  x = "[%f]" % xa
                else:
                  x = "%s" % xa
            else:
                xb = self._x[-1][best]
                if not list_or_tuple_or_ndarray(xb):
                  x = "[%f]" % xb
                else:
                  x = "%s" % xb
            step = [self._step]
            if id != None: step.append(id)
            self._file.write("  %s     %s   %s\n" % (tuple(step), y, x))
        self._step += 1
        self._file.close()
        return
    pass

class VerboseLoggingMonitor(LoggingMonitor):
    """A Monitor that writes to a file and the screen at specified intervals.

Logs ChiSq and parameters to a file every 'interval', print every 'yinterval'
    """
    import numpy
    def __init__(self, interval=1, yinterval=10, xinterval=numpy.inf, filename='log.txt', new=False, all=True):
        super(VerboseLoggingMonitor,self).__init__(interval,filename,new,all)
        self._vyinterval = yinterval
        self._vxinterval = xinterval
        return
    def __call__(self, x, y, id=None, best=0):
        from mystic.tools import list_or_tuple_or_ndarray
        super(VerboseLoggingMonitor,self).__call__(x, y, id, best)
        self._step += -1  # rollback step counter (incremented in super call)
        if int(self._step % self._vyinterval) == 0:
            if not list_or_tuple_or_ndarray(y):
                who = ''
                y = " %f" % self._y[-1]
            elif self._all:
                who = ''
                y = " %s" % self._y[-1]
            else:
                who = ' best'
                y = " %f" % self._y[-1][best]
            msg = "Generation %d has%s Chi-Squared:%s" % (self._step, who, y)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        if int(self._step % self._vxinterval) == 0:
            if not list_or_tuple_or_ndarray(x):
                who = ''
                x = " %f" % self._x[-1]
            elif self._all:
                who = ''
                x = "\n %s" % self._x[-1]
            else:
                who = ' best'
                x = "\n %s" % self._x[-1][best]
            msg = "Generation %d has%s fit parameters:%s" % (self._step, who, x)
            if id != None: msg = "[id: %d] " % (id) + msg
            print msg
        self._step += 1
        return
    pass

def CustomMonitor(*args,**kwds):
    """
generate a custom Monitor

takes *args & **kwds, where args will be required inputs for the Monitor::
    - args: property name strings (i.e. 'x')
    - kwds: must be in the form: property="doc" (i.e. x='Params')

example usage...
    >>> sow = CustomMonitor('x','y',x="Params",y="Costs",e="Error",d="Deriv")
    >>> sow(1,1)
    >>> sow(2,4,e=0)
    >>> sow.x
    [1,2]
    >>> sow.y
    [1,4]
    >>> sow.e
    [0]
    >>> sow.d
    []
    """
    from _genSow import genSow
    return genSow(**kwds)(*args)

# end of file
<|endoftext|>


<commit_before>"""
:class:`.YahooPlaceFinder` geocoder.
"""

from functools import partial

try:
    from requests import get, Request
    from requests_oauthlib import OAuth1
    requests_missing = False
except ImportError:
    requests_missing = True

from geopy.geocoders.base import Geocoder, DEFAULT_TIMEOUT
from geopy.exc import GeocoderParseError
from geopy.location import Location
from geopy.compat import string_compare, py3k

__all__ = ("YahooPlaceFinder", )

class YahooPlaceFinder(Geocoder): # pylint: disable=W0223
    """
    Geocoder that utilizes the Yahoo! BOSS PlaceFinder API. Documentation at:
        https://developer.yahoo.com/boss/geo/docs/
    """

    def __init__(
            self,
            consumer_key,
            consumer_secret,
            timeout=DEFAULT_TIMEOUT,
            proxies=None,
            user_agent=None,
        ):  # pylint: disable=R0913
        """
        :param string consumer_key: Key provided by Yahoo.

        :param string consumer_secret: Secret corresponding to the key
            provided by Yahoo.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception.

        :param dict proxies: If specified, routes this geocoder"s requests
            through the specified proxy. E.g., {"https": "192.0.2.0"}. For
            more information, see documentation on
            :class:`urllib2.ProxyHandler`.

            .. versionadded:: 0.96
        """
        if requests_missing:
            raise ImportError(
                'requests-oauthlib is needed for YahooPlaceFinder.'
                ' Install with `pip install geopy -e ".[placefinder]"`.'
            )
        super(YahooPlaceFinder, self).__init__(
            timeout=timeout, proxies=proxies, user_agent=user_agent
        )
        self.consumer_key = (
            unicode(consumer_key)
            if not py3k
            else str(consumer_key)
        )
        self.consumer_secret = (
            unicode(consumer_secret)
            if not py3k
            else str(consumer_secret)
        )
        self.auth = OAuth1(
            client_key=self.consumer_key,
            client_secret=self.consumer_secret,
            signature_method="HMAC-SHA1",
            signature_type="AUTH_HEADER",
        )
        self.api = "https://yboss.yahooapis.com/geo/placefinder"

    @staticmethod
    def _filtered_results(results, min_quality, valid_country_codes):
        """
        Returns only the results that meet the minimum quality threshold
        and are located in expected countries.
        """
        if min_quality:
            results = [
                loc
                for loc in results
                if int(loc.raw["quality"]) > min_quality
            ]

        if valid_country_codes:
            results = [
                loc
                for loc in results
                if loc.raw["countrycode"] in valid_country_codes
            ]

        return results

    def _parse_response(self, content):
        """
        Returns the parsed result of a PlaceFinder API call.
        """
        try:
            placefinder = (
                content["bossresponse"]["placefinder"]
            )
            if not len(placefinder) or not len(placefinder.get("results", [])):
                return None
            results = [
                Location(
                    self.humanize(place),
                    (float(place["latitude"]), float(place["longitude"])),
                    raw=place
                )
                for place in placefinder["results"]
            ]
        except (KeyError, ValueError):
            raise GeocoderParseError("Error parsing PlaceFinder result")

        return results

    @staticmethod
    def humanize(location):
        """
        Returns a human readable representation of a raw PlaceFinder location
        """
        return ", ".join([
            location[line]
            for line in ["line1", "line2", "line3", "line4"]
            if location[line]
        ])

    def geocode(
            self,
            query,
            exactly_one=True,
            timeout=None,
            min_quality=0,
            reverse=False,
            valid_country_codes=None,
            with_timezone=False,
        ):  # pylint: disable=W0221,R0913
        """
        Geocode a location query.

        :param string query: The address or query you wish to geocode.

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int min_quality:

        :param bool reverse:

        :param valid_country_codes:
        :type valid_country_codes: list or tuple

        :param bool with_timezone: Include the timezone in the response's
            `raw` dictionary (as `timezone`).
        """
        params = {
            "location": query,
            "flags": "J", # JSON
        }

        if reverse is True:
            params["gflags"] = "R"
        if exactly_one is True:
            params["count"] = "1"
        if with_timezone is True:
            params['flags'] += 'T' #Return timezone

        response = self._call_geocoder(
            self.api,
            timeout=timeout,
            requester=get,
            params=params,
            auth=self.auth,
        )
        results = self._parse_response(response)
        if results is None:
            return None

        results = self._filtered_results(
            results,
            min_quality,
            valid_country_codes,
        )

        if exactly_one:
            return results[0]
        else:
            return results

    def reverse(self, query, exactly_one=True, timeout=None):
        """
        Returns a reverse geocoded location using Yahoo"s PlaceFinder API.

        :param query: The coordinates for which you wish to obtain the
            closest human-readable addresses.
        :type query: :class:`geopy.point.Point`, list or tuple of (latitude,
            longitude), or string as "%(latitude)s, %(longitude)s"

        :param bool exactly_one: Return one result or a list of results, if
            available.
        """
        query = self._coerce_point_to_string(query)
        if isinstance(query, string_compare):
            query = query.replace(" ", "") # oauth signature failure; todo
        return self.geocode(
            query,
            exactly_one=exactly_one,
            timeout=timeout,
            reverse=True
        )
<commit_msg>Adds locale to placefinder and min_quality to reverse placefinder<commit_after>"""
:class:`.YahooPlaceFinder` geocoder.
"""

from functools import partial

try:
    from requests import get, Request
    from requests_oauthlib import OAuth1
    requests_missing = False
except ImportError:
    requests_missing = True

from geopy.geocoders.base import Geocoder, DEFAULT_TIMEOUT
from geopy.exc import GeocoderParseError
from geopy.location import Location
from geopy.compat import string_compare, py3k

__all__ = ("YahooPlaceFinder", )

class YahooPlaceFinder(Geocoder): # pylint: disable=W0223
    """
    Geocoder that utilizes the Yahoo! BOSS PlaceFinder API. Documentation at:
        https://developer.yahoo.com/boss/geo/docs/
    """

    def __init__(
            self,
            consumer_key,
            consumer_secret,
            timeout=DEFAULT_TIMEOUT,
            proxies=None,
            user_agent=None,
        ):  # pylint: disable=R0913
        """
        :param string consumer_key: Key provided by Yahoo.

        :param string consumer_secret: Secret corresponding to the key
            provided by Yahoo.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception.

        :param dict proxies: If specified, routes this geocoder"s requests
            through the specified proxy. E.g., {"https": "192.0.2.0"}. For
            more information, see documentation on
            :class:`urllib2.ProxyHandler`.

            .. versionadded:: 0.96
        """
        if requests_missing:
            raise ImportError(
                'requests-oauthlib is needed for YahooPlaceFinder.'
                ' Install with `pip install geopy -e ".[placefinder]"`.'
            )
        super(YahooPlaceFinder, self).__init__(
            timeout=timeout, proxies=proxies, user_agent=user_agent
        )
        self.consumer_key = (
            unicode(consumer_key)
            if not py3k
            else str(consumer_key)
        )
        self.consumer_secret = (
            unicode(consumer_secret)
            if not py3k
            else str(consumer_secret)
        )
        self.auth = OAuth1(
            client_key=self.consumer_key,
            client_secret=self.consumer_secret,
            signature_method="HMAC-SHA1",
            signature_type="AUTH_HEADER",
        )
        self.api = "https://yboss.yahooapis.com/geo/placefinder"

    @staticmethod
    def _filtered_results(results, min_quality, valid_country_codes):
        """
        Returns only the results that meet the minimum quality threshold
        and are located in expected countries.
        """
        if min_quality:
            results = [
                loc
                for loc in results
                if int(loc.raw["quality"]) > min_quality
            ]

        if valid_country_codes:
            results = [
                loc
                for loc in results
                if loc.raw["countrycode"] in valid_country_codes
            ]

        return results

    def _parse_response(self, content):
        """
        Returns the parsed result of a PlaceFinder API call.
        """
        try:
            placefinder = (
                content["bossresponse"]["placefinder"]
            )
            if not len(placefinder) or not len(placefinder.get("results", [])):
                return None
            results = [
                Location(
                    self.humanize(place),
                    (float(place["latitude"]), float(place["longitude"])),
                    raw=place
                )
                for place in placefinder["results"]
            ]
        except (KeyError, ValueError):
            raise GeocoderParseError("Error parsing PlaceFinder result")

        return results

    @staticmethod
    def humanize(location):
        """
        Returns a human readable representation of a raw PlaceFinder location
        """
        return ", ".join([
            location[line]
            for line in ["line1", "line2", "line3", "line4"]
            if location[line]
        ])

    def geocode(
            self,
            query,
            exactly_one=True,
            timeout=None,
            min_quality=0,
            reverse=False,
            valid_country_codes=None,
            with_timezone=False,
            locale=None,
        ):  # pylint: disable=W0221,R0913
        """
        Geocode a location query.

        :param string query: The address or query you wish to geocode.

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int min_quality:

        :param bool reverse:

        :param valid_country_codes:
        :type valid_country_codes: list or tuple

        :param bool with_timezone: Include the timezone in the response's
            `raw` dictionary (as `timezone`).
        """
        params = {
            "location": query,
            "flags": "J", # JSON
        }

        if reverse is True:
            params["gflags"] = "R"
        if exactly_one is True:
            params["count"] = "1"
        if with_timezone is True:
            params['flags'] += 'T' #Return timezone
        if locale:
            params["locale"] = locale

        response = self._call_geocoder(
            self.api,
            timeout=timeout,
            requester=get,
            params=params,
            auth=self.auth,
        )
        results = self._parse_response(response)
        if results is None:
            return None

        results = self._filtered_results(
            results,
            min_quality,
            valid_country_codes,
        )

        if exactly_one:
            return results[0]
        else:
            return results

    def reverse(self, query, exactly_one=True, timeout=None, min_quality=0, locale=None):
        """
        Returns a reverse geocoded location using Yahoo"s PlaceFinder API.

        :param query: The coordinates for which you wish to obtain the
            closest human-readable addresses.
        :type query: :class:`geopy.point.Point`, list or tuple of (latitude,
            longitude), or string as "%(latitude)s, %(longitude)s"

        :param bool exactly_one: Return one result or a list of results, if
            available.
        """
        query = self._coerce_point_to_string(query)
        if isinstance(query, string_compare):
            query = query.replace(" ", "") # oauth signature failure; todo
        return self.geocode(
            query,
            exactly_one=exactly_one,
            timeout=timeout,
            reverse=True,
            min_quality=min_quality,
            locale=locale
        )
<|endoftext|>


<commit_before>"""
    sphinxcontrib.openapi.openapi30
    -------------------------------

    The OpenAPI 3.0.0 spec renderer. Based on ``sphinxcontrib-httpdomain``.

    :copyright: (c) 2016, Ihor Kalnytskyi.
    :license: BSD, see LICENSE for details.
"""

from __future__ import unicode_literals

import copy
import collections
from datetime import datetime
import itertools
import json

import six
from sphinx.util import logging

from sphinxcontrib.openapi import utils

try:
    from httplib import responses as http_status_codes  # python2
except ImportError:
    from http.client import responses as http_status_codes  # python3

LOG = logging.getLogger(__name__)

# https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#data-types
_TYPE_MAPPING = {
    ('integer', 'int32'): 1,  # integer
    ('integer', 'int64'): 1,  # long
    ('number', 'float'): 1.0,  # float
    ('number', 'double'): 1.0,  # double
    ('boolean', None): True,  # boolean
    ('string', None): 'string',  # string
    ('string', 'byte'): 'c3RyaW5n',  # b'string' encoded in base64,  # byte
    ('string', 'binary'): '01010101',  # binary
    ('string', 'date'): datetime.now().date().isoformat(),  # date
    ('string', 'date-time'): datetime.now().isoformat(),  # dateTime
    ('string', 'password'): '********',  # password

    # custom extensions to handle common formats
    ('string', 'email'): 'name@example.com',
    ('string', 'zip-code'): '90210',
    ('string', 'uri'): 'https://example.com',

    # additional fallthrough cases
    ('integer', None): 1,  # integer
    ('number', None): 1.0,  # <fallthrough>
}

_READONLY_PROPERTY = object()  # sentinel for values not included in requests

def _dict_merge(dct, merge_dct):
    """Recursive dict merge.

    Inspired by :meth:``dict.update()``, instead of updating only top-level
    keys, dict_merge recurses down into dicts nested to an arbitrary depth,
    updating keys. The ``merge_dct`` is merged into ``dct``.

    From https://gist.github.com/angstwad/bf22d1822c38a92ec0a9

    Arguments:
        dct: dict onto which the merge is executed
        merge_dct: dct merged into dct
    """
    for k, v in merge_dct.items():
        if (k in dct and isinstance(dct[k], dict)
                and isinstance(merge_dct[k], collections.Mapping)):
            _dict_merge(dct[k], merge_dct[k])
        else:
            dct[k] = merge_dct[k]

def _parse_schema(schema, method):
    """
    Convert a Schema Object to a Python object.

    Args:
        schema: An ``OrderedDict`` representing the schema object.
    """
    if method and schema.get('readOnly', False):
        return _READONLY_PROPERTY

    # allOf: Must be valid against all of the subschemas
    if 'allOf' in schema:
        schema_ = copy.deepcopy(schema['allOf'][0])
        for x in schema['allOf'][1:]:
            _dict_merge(schema_, x)

        return _parse_schema(schema_, method)

    # anyOf: Must be valid against any of the subschemas
    # TODO(stephenfin): Handle anyOf

    # oneOf: Must be valid against exactly one of the subschemas
    if 'oneOf' in schema:
        # we only show the first one since we can't show everything
        return _parse_schema(schema['oneOf'][0], method)

    if 'enum' in schema:
        # we only show the first one since we can't show everything
        return schema['enum'][0]

    schema_type = schema.get('type', 'object')

    if schema_type == 'array':
        # special case oneOf so that we can show examples for all possible
        # combinations
        if 'oneOf' in schema['items']:
            return [
                _parse_schema(x, method) for x in schema['items']['oneOf']]

        return [_parse_schema(schema['items'], method)]

    if schema_type == 'object':
        if method and all(v.get('readOnly', False)
                          for v in schema['properties'].values()):
            return _READONLY_PROPERTY

        results = []
        for name, prop in schema.get('properties', {}).items():
            result = _parse_schema(prop, method)
            if result != _READONLY_PROPERTY:
                results.append((name, result))

        return collections.OrderedDict(results)

    if (schema_type, schema.get('format')) in _TYPE_MAPPING:
        return _TYPE_MAPPING[(schema_type, schema.get('format'))]

    return _TYPE_MAPPING[(schema_type, None)]  # unrecognized format

def _example(media_type_objects, method=None, endpoint=None, status=None,
             nb_indent=0):
    """
    Format examples in `Media Type Object` openapi v3 to HTTP request or
    HTTP response example.
    If method and endpoint is provided, this function prints a request example
    else status should be provided to print a response example.

    Arguments:
        media_type_objects (Dict[str, Dict]): Dict containing
            Media Type Objects.
        method: The HTTP method to use in example.
        endpoint: The HTTP route to use in example.
        status: The HTTP status to use in example.
    """
    indent = '   '
    extra_indent = indent * nb_indent

    if method is not None:
        method = method.upper()
    else:
        try:
            # one of possible values for status might be 'default'.
            # in the case, just fallback to '-'
            status_text = http_status_codes[int(status)]
        except (ValueError, KeyError):
            status_text = '-'

    for content_type, content in media_type_objects.items():
        examples = content.get('examples')
        example = content.get('example')

        if examples is None:
            examples = {}
            if not example:
                if content_type != 'application/json':
                    LOG.info('skipping non-JSON example generation.')
                    continue
                example = _parse_schema(content['schema'], method=method)

            if method is None:
                examples['Example response'] = {
                    'value': example,
                }
            else:
                examples['Example request'] = {
                    'value': example,
                }

        for example in examples.values():
            if not isinstance(example['value'], six.string_types):
                example['value'] = json.dumps(
                    example['value'], indent=4, separators=(',', ': '))

        for example_name, example in examples.items():
            if 'summary' in example:
                example_title = '{example_name} - {example[summary]}'.format(
                    **locals())
            else:
                example_title = example_name

            yield ''
            yield '{extra_indent}**{example_title}:**'.format(**locals())
            yield ''
            yield '{extra_indent}.. sourcecode:: http'.format(**locals())
            yield ''

            # Print http request example
            if method:
                yield '{extra_indent}{indent}{method} {endpoint} HTTP/1.1' \
                    .format(**locals())
                yield '{extra_indent}{indent}Host: example.com' \
                    .format(**locals())
                yield '{extra_indent}{indent}Content-Type: {content_type}' \
                    .format(**locals())

            # Print http response example
            else:
                yield '{extra_indent}{indent}HTTP/1.1 {status} {status_text}' \
                    .format(**locals())
                yield '{extra_indent}{indent}Content-Type: {content_type}' \
                    .format(**locals())

            yield ''
            for example_line in example['value'].splitlines():
                yield '{extra_indent}{indent}{example_line}'.format(**locals())
            yield ''

def _httpresource(endpoint, method, properties, convert, render_examples, render_request):
    # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#operation-object
    parameters = properties.get('parameters', [])
    responses = properties['responses']
    indent = '   '

    yield '.. http:{0}:: {1}'.format(method, endpoint)
    yield '   :synopsis: {0}'.format(properties.get('summary', 'null'))
    yield ''

    if 'summary' in properties:
        for line in properties['summary'].splitlines():
            yield '{indent}**{line}**'.format(**locals())
        yield ''

    if 'description' in properties:
        for line in convert(properties['description']).splitlines():
            yield '{indent}{line}'.format(**locals())
        yield ''

    # print request's path params
    for param in filter(lambda p: p['in'] == 'path', parameters):
        yield indent + ':param {type} {name}:'.format(
            type=param['schema']['type'],
            name=param['name'])

        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())

    # print request's query params
    for param in filter(lambda p: p['in'] == 'query', parameters):
        yield indent + ':query {type} {name}:'.format(
            type=param['schema']['type'],
            name=param['name'])
        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())
        if param.get('required', False):
            yield '{indent}{indent}(Required)'.format(**locals())

    # print request content
    if render_request:
        request_content = properties.get('requestBody', {}).get('content', {})
        if request_content and request_content['application/json']:
            schema = request_content['application/json']['schema']
            req_properties = json.dumps(schema['properties'], indent=2,
                                        separators=(',', ':'))
            yield '{indent}**Request body:**'.format(**locals())
            yield ''
            yield '{indent}.. sourcecode:: json'.format(**locals())
            yield ''
            for line in req_properties.splitlines():
                # yield indent + line
                yield '{indent}{indent}{line}'.format(**locals())
                # yield ''

    # print request example
    if render_examples:
        request_content = properties.get('requestBody', {}).get('content', {})
        for line in _example(
                request_content, method, endpoint=endpoint, nb_indent=1):
            yield line

    # print response status codes
    for status, response in responses.items():
        yield '{indent}:status {status}:'.format(**locals())
        for line in convert(response['description']).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())

        # print response example
        if render_examples:
            for line in _example(
                    response.get('content', {}), status=status, nb_indent=2):
                yield line

    # print request header params
    for param in filter(lambda p: p['in'] == 'header', parameters):
        yield indent + ':reqheader {name}:'.format(**param)
        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())
        if param.get('required', False):
            yield '{indent}{indent}(Required)'.format(**locals())

    # print response headers
    for status, response in responses.items():
        for headername, header in response.get('headers', {}).items():
            yield indent + ':resheader {name}:'.format(name=headername)
            for line in convert(header['description']).splitlines():
                yield '{indent}{indent}{line}'.format(**locals())

    for cb_name, cb_specs in properties.get('callbacks', {}).items():
        yield ''
        yield indent + '.. admonition:: Callback: ' + cb_name
        yield ''

        for cb_endpoint in cb_specs.keys():
            for cb_method, cb_properties in cb_specs[cb_endpoint].items():
                for line in _httpresource(
                        cb_endpoint,
                        cb_method,
                        cb_properties,
                        convert=convert,
                        render_examples=render_examples):
                    if line:
                        yield indent+indent+line
                    else:
                        yield ''

    yield ''

def _header(title):
    yield title
    yield '=' * len(title)
    yield ''

def openapihttpdomain(spec, **options):
    generators = []

    # OpenAPI spec may contain JSON references, common properties, etc.
    # Trying to render the spec "As Is" will require to put multiple
    # if-s around the code. In order to simplify flow, let's make the
    # spec to have only one (expected) schema, i.e. normalize it.
    utils.normalize_spec(spec, **options)

    # If 'paths' are passed we've got to ensure they exist within an OpenAPI
    # spec; otherwise raise error and ask user to fix that.
    if 'paths' in options:
        if not set(options['paths']).issubset(spec['paths']):
            raise ValueError(
                'One or more paths are not defined in the spec: %s.' % (
                    ', '.join(set(options['paths']) - set(spec['paths'])),
                )
            )

    render_request = False
    if 'request' in options:
        render_request = True

    convert = utils.get_text_converter(options)

    # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#paths-object
    if 'group' in options:
        groups = collections.defaultdict(list)

        for endpoint in options.get('paths', spec['paths']):
            for method, properties in spec['paths'][endpoint].items():
                key = properties.get('tags', [''])[0]
                groups[key].append(_httpresource(
                    endpoint,
                    method,
                    properties,

                    convert,
                    render_examples='examples' in options,
                    render_request=render_request))

        for key in sorted(groups.keys()):
            if key:
                generators.append(_header(key))
            else:
                generators.append(_header('default'))

            generators.extend(groups[key])
    else:
        for endpoint in options.get('paths', spec['paths']):
            for method, properties in spec['paths'][endpoint].items():
                generators.append(_httpresource(
                    endpoint,
                    method,
                    properties,
                    convert,
                    render_examples='examples' in options,
                    render_request=render_request))

    return iter(itertools.chain(*generators))
<commit_msg>RequestBody: Cut the statement length below 80 chars as requested by the test."<commit_after>"""
    sphinxcontrib.openapi.openapi30
    -------------------------------

    The OpenAPI 3.0.0 spec renderer. Based on ``sphinxcontrib-httpdomain``.

    :copyright: (c) 2016, Ihor Kalnytskyi.
    :license: BSD, see LICENSE for details.
"""

from __future__ import unicode_literals

import copy
import collections
from datetime import datetime
import itertools
import json

import six
from sphinx.util import logging

from sphinxcontrib.openapi import utils

try:
    from httplib import responses as http_status_codes  # python2
except ImportError:
    from http.client import responses as http_status_codes  # python3

LOG = logging.getLogger(__name__)

# https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#data-types
_TYPE_MAPPING = {
    ('integer', 'int32'): 1,  # integer
    ('integer', 'int64'): 1,  # long
    ('number', 'float'): 1.0,  # float
    ('number', 'double'): 1.0,  # double
    ('boolean', None): True,  # boolean
    ('string', None): 'string',  # string
    ('string', 'byte'): 'c3RyaW5n',  # b'string' encoded in base64,  # byte
    ('string', 'binary'): '01010101',  # binary
    ('string', 'date'): datetime.now().date().isoformat(),  # date
    ('string', 'date-time'): datetime.now().isoformat(),  # dateTime
    ('string', 'password'): '********',  # password

    # custom extensions to handle common formats
    ('string', 'email'): 'name@example.com',
    ('string', 'zip-code'): '90210',
    ('string', 'uri'): 'https://example.com',

    # additional fallthrough cases
    ('integer', None): 1,  # integer
    ('number', None): 1.0,  # <fallthrough>
}

_READONLY_PROPERTY = object()  # sentinel for values not included in requests

def _dict_merge(dct, merge_dct):
    """Recursive dict merge.

    Inspired by :meth:``dict.update()``, instead of updating only top-level
    keys, dict_merge recurses down into dicts nested to an arbitrary depth,
    updating keys. The ``merge_dct`` is merged into ``dct``.

    From https://gist.github.com/angstwad/bf22d1822c38a92ec0a9

    Arguments:
        dct: dict onto which the merge is executed
        merge_dct: dct merged into dct
    """
    for k, v in merge_dct.items():
        if (k in dct and isinstance(dct[k], dict)
                and isinstance(merge_dct[k], collections.Mapping)):
            _dict_merge(dct[k], merge_dct[k])
        else:
            dct[k] = merge_dct[k]

def _parse_schema(schema, method):
    """
    Convert a Schema Object to a Python object.

    Args:
        schema: An ``OrderedDict`` representing the schema object.
    """
    if method and schema.get('readOnly', False):
        return _READONLY_PROPERTY

    # allOf: Must be valid against all of the subschemas
    if 'allOf' in schema:
        schema_ = copy.deepcopy(schema['allOf'][0])
        for x in schema['allOf'][1:]:
            _dict_merge(schema_, x)

        return _parse_schema(schema_, method)

    # anyOf: Must be valid against any of the subschemas
    # TODO(stephenfin): Handle anyOf

    # oneOf: Must be valid against exactly one of the subschemas
    if 'oneOf' in schema:
        # we only show the first one since we can't show everything
        return _parse_schema(schema['oneOf'][0], method)

    if 'enum' in schema:
        # we only show the first one since we can't show everything
        return schema['enum'][0]

    schema_type = schema.get('type', 'object')

    if schema_type == 'array':
        # special case oneOf so that we can show examples for all possible
        # combinations
        if 'oneOf' in schema['items']:
            return [
                _parse_schema(x, method) for x in schema['items']['oneOf']]

        return [_parse_schema(schema['items'], method)]

    if schema_type == 'object':
        if method and all(v.get('readOnly', False)
                          for v in schema['properties'].values()):
            return _READONLY_PROPERTY

        results = []
        for name, prop in schema.get('properties', {}).items():
            result = _parse_schema(prop, method)
            if result != _READONLY_PROPERTY:
                results.append((name, result))

        return collections.OrderedDict(results)

    if (schema_type, schema.get('format')) in _TYPE_MAPPING:
        return _TYPE_MAPPING[(schema_type, schema.get('format'))]

    return _TYPE_MAPPING[(schema_type, None)]  # unrecognized format

def _example(media_type_objects, method=None, endpoint=None, status=None,
             nb_indent=0):
    """
    Format examples in `Media Type Object` openapi v3 to HTTP request or
    HTTP response example.
    If method and endpoint is provided, this function prints a request example
    else status should be provided to print a response example.

    Arguments:
        media_type_objects (Dict[str, Dict]): Dict containing
            Media Type Objects.
        method: The HTTP method to use in example.
        endpoint: The HTTP route to use in example.
        status: The HTTP status to use in example.
    """
    indent = '   '
    extra_indent = indent * nb_indent

    if method is not None:
        method = method.upper()
    else:
        try:
            # one of possible values for status might be 'default'.
            # in the case, just fallback to '-'
            status_text = http_status_codes[int(status)]
        except (ValueError, KeyError):
            status_text = '-'

    for content_type, content in media_type_objects.items():
        examples = content.get('examples')
        example = content.get('example')

        if examples is None:
            examples = {}
            if not example:
                if content_type != 'application/json':
                    LOG.info('skipping non-JSON example generation.')
                    continue
                example = _parse_schema(content['schema'], method=method)

            if method is None:
                examples['Example response'] = {
                    'value': example,
                }
            else:
                examples['Example request'] = {
                    'value': example,
                }

        for example in examples.values():
            if not isinstance(example['value'], six.string_types):
                example['value'] = json.dumps(
                    example['value'], indent=4, separators=(',', ': '))

        for example_name, example in examples.items():
            if 'summary' in example:
                example_title = '{example_name} - {example[summary]}'.format(
                    **locals())
            else:
                example_title = example_name

            yield ''
            yield '{extra_indent}**{example_title}:**'.format(**locals())
            yield ''
            yield '{extra_indent}.. sourcecode:: http'.format(**locals())
            yield ''

            # Print http request example
            if method:
                yield '{extra_indent}{indent}{method} {endpoint} HTTP/1.1' \
                    .format(**locals())
                yield '{extra_indent}{indent}Host: example.com' \
                    .format(**locals())
                yield '{extra_indent}{indent}Content-Type: {content_type}' \
                    .format(**locals())

            # Print http response example
            else:
                yield '{extra_indent}{indent}HTTP/1.1 {status} {status_text}' \
                    .format(**locals())
                yield '{extra_indent}{indent}Content-Type: {content_type}' \
                    .format(**locals())

            yield ''
            for example_line in example['value'].splitlines():
                yield '{extra_indent}{indent}{example_line}'.format(**locals())
            yield ''

def _httpresource(endpoint, method, properties, convert, render_examples,
                  render_request):
    # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#operation-object
    parameters = properties.get('parameters', [])
    responses = properties['responses']
    indent = '   '

    yield '.. http:{0}:: {1}'.format(method, endpoint)
    yield '   :synopsis: {0}'.format(properties.get('summary', 'null'))
    yield ''

    if 'summary' in properties:
        for line in properties['summary'].splitlines():
            yield '{indent}**{line}**'.format(**locals())
        yield ''

    if 'description' in properties:
        for line in convert(properties['description']).splitlines():
            yield '{indent}{line}'.format(**locals())
        yield ''

    # print request's path params
    for param in filter(lambda p: p['in'] == 'path', parameters):
        yield indent + ':param {type} {name}:'.format(
            type=param['schema']['type'],
            name=param['name'])

        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())

    # print request's query params
    for param in filter(lambda p: p['in'] == 'query', parameters):
        yield indent + ':query {type} {name}:'.format(
            type=param['schema']['type'],
            name=param['name'])
        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())
        if param.get('required', False):
            yield '{indent}{indent}(Required)'.format(**locals())

    # print request content
    if render_request:
        request_content = properties.get('requestBody', {}).get('content', {})
        if request_content and request_content['application/json']:
            schema = request_content['application/json']['schema']
            req_properties = json.dumps(schema['properties'], indent=2,
                                        separators=(',', ':'))
            yield '{indent}**Request body:**'.format(**locals())
            yield ''
            yield '{indent}.. sourcecode:: json'.format(**locals())
            yield ''
            for line in req_properties.splitlines():
                # yield indent + line
                yield '{indent}{indent}{line}'.format(**locals())
                # yield ''

    # print request example
    if render_examples:
        request_content = properties.get('requestBody', {}).get('content', {})
        for line in _example(
                request_content, method, endpoint=endpoint, nb_indent=1):
            yield line

    # print response status codes
    for status, response in responses.items():
        yield '{indent}:status {status}:'.format(**locals())
        for line in convert(response['description']).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())

        # print response example
        if render_examples:
            for line in _example(
                    response.get('content', {}), status=status, nb_indent=2):
                yield line

    # print request header params
    for param in filter(lambda p: p['in'] == 'header', parameters):
        yield indent + ':reqheader {name}:'.format(**param)
        for line in convert(param.get('description', '')).splitlines():
            yield '{indent}{indent}{line}'.format(**locals())
        if param.get('required', False):
            yield '{indent}{indent}(Required)'.format(**locals())

    # print response headers
    for status, response in responses.items():
        for headername, header in response.get('headers', {}).items():
            yield indent + ':resheader {name}:'.format(name=headername)
            for line in convert(header['description']).splitlines():
                yield '{indent}{indent}{line}'.format(**locals())

    for cb_name, cb_specs in properties.get('callbacks', {}).items():
        yield ''
        yield indent + '.. admonition:: Callback: ' + cb_name
        yield ''

        for cb_endpoint in cb_specs.keys():
            for cb_method, cb_properties in cb_specs[cb_endpoint].items():
                for line in _httpresource(
                        cb_endpoint,
                        cb_method,
                        cb_properties,
                        convert=convert,
                        render_examples=render_examples):
                    if line:
                        yield indent+indent+line
                    else:
                        yield ''

    yield ''

def _header(title):
    yield title
    yield '=' * len(title)
    yield ''

def openapihttpdomain(spec, **options):
    generators = []

    # OpenAPI spec may contain JSON references, common properties, etc.
    # Trying to render the spec "As Is" will require to put multiple
    # if-s around the code. In order to simplify flow, let's make the
    # spec to have only one (expected) schema, i.e. normalize it.
    utils.normalize_spec(spec, **options)

    # If 'paths' are passed we've got to ensure they exist within an OpenAPI
    # spec; otherwise raise error and ask user to fix that.
    if 'paths' in options:
        if not set(options['paths']).issubset(spec['paths']):
            raise ValueError(
                'One or more paths are not defined in the spec: %s.' % (
                    ', '.join(set(options['paths']) - set(spec['paths'])),
                )
            )

    render_request = False
    if 'request' in options:
        render_request = True

    convert = utils.get_text_converter(options)

    # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#paths-object
    if 'group' in options:
        groups = collections.defaultdict(list)

        for endpoint in options.get('paths', spec['paths']):
            for method, properties in spec['paths'][endpoint].items():
                key = properties.get('tags', [''])[0]
                groups[key].append(_httpresource(
                    endpoint,
                    method,
                    properties,

                    convert,
                    render_examples='examples' in options,
                    render_request=render_request))

        for key in sorted(groups.keys()):
            if key:
                generators.append(_header(key))
            else:
                generators.append(_header('default'))

            generators.extend(groups[key])
    else:
        for endpoint in options.get('paths', spec['paths']):
            for method, properties in spec['paths'][endpoint].items():
                generators.append(_httpresource(
                    endpoint,
                    method,
                    properties,
                    convert,
                    render_examples='examples' in options,
                    render_request=render_request))

    return iter(itertools.chain(*generators))
<|endoftext|>


<commit_before>"""
Atmosphere service tag rest api.

"""

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from core.models import Tag as CoreTag
from api import failure_response
from api.serializers import TagSerializer
from api.permissions import InMaintenance, ApiAuthRequired

class TagList(APIView):
    """
        Tags are a easy way to allow users to group several images as similar
        based on a feature/program of the application.
    """
    permission_classes = (ApiAuthRequired,)

    def get(self, request, *args, **kwargs):
        """
        List all public tags.
        """
        tags = CoreTag.objects.all()
        serializer = TagSerializer(tags, many=True)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        """Create a new tag resource
        Params:name -- Name of the new Tag
        Returns:
        Status Code: 201 Body: A new Tag object
        Status Code: 400 Body: Errors (Duplicate/Invalid Name)
        """
        user = request.user
        data = request.DATA.copy()
        same_name_tags = CoreTag.objects.filter(name__iexact=data['name'])
        if same_name_tags:
            return Response(['A tag with this name already exists: %s'
                             % same_name_tags],
                            status=status.HTTP_400_BAD_REQUEST)
        data['user'] = user.username
        data['name'] = data['name'].lower()
        serializer = TagSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class Tag(APIView):
    """
        Tags are a easy way to allow users to group several images as similar
        based on a feature/program of the application.

        This API resource allows you to Retrieve, Update, or Delete your Tag.
    """
    permission_classes = (ApiAuthRequired,)

    def delete(self, request, tag_slug, *args, **kwargs):
        """
        Remove the tag, if it is no longer in use.
        """
        try:
            tag = CoreTag.objects.get(name__iexact=tag_slug)
        except CoreTag.DoesNotExist:
            return failure_response(status.HTTP_404_NOT_FOUND,
                                    'Tag %s does not exist' % tag_slug)
        if tag.in_use():
            instance_count = tag.instance_set.count()
            app_count = tag.application_set.count()
            return failure_response(
                    status.HTTP_409_CONFLICT,
                    "Tag cannot be deleted while it is in use by"
                             "%s instances and %s applications. "
                             "To delete the tag, first remove "
                             "the tag from ALL objects using it"
                             % (instance_count, app_count))
        tag.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    def get(self, request, tag_slug, *args, **kwargs):
        """
        Return the credential information for this tag
        """
        try:
            tag = CoreTag.objects.get(name__iexact=tag_slug)
        except CoreTag.DoesNotExist:
            return Response(['Tag does not exist'],
                            status=status.HTTP_404_NOT_FOUND)
        serializer = TagSerializer(tag)
        return Response(serializer.data)

    def put(self, request, tag_slug, *args, **kwargs):
        """
        Return the credential information for this tag
        """
        user = request.user
        tag = CoreTag.objects.get(name__iexact=tag_slug)
        if not user.is_staff and user != tag.user:
            return Response([
                'Only the tag creator can update a tag.'
                + 'Contact support if you need to change '
                + 'a tag that is not yours.'],
                status=status.HTTP_400_BAD_REQUEST)
        #Allowed to update tags..
        data = request.DATA.copy()
        if tag.user:
            data['user'] = tag.user.id
        else:
            data['user'] = user.id

        # Tag names are immutable
        data['name'] = tag.name
        serializer = TagSerializer(tag, data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
<commit_msg>Tag list API is public( Auth Optional)<commit_after>"""
Atmosphere service tag rest api.

"""

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from core.models import Tag as CoreTag
from api import failure_response
from api.serializers import TagSerializer
from api.permissions import InMaintenance, ApiAuthRequired, ApiAuthOptional

class TagList(APIView):
    """
        Tags are a easy way to allow users to group several images as similar
        based on a feature/program of the application.
    """
    permission_classes = (ApiAuthOptional,)

    def get(self, request, *args, **kwargs):
        """
        List all public tags.
        """
        tags = CoreTag.objects.all()
        serializer = TagSerializer(tags, many=True)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        """Create a new tag resource
        Params:name -- Name of the new Tag
        Returns:
        Status Code: 201 Body: A new Tag object
        Status Code: 400 Body: Errors (Duplicate/Invalid Name)
        """
        user = request.user
        data = request.DATA.copy()
        same_name_tags = CoreTag.objects.filter(name__iexact=data['name'])
        if same_name_tags:
            return Response(['A tag with this name already exists: %s'
                             % same_name_tags],
                            status=status.HTTP_400_BAD_REQUEST)
        data['user'] = user.username
        data['name'] = data['name'].lower()
        serializer = TagSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class Tag(APIView):
    """
        Tags are a easy way to allow users to group several images as similar
        based on a feature/program of the application.

        This API resource allows you to Retrieve, Update, or Delete your Tag.
    """
    permission_classes = (ApiAuthRequired,)

    def delete(self, request, tag_slug, *args, **kwargs):
        """
        Remove the tag, if it is no longer in use.
        """
        try:
            tag = CoreTag.objects.get(name__iexact=tag_slug)
        except CoreTag.DoesNotExist:
            return failure_response(status.HTTP_404_NOT_FOUND,
                                    'Tag %s does not exist' % tag_slug)
        if tag.in_use():
            instance_count = tag.instance_set.count()
            app_count = tag.application_set.count()
            return failure_response(
                    status.HTTP_409_CONFLICT,
                    "Tag cannot be deleted while it is in use by"
                             "%s instances and %s applications. "
                             "To delete the tag, first remove "
                             "the tag from ALL objects using it"
                             % (instance_count, app_count))
        tag.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    def get(self, request, tag_slug, *args, **kwargs):
        """
        Return the credential information for this tag
        """
        try:
            tag = CoreTag.objects.get(name__iexact=tag_slug)
        except CoreTag.DoesNotExist:
            return Response(['Tag does not exist'],
                            status=status.HTTP_404_NOT_FOUND)
        serializer = TagSerializer(tag)
        return Response(serializer.data)

    def put(self, request, tag_slug, *args, **kwargs):
        """
        Return the credential information for this tag
        """
        user = request.user
        tag = CoreTag.objects.get(name__iexact=tag_slug)
        if not user.is_staff and user != tag.user:
            return Response([
                'Only the tag creator can update a tag.'
                + 'Contact support if you need to change '
                + 'a tag that is not yours.'],
                status=status.HTTP_400_BAD_REQUEST)
        #Allowed to update tags..
        data = request.DATA.copy()
        if tag.user:
            data['user'] = tag.user.id
        else:
            data['user'] = user.id

        # Tag names are immutable
        data['name'] = tag.name
        serializer = TagSerializer(tag, data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
<|endoftext|>