How do you input and output text with Pyscript? - python

I’m learning py-script where you can use <py-script></py-script> in an HTML5 file to write Python Code. As a python coder, I would like to try web development while still using python, so it would be helpful if we could output and input information using py-script.
For example, could someone explain how to get this function to work:
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<div>Type an sample input here</div>
<input id = “test_input”></input>
<-- How would you get this button to display the text you typed into the input into the div with the id, “test”--!>
<button id = “submit-button” onClick = “py-script-function”>
<div id = “test”></div>
<div
<py-script>
<py-script>
</body>
</html
I would appreciate it and I hope this will also help the other py-script users.

I checked source code on GitHub and found folder examples.
Using files todo.html and todo.py I created this index.html
(which I tested using local server python -m http.server)
Some elements I figured out because I have some experience with JavaScript and CSS - so it could be good to learn JavaScript and CSS to work with HTML elements.
index.html
<!DOCTYPE html>
<html>
<head>
<!--<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />-->
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<div>Type an sample input here</div>
<input type="text" id="test-input"/>
<button id="submit-button" type="submit" pys-onClick="my_function">OK</button>
<div id="test-output"></div>
<py-script>
from js import console
def my_function(*args, **kwargs):
#print('args:', args)
#print('kwargs:', kwargs)
console.log(f'args: {args}')
console.log(f'kwargs: {kwargs}')
text = Element('test-input').element.value
#print('text:', text)
console.log(f'text: {text}')
Element('test-output').element.innerText = text
</py-script>
</body>
</html>
Here screenshot with JavaScript console in DevTool in Firefox.
It needed longer time to load all modules
(from Create pyodine runtime to Collecting nodes...)
Next you can see outputs from console.log().
You may also use print() but it shows text with extra error writing to undefined ....

An alternative to way to display the output would be to replace the
Element('test-output').element.innerText = text
by
pyscript.write('test-output', text)

Related

How do I use pyscript in my HTML code and return output

I am trying to call my python function created. But not getting any output and no resource how to achieve.
Code :
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<p>Click on the "Choose File" button to upload a file:</p>
<form>
<input type="file" id="myFile" name="filename">
<input type="submit" onClick="readfile(filename)" name="SUBMIT">
</form>
<py-script>
def readfile(filename):
with open(filename) as mfile:
head = [next(mfile) for x in range(1,5)]
print(head)
</py-script>
</body>
</html>
It would be great helpful if some one provide input like …
How to pass selected file to my function and python will be executed & return output on screen.
When writing Python in the browser, you must rethink how actions are performed. Typically, Python programs are procedural. Browser-based applications are asynchronous.
The first step is to enable asynchronous features:
import asyncio
Browser based programs cannot directly access the local file system. Your code is not doing what you think it is.
def readfile(filename):
with open(filename) as mfile:
head = [next(mfile) for x in range(1,5)]
print(head)
Your code is reading from the browser virtual file system which is allowed. You are trying to process the event from the ` element but trying to access a different location.
Note: I do not know what the file contents of "filename" are, so I did not incorporate your code after the file is read.
Your code cannot read files. You must ask the browser to read a file for your application. This is performed with the FileReader class.
Example:
async def process_file(event):
# Currently, PyScript print() does not work in this
# type of code (async callbacks)
# use console.log() to debug output
fileList = event.target.files.to_py()
for f in fileList:
data = await f.text()
document.getElementById("content").innerHTML = data
# Add your own code to process the "data" variable
# which contains the content of the selected file
Another problem is that you are passing a Python function as a callback. That will not work. Instead, you must call create_proxy() to create a callback proxy for the Python function. The browser will call the proxy which then calls your Python function.
Example:
# Create a Python proxy for the callback function
# process_file() is your function to process events from FileReader
file_event = create_proxy(process_file)
# Set the listener to the callback
document.getElementById("myfile").addEventListener("change", file_event, False)
I put a copy of this solution on my website. You can right-click on the page to download the source code.
File Example Demo
Complete solution:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<title>File Example</title>
</head>
<body>
<p>This example shows how to read a file from the local file system and display its contents</p>
<br />
<p>Warning: Not every file type will display. PyScript removes content with tags such as XML, HTML, PHP, etc. Normal text files will work.</p>
<br />
<p>No content type checking is performed to detect images, executables, etc.</p>
<br />
<label for="myfile">Select a file:</label>
<input type="file" id="myfile" name="myfile">
<br />
<br />
<div id="print_output"></div>
<br />
<p>File Content:</p>
<div style="border:2px inset #AAA;cursor:text;height:120px;overflow:auto;width:600px; resize:both">
<div id="content">
</div>
</div>
<py-script output="print_output">
import asyncio
from js import document, FileReader
from pyodide import create_proxy
async def process_file(event):
fileList = event.target.files.to_py()
for f in fileList:
data = await f.text()
document.getElementById("content").innerHTML = data
def main():
# Create a Python proxy for the callback function
# process_file() is your function to process events from FileReader
file_event = create_proxy(process_file)
# Set the listener to the callback
e = document.getElementById("myfile")
e.addEventListener("change", file_event, False)
main()
</py-script>
</body>
</html>

How to print variable present in python with the help of html?

I've written some code for deep learning text summarization, and I'm trying to render the template using the Flask library. I'm unable to see the results. The python code can be found below.
text = ' '.join([summ['summary_text'] for summ in res])
print(text)
return render_template('result.html', prediction=text)
I'm trying to print the prediction variable which is present in the above code. Below is the html code
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<header>
<div class="container">
<div id="brandname">
Deep Learning App
</div>
<h2>Summarized text</h2>
</div>
</header>
<p style="color:blue;font-size:20;text-align: center;"><b>Result for Text</b></p>
<div class="results">
<p><strong>{prediction}</strong></p>
</div>
</body>
</html>
Below is output image
enter image description here
Can anyone help me how to display text present in prediction variable on web page?
You need double curly braces
<p><strong>{{ prediction }}</strong></p>

Recaptcha 2 (a.k.a. nocaptcha) doesn't load on Internet Explorer 8 on first load

I am using new recaptcha2 and everything seems to work flawlessly on all modern browsers, however I have a problem only with IE8.
Captcha load properly on second and next visit on the page, but never on first load or in Private Mode.
What is even more strange, google recaptcha 2 page demo doesn't have this problems. I am using django-nocaptcha-recaptcha package, which is based on recaptcha-client for python, so I believe my configuration is pretty standard.
Console doesn't show any errors. Divs are not populate by recaptcha code.
Google on their recaptcha2 developers guide suggest to use a snipet like this:
<html>
<head>
<title>reCAPTCHA demo: Simple page</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="?" method="POST">
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
<br/>
<input type="submit" value="Submit">
</form>
</body>
</html>
django-nocaptcha-recaptcha use similar piece of code and also use a line like this:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
This suppose to cause a problem, since ascync and defer are supported in IE 10+. In my case, when I used:
<script src="https://www.google.com/recaptcha/api.js"></script>
Problem disappeared :)

Configurable head with chameleon load

When using chameleon, I can replace element from a base template using the concept of slot. Where you define a slot and fill it using another tag. As there is no container element in head, how can one add elements to head ? :
The Layout file
<html>
<head>
<div metal:define-slot="extra_head"></div>
</head>
<body>
...
</body>
</html>
The content template that need to specify extra head.
<html metal:use-macro="load: main.pt">
<div metal:fill-slot="extra_head">
<script type="text/javascript" src="http://example/script.js"></script>
</div>
...
</html>
This gets rendered in :
<html>
<head>
<div metal:fill-slot="extra_head">
<script type="text/javascript" src="http://example/script.js"></script>
</div>
</head>
<body>
...
</body>
</html>
But there's no container tag in head so how can one define a slot to add stuff in the head ?
There's an alternative to using tal:omit-tag (which I'm finding annoyingly confusing - more than once I spent many minutes trying to figure out why a certain tag does not appear in the output when it's clearly present in the template, only to find tal:omit-tag neatly tucked in the far corner): if you use xml tags with tal: and metal: namespaces they won't appear in the output:
<html>
<head>
<metal:my-slot define-slot="extra_head"></metal:my-slot>
</head>
<body>
...
</body>
</html>
and in the child template:
<metal:template use-macro="load: main.pt">
<metal:any-descriptive-name fill-slot="extra_head">
<script type="text/javascript" src="http://example/script.js"></script>
</metal:any-descriptive-name>
...
</metal:template>
Note how the template becomes much more readable and self-descriptive and does not contain weird things such as a <div> inside <head> :)
You also can omit tal: and metal: prefixes on attributes when using namespaced tags, so
<h1 tal:condition="..." tal:content="..." tal:omit-tag="">Hi there! Bogus content for added confusion!</h1>
becomes
<tal:greeting condition="..." content="..." />
To remove the tag one has to use tal:omit-tag :
In the content template, use :
<html metal:use-macro="load: main.pt">
<div metal:fill-slot="extra_head" tal:omit-tag="">
<script type="text/javascript" src="http://example/script.js"></script>
</div>
...
</html>
The div is not part of the result. Read the doc.

Web interface with python backend

I developed a simple application in Python (with a Tkinter interface). But now I want provide a web interface for the same. I know that the python script will wun on the server as CGI. But I would like everything to happen on one page i.e. something like this:
There is a text box for the user to provide input
When a submit button is clicked, the python script runs on the input and generates the output
The output is displayed on the same page without the page reloading
I think Ajax can be used to do this (and I'll learn it if that's the only way), but is there any easier way to do this? I tried generating the front end in python, and linking the button to a function in the same script but that doesn't work...
Thanks
PS: Sorry if the title and the tags are a bit misleadsing...i wasn't so sure what to pick...
EDIT: I tried this but it doesn't work
#!/usr/bin/python2
import cgi
print 'Content-type: text/html'
print """
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
"""
data = cgi.FieldStorage()
sometext = data['sometext'].value
if sometext != '':
print "<p>" + sometext + "</p>"
print """
<form action="test.py" method="post">
<input type="text" name="sometext">
<input type="submit">
</form>
</body>
</html>
"""

Categories

Resources