-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
120 lines (103 loc) · 4 KB
/
app.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
120
# Created: August 2020
# Author: Aaron Mansheim <[email protected]>
from flask import Flask
from flask import request
from flask import make_response
import json
import jsonschema
import suffix_trees.STree
class MySTree(suffix_trees.STree.STree):
# Overrides library code with changes, in order to
# return every lcs, not only the first one.
# The changes can be sent to the library's GitHub project as pull requests.
def lcs(self, stringIdxs=-1):
"""Returns the Largest Common Substrings of Strings provided in stringIdxs.
If stringIdxs is not provided, the LCS's of all strings are returned.
::param stringIdxs: Optional: List of indexes of strings.
"""
if stringIdxs == -1 or not isinstance(stringIdxs, list):
stringIdxs = set(range(len(self.word_starts)))
else:
stringIdxs = set(stringIdxs)
deepestNodes = self._find_lcs(self.root, stringIdxs)
return [self.word[n.idx:n.idx + n.depth]
for n in deepestNodes]
# Overrides library code with changes, in order to
# return every lcs, not only the first one.
# The changes can be sent to the library's GitHub project as pull requests.
def _find_lcs(self, node, stringIdxs):
"""Helper method that finds LCS's by traversing the labeled GST."""
nodes = [deepestNode
for n in node.transition_links.values()
if n.generalized_idxs.issuperset(stringIdxs)
for deepestNode in self._find_lcs(n, stringIdxs)]
if nodes == []:
return [node]
deepestNode = max(nodes, key=lambda n: n.depth)
deepestNodes = [n for n in nodes if n.depth == deepestNode.depth]
return deepestNodes
# The library's version 0.3.0 is limited to this many strings.
content_length_limit = 137465
app = Flask(__name__)
@app.route('/lcs', methods=['POST'])
def lcs():
BAD_FORMAT = 'The format of the request was not acceptable. '
if content_length_limit <= request.content_length:
return make_response(
BAD_FORMAT + 'Too much content.',
413)
elif request.content_length <= 0:
return make_response(
BAD_FORMAT + 'No content.',
400)
data = request.get_data()
try:
request_json = json.loads(data)
except json.JSONDecodeError:
return make_response(
BAD_FORMAT + 'Not understood as JSON.',
400)
try:
jsonschema.validate(
instance=request_json,
schema={
'type': 'object',
'properties': {
'setOfStrings': {
'type': 'array',
# 'minItems': 1,
'items': {
'type': 'object',
'properties': {
'value': {
'type': 'string'
}
}
}
}
}
}
)
except ValidationError:
return make_response(
BAD_FORMAT + 'Not in the correct format.',
400)
values = [item['value'] for item in request_json['setOfStrings']]
if not values:
return make_response(
BAD_FORMAT + 'setOfStrings should not be empty.',
400)
if len(set(values)) < len(values):
return make_response(
BAD_FORMAT + 'setOfStrings must be a Set.',
400)
tree = MySTree(values)
result = sorted(tree.lcs())
response_json = json.dumps(
{
'lcs': [{'value': value} for value in result]
},
separators=(',', ':'))
response = make_response(response_json)
response.mimetype = 'application/json'
return response