Skip to content

Commit f7076b7

Browse files
authored
Merge pull request #89 from amal-thundiyil/build
Fixed build errors and added Docker
2 parents e1e13b1 + 684e979 commit f7076b7

File tree

14 files changed

+23544
-10294
lines changed

14 files changed

+23544
-10294
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
Fixes #
55

66
### Checklist
7+
78
- [ ] My branch is up-to-date with upstream/develop branch.
8-
- [ ] Everything works and tested for Python 3.5.2 and above.
9+
- [ ] Everything works and tested for Python 3.8 and above.
910

1011
### Description
12+
1113
<!-- Describe about what this PR does, previous state and new state of the output -->
1214

1315
### Change logs
@@ -17,18 +19,15 @@ Fixes #
1719
<!-- - Feature 1 -->
1820
<!-- - Feature 2 -->
1921

20-
2122
<!-- #### Changed -->
2223
<!-- Edit these points below to describe the changes made in existing functionality with this PR -->
2324
<!-- - Change 1 -->
2425
<!-- - Change 1 -->
2526

26-
2727
<!-- #### Fixed -->
2828
<!-- Edit these points below to describe the bug fixes made with this PR -->
2929
<!-- - Bug 1 -->
3030

31-
3231
<!-- #### Removed -->
3332
<!-- Edit these points below to describe the removed features with this PR -->
3433
<!-- - Deprecated feature 1 -->

.travis.yml

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
1-
language: node_js
2-
node_js:
3-
- "node"
4-
5-
script:
6-
- cd console-frontend
7-
- npm install
8-
- npm run lint
1+
jobs:
2+
include:
3+
- language: node_js
4+
node: "node"
5+
6+
script:
7+
- cd console-frontend
8+
- npm install
9+
- npm run lint
10+
11+
- language: python
12+
python:
13+
- "3.8"
14+
- "3.8-dev" # 3.8 development branch
15+
16+
services:
17+
- docker
18+
19+
before_script:
20+
- docker run -d -p 6379:6379 -it --rm --name redisgraph redislabs/redisgraph:2.0-edge
21+
22+
install:
23+
- pip install -r requirements.txt --no-cache
24+
25+
script:
26+
- echo "skipping tests"

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM python:3
2+
3+
WORKDIR /app
4+
5+
COPY ./requirements.txt requirements.txt
6+
7+
RUN pip install -U pip && pip install --upgrade pip setuptools \
8+
&& pip install -r requirements.txt
9+
10+
COPY . /app
11+
12+
ENV PYTHONPATH "${PYTHONPATH}:/app"
13+
14+
ENV MESSAGE "Hail Hydra"

app.py

Lines changed: 205 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
from flask_cors import CORS
33
from hydra_agent.agent import Agent
44
import sys
5-
import json, os
6-
from requests import get
5+
import json
6+
import os
77

8-
from lib.utils import serve, start_agent, hydra_doc, apidoc_graph, send_command, default
9-
10-
app = Flask(__name__, static_folder='console-frontend/build/')
8+
app = Flask(__name__, static_folder="console-frontend/build/")
119

1210
# Setting CORS so it allows requests from our React app in localhost:3000
1311
CORS(app, resources={r"*": {"origins": "http://localhost:3000"}})
@@ -16,13 +14,208 @@
1614
url = "http://localhost:8080/serverapi"
1715
agent = Agent(url)
1816

19-
app.add_url_rule('/<path:path>', 'serve', serve)
20-
app.add_url_rule('/start-agent', 'start-agent', start_agent)
21-
app.add_url_rule('/hydra-doc', 'hydra-doc', hydra_doc)
22-
app.add_url_rule('/apidoc-graph', 'apidoc-graph', apidoc_graph)
23-
app.add_url_rule('/send-command', 'send-command', send_command)
24-
app.add_url_rule('/','default', default)
17+
18+
@app.route("/", defaults={"path": ""})
19+
@app.route("/<path:path>")
20+
def serve(path):
21+
"""Default endpoint, it serves the built static React App
22+
:return: Served file
23+
"""
24+
file_path = os.path.join(app.static_folder, path)
25+
if path != "" and os.path.exists(file_path):
26+
return send_from_directory(app.static_folder, path)
27+
else:
28+
return send_from_directory(app.static_folder, "index.html")
29+
30+
31+
@app.route("/start-agent", methods=["POST"])
32+
def start_agent():
33+
"""Receive hydrus server URL and start the Agent
34+
:param body['url']: Entrypoint URL for the hydrus server
35+
:return: Success message
36+
"""
37+
global agent
38+
global url
39+
body = request.get_data()
40+
body = body.decode("utf8").replace("'", '"')
41+
body = json.loads(body)
42+
url = body["url"]
43+
agent = Agent(url)
44+
return "Server started successfully"
45+
46+
47+
@app.route("/hydra-doc", methods=["GET"])
48+
def hydra_doc():
49+
"""Serve Hydra Doc
50+
:return: Hydra Doc loaded on the agent with url for current connected
51+
"""
52+
apidoc = agent.fetch_apidoc()
53+
generatedApiDoc = apidoc.generate()
54+
generatedApiDoc["serverURL"] = url
55+
return generatedApiDoc
56+
57+
58+
@app.route("/apidoc-graph", methods=["GET"])
59+
def apidoc_graph():
60+
"""Sends Formatted ApiDoc Graph in Vis.js network format to Frontend
61+
:return: Dict containing Nodes and Edges
62+
"""
63+
global agent
64+
if agent is None:
65+
return "No agent connected."
66+
# Add the entrypoint node
67+
nodes = [{"id": 1, "shape": "hexagon", "size": 15, "label": "Entrypoint"}]
68+
edges = list()
69+
id = 1
70+
api_doc = agent.fetch_apidoc()
71+
for resource_endpoint in api_doc.entrypoint.entrypoint.supportedProperty:
72+
id += 1
73+
endpoint_id = id
74+
endpoint_path = resource_endpoint.id_.replace("vocab:EntryPoint/", "")
75+
endpoint_node = create_node(endpoint_id, "box", 12, endpoint_path)
76+
nodes.append(endpoint_node)
77+
edge = create_edge(1, endpoint_id)
78+
edges.append(edge)
79+
for supportedOp in resource_endpoint.supportedOperation:
80+
id += 1
81+
op_id = id
82+
operation_node = create_node(op_id, "circle", 10, supportedOp.method)
83+
nodes.append(operation_node)
84+
supportedOp_edge = create_edge(endpoint_id, op_id, "supportedOp")
85+
edges.append(supportedOp_edge)
86+
if supportedOp.expects:
87+
expects = supportedOp.expects
88+
else:
89+
expects = "null"
90+
if supportedOp.returns:
91+
returns = supportedOp.returns
92+
else:
93+
returns = "null"
94+
# Extract class name
95+
if "vocab:" in expects:
96+
expects = expects.replace("vocab:", "")
97+
if "vocab:" in returns:
98+
returns = returns.replace("vocab:", "")
99+
id += 1
100+
expected_class_node = create_node(id, "circle", 8, expects)
101+
nodes.append(expected_class_node)
102+
expects_edge = create_edge(op_id, id, "expects")
103+
edges.append(expects_edge)
104+
if expects in api_doc.parsed_classes:
105+
class_id = id
106+
for supportedProp in api_doc.parsed_classes[expects][
107+
"class"
108+
].supportedProperty:
109+
id += 1
110+
property_node = create_node(id, "box", 7, supportedProp.title)
111+
nodes.append(property_node)
112+
property_edge = create_edge(class_id, id, "supportedProp")
113+
edges.append(property_edge)
114+
id += 1
115+
returned_class_node = create_node(id, "circle", 8, returns)
116+
nodes.append(returned_class_node)
117+
returns_edge = create_edge(op_id, id, "returns")
118+
edges.append(returns_edge)
119+
if returns in api_doc.parsed_classes:
120+
class_id = id
121+
for supportedProp in api_doc.parsed_classes[returns][
122+
"class"
123+
].supportedProperty:
124+
id += 1
125+
property_node = create_node(id, "box", 7, supportedProp.title)
126+
nodes.append(property_node)
127+
property_edge = create_edge(class_id, id, "supportedProp")
128+
edges.append(property_edge)
129+
graph = {"nodes": nodes, "edges": edges}
130+
return graph
131+
132+
133+
def create_node(id, shape, size, label):
134+
"""Auxiliary function that creates a Node in Vis.js format
135+
:return: Dict with Node attributes
136+
"""
137+
node = {
138+
"id": id,
139+
"shape": shape,
140+
"size": size,
141+
"label": label,
142+
"color": {"background": "#FBD20B"},
143+
}
144+
return node
145+
146+
147+
def create_edge(from_, to, label=None):
148+
"""Auxiliary function that creates a Edge in Vis.js format
149+
:return: Dict with Edge attributes
150+
"""
151+
edge = {"from": from_, "to": to}
152+
if label is not None:
153+
edge["label"] = label
154+
return edge
155+
156+
157+
@app.route("/send-command", methods=["POST"])
158+
def send_command():
159+
"""Send Command to Agent and returns hydrus response
160+
:param: All parameters enabled by the Agent.
161+
:param: Please check Agent.py in Agent's main repository.
162+
:return: hydrus response to the request
163+
"""
164+
global agent
165+
if agent is None:
166+
return "No agent connected."
167+
body = request.get_data()
168+
body = body.decode("utf8")
169+
body = json.loads(body)
170+
if "method" not in body:
171+
return "Request must have a method."
172+
if body["method"] == "get":
173+
# Get optional parameters
174+
filters = body.get("filters", {})
175+
cached_limit = body.get("cached_limit", sys.maxsize)
176+
if "url" in body:
177+
return json.dumps(
178+
agent.get(url=body["url"], filters=filters, cached_limit=cached_limit)
179+
)
180+
elif "resource_type" in body:
181+
return json.dumps(
182+
agent.get(
183+
resource_type=body["resource_type"],
184+
filters=filters,
185+
cached_limit=cached_limit,
186+
)
187+
)
188+
else:
189+
return "Must contain url or the resource type"
190+
elif body["method"] == "put":
191+
if "url" in body:
192+
url = body["url"]
193+
else:
194+
return "Put request must contain a url"
195+
if "new_object" in body:
196+
new_object = body["new_object"]
197+
else:
198+
return "Put request must contain the new_object."
199+
return json.dumps(agent.put(url, new_object))
200+
elif body["method"] == "post":
201+
if "url" in body:
202+
url = body["url"]
203+
else:
204+
return "Post request must contain a url"
205+
if "updated_object" in body:
206+
updated_object = body["updated_object"]
207+
else:
208+
return "Put request must contain the updated_object."
209+
return json.dumps(agent.post(url, updated_object))
210+
elif body["method"] == "delete":
211+
if "url" in body:
212+
url = body["url"]
213+
else:
214+
return "Delete request must contain a url"
215+
return json.dumps(agent.delete(url))
216+
else:
217+
return "Method not supported."
25218

26219

27-
if __name__ == '__main__':
220+
if __name__ == "__main__":
28221
app.run(use_reloader=True, port=3000, threaded=True)

0 commit comments

Comments
 (0)