Skip to content

Commit 0e6e93e

Browse files
committed
merging pandas release to main branch
2 parents 536176a + b4629a9 commit 0e6e93e

14 files changed

Lines changed: 2581 additions & 232 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ APIkeys
77
*.cgi
88
migration.py
99
shipping.py
10-
bookworm
1110
genderizer*
11+
*.pyc

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,17 @@ They are used with the [Bookworm GUI](https://github.com/econpy/BookwormGUI) and
66
For a more interactive explanation of how the GUI works, see the [D3 bookworm browser](http://github.com/bmschmidt/Presidio)
77

88
### General Description
9-
`dbbindings.py` is called as a CGI script and uses `APIimplementation.py` to construct a database query and return the data to the web client.
9+
`dbbindings.py` is called as a CGI script and uses a number of modules in `bookworm` to construct a database query and return the data to the web client.
1010

1111

1212
### Installation
1313

14-
On Ubuntu, you can simply run the `Makefile` to install dependencies for the API software.
15-
16-
```bash
17-
sudo make ubuntu-install
18-
```
19-
20-
However, you may wish to open the Makefile and see what is going on for yourself. The idea is to move the 3 python scripts to your cgi-bin, make them executable, and make the Apache user the owner of the files.
14+
Just put all the files in this repo into your core CGI-script folder. Hopefully we'll streamline a little bit soon.
2115

2216
### Usage
2317

2418
If the bookworm is located on your server, there is no need to do anything--it should be drag-and-drop. (Although on anything but debian, settings might require a small amount of tweaking.
25-
If you want to have the webserver and database server on different machines, that needs to be specified in the knownhosts.py.
19+
If you want to have the webserver and database server on different machines, that needs to be specified in the configuration file for mysql that this reads: if you want to have multiple mysql servers, you may need to get fancy.
20+
.
2621
This tells the API where to look for the data for a particular bookworm. The benefit of this setup is that you can have your webserver on one server and the database on another server.
22+

bookworm/#APIimplementation.py#

Lines changed: 727 additions & 0 deletions
Large diffs are not rendered by default.

bookworm/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
old/*
2+
*~
3+
APIkeys
4+
#*
5+
.#*

bookworm/APIimplementation.py

Lines changed: 846 additions & 0 deletions
Large diffs are not rendered by default.

bookworm/MetaWorm.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import pandas
2+
import json
3+
import copy
4+
import threading
5+
import time
6+
from collections import defaultdict
7+
8+
def hostlist(dblist):
9+
#This could do something fancier, but for now we look by default only on localhost.
10+
return ["localhost"]*len(dblist)
11+
12+
class childQuery(threading.Thread):
13+
def __init__(self,dictJSON,host):
14+
super(SummingThread, self).__init__()
15+
self.dict = json.dumps(dict)
16+
self.host = host
17+
18+
def runQuery(self):
19+
#make a webquery, assign it to self.data
20+
url = self.host + "/cgi-bin/bookwormAPI?query=" + self.dict
21+
22+
def parseResults(self):
23+
pass
24+
#return json.loads(self.data)
25+
26+
def run(self):
27+
self.runQuery()
28+
29+
def flatten(dictOfdicts):
30+
"""
31+
Recursive function: transforms a dict with nested entries like
32+
foo["a"]["b"]["c"] = 3
33+
to one with tuple entries like
34+
fooPrime[("a","b","c")] = 3
35+
"""
36+
output = []
37+
for (key,value) in dictOfdicts.iteritems():
38+
if isinstance(value,dict):
39+
output.append([(key),value])
40+
else:
41+
children = flatten(value)
42+
for child in children:
43+
output.append([(key,) + child[0],child[1]])
44+
return output
45+
46+
def animate(dictOfTuples):
47+
"""
48+
opposite of flatten
49+
"""
50+
51+
def tree():
52+
return defaultdict(tree)
53+
54+
output = defaultdict(tree)
55+
56+
57+
58+
def combineDicts(master,new):
59+
"""
60+
instead of a dict of dicts of arbitrary depth, use a dict of tuples to store.
61+
"""
62+
63+
for (keysequence, valuesequence) in flatten(new):
64+
try:
65+
master[keysequence] = map(sum,zip(master[keysequence],valuesequence))
66+
except KeyError:
67+
master[keysequence] = valuesequence
68+
return dict1
69+
70+
class MetaQuery(object):
71+
def __init__(self,dictJSON):
72+
self.outside_outdictionary = json.dumps(dictJSON)
73+
74+
def setDefaults(self):
75+
for specialKey in ["database","host"]:
76+
try:
77+
if isinstance(self.outside_dictionary[specialKey],basestring):
78+
#coerce strings to list:
79+
self.outside_dictionary[specialKey] = [self.outside_dictionary[specialKey]]
80+
except KeyError:
81+
#It's OK not to define host.
82+
if specialKey=="host":
83+
pass
84+
85+
if 'host' not in self.outside_dictionary:
86+
#Build a hostlist: usually just localhost a bunch of times.
87+
self.outside_dictionary['host'] = hostlist(self.outside_dictionary['database'])
88+
89+
for (target, dest) in [("database","host"),("host","database")]:
90+
#Expand out so you can search for the same database on multiple databases, or multiple databases on the same host.
91+
if len(self.outside_dictionary[target])==1 and len(self.outside_dictionary[dest]) != 1:
92+
self.outside_dictionary[target] = self.outside_dictionary[target] * len(self.outside_dictionary[dest])
93+
94+
95+
def buildChildren(self):
96+
desiredCounts = []
97+
for (host,dbname) in zip(self.outside_dictionary["host"],self.outside_dictionary["database"]):
98+
query = copy.deepcopy(self.outside_dictionary)
99+
del(query['host'])
100+
query['database'] = dbname
101+
102+
desiredCounts.append(childQuery(query,host))
103+
self.children = desiredCounts
104+
105+
def runChildren(self):
106+
for child in self.children:
107+
child.start()
108+
109+
def combineChildren(self):
110+
complete = dict()
111+
while (threading.enumerate()):
112+
for child in self.children:
113+
if not child.is_alive():
114+
complete=combineDicts(complete,child.parseResult())
115+
time.sleep(.05)
116+
117+
def return_json(self):
118+
pass
119+
120+
121+

0 commit comments

Comments
 (0)