2

I'm working locally with a python script on my mac using

python3 -m http.server --cgi

My script works. I creates a graphic and a dynamic web page and opens that web page in a new tab. What I don't like is that it leaves a blank window where the script's address is. So when I run the webpage with the form and hit submit. I get a blank page and a new page. I'd just like it to go to the new page. I'm new to python, so I'm not quite sure what I'm doing wrong. Here is my script:

#!/usr/bin/env python3

import pyromat as pm
import matplotlib.pyplot as plt
import numpy as np
import webbrowser

# Create a temperature array in steps of 10K
T = np.arange(300,2000,10)
# Get the Oxygen object
O2 = pm.get('ig.O2')

f = plt.figure(1)   # Call up figure 1
f.clf()         # clear it (if it already exists)
ax = f.add_subplot(111) # Create an axes object on the figure
ax.plot(T, O2.cp(T))    # Add a curve to that axes
ax.set_xlabel('Temperature (K)')
ax.set_ylabel('Specific Heat (kJ/kg/K)')
f.savefig('cp.png') # Make a file

f = open('test.html','w')

message = """<html>
<head></head>
<body><p>Graph Test</p><img src="cp.png"></body>
</html>"""

f.write(message)
f.close()

filename = 'file:///Users/pzb4/Documents/Environments/test.html'
webbrowser.open(filename,new=0,autoraise=True)

Idea is to create a form where I can change the inputs to the graph. Ideally it would just rewrite the form page so the student can keep changing the data and see how it affects the graph.

YakovL
  • 7,557
  • 12
  • 62
  • 102
user3499381
  • 467
  • 1
  • 4
  • 12
  • Have I understood correctly that this script is at the URL that you submit another page to? – Aankhen Jul 02 '18 at 20:17
  • yes, when i hit submit it calls the script above. – user3499381 Jul 02 '18 at 20:56
  • Okay. Modifying this script to avoid creating a new page is simple, so I’ll add an answer for that. If you want to implement rewriting the form page, you’ll need to show the (relevant part of) the code for that page. – Aankhen Jul 02 '18 at 21:18
  • i can handle that part i think. right now it's just a submit button. – user3499381 Jul 02 '18 at 22:33

1 Answers1

1

Since you’re running this as a CGI script, you can write to standard output:

#!/usr/bin/env python3

import pyromat as pm
import matplotlib.pyplot as plt
import numpy as np
import webbrowser
from io import BytesIO
import base64

# Create a temperature array in steps of 10K
T = np.arange(300,2000,10)
# Get the Oxygen object
O2 = pm.get('ig.O2')

f = plt.figure(1)   # Call up figure 1
f.clf()         # clear it (if it already exists)
ax = f.add_subplot(111) # Create an axes object on the figure
ax.plot(T, O2.cp(T))    # Add a curve to that axes
ax.set_xlabel('Temperature (K)')
ax.set_ylabel('Specific Heat (kJ/kg/K)')

image_bytes = BytesIO()

f.savefig(image_bytes, format="png") # write bytes to in-memory object
image_bytes.seek(0) # go to beginning of bytes

# print HTTP headers
print("Content-Type: text/html; charset=utf-8")
print()

# encode as Base64
src = base64.b64encode(image_bytes.read())

message = """<html lang="en"><head><title>Result</title></head>
<body><p>Graph Test</p><img src="data:image/png;base64,{}"></body></html>"""

# print HTML with embedded image
print(message.format(src))

This avoids writing either the HTML or the image to disk. Instead, it writes the HTML to standard output (which should show up in the browser) and embeds the image directly in the HTML source as Base64 data.

Aankhen
  • 2,198
  • 11
  • 19
  • Hat tip to [this question and its answers](https://stackoverflow.com/questions/31492525/converting-matplotlib-png-to-base64-for-viewing-in-html-template) for the Base64 technique. – Aankhen Jul 02 '18 at 21:36