2019-11-17

28: 'Hi, Console Python UNO Clients', a Sample

<The previous article in this series | The table of contents of this series | The next article in this series>

Connecting your program to the LibreOffice/OpenOffice instance (or any UNO server), in order to read/write an office document or handle the instance.

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: the Python programming language

The table of contents of this article


Starting Context



Target Context


  • The reader will know how to make his or her external console Python program connect to any UNO server (for example, a LibreOffice or Apache OpenOffice instance).
Stage Direction
Here are Hypothesizer 7, Objector 28A, and Objector 28B in front of a computer.


Orientation


Hypothesizer 7
In this article, we will get, build, execute, and understand a console Python UNO client sample.

Objector 28B
That is good, but make it simple please.

Hypothesizer 7
. . . Madam, what do you expect me to make "simple"? The sample or the explanation?

Objector 28B
Everything! You know, "Simple is best.".

Hypothesizer 7
Actually, I do not know. . . . As for recognition and description, I try to make it accurate, not "simple". In fact, simplifying it at any sacrifice of accuracy seems the root of all evil, to me.

Objector 28B
. . . I didn't tell you to lie!

Hypothesizer 7
Ah, I am relieved to know that we agree that if a truth is not described as complicated as it really is, the description will be a lie, because the truth will be distorted to be untruthfully simpler.

Objector 28B
. . . It is good for you that you have attained your peace of mind! So, how about the sample?

Hypothesizer 7
If you mean 'taking a short cut at any sacrifice of flexibility' by "simple", I must admit that that is not my objective, which is to show the most flexible, the most expandable way.

Objector 28B
. . . I don't understand what is 'flexibility' or 'expandability' of connecting to a LibreOffice instance: it just connects, right?

Hypothesizer 7
Flexibility is about whether the program can connect to any TCP/IP socket UNO server (whether it is local or remote), whether the program can offer some initial UNO objects to the UNO server, and whether the program can detect any UNO disconnection; expandability is about whether the way can be expanded to creating any UNO server.

Objector 28B
. . . So, you present me an unnecessarily complicated sample in order to accomplish flexibility and expandability I don't care at all!

Hypothesizer 7
First, I care; second, a flexible one serves for an inflexible one; third, you can just create a system of utility classes only once.

Objector 28B
They are no valid incentives for me, who am sure that I will never want such flexibility, to adopt an unnecessarily complicated way!

Hypothesizer 7
You are right.

Objector 28B
So?

Hypothesizer 7
"So?"? . . . So, I wish you good luck to find what you demand somewhere.

Objector 28B
. . .

Objector 28A
That your 'Starting Context' . . . is what?

Hypothesizer 7
Sir, that 'Starting Context' is the context in which this article begins to unfold.

Objector 28A
. . . Do you, a mere author, have the impudence to make such demands on me?

Hypothesizer 7
Well, every author, even "a mere author", demands certain knowledge of the readers, because he or she cannot guarantee that a baby can understand the document; it is just a matter of whether the demand is explicitly stated or not.

Objector 28A
But the monstrosity of the demands!

Hypothesizer 7
. . . Monstrous or not, the demands are logically determined by the contents of this article, not by my "impudence". You know, what are necessary are necessary, regardless of my disposition. You know, the knowledge of what UNO is is necessary for most UNO-related articles.

Objector 28A
. . . You can just explain kindly.

Hypothesizer 7
. . . Should I kindly begin my every UNO-related article with the explanation of what UNO is?

Objector 28A
Why not?

Hypothesizer 7
Because it would be so annoying to the readers: I would say "I know it already! Do not repeat the same thing!". . . . Is it kindness?

Objector 28A
. . .


Main Body


0: A Note


Hypothesizer 7
As a note, the sample program is only for Python 3.6 or newer.

Objector 28A
. . . What is special about the version, 3.6?

Hypothesizer 7
The version supports the variable type annotations feature.

Objector 28A
Huh? Such a feature is trash: it's not Pythonic!

Hypothesizer 7
"not Pythonic" . . ., and?

Objector 28A
"and?"?! You said "and?"?!

Hypothesizer 7
I did . . ., and?

Objector 28A
"and?"?! What is that supposed to mean?!

Hypothesizer 7
I mean, I care the maintainability of my code very much, but the "Pythonic"ity of my code? . . . I cannot care less.

Objector 28A
. . .

Hypothesizer 7
Anyway, if you strip the variable type annotations off the source files and bypass the static types checking that is automatically invoked by the build scripts, the sample will probably work fine.

Objector 28A
"bypass"? How?

Hypothesizer 7
The static types checking is invoked because the 'i_pythonCompileTask' task depends on the 'i_pythonCheckTypesTask' task in the 'commonTasks.gradle' file, which does the static types checking. So, you can just eleminate the dependency, probably.

Objector 28A
. . .


1: Getting and Building the Console Python UNO Client Sample


Hypothesizer 7
Here is a console Python UNO client sample. How to build any sample project of this series is described in a previous article.

Objector 28A
"build"? Any Python program doesn't have to be built, right?

Hypothesizer 7
Right, but my build system does 'mypy' static types checking, creates 'mypy' stubs, and explicitly compile source files.

Objector 28A
Whatever.

Hypothesizer 7
After expanding the ZIP file, 'hiConsolePythonUnoClients' is the project directory of the sample program; the other 2 directories are of 2 projects-common projects.

How to build your development environment is explained in a previous article (here for Linux and here for Windows).

Stage Direction
Hypothesizer 7 opens a terminal and builds the sample project.


2: Executing the Sample Program


Hypothesizer 7
Before we execute the sample program, we have to have started a LibreOffice or Apache OpenOffice instance so that it accepts connections from clients, as we can know how in a previous article.

Stage Direction
Hypothesizer 7 starts a LibreOffice instance with the port number 2002.

Hypothesizer 7
We can execute the sample program like this with the current directory positioned at the sample project directory and the file URL adjusted to our environment.

@bash Source Code
gradle i_executePythonExecutableFileTask -Pc_mainModuleName="theBiasPlanet.hiConsolePythonUnoClients.programs.HiConsolePythonUnoClients" -Pc_commandLineArguments="socket,host=localhost,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext file://${HOME}/myData/development/hiConsolePythonUnoClients/execution/HiConsolePythonUnoClientsTests.odt"

Stage Direction
Hypothesizer 7 executes the command in the terminal with the current directory positioned at the sample project directory. A OpenDocument Text file is opened and then closed immediately.

Objector 28A
. . . Will the document be inevitably shown on the display?

Hypothesizer 7
No. It is intentionally shown on the display in order to demonstrate that the sample program has successfully connected to the office instance.

Objector 28A
It's fine then.

Hypothesizer 7
We can just change the host name from 'localhost' if the office instance is in a remote host, if some firewalls do not block the communication, of course.

Note that in Windows, '${HOME}' is like '/E:/home/tanichida'.


3: Understanding the Sample Program


Hypothesizer 7
The explanation for the console Python UNO client sample is mostly same with that of the console Java UNO client sample, and I will cite some subsections of the previous article and indicate only the differences, without making almost-same-with-some-descriptions-in-the-previous-article descriptions here.


3-1: Understanding the Projects Structure


Hypothesizer 7
There are three projects: 'coreUtilitiesToBeDisclosed', 'unoUtilitiesToBeDisclosed', and 'hiConsolePythonUnoClients'. 'coreUtilitiesToBeDisclosed' contains utility code pieces that are supposed to be commonly used in all kinds of projects; 'unoUtilitiesToBeDisclosed' contains utility code pieces that are supposed to be commonly used in UNO program projects; 'hiConsolePythonUnoClients' is the sample project.

As the sample program does not do much than just uses 'unoUtilitiesToBeDisclosed', we have to look into the 'unoUtilitiesToBeDisclosed' project in order to learn how to make our external console Python program connect to any UNO server.


3-2: What Matter in Order to Go Beyond Connecting to the UNO Server Using the Utility Projects


Hypothesizer 7
Just in case that you use the utility projects as they are, let us see what matter in order to go beyond connecting to the UNO server using the utility projects.

In fact, as the structure of the Python utility classes accords with that of the Java utility classes and interfaces, the descriptions of this subsection of the previous article are valid.


3-3: The Wrapper of UNO Objects Context


Hypothesizer 7
The 'theBiasPlanet.unoUtilities.connectionsHandling.UnoObjectsContext' class in the 'unoUtilitiesToBeDisclosed' project is a wrapper of 'UNO objects context'.

The descriptions on the wrapper of this subsection of the previous article are valid for here.


3-4: Creating a Local UNO Objects Context (Bootstrapping)


Hypothesizer 7
The descriptions on the concept of 'bootstrapping' of this subsection of the previous article are valid for here, although how to create the local UNO objects context is different for Python.

This is how to create the local UNO objects context, as can be seen in the constructor of the 'theBiasPlanet.unoUtilities.programsHandling.UnoProcessEnvironment' class.

@C# Source Code
import uno
from com.sun.star.uno import XComponentContext

			l_originalLocalObjectsContext: XComponentContext = uno.getComponentContext ()


3-5: Connecting to the UNO Server


Hypothesizer 7
The descriptions on connecting to the UNO server of this subsection of the previous article are valid for here.


3-6: Cutting the Connection


Hypothesizer 7
The descriptions on cutting the connection of this subsection of the previous article are valid for here.


4: Although There Is a Simpler Way of Connecting to an Office Instance . . .


Hypothesizer 7
Actually, there is a simpler way of connecting to an office instance, but that way has some limitations, which are critical in certain cases.

The discussion in this section of the previous article is valid for here.


5: The Conclusion and Beyond


Hypothesizer 7
Now, we can connect to any UNO server from our console Python UNO client.

The reason why I have specified that the sample is a 'console' client is that a GUI Python UNO client sample will come in a future article.

The GUI Python UNO client might not seem to have to be different from the console Python UNO client UNO-wise, but there is a difference: as the UNO client is supposed to be up for some long duration, it is more appropriate to detect connection cuts caused by the UNO server or the network.


References


<The previous article in this series | The table of contents of this series | The next article in this series>