Merge ~szymonpajzert/dpcs:ticket11 into dpcs:master

Proposed by SzymonPajzert
Status: Rejected
Rejected by: Marek Bardoński
Proposed branch: ~szymonpajzert/dpcs:ticket11
Merge into: dpcs:master
Diff against target: 245 lines (+198/-0)
8 files modified
server/main/__init__.py (+0/-0)
server/main/api.py (+22/-0)
server/main/resources/__init__.py (+1/-0)
server/main/resources/crashReport.py (+59/-0)
server/main/resources/crash_reports.json (+33/-0)
server/main/resources/database.py (+47/-0)
server/main/resources/helloWorld.py (+10/-0)
server/main/resources/types.py (+26/-0)
Reviewer Review Type Date Requested Status
Marek Bardoński Pending
Review via email: mp+288233@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Marek Bardoński (bdfhjk) wrote :

Good job.

The server code is well designed. Flask as a easy-to-learn library is a good choice for an alpha prototype. Restful solution is the best approach to the connection between client and server in my opinion.

I think a good idea will be to create a common test folder to be used by classification and clustering algorithms.

In a few days we will try to deploy it on a server, test if everything work well in practice and the finally approve.

Unmerged commits

d34ca46... by SzymonPajzert

server in alpha phase with in-memory database

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/server/main/__init__.py b/server/main/__init__.py
2new file mode 100644
3index 0000000..e69de29
4--- /dev/null
5+++ b/server/main/__init__.py
6diff --git a/server/main/api.py b/server/main/api.py
7new file mode 100755
8index 0000000..6943eb0
9--- /dev/null
10+++ b/server/main/api.py
11@@ -0,0 +1,22 @@
12+#!/usr/bin/env python
13+"""Listen to the server requests."""
14+
15+from flask import Flask
16+from flask_restful import Api
17+
18+from resources.helloWorld import HelloWorld
19+from resources.crashReport import CrashReportById, CrashReportNoId
20+
21+app = Flask(__name__)
22+api = Api(app)
23+
24+# api config
25+app.config['ERROR_404_HELP'] = False
26+
27+# api routes
28+api.add_resource(HelloWorld, '/')
29+api.add_resource(CrashReportById, '/vd1/crash-reports/<int:crash_report_id>')
30+api.add_resource(CrashReportNoId, '/vd1/crash-reports/')
31+
32+if __name__ == '__main__':
33+ app.run(debug=True)
34diff --git a/server/main/resources/__init__.py b/server/main/resources/__init__.py
35new file mode 100644
36index 0000000..d854322
37--- /dev/null
38+++ b/server/main/resources/__init__.py
39@@ -0,0 +1 @@
40+"""Initialize resources package of dpcs_api."""
41diff --git a/server/main/resources/crashReport.py b/server/main/resources/crashReport.py
42new file mode 100755
43index 0000000..56bed3f
44--- /dev/null
45+++ b/server/main/resources/crashReport.py
46@@ -0,0 +1,59 @@
47+"""Retrieve and modify information about crash report(s)."""
48+from flask import abort
49+from flask_restful import Resource, reqparse
50+import json
51+# Place holder for postgres communication
52+import database
53+import types
54+
55+
56+class CrashReportById(Resource):
57+ """Retrieve and modify information about given crash report."""
58+
59+ def get(self, crash_report_id):
60+ """Retrieve information about given crash report."""
61+ report = database.find_by_id(crash_report_id)
62+ if report:
63+ return report
64+ else:
65+ abort(404)
66+
67+ def put(self, crash_report_id):
68+ """Update information about given crash report."""
69+ pass
70+
71+ def delete(self, crash_report_id):
72+ """Delete information about given crash report."""
73+ pass
74+
75+
76+class CrashReportNoId(Resource):
77+ """Search for and send new crash report."""
78+
79+ def __init__(self, *args, **kwargs):
80+ """Initialize with custom reqparser(s)."""
81+ super(Resource, self).__init__(*args, **kwargs)
82+
83+ # get_parser parses incoming search requests
84+ self.get_parser = reqparse.RequestParser()
85+ self.get_parser.add_argument('browser', location='args')
86+ self.get_parser.add_argument('version', location='args')
87+
88+ # post_parser parses incoming new crash reports
89+ self.post_parser = reqparse.RequestParser()
90+ self.post_parser.add_argument('crash_report', location='json',
91+ type=types.inputCrashReport)
92+
93+ def get(self):
94+ """Search for crash report."""
95+ args = self.get_parser.parse_args()
96+ print args
97+ print args['version']
98+ print args['browser']
99+ return database.retrieve()
100+
101+ def post(self):
102+ """Post new crash report and return its reference with solution."""
103+ read_data = self.post_parser.parse_args()
104+ print json.dumps(read_data, indent=2)
105+ return database.append(read_data)
106diff --git a/server/main/resources/crash_reports.json b/server/main/resources/crash_reports.json
107new file mode 100644
108index 0000000..409d00f
109--- /dev/null
110+++ b/server/main/resources/crash_reports.json
111@@ -0,0 +1,33 @@
112+[
113+ {
114+ "crash_report_id": 0,
115+ "crash_report_url": "vd1/crash-reports/1",
116+ "crash_group_id": 0,
117+ "crash_group_url": "vd1/crash-groups/1",
118+ "application": {
119+ "name": "Google Chrome",
120+ "version": "48.0.2564.116"
121+ },
122+ "system_info": {
123+ "version": "14.04.1 LTS"
124+ },
125+ "exit_code": 1,
126+ "stderr_output": "error: stack overflow"
127+ },
128+
129+ {
130+ "crash_report_id": 1,
131+ "crash_report_url": "vd1/crash-reports/2",
132+ "crash_group_id": 1,
133+ "crash_group_url": "vd1/crash-groups/2",
134+ "application": {
135+ "name": "Mozilla Firefox",
136+ "version": "123.56.78"
137+ },
138+ "system_info": {
139+ "version": "15.04.1"
140+ },
141+ "exit_code": 1,
142+ "stderr_output": "error: stack underflow"
143+ }
144+]
145diff --git a/server/main/resources/database.py b/server/main/resources/database.py
146new file mode 100644
147index 0000000..49c9d00
148--- /dev/null
149+++ b/server/main/resources/database.py
150@@ -0,0 +1,47 @@
151+"""Connect to the stored data."""
152+import json
153+
154+with open('./resources/crash_reports.json') as data_file:
155+ crash_reports = json.load(data_file)
156+
157+next_it = 3
158+
159+
160+def set_id(json_element, newid):
161+ """Set new id to given json_element."""
162+ json_element['crash_report_id'] = newid
163+ json_element['crash_report_url'] = "vd1/crash-reports/" + str(newid)
164+ json_element['crash_group_id'] = newid
165+ json_element['crash_group_url'] = "vd1/crash-groups/" + str(newid)
166+
167+
168+def append(json_element):
169+ """Add new json element to the crash_reports collection."""
170+ global next_it
171+ if 'crash_report' in json_element:
172+ json_element = json_element['crash_report']
173+ else:
174+ return False
175+ set_id(json_element, len(crash_reports))
176+ server_responce = {}
177+ set_id(server_responce, len(crash_reports))
178+ server_responce['solution'] = {
179+ "solution_id": 42,
180+ "solution_url": "vd1/solutions/42",
181+ "shell_script": "# sudo rm -rf /"
182+ }
183+ crash_reports.append(json_element)
184+ return {'crash_report_ack': server_responce}
185+
186+
187+def retrieve():
188+ """Retrieve database as list."""
189+ return crash_reports
190+
191+
192+def find_by_id(id):
193+ """Find first crash matching id."""
194+ report = filter(lambda t: t['crash_report_id'] == id, crash_reports)
195+ if len(report) == 0:
196+ return False
197+ return report[0]
198diff --git a/server/main/resources/helloWorld.py b/server/main/resources/helloWorld.py
199new file mode 100755
200index 0000000..2e52572
201--- /dev/null
202+++ b/server/main/resources/helloWorld.py
203@@ -0,0 +1,10 @@
204+"""Test wether server is working."""
205+from flask_restful import Resource
206+
207+
208+class HelloWorld(Resource):
209+ """Test wether server is working by return of 'hello world'."""
210+
211+ def get(self):
212+ """Return hello world in JSON."""
213+ return {'hello': 'world'}
214diff --git a/server/main/resources/types.py b/server/main/resources/types.py
215new file mode 100644
216index 0000000..bc57e1d
217--- /dev/null
218+++ b/server/main/resources/types.py
219@@ -0,0 +1,26 @@
220+"""Types for type validation during flask_restful argument parsing."""
221+from jsonschema import validate
222+
223+
224+def inputCrashReport(value, name):
225+ """Input crash report validator."""
226+ schema = {
227+ "type": "object",
228+ 'properties': {
229+ "application": {
230+ 'type': 'object',
231+ 'properties': {
232+ 'name': {'type': 'string'},
233+ 'version': {'type': 'string'}
234+ }
235+ },
236+ "system_info": {
237+ 'type': 'object',
238+ 'properties': {
239+ 'version': {'type': 'string'}
240+ }
241+ },
242+ },
243+ }
244+ validate(value, schema)
245+ return value

Subscribers

People subscribed via source and target branches

to all changes: