1

I'm new to Python and I want my Python script to be able to communicate with my Windows program (developed in Delphi, FWIW).

Basically, the Python script will download a set of data from other data sources, and for each record it's downloaded, I'll log it and tell the Windows program. For logging I'll use the Python standard logging library if possible, but what's the easiest way to tell the win32 program so that I can show the process of the downloading to the end user?

Note: I know Python4Delphi, but it's not documented well, and I want to keep things simple.

Edit 1: There will be only one Delphi exe and multiple python scripts.

Thanks.

Edwin Yip
  • 4,089
  • 4
  • 40
  • 86

5 Answers5

3

If your Delphi program is the one executing the Python program, then you can simply have the script write progress messages to standard output, and you can read them in your Delphi program. (If you do it this way, then it doesn't matter that one program is in Python and the other is in Delphi. Either program can be written in whatever language you want.)

Community
  • 1
  • 1
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • Thanks Rob, but I'm wondering if we can call CreateProcess **in a thread** to run the python script? Since there will be only one Delphi exe and multiple python scripts. – Edwin Yip Mar 31 '11 at 16:50
  • Of course. It doesn't really matter since CreateProcess creates a *new process*, completely unrelated to whatever thread called it. What you're probably concerned about is the code that runs *afterward* to receive the scripts' output. You can run that in threads, or you can process them all from one. (I've just noticed that the answer in the question I linked to does it wrong; it waits for the whole process to terminate before reading any of its output, which is wrong for multiple reasons. If you go this route, post a new question: How do I read output from multiple spawned processes?) – Rob Kennedy Mar 31 '11 at 17:44
  • +1 for the suggestion, IMHO, this is the best because the independence gained at both sides ;) – jachguate Mar 31 '11 at 18:33
  • It's actually severely limited. Your program must output everything and then have that output read, all at once. You can't use it interactively, and as your output tends towards something other than flat text, and only a small amount of it, this gets less and less pretty. – Warren P Mar 31 '11 at 20:35
  • @Rob, why I'm asking creating new python process in threads because I want to use each thread to run and capture output from python, then send it to the main UI to display to the user, as Warren P said, I'll have to communicate with python **interactively**. – Edwin Yip Apr 06 '11 at 13:28
  • No, Edwin, that doesn't sound interactive to me. Using a script interactively means you read some output from the script, interpret it, and then *send more input* back to the script so that it can give you the next output. Merely collecting output isn't interactive. The main problem with the Delphi answer I linked to is that it waits for the whole script to finish running before it starts collecting input, which is suitable only for short-lived scripts that have no danger of exhausting the output buffer. Ideally, the program should read output as it becomes available, making room for more. – Rob Kennedy Apr 06 '11 at 13:55
1

You could use a named pipe or a socket to communicate between the Python code and the Delphi code. For interfacing Python to named pipes you could could use ctypes (example here).

Altermatively, you could create a COM component in Delphi and make calls to it from Python (ActivePython includes all the Windows bits you need).

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
1

Use PyWin32 package: http://pypi.python.org/pypi/pywin32 It provides you with access to the whole WinAPI.

You could use for example COM: http://docs.activestate.com/activepython/2.7/pywin32/html/com/win32com/HTML/docindex.html

vartec
  • 131,205
  • 36
  • 218
  • 244
0

My own idea:

Maybe call PostMessage(WM_CopyData) in the Python script? But what's the best/standard way of calling that win32 API in Python?

Edwin Yip
  • 4,089
  • 4
  • 40
  • 86
0

I would make a simple socket server in one side, and a simple socket client on the other one. Now I can have them talking on the same computer, and also, talking across a local area network, or across the internet. Easy and fun.

In python, socket programming library options abound, as they do in Delphi. Indy is the most common solution in Delphi. Simple socket servers that are quite robust enough for you to use, are also built into python.

Also, since Python is portable beyond windows, do you really want to limit yourself to named pipes and COM and chain your Python program to windows forever?

If however, your scripts are an adjunct to the Delphi program, then Python4Delphi (ability to call Python functions and consume their results) is exactly what you need, and as far as I know, it's not well documented because it's so easy to use, it doesn't need to be. How much documentation did you read about WriteLn before you did your first WriteLn('HelloWorld')?

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • Hi Warren, socket is a good idea, but the communication will have to pass the firewall even it's on the same computer, at least with ESET Smart Security. – Edwin Yip Apr 01 '11 at 05:52
  • Regarding Python4Delphi, the version downloaded from mmm-experts.com doesn't support Python 2.7, but the latest source checked out from google code SVN server is missing several source file. I even couldn't get it to compiled... – Edwin Yip Apr 01 '11 at 05:58
  • Good point. IDLE (the python IDE) uses sockets, and it's a pain even inside a single app, that IDLE functionality – Warren P Apr 01 '11 at 15:39
  • UPDATE: the author of python4delphi have just fixed the dated dependency problem, now I can compile and install the package. – Edwin Yip May 29 '11 at 10:44