2-way interop/IPC between SWI Prolog & Python - python

There is module to call from Python (pyswip) =to=> Prolog, but is there a way to call the other way around from Prolog =to=> Python ?
I need it so I can call Spacy-NLP module from SWI-Prolog
couldn't find if SWI supports ZeroMQ.

This is the sample python code in a file "c:\hello.py" that extracts the argumentq on the command line (optional). It's results are echoed to the standard output stream.
import sys
def hello():
return 'hello world: ' + ','.join(sys.argv[1:])
if __name__ == '__main__':
print(hello())
Here is the prolog program in file "c:\hello.pl" invoking the above python code as a process:
do :-
process_create(path('python3.7'),
['c:/hello.py', foo, bar],
[stdout(pipe(In))]), %output stream named In
read_string(In, Len, X), %In=input stream to read_string/3
write(X), nl, halt.
To activate this prolog/python combo and writting the results to the output stream
$ swipl -g do c:\hello.pl
hello world: foo,bar
Does this do what you wanted?

Related

How to access a docstring from a separate script?

Building a GUI for users to select Python scripts they want to run. Each script has its own docstring explaining inputs and outputs for the script. I want to display that information in the UI once they've highlighted the script, but not selected to run it, and I can't seem to get access to the docstrings from the base program.
ex.
test.py
"""this is a docstring"""
print('hello world')
program.py
index is test.py for this example, but is normally not known because it's whatever the user has selected in the GUI.
# index is test.py
def on_selected(self, index):
script_path = self.tree_view_model.filePath(index)
fparse = ast.parse(''.join(open(script_path)))
self.textBrowser_description.setPlainText(ast.get_docstring(fparse))
Let's the docstring you want to access belongs to the file, file.py.
You can get the docstring by doing the following:
import file
print(file.__doc__)
If you want to get the docstring before you import it then the you could read the file and extract the docstring. Here is an example:
import re
def get_docstring(file)
with open(file, "r") as f:
content = f.read() # read file
quote = content[0] # get type of quote
pattern = re.compile(rf"^{quote}{quote}{quote}[^{quote}]*{quote}{quote}{quote}") # create docstring pattern
return re.findall(pattern, content)[0][3:-3] # return docstring without quotes
print(get_docstring("file.py"))
Note: For this regex to work the docstring will need to be at the very top.
Here's how to get it via importlib. Most of the logic has been put in a function. Note that using importlib does import the script (which causes all its top-level statements to be executed), but the module itself is discarded when the function returns.
If this was the script docstring_test.py in the current directory that I wanted to get the docstring from:
""" this is a multiline
docstring.
"""
print('hello world')
Here's how to do it:
import importlib.util
def get_docstring(script_name, script_path):
spec = importlib.util.spec_from_file_location(script_name, script_path)
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
return foo.__doc__
if __name__ == '__main__':
print(get_docstring('docstring_test', "./docstring_test.py"))
Output:
hello world
this is a multiline
docstring.
Update:
Here's how to do it by letting the ast module in the standard library do the parsing which avoids both importing/executing the script as well as trying to parse it yourself with a regex.
This looks more-or-less equivalent to what's in your question, so it's unclear why what you have isn't working for you.
import ast
def get_docstring(script_path):
with open(script_path, 'r') as file:
tree = ast.parse(file.read())
return ast.get_docstring(tree, clean=False)
if __name__ == '__main__':
print(repr(get_docstring('./docstring_test.py')))
Output:
' this is a multiline\n docstring.\n'

How does Python get the log log of exE software output

The exe file is also written in Python, which USES Pyinstaller to convert to exe. This EXE outputs warninglevel logs at the end. For example, Logger.warning (" Hello World ") outputs "Hello World". So how do I get this "Hello World" when the main thread calls this exe subroutine?
This is the code for logTest.exe
import logging
logger = logging.getLogger(__name__)
logger.warning("Something maybe fail.")
This is the code for output.py
import os
import subprocess
import logging
main=r"D:\python\commendTest\dist\logTest.exe"
f=os.popen(main)
data=f.readlines()
f.close()
log:
Something maybe fail.
But I want to get "Something maybe fail." into the string

How to know which file is calling which file, filesystem

How to know which file is calling which file in filesystem, like file1.exe is calling file2.exe
so file2.exe is modified,
and file1.exe is entered in log file.
winos
I have searched INTERNET but not able to find any samples.
In order know which file is calling which file you can use the Trace module
exp: if you have 2 files
***file1.py***
import file2
def call1():
file2.call2()
***file2.py***
def call2():
print "---------"
u can use it using console:
$ python -m trace --trackcalls path/to/file1.py
or within a program using a Trace object
****tracefile.py***
import trace,sys
from file1 import call1
#specify what to trace here
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], trace=0, count=1)
tracer.runfunc(call1) #call the function call1 in fille1
results = tracer.results()
results.write_results(summary=True, coverdir='.')

Call custom AutoIt function from python

I found a way to run built in auto it functions from python using the following code
from win32com.client import Dispatch
Auto = Dispatch("AutoItX3.Control")
Auto.Run("notepad.exe", "", 5)
Is there a similar way to call custom methods i.e methods defined in my_AutoIt_File.au3
Say I have a method in this file
Func my_autoit_method
;some code
EndFunc
Is there a way to call this my_autoit_method from python?
From the help file:
AutoIt specific command Line Switches
Form1: AutoIt3.exe [/ErrorStdOut] [/AutoIt3ExecuteScript] file
[params ...]
Execute an AutoIt3 Script File
/ErrorStdOut Allows to redirect fatal error to StdOut which can be captured by an application as Scite editor. This switch can be used with a compiled script.
To execute a standard AutoIt Script File 'myscript.au3', use the command:
'AutoIt3.exe myscript.au3'
Form2: Compiled.exe [/ErrorStdOut] [params ...]
Execute an compiled AutoIt3 Script File produced with Aut2Exe.
Form3: Compiled.exe [/ErrorStdOut] [/AutoIt3ExecuteScript file]
[params ...]
Execute another script file from a compiled AutoIt3 Script File. Then you don't need to fileinstall another copy of AutoIT3.exe in your compiled file.
Form4: AutoIt3.exe [/ErrorStdOut] /AutoIt3ExecuteLine "command line"
Execute one line of code.
To execute a single line of code, use the command:
Run(#AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(0, ''Hello World!'', ''Hi!'')"')
You have to expose your AutoIt Function to other applications. This could be done easily with AutoItObject, which can register an object in the ROT.
The AutoIt Code would be:
#include <AutoItObject.au3>
$oObject = _AutoItObject_Create()
_AutoItObject_RegisterObject($oObject, 'MyVery.CustomApplication')
_AutoItObject_AddMethod($oObject, '_my_custom_function', '_my_custom_function')
While Sleep(100)
WEnd
Func _my_custom_function($oSelf)
MsgBox(0, '', 'AutoIt says Hi')
Exit
EndFunc
The Python Code should be:
from win32com.client import Dispatch
Auto = Dispatch("MyVery.CustomApplication")
Auto._my_custom_function()

Passing command line argument to another file imported in Python

I have a python file (html2text.py) which gives the desired result when i pass command line argument to it i.e., in the following way:
python html2text.py file.txt
where file.txt contains the source code of a web-site and the result is displayed on the console...
I want to use it in another file (let say a.py) and store the result (which was getting printed on the console) in a string.
For this I need to first import the file (html2text.py) in my file (a.py). Can anyone tell me how do I proceed further...?
Good way is to create some API in your html2text.py. For example:
# html2text.py
def parse(filename):
f = open(filename)
# do the stuff
return output_string
def main():
import sys
print parse(sys.argv[1])
if __name__ == '__main__':
main()
Then you will be able to use it in your a.py:
import html2text # main() will not run
import sys
output = html2text.parse(sys.argv[1])
I think the best way is the reorganize a little your html2text.py file. Append the line like this to your file:
def main():
message = sys.stdin.readlines()
a = your_def(message)
if __name__ == '__main__': main()
Now you're sure, that when invoking the file from command line, everything will go fine. Moreover, if you have everything kept in functions and classes, you can now in your a.py
import html2text
and work on it already in a.py.

Categories