Call certain Python function from JavaScript - javascript

I've searched this subject already for a bit on the Internet and I couldn't find anything decent:
I was wondering if it possible to call a single Python function from a Python file from JavaScript?
I already came across suggestions such as $ajax-requests, (Call Python function from Javascript code) but this only seems to execute the __main__ method of said Python file. Other suggestions I came across also just execute the entire Python file, without the possibility of just executing a single method of it.
What I want is for example a Python-class containing methods this:
def testMethod(self):
print "testMethod called from JavaScript"
return "It worked!"
and that I would be able to call this testMethod() from JavaScript (optionally with parameters etc. of course if the method expects them).
Is this possible in a simple way? I mention the word simple because frameworks like Flask etc. would be my last resort, I'd much more prefer something fast and doesn't change my webproject too much for the rest.

Related

Passing values from JavaScript to C# ASP.NET Core Razor Pages for SQL Querying

I am making a simple web-shop application prototype and need to pass shopping cart items (which are stored in localStorage) to our SQLServer. The localStorage is as follows
{"grootfigure":{"name":"Groot figure","tag":"grootfigure","price":600,"inCart":2},"owlfigure":{"name":"Owl figure","tag":"owlfigure","price":350,"inCart":4},"dragonfigure":{"name":"Dragon figure","tag":"dragonfigure","price":475,"inCart":5}}
The first idea was to pass the quantity of each product in cart to each counter variable in C# and then use a separate method in C# to run an SQL Query. But this seemed difficult to accomplish.
When I tried to pass variables between JS and C# by
function addOwl(){
#Globals.String = localStorage.getItem('productsInCart')
alert(#Globals.String)
}
I get this in the web browser console
Uncaught ReferenceError: addOwl is not defined at HTMLButtonElement.onclick (cart:71:68)
Any ideas how I can easily run SQL query from localStorage values?
Thank you
You need to understand where, when and how both JavaScript and C# are executed in Razor Pages.
C# is executed on the server, before the output is sent to the browser. Once the server executes the C# code, it produces text (which may be plain text, HTML, CSS, JavaScript, etc), which it then sends out. It then discards the request.
By contrast, JavaScript is only executed in the browser, not on the server. It knows nothng about C#, and cannot call C# code directly.
Specifically, the line of code...
#Globals.String = localStorage.getItem('productsInCart')
..will be interpreted by the server-side C# as "get the value of the String property of a C# object named Globals and insert that into the output that will be sent to the browser."
Given that you probably don't have that, I would expect a compiler error at this point. If you're not getting that, then it sounds like you aren't giving us the full story.
Assuming it can find such an object with such a property, let's say it has the value jim, it will mean that the following text (that's very important, the server treats all of this as text, it doesn't know about JavaScript, and will not attempt to interpret it) will be sent to the browser...
function addOwl(){
jim = localStorage.getItem('productsInCart')
alert(jim)
}
This is almost certaily not what you want.
So, to answer your basic question, the way to send data from your JavaScript to the server, where it will be used in your C# is to use AJAX. There are other ways, but this is probably the simplest.
If you use jQuery, then it gives you JavaScript functions to make this relatively easy. You'll need to write some C# code to accept the AJAX request.

write to Java console when my Javascript callback (made in Selenium) returns

I have learned how to create Javascript callback functions and I have a basic understanding of 'functional programming' since it seems easy enough. I am however, new to javascript and it's syntax and I can't find a good way to test said syntax while in my IntelliJ IDE.
What is it you're doing?
I'm creating a Selenium based tool to click on a webelement, wait for it to reload the page, become stale or wait for a timeout. The reason I'm doing this is to classify webelements into three categories: causes a page reload, becomes stale, doesn't change. To do this I've made a simple javascript script with the JavascriptExecutor that comes with Java. Most of my code is in java and that is the language I am proficient in. I want to learn how to use javascript with java to do the things I want with web pages.
Ok but what specifically is the problem?
I have a javascript callback function:
function test(callback) {callback();}
function Return() {SeleniumTest.isPageReloaded.JavascriptWorking}
window.addEventListener('onload', test(Return));
which is executed inside a Javascript Executor like so:
System.setProperty("webdriver.chrome.driver",
"C:\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String script = "function test(callback) {callback();}" +
"function Return()" +
"{SeleniumTest.isPageReloaded.JavascriptWorking}" +
"window.addEventListener('onload', test(Return));";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
Which is basically the Javascript script from before, executing as a String. As you can see I am attempting to call a java class. SeleniumTest is my package, isPageReloaded is the current class and JavascriptWorking is a static method within that class. That static method looks like this:
public static void JavascriptWorking(){
System.out.println("Javascript ran here");
}
Its meant to be a simple way to get something from the javascript to my java code. The reason I tried it this way is because I read this:
https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/bpm-appdev/invoking-java-methods-in-javascript.html
But then I realized that it wouldn't work and I dug deeper. I read that Javascript and Java are seperated by server and client and I gained some insight from this question:
calling java methods in javascript code
However I'm not 100% sure this is accurate to my case since the Javascript I'm executing isn't coming from the webpage I'm testing, Rather I made it myself inside the java code as a String. Additionally I'm still highly confused on if the answer to that question actually applies to me. There is only one and it basically just says, 'install some stuff because java is clientside and javascript is serverside'. I (kindof) understand what those terms mean but I'm not sure that the javascript I made in my class would be considered 'server-side' in fact it would seem to not be that way. What I need is clarification on A: is the javascript I'm running/creating in my java code actually serverside?
B: if yes then can someone give me a basic rundown on how I would go about calling java code from the server? does this require permissions? I assume I have to communicate with said server so does that mean I use GET and POSt requests?
C: If the Javascript Isn't server side then it must be clientside and I should be able to call it pretty easily right? How do I do this?
Show us what exactly you want
I want to be able to run:
System.setProperty("webdriver.chrome.driver",
"C:\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String script = "function test(callback) {callback();}" +
"function Return()" +
"{//insert callback code here}" +
"window.addEventListener('onload', test(Return));";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
and get either a static java method ran, something printed to console, or some other means that links the javascript code to the javacode. So for example if I inserted the correct code to call my static method:
SeleniumTest.IsPageReloaded.JavascriptWorking
(which again looks like):
public static void JavascriptWorking(){
System.out.println("Javascript ran here");
}
Then I'd want to see "Javascript ran here" on my java console. The driver being used is interchangebale, I just used chrome first because its fast. All that this needs is an enclosing main class and It ((should)) be runnable but no promises.
The purpose is to get something in java that I can then use as a flag to know that my asynchronous javascript is done in java and I can continue on with program execution. I can get the async javascript part and I understand it, I just need a link back to my java code.
Possible Solutions
I've been told that the common way to provide a flag for your java code is to create a certain webelement on the page with javascript and test for it in java (hence the link). I don't feel like adding to the webpages I test because I want to test them without actually editing/changing them. I'm generally open to other simple solutions but the biggest thing I need is clarification on the whole clientside serverside issue because its specific to my setup (Selenium java -> javascript -> java) where most questions only cover (javascript -> java) or vice versa.
The link you mentioned about JS invoking Java is for a specific application, that is meant to do that. Not saying it is impossible (I wrote FF plugins based on similar principle), but it is not applicable in this case. It also requires special application support (by default Javascript executed in browser is heavily sandboxed - it can't access anything out of its own scope. Invoking other apps on its own is a big no.).
The scripts you are injecting are always client side, they are executed only in the browser, that is isolated from the java code itself. With that said nothing is impossible.
Would like to mention two interesting features of the Selenium library that can come handy for you.
You mention a magic term many times "async Javascript execution" - and as I can see you are implementing your own version of executeAsyncScript. Webdriver does provide this method out of the box, pretty much for the purpose you want to use it with.
When you use executeScript, it will return pretty much immediately once it finished - in your case it will just inject your listener with your code, and then it returns. Using executeAsyncScript you can get a callback - just what you are doing. When calling executeAsyncScript, a default callback method is added to your code as the last argument, that needs to be called by your JS code for the method to return.
A simple example:
String script = "var callback = arguments[arguments.length - 1];" + //the last argument is the callback function
"var classToCall = 'SeleniumTest.IsPageReloaded';" + //the classname you want to return to call from Java in case of success)
"window.addEventListener('onload', callback(classToCall));";
//you can give any supported return value to the callback function. Here I assume that you want to call a static method. This is the class name that can be used later.
try {
JavascriptExecutor js = (JavascriptExecutor)driver;
//classToCall has the value we passed to the callback function
String classToCall = js.executeAsyncScript(script);
} catch (ScriptTimeoutException e) {
System.err.println("Uhhh... this failed I guess");
e.printStackTrace();
}
The executeAsyncScript does not return until the callback is called - to avoid infinite hangs, you can set the WebDriver.Timeouts.setScriptTimeout property to control this. If the script takes longer, JavascriptExecutor will throw an exception. Once returned, you can instantiate the returned class, and print like
Class clazz = Class.forName(classToCall); //it is only necessary if the classname is dynamic. If it is the same always, you can just go ahead with that.
((IsPageReloaded)clazz.newInstance()).JavascriptWorking();
Of course you can return a more complex datastructure also from the JS where you specify the method name also, but using reflection is really offtopic here.
Take a look at EventFiringWebdriver. This is a useful class that makes use of WebDriverEventListener to create custom Webdriver wrappers, with hooks on many events, allowing you to execute custom code before/after clicking, before/after pageload... and beside some others more importantly before/after executing javascript in the webdriver. You could leverage this to always call the same code around javascript execution - just create your own WebDriverEventListener.
You can find more info on the js executor here, and on WebDriverEventListener here.

What is the equivalent of using python-firebase's ".get" statement in Javascript?

I wrote python code that looks like this and returns the enire JSON database.
from firebase import firebase
firebase = firebase.FirebaseApplication('https://name_name_name.firebaseio.com/')
result = firebase.get('/results', None)
I have tried to do the same thing in javascript with no success. This should be straight forward but I haven't seen any solutions.
The idea is to host this on the server. It will pass the result variable to an XML converter. The XML will print to either that same document or another document in the directory.
What is the JavaScript equivalent of my Python code?
Without any real information on where your code runs, you probably want https://www.npmjs.com/package/firebase, which can be used both in the client (e.g. browsers) as well as in standard OS context (offline/server/general scripting language).
for anything JavaScript, http://npmjs.com is your one stop "is there something to do X" open source shop.

How compile function written in python to JavaScript (emscripten)?

I have a simple function written in python which I want to port to javascript.
I have compiled python 2.7 into a .so library, so thats not the issue.
The problem I'm having is that after I compile my program with cython, the function names get all scrambled up, which means I don't know how to preserve the functions when i run emcc.
Does anybody have any experience compiling python programs to js with emscripten?
Any information would be appreciated.
Note: I want to preserve the exact functionality to that of python, I don't want something that translates a python program into javascript.
This other question, with an accepted answer, complains about the same issue: Cython mangling function names and making it difficult to access from C++: Embed python function in C++
The accepted answer states that Cython isn't meant for this sort of thing at all, suggesting you can't do what you want in this fashion:
You're not going to be able to get the interoperation you want that way. If you open and inspect hello.c you won't find "static int say_hello" anywhere in there. Cython is designed for letting Python use C libraries, not letting C libraries use python.
The not-accepted next answer suggest that specifying public will not mangle the function name, although he also mentions linking problems.
# (in the generated C file hello.c)
__PYX_EXTERN_C DL_IMPORT(...) say_hello(...);
Worth a shot, but please consider the other options in the comments if it fails.

Is there a good way of automatically generating javascript client code from server side python

I basically want to be able to:
Write a few functions in python (with the minimum amount of extra meta data)
Turn these functions into a web service (with the minimum of effort / boiler plate)
Automatically generate some javascript functions / objects for rpc (this should prevent me from doing as many stupid things as possible like mistyping method names, forgetting the names of methods, passing the wrong number of arguments)
Example
python:
def hello_world():
return "Hello world"
javascript:
...
<!-- This file is automatically generated (either dynamically or statically) -->
<script src="http://myurl.com/webservice/client_side_javascript"> </script>
...
<script>
$('#button').click(function () {
hello_world(function (data){ $('#label').text(data)))
}
</script>
A bit of research has shown me some approaches that come close to this:
Automatic generation of json-rpc services from functions with a little boiler plate code in python and then using jquery and json to do the calls (still easy to make mistakes with method names - still need to be aware of urls when calling, very irritating to write these calls yourself in the firebug shell)
Using a library like soaplib to generate wsdl from python (by adding copious type information). And then somehow convert this into javascript (not sure if there is even a library to do this)
But are there any approaches closer to what I want?
Yes there is, there is Pyjamas. Some people bill this as the "GWT for Python"
It looks like using a javascript XML RPC client (there is jquery plugin for this) together with an XML RPC server is a good way to go.
The jquery plugin will introspect your rpc service and will populate method names make it impossible to mis type the name of a method call without getting early warning. It will not however test the number of arguments that you pass, or their type.
There doesn't seem to be the same support for introspection on json rpc (or rather there doesn't seem to be a consistent standard). This approach can also be used with django.
I've put together some example code and uploaded it here (I hope that linking to one's blog posts isn't considered terrible form - a brief search of the internet didn't seem to suggest it was)...

Categories

Resources