Skip to content

Rework using flask and add celery launch command #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions opv_status_api/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
# Email: [email protected]
# Description: OPV status api

from http.server import HTTPServer
from opv_status_api.httpHandler import HttpHandler
import docopt
import logging
from opv_status_api.logging import setup_logging
from opv_status_api.service import Service

__doc__ = """
An api for opv-status front
Expand All @@ -43,8 +42,9 @@ def main():

server_address = ('', int(args["--port"]))
logger.info("Starting http server at http://localhost:{} open to {}".format(server_address[1], server_address[0]))
httpd = HTTPServer(server_address, HttpHandler)
httpd.serve_forever()

service = Service(host=server_address[0], port=server_address[1])
service.start()


if __name__ == "__main__":
Expand Down
Empty file.
37 changes: 37 additions & 0 deletions opv_status_api/celery/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# coding: utf-8

# Copyright (C) 2017 Open Path View, Maison Du Libre
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

# Contributors: Simon Archieri <[email protected]>
# Email: [email protected]
# Description: OPV status api
import logging
from opv_celery.__main__ import launch


class Celery:
logger = logging.getLogger("opv_status_api")

def LaunchCelery(self, data):
output = {
"answer": None,
"error": None
}
if "campaign_id" in data and "malette_id" in data:
launch(data["campaign_id"], data["malette_id"])

output["answer"] = "Celery launched you should check the api"
else:
output["error"] = "Missing parameter"

return output
85 changes: 0 additions & 85 deletions opv_status_api/httpHandler.py

This file was deleted.

93 changes: 26 additions & 67 deletions opv_status_api/importData/importData.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,86 +23,45 @@


class ImportData:
defaultOutput = {
"httpCode": 200,
"answer": {
"error": None,
"answer": {}
}
}

logger = logging.getLogger("opv_status_api")

defaultLogFile = "/tmp/importData.log"

importDataThread = ImportDataThread()

def getStatus(self, path=[], data={}, type="GET"):
output = copy.deepcopy(self.defaultOutput).copy()

if type == "GET":
info = self.importDataThread.getInfo()

output["answer"]["answer"] = info

else:
output["httpCode"] = 400
output["answer"]["error"] = "You must use GET"

return output

def launchImport(self, path=[], data={}, type="POST"):
output = copy.deepcopy(self.defaultOutput).copy()

if type == "POST":
if "path" in data and "id_malette" in data and "camera_number" in data and "description" in data and "campaign_name" in data and "id_rederbro" in data:
self.importDataThread = ImportDataThread(data=data)
self.importDataThread.start()
def getStatus(self):
return {
"answer": self.importDataThread.getInfo(),
"error": None
}

output["answer"]["answer"] = "Launched, you should check status to know if it work"
else:
output["httpCode"] = 400
output["answer"]["error"] = "You must set all param"
def launchImport(self, data):
output = {
"answer": None,
"error": None
}
if "path" in data and "id_malette" in data and "camera_number" in data and "description" in data and "campaign_name" in data and "id_rederbro" in data:
self.importDataThread = ImportDataThread(data=data)
self.importDataThread.start()

output["answer"] = "Launched, you should check status to know if it work"
else:
output["httpCode"] = 400
output["answer"]["error"] = "You must use POST"
output["error"] = "Missing param"

return output

def getLog(self, path=[], data={}, type="POST"):
output = copy.deepcopy(self.defaultOutput).copy()

if type == "POST":
logFile = self.defaultLogFile if "logFile" not in data else data["logFile"]

if os.path.isfile(logFile):
with open(logFile) as log:
output["answer"]["answer"] = log.read()
def getLog(self, data):
output = {
"answer": None,
"error": None
}
logFile = self.defaultLogFile if "logFile" not in data else data["logFile"]

else:
output["httpCode"] = 400
output["answer"]["error"] = "Can't find log file"
if os.path.isfile(logFile):
with open(logFile) as log:
output["answer"] = log.read()

else:
output["httpCode"] = 400
output["answer"]["error"] = "You must use POST"
output["error"] = "Log file not found"

return output

command = {
"status": getStatus,
"log": getLog,
"launch": launchImport
}

def newCommand(self, path=[], data={}, type="GET"):
if path[0] in self.command:
self.logger.debug("Launch command {} with path={}, data={}, type={}".format(path[0], path, data, type))
return self.command[path[0]](self, path=path, data=data, type=type)
else:
self.logger.debug("Asked ressource ({}) can't be find in importData".format(path[0]))
output = copy.deepcopy(self.defaultOutput).copy()
output["httpCode"] = 400
output["answer"]["error"] = "We can't find {}".format(path[0])
return output
return output
77 changes: 77 additions & 0 deletions opv_status_api/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from flask import Flask, request, abort
from flask_cors import CORS
from gevent.pywsgi import WSGIServer
from opv_status_api.importData.importData import ImportData
from opv_status_api.spark.spark import Spark
from opv_status_api.celery.celery import Celery
import json
import logging


class Service:
def __init__(self, host="", port=5001):
self.port = port
self.host = host

def start(self):
app = Flask("opv-status-api")
CORS(app)

logger = logging.getLogger("opv_status_api")

importService = ImportData()
spark = Spark()
celery = Celery()

mimetype = {'Content-Type': 'application/json'}

service = {
"import": {
"log": (importService.getLog, "POST"),
"launch": (importService.launchImport, "POST"),
"status": (importService.getStatus, "GET")
},
"spark": {
"launch": (spark.launchSpark, "POST"),
"port": (spark.getSparkPort, "GET")
},
"celery": {
"launch": (celery.LaunchCelery, "POST")
}
}

def check_args(service_name, command_name):
logger.debug("---- New request ----")
logger.debug("Request type : {}".format(request.method))
logger.debug("Body : {}".format(request.data.decode()))
logger.debug("Service : {}, Command : {}".format(service_name, command_name))
if (service_name in service and
command_name in service[service_name]):
if request.method == service[service_name][command_name][1]:
if request.method == "POST":
try:
json.loads(request.data.decode())
logger.info("-- Valid request for {} {} --".format(service_name, command_name))
except ValueError:
logger.debug("-- Error ==> POST request + body isn't json --")
abort(415)
return
logger.debug("-- Error ==> unsupported method for this command --")
abort(405)
logger.debug("-- Error ==> unknow command --")
abort(404)

@app.route("/<string:service_name>/<string:command_name>", methods=["POST", "GET"])
def launchCommand(service_name, command_name):
check_args(service_name, command_name)
if request.method == "POST":
answer = service[service_name][command_name][0](json.loads(request.data.decode()))
else:
answer = service[service_name][command_name][0]()

answer = json.dumps(answer), 400 if answer["error"] else 200, mimetype
logger.debug("Request answer : {}".format(answer))
return answer

http_server = WSGIServer((self.host, self.port), app)
http_server.serve_forever()
Loading