-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathanonymizer-api.py
119 lines (99 loc) · 3.78 KB
/
anonymizer-api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
This file holds the anonymizer API service
which exposes an RESTful API for inquering
anonymization tasks of a user.
"""
from flask import Flask, request
from flask_restful import reqparse, abort, Resource, Api
import anonymizer
import sys
import string
import random
import json
import redis
app = Flask(__name__)
api = Api(app)
settings = {}
sys.path.append('./')
# fetch credentials from file
def fetch_credentials():
with open('credentials.json') as credentials_file:
return json.load(credentials_file)
def abort_if_job_doesnt_exist(job_id):
if r.get(job_id) is None:
abort(404, message="Job {} doesn't exist".format(job_id))
def abort_if_job_arguments_missing(args):
if "partner_id" not in args:
abort(404, message="partner_id specs are missing")
if "columns" not in args:
abort(404, message="columns specs are missing")
# generates (user) IDs
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
settings = fetch_credentials()
# connect to the redis server
r = redis.StrictRedis(
host=settings["redis"]["host"],
port=settings["redis"]["port"],
db=0
)
parser = reqparse.RequestParser()
parser.add_argument('columns', type = list)
parser.add_argument('partner_id', type = int)
# Job
# shows a single jobs item and lets you delete a todo item
class Job(Resource):
def get(self, job_id):
abort_if_job_doesnt_exist(job_id)
return r.get(job_id)
def delete(self, job_id):
abort_if_job_doesnt_exist(job_id)
return r.delete(job_id), 204
def put(self, job_id):
args = parser.parse_args()
abort_if_job_doesnt_exist(job_id)
abort_if_job_arguments_missing(args)
# since reqparse does not know how to handle JSON properly:
# https://stackoverflow.com/questions/19384526/how-to-parse-the-post-argument-to-a-rest-service
requested_columns = request.json['columns']
value = r.get(key).decode("utf-8")
task = json.loads(value)
task['columns'] = requested_columns
r.set(job_id, json.dumps(task))
return task, 201
# JobList
# shows a list of all jobs, and lets you POST to add new tasks
class JobList(Resource):
def get(self):
result = []
for key in r.scan_iter():
value = r.get(key).decode("utf-8")
result.append(value)
return result
def post(self):
print("recieved request")
args = parser.parse_args()
abort_if_job_arguments_missing(args)
job_id = str(args['partner_id']) +"_"+id_generator()+"_"+id_generator()
table_name = str(args['partner_id']) +"_"+id_generator()
# since reqparse does not know how to handle JSON properly:
# https://stackoverflow.com/questions/19384526/how-to-parse-the-post-argument-to-a-rest-service
requested_columns = request.json['columns']
task = {'job_id':job_id, 'columns': requested_columns, 'partner_id':args['partner_id'], 'table_name':table_name, 'status':'open'}
df = anonymizer.retrieve_meta_data()
colnames = list(df.columns.values)
for req_colname in requested_columns:
if req_colname not in colnames:
error_message = "{0} is not a valid attribute".format(req_colname)
task['status'] = 'failed'
task['cause'] = error_message
return task, 400
r.set(job_id, json.dumps(task))
return task, 201
##
## Actually setup the Api resource routing here
##
api.add_resource(JobList, '/jobs')
api.add_resource(Job, '/jobs/<job_id>')
if __name__ == '__main__':
app.run(debug=True)