<commit_before>#!/usr/bin/env python3.6
import subprocess
from pathlib import Path
from collections import defaultdict
import rdflib
from pyontutils.ttlser import natsort
from pyontutils.utils import TermColors as tc
from pyontutils.core import restriction, annotation, owl, rdf, rdfs, skos, NIFRID, qname, ilxtr, makeGraph
from IPython import embed

def labelkey(line):
    label, *rest = line.split('|', 1)
    return natsort(label)

def edkey(line):
    ed, label, *rest = line.split('|', 2)
    return natsort(ed + ' ' + label)

for filename in ('mbaslim', 'hbaslim', 'paxinos-rat-labels', 'waxholm-rat-labels'):
    filepath = Path.home() / 'git/NIF-Ontology/ttl/generated/parcellation' / (filename + '.ttl')
    dir_ = filepath.parent.as_posix()
    print(dir_)
    file_commit = subprocess.check_output(['git', 'log', '-n', '1',
                                           '--pretty=format:%H', '--',
                                           filepath.name],
                                          cwd=dir_,
                                          stderr=subprocess.DEVNULL).decode().rstrip()
    graph = rdflib.Graph().parse(filepath.as_posix(), format='ttl')
    g = makeGraph('', graph=graph)

    annos = defaultdict(set)
    anno_trips = defaultdict(set)
    for triple, predicate_objects in annotation.parse(graph=graph):
        for a_p, a_o in predicate_objects:
            annos[a_p, a_o].add(triple)
            anno_trips[triple].add((a_p, a_o))

    anno_trips = {k:v for k, v in anno_trips.items()}

    for lifted_triple in restriction.parse(graph=graph):
        graph.add(lifted_triple)

    out_header = 'label|abbrev|curie|superPart curie\n'
    out = []
    editions_header = 'edition|label|abbrev|curie\n'
    editions = []
    for s in graph.subjects(rdf.type, owl.Class):
        rdfsLabel = next(graph.objects(s, rdfs.label))
        try:
            prefLabel = next(graph.objects(s, skos.prefLabel))
        except StopIteration:
            print(tc.red('WARNING:'), f'skipping {s} {rdfsLabel} since it has no prefLabel')
            continue
        syns = sorted(graph.objects(s, NIFRID.synonym))  # TODO are there cases where we need to recaptulate what we are doing for for abbrevs?
        abbrevs = sorted(graph.objects(s, NIFRID.abbrev))  # FIXME paxinos has more than one
        try:
            if annos:
                if len(abbrevs) > 1:
                    print(tc.blue('INFO:'), g.qname(s), repr(prefLabel.value), 'has multiple abbrevs', [a.value for a in abbrevs])
                # prefer latest
                current_edition = ''
                for a in abbrevs:
                    for a_p, edition in anno_trips[s, NIFRID.abbrev, a]:
                        if a_p == ilxtr.literalUsedBy:
                            if current_edition < edition:
                                current_edition = edition
                                abbrev = a
            else:
                abbrev = abbrevs[0]
        except IndexError:
            abbrev = ''
        try:
            superPart = next(graph.objects(s, ilxtr.labelPartOf))
        except StopIteration:
            superPart = ''

        out.append(f'{prefLabel}|{abbrev}|{g.qname(s)}|{g.qname(superPart)}')

        if annos:
            #asdf = {'ed':{'label':,'abbrev':,'curie':}}
            asdf = defaultdict(dict)
            triple = s, skos.prefLabel, prefLabel
            eds = anno_trips[triple]
            for a_p, a_o in eds:
                asdf[a_o]['curie'] = g.qname(s)
                asdf[a_o]['label'] = prefLabel
            for syn in graph.objects(s, NIFRID.synonym):
                triple = s, NIFRID.synonym, syn
                eds = anno_trips[triple]
                for a_p, a_o in eds:
                    asdf[a_o]['curie'] = g.qname(s)
                    if 'label' in asdf[a_o]:
                        print(tc.red('WARNING:'), f'{a_o} already has a label "{asdf[a_o]["label"]}" for "{syn}"')
                    asdf[a_o]['label'] = syn
            for abbrev in graph.objects(s, NIFRID.abbrev):
                triple = s, NIFRID.abbrev, abbrev
                eds = anno_trips[triple]
                #print('aaaaaaaaaaa', g.qname(s), )
                for a_p, a_o in eds:
                    asdf[a_o]['curie'] = g.qname(s)
                    if 'abbrev' in asdf[a_o]:
                        print(tc.red('WARNING:'), f'{a_o} already has a abbrev "{asdf[a_o]["abbrev"]}" for "{abbrev}"')
                    asdf[a_o]['abbrev'] = abbrev

            #print(asdf)
            for ed, kwargs in sorted(asdf.items()):
                if 'abbrev' not in kwargs:
                    print('Skipping', ed, 'for\n', kwargs)
                    continue
                editions.append('{ed}|{label}|{abbrev}|{curie}'.format(ed=g.qname(ed), **kwargs))

    with open('/tmp/' + filename + f'-{file_commit[:8]}.psv', 'wt') as f:
        f.write(out_header + '\n'.join(sorted(out, key=labelkey)))
    if editions:
        with open('/tmp/' + filename + f'-editions-{file_commit[:8]}.psv', 'wt') as f:
            f.write(editions_header + '\n'.join(sorted(editions, key=edkey)))

<commit_msg>missed gitf fix<commit_after>#!/usr/bin/env python3.6
import subprocess
from pathlib import Path
from collections import defaultdict
import rdflib
from pyontutils.ttlser import natsort
from pyontutils.utils import TermColors as tc
from pyontutils.core import restriction, annotation, owl, rdf, rdfs, skos, NIFRID, qname, ilxtr, makeGraph
from IPython import embed

current_file = Path(__file__).absolute()
gitf = current_file.parent.parent.parent

def labelkey(line):
    label, *rest = line.split('|', 1)
    return natsort(label)

def edkey(line):
    ed, label, *rest = line.split('|', 2)
    return natsort(ed + ' ' + label)

for filename in ('mbaslim', 'hbaslim', 'paxinos-rat-labels', 'waxholm-rat-labels'):
    filepath = gitf / 'NIF-Ontology/ttl/generated/parcellation' / (filename + '.ttl')
    dir_ = filepath.parent.as_posix()
    print(dir_)
    file_commit = subprocess.check_output(['git', 'log', '-n', '1',
                                           '--pretty=format:%H', '--',
                                           filepath.name],
                                          cwd=dir_,
                                          stderr=subprocess.DEVNULL).decode().rstrip()
    graph = rdflib.Graph().parse(filepath.as_posix(), format='ttl')
    g = makeGraph('', graph=graph)

    annos = defaultdict(set)
    anno_trips = defaultdict(set)
    for triple, predicate_objects in annotation.parse(graph=graph):
        for a_p, a_o in predicate_objects:
            annos[a_p, a_o].add(triple)
            anno_trips[triple].add((a_p, a_o))

    anno_trips = {k:v for k, v in anno_trips.items()}

    for lifted_triple in restriction.parse(graph=graph):
        graph.add(lifted_triple)

    out_header = 'label|abbrev|curie|superPart curie\n'
    out = []
    editions_header = 'edition|label|abbrev|curie\n'
    editions = []
    for s in graph.subjects(rdf.type, owl.Class):
        rdfsLabel = next(graph.objects(s, rdfs.label))
        try:
            prefLabel = next(graph.objects(s, skos.prefLabel))
        except StopIteration:
            print(tc.red('WARNING:'), f'skipping {s} {rdfsLabel} since it has no prefLabel')
            continue
        syns = sorted(graph.objects(s, NIFRID.synonym))  # TODO are there cases where we need to recaptulate what we are doing for for abbrevs?
        abbrevs = sorted(graph.objects(s, NIFRID.abbrev))  # FIXME paxinos has more than one
        try:
            if annos:
                if len(abbrevs) > 1:
                    print(tc.blue('INFO:'), g.qname(s), repr(prefLabel.value), 'has multiple abbrevs', [a.value for a in abbrevs])
                # prefer latest
                current_edition = ''
                for a in abbrevs:
                    for a_p, edition in anno_trips[s, NIFRID.abbrev, a]:
                        if a_p == ilxtr.literalUsedBy:
                            if current_edition < edition:
                                current_edition = edition
                                abbrev = a
            else:
                abbrev = abbrevs[0]
        except IndexError:
            abbrev = ''
        try:
            superPart = next(graph.objects(s, ilxtr.labelPartOf))
        except StopIteration:
            superPart = ''

        out.append(f'{prefLabel}|{abbrev}|{g.qname(s)}|{g.qname(superPart)}')

        if annos:
            #asdf = {'ed':{'label':,'abbrev':,'curie':}}
            asdf = defaultdict(dict)
            triple = s, skos.prefLabel, prefLabel
            eds = anno_trips[triple]
            for a_p, a_o in eds:
                asdf[a_o]['curie'] = g.qname(s)
                asdf[a_o]['label'] = prefLabel
            for syn in graph.objects(s, NIFRID.synonym):
                triple = s, NIFRID.synonym, syn
                eds = anno_trips[triple]
                for a_p, a_o in eds:
                    asdf[a_o]['curie'] = g.qname(s)
                    if 'label' in asdf[a_o]:
                        print(tc.red('WARNING:'), f'{a_o} already has a label "{asdf[a_o]["label"]}" for "{syn}"')
                    asdf[a_o]['label'] = syn
            for abbrev in graph.objects(s, NIFRID.abbrev):
                triple = s, NIFRID.abbrev, abbrev
                eds = anno_trips[triple]
                #print('aaaaaaaaaaa', g.qname(s), )
                for a_p, a_o in eds:
                    asdf[a_o]['curie'] = g.qname(s)
                    if 'abbrev' in asdf[a_o]:
                        print(tc.red('WARNING:'), f'{a_o} already has a abbrev "{asdf[a_o]["abbrev"]}" for "{abbrev}"')
                    asdf[a_o]['abbrev'] = abbrev

            #print(asdf)
            for ed, kwargs in sorted(asdf.items()):
                if 'abbrev' not in kwargs:
                    print('Skipping', ed, 'for\n', kwargs)
                    continue
                editions.append('{ed}|{label}|{abbrev}|{curie}'.format(ed=g.qname(ed), **kwargs))

    with open('/tmp/' + filename + f'-{file_commit[:8]}.psv', 'wt') as f:
        f.write(out_header + '\n'.join(sorted(out, key=labelkey)))
    if editions:
        with open('/tmp/' + filename + f'-editions-{file_commit[:8]}.psv', 'wt') as f:
            f.write(editions_header + '\n'.join(sorted(editions, key=edkey)))

<|endoftext|>


<commit_before>import os
import unittest

from pyramid import testing

from pyramid.config import Configurator
from pyramid.testing import DummyRequest
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.authentication import AuthTktAuthenticationPolicy

from .base import DATA_DIR
from .resource import BOOKS

class ResourceFunctionalTests(unittest.TestCase):

    def setUp(self):
        settings = {
            'pyramid_raml.apidef_path': os.path.join(DATA_DIR, 'test-api.raml'),
        }
        self.config = testing.setUp(settings=settings)
        self.config.include('pyramid_raml')
        self.config.scan('.resource')
        from webtest import TestApp
        self.testapp = TestApp(self.config.make_wsgi_app())

    def tearDown(self):
        testing.tearDown()

    def test_get_list(self):
        r = self.testapp.get('/api/v1/books', status=200)
        assert r.json_body == list(BOOKS.values())

    def test_get_one(self):
        app = self.testapp
        r = app.get('/api/v1/books/123', status=200)
        assert r.json_body == BOOKS[123]
        r = app.get('/api/v1/books/456', status=200)
        assert r.json_body == BOOKS[456]

    def test_get_notfound(self):
        app = self.testapp
        r = app.get('/api/v1/books/111', status=404)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "Book with id 111 could not be found."

        book_id = 10
        fake_book = {'id': book_id, 'title': 'Foo', 'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=404)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "Book with id {} could not be found.".format(book_id)

    def test_get_general_error(self):
        app = self.testapp
        r = app.get('/api/v1/books/zzz', status=500)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "invalid literal for int() with base 10: 'zzz'"

    def test_json_validation_error(self):
        app = self.testapp
        r = app.put('/api/v1/books/111', status=400)
        assert r.json_body['message'] == "Empty JSON body!"
        assert r.json_body['success'] == False

        book_id = 10
        fake_book = {'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=400)
        assert r.json_body['success'] == False
        assert 'Failed validating' in r.json_body['message']

    def test_succesful_put(self):
        app = self.testapp
        book_id = 123
        fake_book = {'id': book_id, 'title': 'Foo', 'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=200)

<commit_msg>removed unused imports<commit_after>import os
import unittest

from pyramid import testing

from pyramid.config import Configurator

from .base import DATA_DIR
from .resource import BOOKS

class ResourceFunctionalTests(unittest.TestCase):

    def setUp(self):
        settings = {
            'pyramid_raml.apidef_path': os.path.join(DATA_DIR, 'test-api.raml'),
        }
        self.config = testing.setUp(settings=settings)
        self.config.include('pyramid_raml')
        self.config.scan('.resource')
        from webtest import TestApp
        self.testapp = TestApp(self.config.make_wsgi_app())

    def tearDown(self):
        testing.tearDown()

    def test_get_list(self):
        r = self.testapp.get('/api/v1/books', status=200)
        assert r.json_body == list(BOOKS.values())

    def test_get_one(self):
        app = self.testapp
        r = app.get('/api/v1/books/123', status=200)
        assert r.json_body == BOOKS[123]
        r = app.get('/api/v1/books/456', status=200)
        assert r.json_body == BOOKS[456]

    def test_get_notfound(self):
        app = self.testapp
        r = app.get('/api/v1/books/111', status=404)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "Book with id 111 could not be found."

        book_id = 10
        fake_book = {'id': book_id, 'title': 'Foo', 'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=404)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "Book with id {} could not be found.".format(book_id)

    def test_get_general_error(self):
        app = self.testapp
        r = app.get('/api/v1/books/zzz', status=500)
        assert r.json_body['success'] == False
        assert r.json_body['message'] == "invalid literal for int() with base 10: 'zzz'"

    def test_json_validation_error(self):
        app = self.testapp
        r = app.put('/api/v1/books/111', status=400)
        assert r.json_body['message'] == "Empty JSON body!"
        assert r.json_body['success'] == False

        book_id = 10
        fake_book = {'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=400)
        assert r.json_body['success'] == False
        assert 'Failed validating' in r.json_body['message']

    def test_succesful_put(self):
        app = self.testapp
        book_id = 123
        fake_book = {'id': book_id, 'title': 'Foo', 'author': 'Blah'}
        r = app.put_json('/api/v1/books/{}'.format(book_id), params=fake_book, status=200)

<|endoftext|>


<commit_before># -*-python-*-

import cgi
import os
import shutil
import tempfile
import subprocess
import json

from cherrypy.lib.static import serve_file

# ============================================================
# Whiley Compiler Config
# ============================================================

WYJC_JAR="lib/wyjc-all-v0.3.22b.jar"
WYRT_JAR="lib/wyrt-v0.3.22.jar"

# ============================================================
# Java Config
# ============================================================

JAVA_CMD="/usr/pkg/java/sun-6/bin/java"
#JAVA_CMD="java"

# ============================================================
# Mako Config
# ============================================================

from mako.template import Template
from mako.lookup import TemplateLookup
lookup = TemplateLookup(directories=['html'])

# ============================================================
# Application Config
# ============================================================
WORKING_DIR="data"

# ============================================================
# Application Entry
# ============================================================

class Main(object):
    def __init__(self,root_url,username):
        self.root_url = root_url
        self.username = username

    # gives access to images/
    def images(self, filename):
        abspath = os.path.abspath("images/" + filename)
        return serve_file(abspath, "image/png")
    images.exposed = True

    def js(self, filename):
        abspath = os.path.abspath("js/" + filename)
        return serve_file(abspath, "application/javascript")
    js.exposed = True

    def css(self, filename):
        abspath = os.path.abspath("css/" + filename)
        return serve_file(abspath, "text/css")
    css.exposed = True

    def compile(self,code,verify):
        # First, create working directory
        dir = createWorkingDirectory()
        dir = WORKING_DIR + "/" + dir
        # Second, compile the code
        result = compile(code,verify,dir)
        # Third, delete working directory
        shutil.rmtree(dir)
        # Fouth, return result as JSON
        return json.dumps(result)
    compile.exposed = True

    def save(self,code):
        # First, create working directory
        dir = createWorkingDirectory()
        # Second, save the file
        save(WORKING_DIR + "/" + dir + "/tmp.whiley", code)
        # Fouth, return result as JSON
        return json.dumps({
            "id": dir
            })
    save.exposed = True

    def run(self,code):
        # First, create working directory
        dir = createWorkingDirectory()
        dir = WORKING_DIR + "/" + dir
        # Second, compile the code and then run it
        result = compile(code,"false",dir)
        # Third, run the code
        output = run(dir)
        # Third, delete working directory
        shutil.rmtree(dir)
        # Fouth, return result as JSON
        return json.dumps({
            "errors": result,
            "output": output
            })
    run.exposed = True

    # application root
    def index(self,id=None):
        if id != None:
            # Load the file
            code = load(WORKING_DIR + "/" + id + "/tmp.whiley")
            # Escape the code
            code = cgi.escape(code)
        else:
            code = ""
        template = lookup.get_template("index.html")
        return template.render(ROOT_URL=self.root_url,CODE=code)
    index.exposed = True
    # exposed

# ============================================================
# Compiler Interface
# ============================================================

# Load a given JSON file from the filesystem
def load(filename):
    f = open(filename,"r")
    data = f.read()
    f.close()
    return data

# Save a given file to the filesystem
def save(filename,data):
    f = open(filename,"w")
    f.write(data)
    f.close()
    return

# Compile a snippet of Whiley code.  This is done by saving the file
# to disk in a temporary location, compiling it using the Whiley2Java
# Compiler and then returning the compilation output.
def compile(code,verify,dir):
    filename = dir + "/tmp.whiley"
    # set required arguments
    args = [
        JAVA_CMD,
        "-jar",
        WYJC_JAR,
        "-bootpath", WYRT_JAR, # set bootpath
        "-whileydir", dir,     # set location of Whiley source file(s)
        "-classdir", dir,      # set location to place class file(s)
        "-brief"              # enable brief compiler output (easier to parse)
    ]
    # Configure optional arguments
    if verify == "true":
        args.append("-verify")
    # save the file
    save(filename, code)
    args.append(filename)
    # run the compiler
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
    (out, err) = proc.communicate()
    if err == None:
        return splitErrors(out)
    else:
        return splitErrors(err)

def run(dir):
    # run the JVM
    proc = subprocess.Popen([
        JAVA_CMD,
        "-cp",WYJC_JAR + ":" + dir,
        "tmp"
        ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
    (out, err) = proc.communicate()
    return out

# Split errors output from WyC into a list of JSON records, each of
# which includes the filename, the line number, the column start and
# end, as well a the text of the error itself.
def splitErrors(errors):
    r = []
    for err in errors.split("\n"):
        if err != "":
            r.append(splitError(err))
    return r

def splitError(error):
    error = error.split(":")
    return {
        "filename": error[0],
        "line": error[1],
        "start": error[2],
        "end": error[3],
        "text": error[4]
    }

# Get the working directory for this request.
def createWorkingDirectory():
    dir = tempfile.mkdtemp(prefix="",dir=WORKING_DIR)
    tail,head = os.path.split(dir)
    return head
<commit_msg>Making progress<commit_after># -*-python-*-

import cgi
import os
import shutil
import tempfile
import subprocess
import json

from cherrypy.lib.static import serve_file

# ============================================================
# Whiley Compiler Config
# ============================================================

WYJC_JAR="lib/wyjc-all-v0.3.22b.jar"
WYRT_JAR="lib/wyrt-v0.3.22.jar"

# ============================================================
# Java Config
# ============================================================

JAVA_CMD="/usr/pkg/java/sun-6/bin/java"
#JAVA_CMD="java"

# ============================================================
# Mako Config
# ============================================================

from mako.template import Template
from mako.lookup import TemplateLookup
lookup = TemplateLookup(directories=['html'])

# ============================================================
# Application Config
# ============================================================
WORKING_DIR="data"

# ============================================================
# Application Entry
# ============================================================

class Main(object):
    def __init__(self,root_url,username):
        self.root_url = root_url
        self.username = username

    # gives access to images/
    def images(self, filename):
        abspath = os.path.abspath("images/" + filename)
        return serve_file(abspath, "image/png")
    images.exposed = True

    def js(self, filename):
        abspath = os.path.abspath("js/" + filename)
        return serve_file(abspath, "application/javascript")
    js.exposed = True

    def css(self, filename):
        abspath = os.path.abspath("css/" + filename)
        return serve_file(abspath, "text/css")
    css.exposed = True

    def compile(self,code,verify):
        # First, create working directory
        dir = createWorkingDirectory()
        dir = WORKING_DIR + "/" + dir
        # Second, compile the code
        result = compile(code,verify,dir)
        # Third, delete working directory
        shutil.rmtree(dir)
        # Fouth, return result as JSON
        return json.dumps(result)
    compile.exposed = True

    def save(self,code):
        # First, create working directory
        dir = createWorkingDirectory()
        # Second, save the file
        save(WORKING_DIR + "/" + dir + "/tmp.whiley", code)
        # Fouth, return result as JSON
        return json.dumps({
            "id": dir
            })
    save.exposed = True

    def run(self,code):
        # First, create working directory
        dir = createWorkingDirectory()
        dir = WORKING_DIR + "/" + dir
        # Second, compile the code and then run it
        result = compile(code,"false",dir)
        # Third, run the code
        output = run(dir)
        # Fourth, delete working directory
        shutil.rmtree(dir)
        # Fifth, return result as JSON
        return json.dumps({
            "errors": result,
            "output": output
            })
    run.exposed = True

    # application root
    def index(self,id=None):
        if id != None:
            # Load the file
            code = load(WORKING_DIR + "/" + id + "/tmp.whiley")
            # Escape the code
            code = cgi.escape(code)
        else:
            code = ""
        template = lookup.get_template("index.html")
        return template.render(ROOT_URL=self.root_url,CODE=code)
    index.exposed = True
    # exposed

# ============================================================
# Compiler Interface
# ============================================================

# Load a given JSON file from the filesystem
def load(filename):
    f = open(filename,"r")
    data = f.read()
    f.close()
    return data

# Save a given file to the filesystem
def save(filename,data):
    f = open(filename,"w")
    f.write(data)
    f.close()
    return

# Compile a snippet of Whiley code.  This is done by saving the file
# to disk in a temporary location, compiling it using the Whiley2Java
# Compiler and then returning the compilation output.
def compile(code,verify,dir):
    filename = dir + "/tmp.whiley"
    # set required arguments
    args = [
        JAVA_CMD,
        "-jar",
        WYJC_JAR,
        "-bootpath", WYRT_JAR, # set bootpath
        "-whileydir", dir,     # set location of Whiley source file(s)
        "-classdir", dir,      # set location to place class file(s)
        "-brief"              # enable brief compiler output (easier to parse)
    ]
    # Configure optional arguments
    if verify == "true":
        args.append("-verify")
    # save the file
    save(filename, code)
    args.append(filename)
    # run the compiler
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
    (out, err) = proc.communicate()
    if err == None:
        return splitErrors(out)
    else:
        return splitErrors(err)

def run(dir):
    # run the JVM
    proc = subprocess.Popen([
        JAVA_CMD,
        "-cp",WYJC_JAR + ":" + dir,
        "tmp"
        ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
    (out, err) = proc.communicate()
    return out

# Split errors output from WyC into a list of JSON records, each of
# which includes the filename, the line number, the column start and
# end, as well a the text of the error itself.
def splitErrors(errors):
    r = []
    for err in errors.split("\n"):
        if err != "":
            r.append(splitError(err))
    return r

def splitError(error):
    error = error.split(":")
    return {
        "filename": error[0],
        "line": error[1],
        "start": error[2],
        "end": error[3],
        "text": error[4]
    }

# Get the working directory for this request.
def createWorkingDirectory():
    dir = tempfile.mkdtemp(prefix="",dir=WORKING_DIR)
    tail,head = os.path.split(dir)
    return head
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''Contains the `VowsDefaultReporter` class, which handles output after tests
have been run.
'''

# pyvows testing engine
# https://github.com/heynemann/pyvows

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 Bernardo Heynemann heynemann@gmail.com

import sys
import re
import traceback

from xml.etree import ElementTree as etree

from pyvows.color import Fore, Style
from pyvows.core import VowsAssertionError

PROGRESS_SIZE = 50

# verbosity levels
V_EXTRA_VERBOSE = 4
V_VERBOSE = 3
V_NORMAL = 2
V_SILENT = 1

def ensure_encoded(thing, encoding='utf-8'):
    if isinstance(thing, unicode):
        return thing.encode(encoding)
    else:
        return thing

class VowsDefaultReporter(object):
    HONORED = '{0}✓{1}'.format(Fore.GREEN + Style.BRIGHT, Fore.RESET + Style.RESET_ALL)
    BROKEN  = '{0}✗{1}'.format(Fore.RED + Style.BRIGHT, Fore.RESET + Style.RESET_ALL)
    TAB     = '  '

    def __init__(self, result, verbosity):
        self.verbosity = verbosity
        self.result    = result
        self.indent    = 1

    def camel_split(self, string):
        return re.sub('((?=[A-Z][a-z])|(?<=[a-z])(?=[A-Z])|(?=[0-9]\b))', ' ', string).strip()

    def under_split(self, string):
        return ' '.join(string.split('_'))

    def format_traceback(self, traceback_list, indentation):
        def indent(msg):
            if msg.startswith('  File'):
                return msg.replace('\n ', '\n {0}'.format(indentation))
            return msg

        return indentation.join(map(indent, traceback_list))

    def get_uncovered_lines(self, uncovered_lines, number_of=3):
        if len(uncovered_lines) > number_of:
            template_str = []
            for i in range(number_of):
                template_str.append(uncovered_lines[i])
                if i is not (number_of - 1):
                    template_str.append(', ')

            template_str.append(' and {0:d} more'.format(len(uncovered_lines) - number_of))

            return ''.join(template_str)

        return ', '.join(uncovered_lines)

    #-------------------------------------------------------------------------
    #   Printing Methods
    #-------------------------------------------------------------------------
    @classmethod
    def handle_success(cls, vow):
        sys.stdout.write(cls.honored)

    @classmethod
    def handle_error(cls, vow):
        sys.stdout.write(cls.broken)

    #-------------------------------------------------------------------------
    #   Printing Methods
    #-------------------------------------------------------------------------
    def print_header(self, msg):
        ruler = ' {0}'.format('=' * len(msg))

        prefix = ''.join((Fore.GREEN, Style.BRIGHT))
        suffix = ''.join((Style.RESET_ALL, Fore.RESET))

        msg = '{prefix} {msg}{suffix}'.format(
            prefix  = prefix,
            msg     = msg,
            suffix  = suffix
        )
        print
        print ruler
        print msg
        print ruler
        print

    def indent_print(self, msg, indentation=None):
        print '{indent}{msg}'.format(
            indent = indentation or (self.TAB * self.indent),
            msg    = msg.capitalize())

    def humanized_print(self, msg, indentation=None):
        msg = self.under_split(msg)
        msg = self.camel_split(msg)
        self.indent_print(msg, indentation)

    def print_traceback(self, exc_type, exc_value, exc_traceback, indentation):
        if isinstance(exc_value, VowsAssertionError):
            exc_values_args = tuple(map(lambda arg: '{0.RESET}{1}{0.RED}'.format(Fore, arg), exc_value.args))
            error_msg = exc_value.msg % exc_values_args
        else:
            error_msg = unicode(exc_value)

        print '{indent}{F.RED}{error}{F.RESET}'.format(
            F      = Fore,
            indent = indentation,
            error  = error_msg)

        if self.verbosity >= V_NORMAL:
            traceback_msg = traceback.format_exception(exc_type, exc_value, exc_traceback)
            traceback_msg = self.format_traceback(traceback_msg, indentation)
            print
            print indentation + traceback_msg

    def pretty_print(self):
        self.print_header('Vows Results')

        if not self.result.contexts:
            # FIXME:
            #   If no vows are found, how could any be broken?
            print '{indent}{broken} No vows found! » 0 honored • 0 broken (0.0s)'.format(
                indent = self.self.TAB * self.indent,
                broken = self.BROKEN,
            )
            return

        if self.verbosity >= V_VERBOSE or self.result.errored_tests:
            print '' * 2

        for context in self.result.contexts:
            self.print_context(context['name'], context)

        print '{0}{1} OK » {honored:d} honored • {broken:d} broken ({time:.6f}s)'.format(
            self.TAB * self.indent,
            self.HONORED if self.result.successful else self.BROKEN,
            honored=self.result.successful_tests,
            broken=self.result.errored_tests,
            time=self.result.elapsed_time
        )

        print

    def print_context(self, name, context):

        self.indent += 1
        indentation2 = self.TAB * (self.indent + 2)

        if self.verbosity >= V_VERBOSE or not self.result.eval_context(context):
            self.humanized_print(name)

        for test in context['tests']:
            if test['succeeded']:
                honored, topic, name = map(
                    ensure_encoded,
                    (VowsDefaultReporter.HONORED, test['topic'], test['name']))

                if self.verbosity == V_VERBOSE:
                    self.humanized_print('{0} {1}'.format(honored, name))
                elif self.verbosity >= V_EXTRA_VERBOSE:
                    if test['enumerated']:
                        self.humanized_print('{0} {1} - {2}'.format(honored, topic, name))
                    else:
                        self.humanized_print('{0} {1}'.format(honored, name))
            else:
                ctx = test['context_instance']

                self.humanized_print('{0} {1}'.format(
                    VowsDefaultReporter.BROKEN,
                    test['name']))

                if ctx.generated_topic:
                    self.humanized_print('')
                    self.humanized_print('\tTopic value:')
                    self.humanized_print('\t{0.YELLOW}{1.BRIGHT}{2}{1.RESET_ALL}'.format(
                        Fore,
                        Style,
                        self.max_length(test['topic'], 250)
                    ))
                    self.humanized_print('\n\n')

                if hasattr(test['topic'], 'error'):
                    self.indent_print('')
                    self.indent_print('{0.BLUE}{1.BRIGHT}Topic Error:{1.RESET_ALL}'.format(Fore, Style))
                    exc_type, exc_value, exc_traceback = test['topic'].error
                    self.print_traceback(exc_type, exc_value, exc_traceback, indentation2)
                else:
                    error = test['error']
                    exc_type, exc_value, exc_traceback = error['type'], error['value'], error['traceback']

                    self.print_traceback(exc_type, exc_value, exc_traceback, indentation2)

                if 'file' in test:
                    print
                    print '{RED}found in {test[file]} at line {test[lineno]}{RESET}'.format(
                        RED   = indentation2 + Fore.RED,
                        RESET = Fore.RESET,
                        test  = test)
                    print

        for context in context['contexts']:
            self.print_context(context['name'], context)

        self.indent -= 1

    #-------------------------------------------------------------------------
    #   Printing (Profile)
    #-------------------------------------------------------------------------
    def print_profile(self, threshold):
        MAX_PATH_SIZE = 30
        topics = self.result.get_worst_topics(number=10, threshold=threshold)

        if topics:
            self.print_header('Slowest Topics')

            print '       elapsed    Context File Path                 Context Name'
            for index, topic in enumerate(topics):
                name = self.under_split(topic['context'])
                name = self.camel_split(name)

                print Style.BRIGHT + ("%s#%02d%s    %.05fs    %s%s%" + str(MAX_PATH_SIZE) + "s%s%s    %s") % (
                        Fore.BLUE,
                        index + 1,
                        Fore.RESET,
                        topic['elapsed'],
                        Style.DIM,
                        Fore.WHITE,
                        topic['path'][-MAX_PATH_SIZE:],
                        Fore.RESET,
                        Style.BRIGHT,
                        name
                ) + Style.RESET_ALL

            print

    #-------------------------------------------------------------------------
    #   Printing (Coverage)
    #-------------------------------------------------------------------------
    def parse_coverage_xml(self, xml):
        result = {}
        root   = etree.fromstring(xml)
        result['overall'] = float(root.attrib['line-rate']) * 100
        result['classes'] = []

        for package in root.findall('.//package'):
            package_name = package.attrib['name']
            for klass in package.findall('.//class'):
                result['classes'].append({
                    'name': '.'.join([package_name, klass.attrib['name']]),
                    'line_rate': float(klass.attrib['line-rate']) * 100,
                    'uncovered_lines': [line.attrib['number']
                                        for line in klass.find('lines')
                                        if  line.attrib['hits'] == '0']
                })
        return result

    def print_coverage(self, xml, cover_threshold):
        write_blue_str  = '{BLUE}{0!s}{RESET}'
        write_white_str = '{WHITE}{0!s}{RESET}'

        write_blue  = lambda msg: write_blue_str.format(
                            msg,
                            BLUE  = Fore.BLUE       + Style.BRIGHT,
                            RESET = Style.RESET_ALL + Fore.RESET)

        write_white = lambda msg: write_white_str.format(
                            msg,
                            WHITE = Fore.WHITE      + Style.BRIGHT,
                            RESET = Style.RESET_ALL + Fore.RESET)

        self.print_header('Code Coverage')

        root         = self.parse_coverage_xml(xml)
        klasses      = sorted(root['classes'], key=lambda klass: klass['line_rate'])
        max_length   = max([len(klass['name']) for klass in root['classes']])
        max_coverage = 0

        for klass in klasses:
            coverage = klass['line_rate']

            if coverage < cover_threshold:
                cover_character = self.BROKEN
            else:
                cover_character = self.HONORED

            if 100.0 < max_coverage < coverage:
                max_coverage = coverage
                if max_coverage == 100.0:
                    print

            coverage = int(round(coverage, 0))
            progress = int(round(coverage / 100.0 * PROGRESS_SIZE, 0))
            offset   = coverage == 0 and 2 or (coverage < 10 and 1 or 0)
                        #   FIXME: explain the `offset` line please?  :)

            if coverage == 0 and not klass['uncovered_lines']:
                continue

            print ' {0} {klass}{space1}\t{progress}{cover_pct}%{space2} {lines}'.format(
                # TODO:
                #   * remove manual spacing, use .format() alignment
                cover_character,
                klass     = write_blue(klass['name']),
                space1    = ' ' * (max_length - len(klass['name'])),
                progress  = '•' * progress,
                cover_pct = write_white(
                                (coverage > 0 and ' ' or '') + '{0:.2f}'.format(coverage)
                ),
                space2    = ' ' * (PROGRESS_SIZE - progress + offset),
                lines     = self.get_uncovered_lines(klass['uncovered_lines']))

        print

        total_coverage = root['overall']
        progress       = int(round(total_coverage / 100.0 * PROGRESS_SIZE, 0))

        print ' {0} {overall}{space}\t{progress} {total}%'.format(
           (total_coverage >= cover_threshold) and self.HONORED or self.BROKEN,
            overall = write_blue('OVERALL'),
            space   = ' ' * (max_length - len('OVERALL')),
            progress= '•' * progress,
            total   = write_white('{0:.2%}'.format(total_coverage)))

        print
    <commit_msg>Colorize tracebacks (for readability)<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''Contains the `VowsDefaultReporter` class, which handles output after tests
have been run.
'''

# pyvows testing engine
# https://github.com/heynemann/pyvows

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 Bernardo Heynemann heynemann@gmail.com

import sys
import re
import traceback

from xml.etree import ElementTree as etree

from pyvows.color import Fore, Style
from pyvows.core import VowsAssertionError

PROGRESS_SIZE = 50

# verbosity levels
V_EXTRA_VERBOSE = 4
V_VERBOSE = 3
V_NORMAL = 2
V_SILENT = 1

def ensure_encoded(thing, encoding='utf-8'):
    if isinstance(thing, unicode):
        return thing.encode(encoding)
    else:
        return thing

class VowsDefaultReporter(object):
    HONORED = '{0}✓{1}'.format(Fore.GREEN + Style.BRIGHT, Fore.RESET + Style.RESET_ALL)
    BROKEN  = '{0}✗{1}'.format(Fore.RED + Style.BRIGHT, Fore.RESET + Style.RESET_ALL)
    TAB     = '  '

    def __init__(self, result, verbosity):
        self.verbosity = verbosity
        self.result    = result
        self.indent    = 1

    def camel_split(self, string):
        return re.sub('((?=[A-Z][a-z])|(?<=[a-z])(?=[A-Z])|(?=[0-9]\b))', ' ', string).strip()

    def under_split(self, string):
        return ' '.join(string.split('_'))

    def format_traceback(self, traceback_list, indentation):
        def indent(msg):
            if msg.startswith('  File'):
                return msg.replace('\n ', '\n {0}'.format(indentation))
            return msg

        return indentation.join(map(indent, traceback_list))

    def get_uncovered_lines(self, uncovered_lines, number_of=3):
        if len(uncovered_lines) > number_of:
            template_str = []
            for i in range(number_of):
                template_str.append(uncovered_lines[i])
                if i is not (number_of - 1):
                    template_str.append(', ')

            template_str.append(' and {0:d} more'.format(len(uncovered_lines) - number_of))

            return ''.join(template_str)

        return ', '.join(uncovered_lines)

    #-------------------------------------------------------------------------
    #   Printing Methods
    #-------------------------------------------------------------------------
    @classmethod
    def handle_success(cls, vow):
        sys.stdout.write(cls.honored)

    @classmethod
    def handle_error(cls, vow):
        sys.stdout.write(cls.broken)

    #-------------------------------------------------------------------------
    #   Printing Methods
    #-------------------------------------------------------------------------
    def print_header(self, msg):
        ruler = ' {0}'.format('=' * len(msg))

        prefix = ''.join((Fore.GREEN, Style.BRIGHT))
        suffix = ''.join((Style.RESET_ALL, Fore.RESET))

        msg = '{prefix} {msg}{suffix}'.format(
            prefix  = prefix,
            msg     = msg,
            suffix  = suffix
        )
        print
        print ruler
        print msg
        print ruler
        print

    def indent_print(self, msg, indentation=None):
        print '{indent}{msg}'.format(
            indent = indentation or (self.TAB * self.indent),
            msg    = msg.capitalize())

    def humanized_print(self, msg, indentation=None):
        msg = self.under_split(msg)
        msg = self.camel_split(msg)
        self.indent_print(msg, indentation)

    def print_traceback(self, exc_type, exc_value, exc_traceback, indentation):
        if isinstance(exc_value, VowsAssertionError):
            exc_values_args = tuple(map(lambda arg: '{0.RESET}{1}{0.RED}'.format(Fore, arg), exc_value.args))
            error_msg = exc_value.msg % exc_values_args
        else:
            error_msg = unicode(exc_value)

        print '{indent}{F.RED}{error}{F.RESET}'.format(
            F      = Fore,
            indent = indentation,
            error  = error_msg)

        if self.verbosity >= V_NORMAL:
            traceback_msg = traceback.format_exception(exc_type, exc_value, exc_traceback)
            traceback_msg = self.format_traceback(traceback_msg, indentation)
            print '\n{indent}{F.YELLOW}{traceback}{S.RESET_ALL}'.format(
                F = Fore,
                S = Style,
                indent      = indentation,
                traceback   = traceback_msg)

    def pretty_print(self):
        self.print_header('Vows Results')

        if not self.result.contexts:
            # FIXME:
            #   If no vows are found, how could any be broken?
            print '{indent}{broken} No vows found! » 0 honored • 0 broken (0.0s)'.format(
                indent = self.self.TAB * self.indent,
                broken = self.BROKEN,
            )
            return

        if self.verbosity >= V_VERBOSE or self.result.errored_tests:
            print '' * 2

        for context in self.result.contexts:
            self.print_context(context['name'], context)

        print '{0}{1} OK » {honored:d} honored • {broken:d} broken ({time:.6f}s)'.format(
            self.TAB * self.indent,
            self.HONORED if self.result.successful else self.BROKEN,
            honored=self.result.successful_tests,
            broken=self.result.errored_tests,
            time=self.result.elapsed_time
        )

        print

    def print_context(self, name, context):

        self.indent += 1
        indentation2 = self.TAB * (self.indent + 2)

        if self.verbosity >= V_VERBOSE or not self.result.eval_context(context):
            self.humanized_print(name)

        for test in context['tests']:
            if test['succeeded']:
                honored, topic, name = map(
                    ensure_encoded,
                    (VowsDefaultReporter.HONORED, test['topic'], test['name']))

                if self.verbosity == V_VERBOSE:
                    self.humanized_print('{0} {1}'.format(honored, name))
                elif self.verbosity >= V_EXTRA_VERBOSE:
                    if test['enumerated']:
                        self.humanized_print('{0} {1} - {2}'.format(honored, topic, name))
                    else:
                        self.humanized_print('{0} {1}'.format(honored, name))
            else:
                ctx = test['context_instance']

                self.humanized_print('{0} {1}'.format(
                    VowsDefaultReporter.BROKEN,
                    test['name']))

                if ctx.generated_topic:
                    self.humanized_print('')
                    self.humanized_print('\tTopic value:')
                    self.humanized_print('\t{0.YELLOW}{1.BRIGHT}{2}{1.RESET_ALL}'.format(
                        Fore,
                        Style,
                        self.max_length(test['topic'], 250)
                    ))
                    self.humanized_print('\n\n')

                if hasattr(test['topic'], 'error'):
                    self.indent_print('')
                    self.indent_print('{0.BLUE}{1.BRIGHT}Topic Error:{1.RESET_ALL}'.format(Fore, Style))
                    exc_type, exc_value, exc_traceback = test['topic'].error
                    self.print_traceback(exc_type, exc_value, exc_traceback, indentation2)
                else:
                    error = test['error']
                    exc_type, exc_value, exc_traceback = error['type'], error['value'], error['traceback']

                    self.print_traceback(exc_type, exc_value, exc_traceback, indentation2)

                if 'file' in test:
                    print
                    print '{RED}found in {test[file]} at line {test[lineno]}{RESET}'.format(
                        RED   = indentation2 + Fore.RED,
                        RESET = Fore.RESET,
                        test  = test)
                    print

        for context in context['contexts']:
            self.print_context(context['name'], context)

        self.indent -= 1

    #-------------------------------------------------------------------------
    #   Printing (Profile)
    #-------------------------------------------------------------------------
    def print_profile(self, threshold):
        MAX_PATH_SIZE = 30
        topics = self.result.get_worst_topics(number=10, threshold=threshold)

        if topics:
            self.print_header('Slowest Topics')

            print '       elapsed    Context File Path                 Context Name'
            for index, topic in enumerate(topics):
                name = self.under_split(topic['context'])
                name = self.camel_split(name)

                print Style.BRIGHT + ("%s#%02d%s    %.05fs    %s%s%" + str(MAX_PATH_SIZE) + "s%s%s    %s") % (
                        Fore.BLUE,
                        index + 1,
                        Fore.RESET,
                        topic['elapsed'],
                        Style.DIM,
                        Fore.WHITE,
                        topic['path'][-MAX_PATH_SIZE:],
                        Fore.RESET,
                        Style.BRIGHT,
                        name
                ) + Style.RESET_ALL

            print

    #-------------------------------------------------------------------------
    #   Printing (Coverage)
    #-------------------------------------------------------------------------
    def parse_coverage_xml(self, xml):
        result = {}
        root   = etree.fromstring(xml)
        result['overall'] = float(root.attrib['line-rate']) * 100
        result['classes'] = []

        for package in root.findall('.//package'):
            package_name = package.attrib['name']
            for klass in package.findall('.//class'):
                result['classes'].append({
                    'name': '.'.join([package_name, klass.attrib['name']]),
                    'line_rate': float(klass.attrib['line-rate']) * 100,
                    'uncovered_lines': [line.attrib['number']
                                        for line in klass.find('lines')
                                        if  line.attrib['hits'] == '0']
                })
        return result

    def print_coverage(self, xml, cover_threshold):
        write_blue_str  = '{BLUE}{0!s}{RESET}'
        write_white_str = '{WHITE}{0!s}{RESET}'

        write_blue  = lambda msg: write_blue_str.format(
                            msg,
                            BLUE  = Fore.BLUE       + Style.BRIGHT,
                            RESET = Style.RESET_ALL + Fore.RESET)

        write_white = lambda msg: write_white_str.format(
                            msg,
                            WHITE = Fore.WHITE      + Style.BRIGHT,
                            RESET = Style.RESET_ALL + Fore.RESET)

        self.print_header('Code Coverage')

        root         = self.parse_coverage_xml(xml)
        klasses      = sorted(root['classes'], key=lambda klass: klass['line_rate'])
        max_length   = max([len(klass['name']) for klass in root['classes']])
        max_coverage = 0

        for klass in klasses:
            coverage = klass['line_rate']

            if coverage < cover_threshold:
                cover_character = self.BROKEN
            else:
                cover_character = self.HONORED

            if 100.0 < max_coverage < coverage:
                max_coverage = coverage
                if max_coverage == 100.0:
                    print

            coverage = int(round(coverage, 0))
            progress = int(round(coverage / 100.0 * PROGRESS_SIZE, 0))
            offset   = coverage == 0 and 2 or (coverage < 10 and 1 or 0)
                        #   FIXME: explain the `offset` line please?  :)

            if coverage == 0 and not klass['uncovered_lines']:
                continue

            print ' {0} {klass}{space1}\t{progress}{cover_pct}%{space2} {lines}'.format(
                # TODO:
                #   * remove manual spacing, use .format() alignment
                cover_character,
                klass     = write_blue(klass['name']),
                space1    = ' ' * (max_length - len(klass['name'])),
                progress  = '•' * progress,
                cover_pct = write_white(
                                (coverage > 0 and ' ' or '') + '{0:.2f}'.format(coverage)
                ),
                space2    = ' ' * (PROGRESS_SIZE - progress + offset),
                lines     = self.get_uncovered_lines(klass['uncovered_lines']))

        print

        total_coverage = root['overall']
        progress       = int(round(total_coverage / 100.0 * PROGRESS_SIZE, 0))

        print ' {0} {overall}{space}\t{progress} {total}%'.format(
           (total_coverage >= cover_threshold) and self.HONORED or self.BROKEN,
            overall = write_blue('OVERALL'),
            space   = ' ' * (max_length - len('OVERALL')),
            progress= '•' * progress,
            total   = write_white('{0:.2%}'.format(total_coverage)))

        print
    <|endoftext|>


<commit_before>import bottle
from bottle import Bottle, request, static_file, template, debug, response
import argparse
from bottle.ext.mongo import MongoPlugin
from bson.json_util import dumps, loads
from os import environ
import time
import json
from math import floor

print ("Initializing")
print ("Reading ignored UUIDs from 'IGNORED_UUIDS' environment variable")
try:
    ignoredUUIDs = environ["IGNORED_UUIDS"]
    ignoredUUIDs = ignoredUUIDs.split(",")
except:
    print ("Couldn't find ignored UUIDs in environment variable 'IGNORED_UUIDS'")
    ignoredUUIDs = []

class EnableCors(object):
    name = 'enable_cors'
    api = 2

    def apply(self, fn, context):
        def _enable_cors(*args, **kwargs):
            # set CORS headers
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Access-Control-Allow-Methods'] = 'POST, GET'
            response.headers['Access-Control-Allow-Headers'] = ''

            if bottle.request.method != 'OPTIONS':
                # actual request; reply with the actual response
                return fn(*args, **kwargs)

        return _enable_cors

app = Bottle()

@app.get("/")
def healthCheck():
    return "I exist!"

@app.get("/<collectionName>")
def all(mongodb, collectionName):
    print ("Fetching all data from collection " + collectionName)
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)
    return dumps({"collectionName": collectionName, "data": rawData, "total": mongodb[collectionName].count()})

@app.get("/<collectionName>/distinct")
def distinct(mongodb, collectionName):
    print ("Fetching distinct uuids from collection " + collectionName)
    rawData = list(mongodb[collectionName].distinct("uuid"))
    output = []
    for uuid in rawData:
        if uuid not in ignoredUUIDs:
            output.append(uuid)

    return dumps({"collectionName": collectionName, "data": output, "total":len(output)})

@app.get("/<collectionName>/byUser")
def grouped(mongodb, collectionName):
    print ("Fetching data grouped by user from collection " + collectionName)
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)

    output = {}
    for document in rawData:
        uuid = document['uuid']
        if uuid not in output:
            output[uuid] = []
        del document['uuid']
        output[uuid].append(document)
    return dumps(output)

@app.get("/<collectionName>/daily")
def daily(mongodb, collectionName):
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)

    output = {}
    for document in rawData:
        dayStart = floor(document['timestamp'] / 86400) * 86400
        if dayStart not in output:
            output[dayStart] = []
        output[dayStart].append(document)
    return dumps(output)

def remove_internal_ids(data):
    """Removes the mongodb internal id from items returned to the user"""
    for document in data:
        del document["_id"]

def remove_ignored_uuids(data):
    """Given a list of documents with uuid at the top level, returns a list of documents without uuids defined in ignoredUUIDs"""
    output = []
    for document in data:
        if document['uuid'] not in ignoredUUIDs:
            output.append(document)
    return output

@app.post("/<collectionName>")
def save_new(mongodb, collectionName, bottleRequest = request, systemTime = time):
    print ("Request received for collection " + collectionName)
    try:
        for key in bottleRequest.POST.keys():
            data_point = key
        if data_point is None:
            print ("No JSON posted, will not try to save")
            return {"message": "this endpoint expects JSON"}
        data_point = json.loads(data_point)
        print ("Saving new from " + str(data_point) + " to collection '" + collectionName + "'")
    except:
        print ("Could not parse JSON provided, will not try to save")
        return {"message": "malformed JSON was provided"}

    print ("Timestamping to data")
    data_point["timestamp"] = systemTime.time()
    print ("Saving to mongodb")
    mongodb[collectionName].insert_one(data_point)
    print ("Save was successful!")
    return dumps(data_point)

if __name__ == "__main__":
    print ("Reading db configuration from 'MONGODB_URI' environment variable")
    mongo_uri = environ["MONGODB_URI"]
    print ("Connecting to mongo")
    plugin = MongoPlugin(uri=mongo_uri, db="mydb", json_mongo=True)
    app.install(plugin)
    print ("Enabling CORS for AJAX requests")
    app.install(EnableCors())

    parser = argparse.ArgumentParser()
    parser.add_argument("--port", type=int, default="5000")
    parser.add_argument("--host", default="127.0.0.1")
    args = parser.parse_args()

    print ("Starting the server\n")
    app.run(port=args.port, host=args.host)
    print ("Shutting down")
<commit_msg>fixing total that was misleading<commit_after>import bottle
from bottle import Bottle, request, static_file, template, debug, response
import argparse
from bottle.ext.mongo import MongoPlugin
from bson.json_util import dumps, loads
from os import environ
import time
import json
from math import floor

print ("Initializing")
print ("Reading ignored UUIDs from 'IGNORED_UUIDS' environment variable")
try:
    ignoredUUIDs = environ["IGNORED_UUIDS"]
    ignoredUUIDs = ignoredUUIDs.split(",")
except:
    print ("Couldn't find ignored UUIDs in environment variable 'IGNORED_UUIDS'")
    ignoredUUIDs = []

class EnableCors(object):
    name = 'enable_cors'
    api = 2

    def apply(self, fn, context):
        def _enable_cors(*args, **kwargs):
            # set CORS headers
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Access-Control-Allow-Methods'] = 'POST, GET'
            response.headers['Access-Control-Allow-Headers'] = ''

            if bottle.request.method != 'OPTIONS':
                # actual request; reply with the actual response
                return fn(*args, **kwargs)

        return _enable_cors

app = Bottle()

@app.get("/")
def healthCheck():
    return "I exist!"

@app.get("/<collectionName>")
def all(mongodb, collectionName):
    print ("Fetching all data from collection " + collectionName)
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)
    return dumps({"collectionName": collectionName, "data": rawData, "total": len(rawData)})

@app.get("/<collectionName>/distinct")
def distinct(mongodb, collectionName):
    print ("Fetching distinct uuids from collection " + collectionName)
    rawData = list(mongodb[collectionName].distinct("uuid"))
    output = []
    for uuid in rawData:
        if uuid not in ignoredUUIDs:
            output.append(uuid)

    return dumps({"collectionName": collectionName, "data": output, "total":len(output)})

@app.get("/<collectionName>/byUser")
def grouped(mongodb, collectionName):
    print ("Fetching data grouped by user from collection " + collectionName)
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)

    output = {}
    for document in rawData:
        uuid = document['uuid']
        if uuid not in output:
            output[uuid] = []
        del document['uuid']
        output[uuid].append(document)
    return dumps(output)

@app.get("/<collectionName>/daily")
def daily(mongodb, collectionName):
    rawData = list(mongodb[collectionName].find())
    remove_internal_ids(rawData)
    rawData = remove_ignored_uuids(rawData)

    output = {}
    for document in rawData:
        dayStart = floor(document['timestamp'] / 86400) * 86400
        if dayStart not in output:
            output[dayStart] = []
        output[dayStart].append(document)
    return dumps(output)

def remove_internal_ids(data):
    """Removes the mongodb internal id from items returned to the user"""
    for document in data:
        del document["_id"]

def remove_ignored_uuids(data):
    """Given a list of documents with uuid at the top level, returns a list of documents without uuids defined in ignoredUUIDs"""
    output = []
    for document in data:
        if document['uuid'] not in ignoredUUIDs:
            output.append(document)
    return output

@app.post("/<collectionName>")
def save_new(mongodb, collectionName, bottleRequest = request, systemTime = time):
    print ("Request received for collection " + collectionName)
    try:
        for key in bottleRequest.POST.keys():
            data_point = key
        if data_point is None:
            print ("No JSON posted, will not try to save")
            return {"message": "this endpoint expects JSON"}
        data_point = json.loads(data_point)
        print ("Saving new from " + str(data_point) + " to collection '" + collectionName + "'")
    except:
        print ("Could not parse JSON provided, will not try to save")
        return {"message": "malformed JSON was provided"}

    print ("Timestamping to data")
    data_point["timestamp"] = systemTime.time()
    print ("Saving to mongodb")
    mongodb[collectionName].insert_one(data_point)
    print ("Save was successful!")
    return dumps(data_point)

if __name__ == "__main__":
    print ("Reading db configuration from 'MONGODB_URI' environment variable")
    mongo_uri = environ["MONGODB_URI"]
    print ("Connecting to mongo")
    plugin = MongoPlugin(uri=mongo_uri, db="mydb", json_mongo=True)
    app.install(plugin)
    print ("Enabling CORS for AJAX requests")
    app.install(EnableCors())

    parser = argparse.ArgumentParser()
    parser.add_argument("--port", type=int, default="5000")
    parser.add_argument("--host", default="127.0.0.1")
    args = parser.parse_args()

    print ("Starting the server\n")
    app.run(port=args.port, host=args.host)
    print ("Shutting down")
<|endoftext|>


<commit_before>"""
Copyright 2013 Steven Diamond

This file is part of CVXPY.

CVXPY is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CVXPY is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CVXPY.  If not, see <http://www.gnu.org/licenses/>.
"""

import cvxpy.lin_ops.lin_op as lo
import cvxpy.interface as intf
import numpy as np
import scipy.sparse as sp
import scipy.linalg as sp_la

# Utility functions for converting LinOps into matrices.

def flatten(matrix):
    """Converts the matrix into a column vector.

    Parameters
    ----------
    matrix :
        The matrix to flatten.
    """
    np_mat = intf.DEFAULT_INTF
    matrix = np_mat.const_to_matrix(matrix, convert_scalars=True)
    size = intf.size(matrix)
    return np_mat.reshape(matrix, (size[0]*size[1], 1))

def get_coefficients(lin_op):
    """Converts a linear op into coefficients.

    Parameters
    ----------
    lin_op : LinOp
        The linear op to convert.

    Returns
    -------
    list
        A list of (id, coefficient) tuples.
    """
    # VARIABLE converts to a giant identity matrix.
    if lin_op.type == lo.VARIABLE:
        coeffs = var_coeffs(lin_op)
    # Constants convert directly to their value.
    elif lin_op.type in CONSTANT_TYPES:
        mat = const_mat(lin_op)
        coeffs = [(lo.CONSTANT_ID, flatten(mat))]
    elif lin_op.type in TYPE_TO_FUNC:
        # A coefficient matrix for each argument.
        coeff_mats = TYPE_TO_FUNC[lin_op.type](lin_op)
        coeffs = []
        for coeff_mat, arg in zip(coeff_mats, lin_op.args):
            rh_coeffs = get_coefficients(arg)
            coeffs += mul_by_const(coeff_mat, rh_coeffs)
    else:
        raise Exception("Unknown linear operator.")
    return coeffs

def get_constant_coeff(lin_op):
    """Converts a linear op into coefficients and returns the constant term.

    Parameters
    ----------
    lin_op : LinOp
        The linear op to convert.

    Returns
    -------
    The constant coefficient or None if none present.
    """
    coeffs = get_coefficients(lin_op)
    for id_, coeff in coeffs:
        if id_ == lo.CONSTANT_ID:
            return coeff
    return None

def var_coeffs(lin_op):
    """Returns the coefficients for a VARIABLE.

    Parameters
    ----------
    lin_op : LinOp
        The variable linear op.

    Returns
    -------
    list
       A list of (id, size, coefficient) tuples.
    """
    id_ = lin_op.data
    coeff = sp.eye(lin_op.size[0]*lin_op.size[1]).tocsc()
    return [(id_, coeff)]

def const_mat(lin_op):
    """Returns the matrix for a constant type.

    Parameters
    ----------
    lin_op : LinOp
        The linear op.

    Returns
    -------
    A numerical constant.
    """
    if lin_op.type == lo.PARAM:
        coeff = lin_op.data.value
    elif lin_op.type in [lo.SCALAR_CONST, lo.DENSE_CONST, lo.SPARSE_CONST]:
        coeff = lin_op.data
    return coeff

def mul_by_const(constant, rh_coeffs):
    """Multiplies a constant by a list of coefficients.

    Parameters
    ----------
    constant : numeric type
        The constant to multiply by.
    rh_coeffs : list
        The coefficients of the right hand side.

    Returns
    -------
    list
        A list of (id, size, coefficient) tuples.
    """
    new_coeffs = []
    # Multiply all right-hand terms by the left-hand constant.
    for (id_, coeff) in rh_coeffs:
        new_coeffs.append((id_, constant*coeff))

    return new_coeffs

def sum_entries_mat(lin_op):
    """Returns the coefficient matrix for SUM_ENTRIES linear op.

    Parameters
    ----------
    lin_op : LinOp
        The sum entries linear op.

    Returns
    -------
    list of NumPy matrix
        The matrix representing the sum_entries operation.
    """
    rows, cols = lin_op.args[0].size
    coeff = np.ones((1, rows*cols))
    return [np.matrix(coeff)]

def trace_mat(lin_op):
    """Returns the coefficient matrix for TRACE linear op.

    Parameters
    ----------
    lin_op : LinOp
        The trace linear op.

    Returns
    -------
    list of NumPy matrix
        The matrix representing the trace operation.
    """
    rows, _ = lin_op.args[0].size
    mat = np.zeros((1, rows**2))
    for i in range(rows):
        mat[0, i*rows + i] = 1
    return [np.matrix(mat)]

def neg_mat(lin_op):
    """Returns the coefficient matrix for NEG linear op.

    Parameters
    ----------
    lin_op : LinOp
        The neg linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix representing the neg operation.
    """
    mat = -sp.eye(lin_op.size[0]*lin_op.size[1])
    return [mat.tocsc()]

def div_mat(lin_op):
    """Returns the coefficient matrix for DIV linear op.

    Assumes dividing by scalar constants.

    Parameters
    ----------
    lin_op : LinOp
        The div linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix representing the div operation.
    """
    divisor = const_mat(lin_op.data)
    mat = sp.eye(lin_op.size[0]*lin_op.size[1])/divisor
    return [mat.tocsc()]

def mul_elemwise_mat(lin_op):
    """Returns the coefficient matrix for MUL_ELEM linear op.

    Parameters
    ----------
    lin_op : LinOp
        The mul_elem linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix representing the mul_elemwise operation.
    """
    constant = const_mat(lin_op.data)
    # Convert the constant to a giant diagonal matrix.
    vectorized = intf.from_2D_to_1D(flatten(constant))
    return [sp.diags(vectorized, 0).tocsc()]

def promote_mat(lin_op):
    """Returns the coefficient matrix for PROMOTE linear op.

    Parameters
    ----------
    lin_op : LinOp
        The promote linear op.

    Returns
    -------
    list of NumPy matrix
        The matrix for scalar promotion.
    """
    num_entries = lin_op.size[0]*lin_op.size[1]
    coeff = np.ones((num_entries, 1))
    return [np.matrix(coeff)]

def mul_mat(lin_op):
    """Returns the coefficient matrix for MUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The mul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the left operator.
    """
    constant = const_mat(lin_op.data)
    # Scalars don't need to be replicated.
    if not intf.is_scalar(constant):
        constant = sp.block_diag(lin_op.size[1]*[constant]).tocsc()
    return [constant]

def rmul_mat(lin_op):
    """Returns the coefficient matrix for RMUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The rmul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the right operator.
    """
    constant = const_mat(lin_op.data)
    # Scalars don't need to be replicated.
    if not intf.is_scalar(constant):
        # Matrix is the kronecker product of constant.T and identity.
        # Each column in the product is a linear combination of the
        # columns of the left hand multiple.
        constant = sp.kron(constant.T, sp.eye(lin_op.size[0])).tocsc()
    return [constant]

def index_mat(lin_op):
    """Returns the coefficient matrix for indexing.

    Parameters
    ----------
    lin_op : LinOp
        The index linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix for the index/slice operation.
    """
    key = lin_op.data
    rows, cols = lin_op.args[0].size
    row_selection = range(rows)[key[0]]
    col_selection = range(cols)[key[1]]
    # Construct a coo matrix.
    val_arr = []
    row_arr = []
    col_arr = []
    counter = 0
    for col in col_selection:
        for row in row_selection:
            val_arr.append(1.0)
            row_arr.append(counter)
            col_arr.append(col*rows + row)
            counter += 1
    block_rows = lin_op.size[0]*lin_op.size[1]
    block_cols = rows*cols
    return [sp.coo_matrix((val_arr, (row_arr, col_arr)),
                          (block_rows, block_cols)).tocsc()]

def transpose_mat(lin_op):
    """Returns the coefficient matrix for TRANSPOSE linear op.

    Parameters
    ----------
    lin_op : LinOp
        The transpose linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix for the transpose operation.
    """
    rows, cols = lin_op.size
    # Create a sparse matrix representing the transpose.
    val_arr = []
    row_arr = []
    col_arr = []
    for col in range(cols):
        for row in range(rows):
            # Index in transposed coeff.
            row_arr.append(col*rows + row)
            # Index in original coeff.
            col_arr.append(row*cols + col)
            val_arr.append(1.0)

    return [sp.coo_matrix((val_arr, (row_arr, col_arr)),
                          (rows*cols, rows*cols)).tocsc()]

def diag_vec_mat(lin_op):
    """Returns the coefficient matrix for DIAG_VEC linear op.

    Parameters
    ----------
    lin_op : LinOp
        The diag vec linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix representing placing a vector on a diagonal.
    """
    rows, _ = lin_op.size

    val_arr = []
    row_arr = []
    col_arr = []
    for i in range(rows):
        # Index in the diagonal matrix.
        row_arr.append(i*rows + i)
        # Index in the original vector.
        col_arr.append(i)
        val_arr.append(1.0)

    return [sp.coo_matrix((val_arr, (row_arr, col_arr)),
                          (rows**2, rows)).tocsc()]

def diag_mat_mat(lin_op):
    """Returns the coefficients matrix for DIAG_MAT linear op.

    Parameters
    ----------
    lin_op : LinOp
        The diag mat linear op.

    Returns
    -------
    SciPy CSC matrix
        The matrix to extract the diagonal from a matrix.
    """
    rows, _ = lin_op.size

    val_arr = []
    row_arr = []
    col_arr = []
    for i in range(rows):
        # Index in the original matrix.
        col_arr.append(i*rows + i)
        # Index in the extracted vector.
        row_arr.append(i)
        val_arr.append(1.0)

    return [sp.coo_matrix((val_arr, (row_arr, col_arr)),
                          (rows, rows**2)).tocsc()]

def upper_tri_mat(lin_op):
    """Returns the coefficients matrix for UPPER_TRI linear op.

    Parameters
    ----------
    lin_op : LinOp
        The upper tri linear op.

    Returns
    -------
    SciPy CSC matrix
        The matrix to vectorize the upper triangle.
    """
    rows, cols = lin_op.args[0].size

    val_arr = []
    row_arr = []
    col_arr = []
    count = 0
    for i in range(rows):
        for j in range(cols):
            if j > i:
                # Index in the original matrix.
                col_arr.append(j*rows + i)
                # Index in the extracted vector.
                row_arr.append(count)
                val_arr.append(1.0)
                count += 1

    entries, _ = lin_op.size
    return [sp.coo_matrix((val_arr, (row_arr, col_arr)),
                          (entries, rows*cols)).tocsc()]

def conv_mat(lin_op):
    """Returns the coefficient matrix for CONV linear op.

    Parameters
    ----------
    lin_op : LinOp
        The conv linear op.

    Returns
    -------
    list of NumPy matrices
        The matrix representing the convolution operation.
    """
    constant = const_mat(lin_op.data)
    # Cast to 1D.
    constant = intf.from_2D_to_1D(constant)

    # Create a Toeplitz matrix with constant as columns.
    rows = lin_op.size[0]
    nonzeros = lin_op.data.size[0]
    toeplitz_col = np.zeros(rows)
    toeplitz_col[0:nonzeros] = constant

    cols = lin_op.args[0].size[0]
    toeplitz_row = np.zeros(cols)
    toeplitz_row[0] = constant[0]
    coeff = sp_la.toeplitz(toeplitz_col, toeplitz_row)

    return [np.matrix(coeff)]

def kron_mat(lin_op):
    """Returns the coefficient matrix for KRON linear op.

    Parameters
    ----------
    lin_op : LinOp
        The conv linear op.

    Returns
    -------
    list of SciPy CSC matrix
        The matrix representing the Kronecker product.
    """
    constant = const_mat(lin_op.data)
    lh_rows, lh_cols = constant.shape
    rh_rows, rh_cols = lin_op.args[0].size
    # Stack sections for each column of the output.
    col_blocks = []
    for j in range(lh_cols):
        # Vertically stack A_{ij}Identity.
        blocks = []
        for i in range(lh_rows):
            blocks.append(constant[i, j]*sp.eye(rh_rows))
        column = sp.vstack(blocks)
        # Make block diagonal matrix by repeating column.
        col_blocks.append( sp.block_diag(rh_cols*[column]) )
    coeff = sp.vstack(col_blocks).tocsc()

    return [coeff]

def stack_mats(lin_op, vertical):
    """Returns the coefficient matrices for VSTACK or HSTACK linear op.

    Parameters
    ----------
    lin_op : LinOp
        The stacked linear op.
    vertical : bool
        Is the stacking vertical?

    Returns
    -------
    list of SciPy CSC matrix
        The matrices representing the stacking operation.
    """
    offset = 0
    coeffs = []
    # Make a coefficient for each argument:
    # an identity with an offset.
    for arg in lin_op.args:
        val_arr = []
        row_arr = []
        col_arr = []
        # In hstack, the arguments are laid out in order.
        # In vstack, the arguments' columns are interleaved.
        if vertical:
            col_offset = lin_op.size[0]
            offset_incr = arg.size[0]
        else:
            col_offset = arg.size[0]
            offset_incr = arg.size[0]*arg.size[1]

        for i in range(arg.size[0]):
            for j in range(arg.size[1]):
                row_arr.append(i + j*col_offset + offset)
                col_arr.append(i + j*arg.size[0])
                val_arr.append(1)

        shape = (lin_op.size[0]*lin_op.size[1],
                 arg.size[0]*arg.size[1])
        coeff = sp.coo_matrix((val_arr, (row_arr, col_arr)), shape).tocsc()
        coeffs.append(coeff)
        offset += offset_incr
    return coeffs

# A list of all the linear operator types for constants.
CONSTANT_TYPES = [lo.PARAM, lo.SCALAR_CONST, lo.DENSE_CONST, lo.SPARSE_CONST]

# A map of LinOp type to the coefficient matrix function.
TYPE_TO_FUNC = {
    lo.PROMOTE: promote_mat,
    lo.NEG: neg_mat,
    lo.MUL: mul_mat,
    lo.RMUL: rmul_mat,
    lo.MUL_ELEM: mul_elemwise_mat,
    lo.DIV: div_mat,
    lo.SUM_ENTRIES: sum_entries_mat,
    lo.TRACE: trace_mat,
    lo.INDEX: index_mat,
    lo.TRANSPOSE: transpose_mat,
    lo.RESHAPE: lambda lin_op: [1],
    lo.SUM: lambda lin_op: [1]*len(lin_op.args),
    lo.DIAG_VEC: diag_vec_mat,
    lo.DIAG_MAT: diag_mat_mat,
    lo.UPPER_TRI: upper_tri_mat,
    lo.CONV: conv_mat,
    lo.KRON: kron_mat,
    lo.HSTACK: lambda lin_op: stack_mats(lin_op, False),
    lo.VSTACK: lambda lin_op: stack_mats(lin_op, True),
}
<commit_msg>remove lin to matrix<commit_after><|endoftext|>


<commit_before>from .views import APIView

from pyramid.httpexceptions import HTTPNotFound
from sqlalchemy import Column
from sqlalchemy.orm.exc import NoResultFound

class ModelAPIView(APIView):

    model = None                # SQLAlchemy model class
    schema_class = None         # marshmallow schema class
    filter_fields = None        # list of Column objects
    lookup_column = 'id'
    pagination_class = None     # todo make default configurable

    def get_query(self):
        assert self.model is not None, (
            "'%s' should include a `model` attribute, "
            "or override the `get_query()` method."
            % self.__class__.__name__
        )

        return self.request.dbsession.query(self.model)

    def get_object(self):
        query = self.filter_query(self.get_query())

        # If query joins more than one table lookup_column must be a
        # tuple of the model class and a string of the column name.

        if isinstance(self.lookup_column, str):
            lookup_col = Column(self.lookup_column)
            lookup_val = self.url_lookup_kwargs[self.lookup_column]
        else:
            assert isinstance(self.lookup_column, tuple), (
                "'%s' `lookup_column` attribute should be a string or a tuple of (<model class>, `column`) "
                % self.__class__.__name__
            )

            lookup_col = getattr(self.lookup_column[0], self.lookup_column[1])
            lookup_val = self.url_lookup_kwargs[self.lookup_column[1]]

        try:
            instance = query.filter(lookup_col == lookup_val).one()
        except NoResultFound:
            raise HTTPNotFound()

        return instance

    def get_schema_class(self):
        """
        Return the class to use for the serializer.
        Defaults to using `self.serializer_class`.

        You may want to override this if you need to provide different
        serializations depending on the incoming request.
        """

        assert self.schema_class is not None, (
            "'%s' should either include a `schema_class` attribute, "
            "or override the `get_schema_class()` method."
            % self.__class__.__name__
        )

        return self.schema_class

    def get_schema(self, *args, **kwargs):
        klass = self.get_schema_class()
        return klass(*args, **kwargs, context=dict(request=self.request))

    def filter_query(self, query):
        filter_list = []

        if self.filter_fields and self.request.params:
            available_fields = list(map(lambda x: x.name, self.filter_fields))

            for key, val in self.request.params.items():
                try:
                    i = available_fields.index(key)
                except ValueError:
                    continue

                filter_list.append(self.filter_fields[i] == val)

        return query.filter(*filter_list) if filter_list else query

    @property
    def paginator(self):
        """
        The paginator instance associated with the view, or `None`.
        """

        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()

        return self._paginator

    def paginate_query(self, query):
        """
        Return single page of results or `None` if pagination is disabled.
        """

        if self.paginator is None:
            return None

        return self.paginator.paginate_query(query, self.request)

    def get_paginated_response(self, data):
        """
        Return a paginated style `Response` object for the given output data.
        """

        assert self.paginator is not None
        return self.paginator.get_paginated_response(data)
<commit_msg>clean up<commit_after>from .views import APIView

from pyramid.httpexceptions import HTTPNotFound
from sqlalchemy import Column
from sqlalchemy.orm.exc import NoResultFound

__all__ = ['ModelAPIView']

class ModelAPIView(APIView):
    model = None  # SQLAlchemy model class
    schema_class = None  # marshmallow schema class
    filter_fields = None  # list of Column objects
    lookup_column = 'id'
    pagination_class = None  # todo make default configurable

    def get_query(self):
        assert self.model is not None, (
            "'%s' should include a `model` attribute, "
            "or override the `get_query()` method."
            % self.__class__.__name__
        )

        return self.request.dbsession.query(self.model)

    def get_object(self):
        query = self.filter_query(self.get_query())

        # If query joins more than one table lookup_column must be a
        # tuple of the model class and a string of the column name.

        if isinstance(self.lookup_column, str):
            lookup_col = Column(self.lookup_column)
            lookup_val = self.url_lookup_kwargs[self.lookup_column]
        else:
            assert isinstance(self.lookup_column, tuple), (
                "'%s' `lookup_column` attribute should be a string or a tuple of (<model class>, `column`) "
                % self.__class__.__name__
            )

            lookup_col = getattr(self.lookup_column[0], self.lookup_column[1])
            lookup_val = self.url_lookup_kwargs[self.lookup_column[1]]

        try:
            instance = query.filter(lookup_col == lookup_val).one()
        except NoResultFound:
            raise HTTPNotFound()

        return instance

    def get_schema_class(self):
        """
        Return the class to use for the serializer.
        Defaults to using `self.serializer_class`.

        You may want to override this if you need to provide different
        serializations depending on the incoming request.
        """

        assert self.schema_class is not None, (
            "'%s' should either include a `schema_class` attribute, "
            "or override the `get_schema_class()` method."
            % self.__class__.__name__
        )

        return self.schema_class

    def get_schema(self, *args, **kwargs):
        klass = self.get_schema_class()
        return klass(*args, **kwargs, context=dict(request=self.request))

    def filter_query(self, query):
        filter_list = []

        if self.filter_fields and self.request.params:
            available_fields = list(map(lambda x: x.name, self.filter_fields))

            for key, val in self.request.params.items():
                try:
                    i = available_fields.index(key)
                except ValueError:
                    continue

                filter_list.append(self.filter_fields[i] == val)

        return query.filter(*filter_list) if filter_list else query

    @property
    def paginator(self):
        """
        The paginator instance associated with the view, or `None`.
        """

        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()

        return self._paginator

    def paginate_query(self, query):
        """
        Return single page of results or `None` if pagination is disabled.
        """

        if self.paginator is None:
            return None

        return self.paginator.paginate_query(query, self.request)

    def get_paginated_response(self, data):
        """
        Return a paginated style `Response` object for the given output data.
        """

        assert self.paginator is not None
        return self.paginator.get_paginated_response(data)
<|endoftext|>


<commit_before>import pytest
from pyethereum import tester, utils, abi

serpent_contract = """
extern solidity: [sub:_:i]

def main(a):
    return(a.sub() * 2)

def sub():
    return(5)

"""

solidity_contract = """
contract foo {
    function main(address a) returns (int256 y) {
        y = a.sub() * 2;
    }
    function sub() returns (int256 y) {
        y = 7;
    }
}

"""

def test_interop():
    s = tester.state()
    c1 = s.abi_contract(serpent_contract)
    c2 = s.abi_contract(solidity_contract, language='solidity')
    assert c1.sub() == 5
    assert c2.sub() == 7
    assert c1.main(c2.address) == 14
    assert c2.main(c1.address) == 10
<commit_msg>Updated testcase<commit_after>import pytest
from pyethereum import tester, utils, abi

serpent_contract = """
extern solidity: [sub2:_:i]

def main(a):
    return(a.sub2() * 2)

def sub1():
    return(5)

"""

solidity_contract = """
contract serpent { function sub1() returns (int256 y) {} }

contract foo {
    function main(address a) returns (int256 y) {
        y = serpent(a).sub1() * 2;
    }
    function sub2() returns (int256 y) {
        y = 7;
    }
}

"""

def test_interop():
    s = tester.state()
    c1 = s.abi_contract(serpent_contract)
    c2 = s.abi_contract(solidity_contract, language='solidity')
    assert c1.sub1() == 5
    assert c2.sub2() == 7
    assert c1.main(c2.address) == 14
    print c2.main(c1.address, output='raw').encode('hex')
    assert c2.main(c1.address) == 10
<|endoftext|>