Skip to content

Commit

Permalink
added Support to upload configfiles with various filetypes at one tim…
Browse files Browse the repository at this point in the history
…e. Updated Interface
  • Loading branch information
pyrokar1993 committed Dec 14, 2022
1 parent a1f9039 commit 601fede
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 115 deletions.
51 changes: 27 additions & 24 deletions api/api.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import os
import uuid
import paramiko
import stat
import uuid
from typing import List

import paramiko
from api import app, templates
from fastapi import File, Request, Response, UploadFile, Form
from fastapi import File, Form, Request, Response, UploadFile
from fastapi.exceptions import HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from InRetEnsys import *


from .constants import FTP_SERVER
from .constants import FTP_SERVER, FTYPE_BINARY, FTYPE_JSON
from .simulate_docker import simulate_docker
from .simulate_unirz import simulate_unirz

Expand All @@ -29,13 +28,14 @@
allow_headers=["*"],
)


@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
return templates.TemplateResponse("base.html", {"request": request})


@app.post("/uploadFileBinary")
async def upload_file(request: Request, datafiles: List[UploadFile] = File(...), docker: str = Form(...), username: str = Form(...), password: str = Form(...)):
async def upload_file(request: Request, datafiles: List[UploadFile] = File(...), docker: str = Form(...), username: str = Form(default=None), password: str = Form(default=None)):
filelist = []

for datafile in datafiles:
Expand All @@ -47,54 +47,57 @@ async def upload_file(request: Request, datafiles: List[UploadFile] = File(...),
return run_simulation(request, input=filelist, ftype="fileBin", username=username, passwd=password)


@app.post("/uploadFileJson")
@app.post("/uploadFile")
async def upload_file(request: Request, datafiles: List[UploadFile] = File(...), docker: str = Form(...), username: str = Form(default=None), password: str = Form(default=None)):
filelist = []

for datafile in datafiles:
filelist.append(await datafile.read())
filelist.append((await datafile.read(), datafile.content_type))

if docker == "docker":
return run_simulation(request, input=filelist, ftype="fileJson", container=True)
return run_simulation(request, input=filelist, container=True)
else:
return run_simulation(request, input=filelist, ftype="fileJson", username=username, passwd=password)
return run_simulation(request, input=filelist, username=username, passwd=password)


@app.post("/uploadJson")
async def upload_file(request: Request, username: str, password: str, docker: bool):
return run_simulation(request, input=[await request.json()], ftype="Json", external=True, container=docker, username=username, passwd=password)
return run_simulation(request, input=[(await request.json(), FTYPE_JSON)], external=True, container=docker, username=username, passwd=password)


def generate_random_folder():
return str(uuid.uuid4().hex)


@app.post("/runSimulation")
def run_simulation(request: Request, input=None, ftype=None, parentfolder="work", external=False, container=False, username=None, passwd=None) -> Response:
def run_simulation(request: Request, input: list = None, parentfolder="work", external=False, container=False, username=None, passwd=None) -> Response:
if input is not None:
folderlist = []
startscript = "#!/bin/csh\n"

for datafile in input:
for datafile, ftype in input:
workdir = os.path.join(os.getcwd(), parentfolder)
name_job = generate_random_folder()

while os.path.exists(os.path.join(workdir, name_job)):
name_job = generate_random_folder()
if ftype == "fileJson" or ftype == "Json":

if ftype == FTYPE_JSON:
name_configfile = "config.json"
elif ftype == "fileBin":
elif ftype == FTYPE_BINARY:
name_configfile = "config.bin"

if container:
simulate_docker(parentfolder, name_configfile, name_job, ftype, datafile)
simulate_docker(parentfolder, name_configfile,
name_job, ftype, datafile)
else:
if username is None or passwd is None:
raise HTTPException(status_code=401, detail="Authentification Error!")
else:
simulate_unirz(name_configfile, name_job, ftype, datafile, str(username), str(passwd))
startscript += "cd " + name_job + "\n"
raise HTTPException(
status_code=401, detail="Authentification Error!")
else:
simulate_unirz(name_configfile, name_job,
ftype, datafile, str(username), str(passwd))
startscript += "cd " + name_job + "\n"
startscript += "bsub -q 'BatchXL' -J '" + name_job + "' batchscript.csh\n"
startscript += "cd ..\n"

Expand All @@ -108,7 +111,7 @@ def run_simulation(request: Request, input=None, ftype=None, parentfolder="work"
with sftp.open("startskript.csh", "at") as sftp_file:
sftp_file.write(startscript)
sftp_file.close()
sftp.chmod("startskript.csh", stat.S_IRWXU)
sftp.chmod("startskript.csh", stat.S_IRWXU)
sftp.close()

folderlist.append(name_job)
Expand Down
3 changes: 3 additions & 0 deletions api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
CONTAINER_NAME = "inret-ensys-testcontainer"

FTP_SERVER = "csdata.tu-ilmenau.de"

FTYPE_BINARY = "application/octet-stream"
FTYPE_JSON = "application/json"
11 changes: 5 additions & 6 deletions api/simulate_docker.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import os
import docker

import docker
from fastapi.exceptions import HTTPException

from .constants import *


def simulate_docker(parentfolder, configfile, foldername, ftype, file):
# Lokalen Ordner anlegen
outputdir = os.path.join(os.getcwd(), parentfolder, foldername)
Expand All @@ -14,12 +15,10 @@ def simulate_docker(parentfolder, configfile, foldername, ftype, file):
licensepath = os.path.join(os.getcwd(), 'gurobi_docker.lic')
docker_wdir = "/app/working"

if ftype == "fileJson":
savefile = open(os.path.join(outputdir, configfile), 'wb')
elif ftype == "fileBin":
savefile = open(os.path.join(outputdir, configfile), 'wb')
elif ftype == "Json":
if ftype == FTYPE_JSON:
savefile = open(os.path.join(outputdir, configfile), 'wt')
elif ftype == FTYPE_BINARY:
savefile = open(os.path.join(outputdir, configfile), 'wb')
savefile.write(file)
savefile.close()

Expand Down
14 changes: 7 additions & 7 deletions api/simulate_unirz.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os
import paramiko
import stat

import paramiko

from .constants import *


def simulate_unirz(configfile, foldername, ftype, file, username, passwd):

csh_value = {
Expand Down Expand Up @@ -53,7 +55,7 @@ def simulate_unirz(configfile, foldername, ftype, file, username, passwd):

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect(FTP_SERVER, 22, "alubojanski", "%.30fpgM") #username, passwd)
client.connect(FTP_SERVER, 22, username, passwd)

with client.open_sftp() as sftp:
sftp.chdir("work")
Expand All @@ -64,12 +66,10 @@ def simulate_unirz(configfile, foldername, ftype, file, username, passwd):
sftp_file.close()
sftp.chmod("batchscript.csh", stat.S_IRWXU)

if ftype == "fileJson":
sftp_file = sftp.open("config.json", 'wb')
elif ftype == "fileBin":
sftp_file = sftp.open("config.bin", 'wb')
elif ftype == "Json":
if ftype == FTYPE_JSON:
sftp_file = sftp.open("config.json", 'wt')
elif ftype == FTYPE_BINARY:
sftp_file = sftp.open("config.bin", 'wb')
sftp_file.write(file)
sftp_file.close()

Expand Down
2 changes: 1 addition & 1 deletion api/static/stylesheet.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
min-width: 1280px;
min-width: 780px;
background-color: #FFEFDF;
}

Expand Down
105 changes: 29 additions & 76 deletions api/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@
<body>
<script type="text/javascript">
function toggle_login_form() {
let item = document.getElementById("loginform");
let loginform = document.getElementById("loginform");
let dockercheck = document.getElementById("docker");
let sshcheck = document.getElementById("ssh");

item.hidden = !item.hidden;
if (sshcheck.checked) {
loginform.hidden = false;
} else {
loginform.hidden = true;
}
}
</script>

Expand All @@ -32,63 +38,25 @@
</div>

<!-- content -->
<div class="accordion" id="accordionExample">
<br />
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne"
aria-expanded="false" aria-controls="collapseOne">
JSON-Dateien
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne"
data-bs-parent="#accordionExample">
<div class="accordion-body">
<form action="/uploadFileJson" enctype="multipart/form-data" method="post">
<h5>Daten des Energiesystems</h5>
<div class="mb-3">
<label for="datafile" class="form-label">Konfigurationsdatei</label>
<input class="form-control" name="datafiles" type="file" id="datafile" multiple="multiple"><br />
<div onchange=toggle_login_form()>
<h5>Ausführungsmethode</h5>
<div class="form-check">
<label class="form-check-label" for="docker">Run with Docker</label>
<input class="form-check-input" type="radio" name="docker" id="docker" value="docker" checked>
</div>
<div class="form-check">
<label class="form-check-label" for="ssh">Run with SSH</label>
<input class="form-check-input" type="radio" name="docker" id="ssh" value="ssh">
</div><br />
<div class="mb-3 row" id="loginform" hidden>
<h5>Logindaten Universitätsrechenzentrum</h5>
<div class="col">
<label for="username" class="form-label">Username</label>
<input type="username" class="form-control" name="username" id="username" placeholder="Nutzername">
</div>
<div class="col">
<label for="password" class="form-label">Email address</label>
<input type="password" class="form-control" name="password" id="password" placeholder="Password">
</div>
</div>
</div><br />
<button class="btn btn-outline-success form-control" type="submit">Run Simulation</button>
<div class="row">
<div>
<h1>Upload verschiedener Dateiformate</h1>
<form action="/uploadFile" enctype="multipart/form-data" method="post">
<h5>Daten des Energiesystems</h5>
<div class="mb-3">
<label for="datafile" class="form-label">Konfigurationsdatei</label>
<input class="form-control" name="datafiles" type="file" id="datafile" multiple="multiple"><br />
<div onchange=toggle_login_form()>
<h5>Ausführungsmethode</h5>
<div class="form-check">
<label class="form-check-label" for="docker">Run with Docker</label>
<input class="form-check-input" type="radio" name="docker" id="docker" value="docker" checked>
</div>
</form>
</div>
</div>
</div>
<div class="accordion-item" hidden>
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
Binärdateien
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo"
data-bs-parent="#accordionExample">
<div class="accordion-body">
<form action="/uploadFileBinary" enctype="multipart/form-data" method="post">
<div class="mb-3 row">
<div class="form-check">
<label class="form-check-label" for="ssh">Run with SSH</label>
<input class="form-check-input" type="radio" name="docker" id="ssh" value="ssh">
</div><br />
<div class="mb-3 row" id="loginform" hidden>
<h5>Logindaten Universitätsrechenzentrum</h5>
<div class="col">
<label for="username" class="form-label">Username</label>
Expand All @@ -99,27 +67,12 @@ <h5>Logindaten Universitätsrechenzentrum</h5>
<input type="password" class="form-control" name="password" id="password" placeholder="Password">
</div>
</div>
<h5>Daten des Energiesystems</h5>
<div class="mb-3">
<label for="datafile" class="form-label">Konfigurationsdatei</label>
<input class="form-control" name="datafiles" type="file" id="datafile" multiple="multiple"><br />
<h5>Ausführungsmethode</h5>
<div class="form-check">
<label class="form-check-label" for="docker">Run with Docker</label>
<input class="form-check-input" type="radio" name="docker" id="docker" value="docker" checked>
</div>
<div class="form-check">
<label class="form-check-label" for="ssh">Run with SSH</label>
<input class="form-check-input" type="radio" name="docker" id="ssh" value="ssh">
</div><br />
<button class="btn btn-outline-success form-control" type="submit">Run Simulation</button>
</div>
</form>
</div><br />
<button class="btn btn-outline-success form-control" type="submit">Run Simulation</button>
</div>
</div>
</form>
</div>
</div>

<div class="row">
{% block content %}

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ fastapi==0.88.0
gurobipy==10.0.0
h11==0.14.0
idna==3.4
InRetEnsys==0.2a2
Jinja2==3.1.2
MarkupSafe==2.1.1
networkx==2.8.8
Expand Down

0 comments on commit 601fede

Please sign in to comment.