Skip to content

Commit 3c2553f

Browse files
Merge pull request #16 from ashirrwad/input-capability
Code runs on a single container, added input capability
2 parents 2522c0c + caf48bc commit 3c2553f

File tree

4 files changed

+103
-41
lines changed

4 files changed

+103
-41
lines changed

Backend/app.py

+54-38
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#importing dependencies - Flask for server and docker to communicate with docker API
1+
# importing dependencies - Flask for server and docker to communicate with docker API
22
from flask import Flask, jsonify, request
3-
from flask_cors import CORS,cross_origin
3+
from flask_cors import CORS, cross_origin
44
import docker
55
import os
66
import tarfile
@@ -9,53 +9,69 @@
99

1010
cors = CORS(app)
1111

12-
app.config['CORS_HEADERS'] = 'Content-Type'
12+
app.config["CORS_HEADERS"] = "Content-Type"
1313

14-
#Editing the file with code inside editor
15-
def edit_file(code):
16-
Fortran_file = open('./File.f90','w+')
17-
Fortran_file.write(code)
14+
# Starting container
15+
client = docker.from_env()
16+
container = client.containers.run("playground-small", tty=True, detach=True)
1817

18+
# Editing the file with code inside editor
19+
def edit_file(code, input=""):
20+
Fortran_file = open("./File.f90", "w+")
21+
Fortran_file.write(code)
22+
program_input = open("./program_input.txt", "w+")
23+
program_input.write(input)
1924

2025

21-
#Copying file with fortran code to container
26+
# Copying file with fortran code to container
2227
def copy_to(src, dst, container):
23-
dst = dst
24-
container = container
28+
dst = dst
29+
container = container
2530

26-
os.chdir(os.path.dirname(src))
27-
srcname = os.path.basename(src)
28-
tar = tarfile.open(src + '.tar', mode='w')
29-
try:
30-
tar.add(srcname)
31-
finally:
32-
tar.close()
31+
os.chdir(os.path.dirname(src))
32+
srcname = os.path.basename(src)
33+
tar = tarfile.open(src + ".tar", mode="w")
34+
try:
35+
tar.add(srcname)
36+
finally:
37+
tar.close()
3338

34-
data = open(src + '.tar', 'rb').read()
35-
container.put_archive(os.path.dirname(dst), data)
39+
data = open(src + ".tar", "rb").read()
40+
container.put_archive(os.path.dirname(dst), data)
3641

3742

38-
#Executing code inside container and getting it's output
43+
# Executing code inside container and getting it's output
3944
def execute_code_in_container():
40-
client = docker.from_env()
41-
container = client.containers.run('playground-small', tty=True,detach=True)
42-
copy_to('./File.f90', '/fortran/File.f90',container)
43-
container.exec_run('gfortran File.f90 -o executed_file.o',demux=True)
44-
a = container.exec_run('./executed_file.o')
45-
container.stop()
46-
return a
47-
48-
49-
#API Endpoint to submit code
50-
@app.route('/run', methods=['POST','GET','OPTIONS'])
45+
copy_to("./File.f90", "/fortran/File.f90", container)
46+
copy_to("./program_input.txt", "/fortran/program_input.txt", container)
47+
executable = container.exec_run(
48+
"gfortran File.f90 -o executed_file.o", demux=True
49+
)
50+
if executable.exit_code == 0:
51+
a = container.exec_run(
52+
'sh -c "cat program_input.txt | ./executed_file.o"', demux=True
53+
)
54+
else:
55+
a = executable
56+
return a
57+
58+
59+
# API Endpoint to submit code
60+
@app.route("/run", methods=["POST", "GET", "OPTIONS"])
5161
@cross_origin()
5262
def run_code():
53-
data = request.get_json()
54-
edit_file(data["code"])
55-
code_result = execute_code_in_container()
56-
output = jsonify({"executed" : code_result.output.decode()})
57-
return output, 202
63+
data = request.get_json()
64+
edit_file(data["code"], data["programInput"])
65+
code_result = execute_code_in_container()
66+
if code_result.exit_code == 0:
67+
print(code_result.output[0].decode())
68+
output = jsonify({"executed": code_result.output[0].decode()})
69+
else:
70+
print(code_result.output[1].decode())
71+
output = jsonify({"executed": code_result.output[1].decode()})
72+
73+
return output, 202
5874

59-
if __name__ == '__main__':
60-
app.run(debug = True)
6175

76+
if __name__ == "__main__":
77+
app.run(debug=True)

frontend/src/App.css

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
height: 35rem;
1010
width: 40%;
1111
border: 2px solid black;
12+
padding: 0.2rem;
13+
display: flex;
14+
flex-direction: column;
15+
justify-content: space-between;
1216

1317
}
1418

@@ -37,3 +41,7 @@
3741

3842
}
3943

44+
.output-formmating{
45+
white-space: pre-wrap;
46+
47+
}

frontend/src/App.js

+24-3
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,38 @@ import Spinner from 'react-bootstrap/Spinner'
1010
import Card from 'react-bootstrap/Card'
1111
import RunCode from './run.png'
1212
import ResetCode from './reset.png'
13+
import InputBox from './InputBox';
14+
15+
16+
function NewlineText(props) {
17+
const text = props.text;
18+
return <div className='output-formmating'>{text}</div>;
19+
}
20+
1321

1422
function App() {
1523
const [ text, setText ] = useState('') //State to store editor code
1624
const [output, setOutput] = useState('')//State to store output
1725
const [isLoading, setIsLoading] = useState(false);//Loading animations
26+
const [ input, setInput ] = useState('')
27+
28+
29+
const handleInputChange = (e) => {
30+
e.preventDefault(); // prevent the default action
31+
setInput(e.target.value); // set name to e.target.value (event)
32+
console.log(input)
33+
};
34+
1835

1936
//POST request to Flask server
2037
const handleClick = async () => {
2138

2239
setOutput('')
2340
setIsLoading(true);
2441
// POST request using axios inside useEffect React hook
25-
await axios.post('http://127.0.0.1:5000/run', {code : text})
42+
await axios.post('http://127.0.0.1:5000/run', {code : text, programInput: input})
2643
.then((response) => {setOutput(response.data.executed)});
2744
setIsLoading(false);
28-
console.log(output)
2945
}
3046

3147
const resetCode = () => {
@@ -40,6 +56,7 @@ function App() {
4056
<div className='code-wrapper'>
4157
{/*Editor Component*/}
4258
<Editor value={text} onChange={value => setText(value)}/>
59+
4360
{/* Buttons */}
4461
<div className='options'><Button onClick={resetCode} ><img src={ResetCode} /></Button>
4562
<Button variant="run" onClick={handleClick}><img src={RunCode} /></Button>
@@ -69,13 +86,17 @@ function App() {
6986
<Card.Body>
7087

7188
<Card.Text>
89+
{/* Spinning Animation While Request is processed */}
7290
{isLoading ? <p className='loading'><Spinner animation="border" size="sm" /></p> : null}
73-
{output}
91+
<NewlineText text={output} />
7492
</Card.Text>
7593

7694
</Card.Body>
7795
</Card>
96+
{/* Input Box to provide input for program */}
97+
<InputBox value={input} onChange={handleInputChange}/>
7898
</div>
99+
79100
</div>
80101
</div>
81102
);

frontend/src/InputBox.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Form from 'react-bootstrap/Form'
2+
3+
export default function InputBox(props){
4+
5+
6+
7+
return(
8+
<>
9+
<Form>
10+
<Form.Group>
11+
<Form.Label>Custom Input</Form.Label>
12+
<Form.Control value={props.value} onChange={props.onChange} as="textarea" rows={3} />
13+
</Form.Group>
14+
</Form>
15+
</>
16+
)
17+
}

0 commit comments

Comments
 (0)