Skip to content

Commit

Permalink
Merge pull request #33 from Process-Discovery-Log-Skeleton/server
Browse files Browse the repository at this point in the history
✨ The Event-Store is now memory based. + Some server improvments.
  • Loading branch information
quangtinator authored Dec 15, 2020
2 parents 936c254 + e2f9412 commit 172d297
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 27 deletions.
52 changes: 34 additions & 18 deletions src/api/server.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
"""Implemenation of the REST-API endpoint."""

from flask import Flask, request, jsonify, flash

from flask import Flask, request, jsonify
from src.components.logic.log_skeleton import Log_Skeleton
from src.components.util.xes_importer \
import XES_Importer, TRACE_START, TRACE_END
import src.components.util.event_store as event_store
from flask_cors import CORS, cross_origin



__PARAMETERS__ = 'parameters'

# HTTP Methods
Expand All @@ -35,7 +33,7 @@
EVENT_LOG = 'event-log'
FILE = 'file'

ALLOWED_EXTENSIONS = {'xes'}
ALLOWED_EXTENSIONS = {'xes', 'csv'}

app = Flask(__name__)
cors = CORS(app)
Expand Down Expand Up @@ -64,19 +62,35 @@ def event_log():

if method == POST:
if FILE not in request.files:
return jsonify({ 'error': "No selected file" }), __BAD_REQUEST__
return jsonify({'error': "No selected file"}), __BAD_REQUEST__
file = request.files[FILE]
if file.filename == '':
return jsonify({ 'error': "Empty files" }), __BAD_REQUEST__
return jsonify({'error': "Empty files"}), __BAD_REQUEST__

if not allowed_file(file.filename):
return jsonify({ 'error': "File type not supported" }), __BAD_REQUEST__
return jsonify({
'error': "File type not supported"
}), __BAD_REQUEST__

id = event_store.put_event_log(file)

return jsonify({'id': id})

return "Something is wrong"
importer = XES_Importer()

try:
content = event_store.pull_event_log(id)

log, activities = importer.import_str(content, [], [])

return jsonify({
'id': id,
'activities': list(activities)
})
except: # noqa: E722
return jsonify({
'error': "Could not import file."
}), __BAD_REQUEST__

return jsonify({'error': "Something is wrong"})


@app.route('/log-skeleton/<id>', methods=['GET', 'POST'])
Expand Down Expand Up @@ -156,13 +170,13 @@ def apply(id, req):
required = []

try:
path = event_store.pull_event_log(id)
content = event_store.pull_event_log(id)

log, all_activities = \
importer.import_file(path,
forbidden,
required,
extended_trace=include_extended_traces)
importer.import_str(content,
forbidden,
required,
extended_trace=include_extended_traces)
except: # noqa: E722

return {'error_msg': 'Unable to import XES log. \
Expand Down Expand Up @@ -191,6 +205,8 @@ def apply(id, req):
return model, __OK__


event_store.start_event_store()
app.run()

# event_store.start_event_store()
# app.run()
if __name__ == "__main__":
print('Server running!...')
app.run(debug=True, host='0.0.0.0')
6 changes: 3 additions & 3 deletions src/components/logic/log_skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ def set_activities(self, activities):
self.all_activities = activities

def get_activities(self):
"""Return the current set of activities"""
"""Return the current set of activities."""
return self.all_activities

def set_working_relationships(self, working_relationships):
"""Choose working set for the relationship
"""Choose working set for the relationship.
Parameters:
working_relationships: A set or list of relationships as string
Expand All @@ -73,7 +73,7 @@ def set_working_relationships(self, working_relationships):
self.working_relationships.add(r)

def get_working_relationships(self):
"""Return current working set of relationships """
"""Return current working set of relationships."""
return self.working_relationships

def apply(self):
Expand Down
41 changes: 35 additions & 6 deletions src/components/util/event_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import appdirs
import time
import _thread
from pm4py.objects.conversion.log import converter as log_conv
import pandas as pd
from pm4py.objects.log.exporter.xes import exporter as xes_exporter

# App name for caching files
__APP_NAME__ = 'Log-Skeleton-Backend'
Expand All @@ -27,6 +30,8 @@
# Caching dir on the respective os
cache_dir = appdirs.user_cache_dir(__APP_NAME__)

print(cache_dir)

# Make sure the cache dir exists
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
Expand Down Expand Up @@ -78,23 +83,47 @@ def put_event_log(file) -> str:
"""Cache the event log."""
id = uuid.uuid4().hex

file.save(os.path.join(cache_dir, id + '.xes'))
# file.save(os.path.join(cache_dir, id + '.xes'))

filename = file.filename

if filename.endswith('csv'):
path = os.path.join(cache_dir, id + '.csv')
file.save(path)

log_csv = pd.read_csv(path, sep=',')
# log_csv.rename(columns={'clientID': 'case:clientID'}, inplace=True)
parameters = {log_conv.Variants.
TO_EVENT_LOG.value.Parameters.CASE_ID_KEY: 'case'}
event_log = log_conv.apply(log_csv,
parameters=parameters,
variant=log_conv.Variants.TO_EVENT_LOG)

xes_exporter.apply(event_log, os.path.join(cache_dir, id + '.xes'))

with open(os.path.join(cache_dir, id + '.xes'), 'r') as f:
content = f.read().decode('utf-8')

event_store[id] = content

else:
content = file.read().decode('utf-8')

event_store[id] = id + '.xes'
event_store[id] = content

print('Storing file at: ' + id + '.xes')
print('Storing file at: ' + id)

__store_delete_time(id)
# __store_delete_time(id)

return id


def pull_event_log(id):
"""Pull the event-log path from the storage."""
# Reschedule the deletion time of the event-log
__store_delete_time(id)
# __store_delete_time(id)

return os.path.join(cache_dir, event_store[id])
return event_store[id]


def event_log_garbage_collector():
Expand Down

0 comments on commit 172d297

Please sign in to comment.