ODEV Object Type

I installed ODEV in a Virtual Environment as per the docs.

Class Calc — OOO Development Tools 0.7.0 documentation shows Return type: XSpreadsheetDocument. How can I get the Return type succinctly from python?

Microsoft Windows [Version 10.0.19044.2251]
(c) Microsoft Corporation. All rights reserved.

E:\SOURCE\repos\python_ooo_dev_tools\.venv\Scripts>activate

(.venv) E:\SOURCE\repos\python_ooo_dev_tools\.venv\Scripts>cd ..\..

(.venv) E:\SOURCE\repos\python_ooo_dev_tools>python
Python 3.8.15 (default, Nov 18 2022, 00:40:36) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from ooodev.utils.lo import Lo
>>> loader = Lo.load_office(Lo.ConnectSocket(headless=True))
>>>
>>> from ooodev.office.calc import Calc
>>> wb = Calc.create_doc()
>>>
>>> type(wb)
<class 'pyuno'>
>>>
>>> wb
pyuno object (com.sun.star.sheet.XSpreadsheetDocument)0x210c4347578{implementationName=ScModelObj, supportedServices={com.sun.star.sheet.SpreadsheetDocument,com.sun.star.sheet.SpreadsheetDocumentSettings,com.sun.star.document.OfficeDocument}, supportedInterfaces={com.sun.star.container.XChild,com.sun.star.document.XDocumentPropertiesSupplier,com.sun.star.document.XCmisDocument,com.sun.star.rdf.XDocumentMetadataAccess,com.sun.star.document.XDocumentRecovery,com.sun.star.document.XUndoManagerSupplier,com.sun.star.document.XShapeEventBroadcaster,com.sun.star.document.XDocumentEventBroadcaster,com.sun.star.lang.XEventListener,com.sun.star.document.XEventsSupplier,com.sun.star.document.XEmbeddedScripts,com.sun.star.document.XScriptInvocationContext,com.sun.star.frame.XModel3,com.sun.star.util.XModifiable2,com.sun.star.view.XPrintable,com.sun.star.view.XPrintJobBroadcaster,com.sun.star.frame.XStorable2,com.sun.star.frame.XLoadable,com.sun.star.script.XStarBasicAccess,com.sun.star.document.XViewDataSupplier,com.sun.star.util.XCloseable,com.sun.star.datatransfer.XTransferable,com.sun.star.document.XDocumentSubStorageSupplier,com.sun.star.document.XStorageBasedDocument,com.sun.star.script.provider.XScriptProviderSupplier,com.sun.star.ui.XUIConfigurationManagerSupplier,com.sun.star.embed.XVisualObject,com.sun.star.lang.XUnoTunnel,com.sun.star.frame.XModule,com.sun.star.frame.XTitle,com.sun.star.frame.XTitleChangeBroadcaster,com.sun.star.frame.XUntitledNumbers,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.util.XNumberFormatsSupplier,com.sun.star.lang.XUnoTunnel,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.uno.XAggregation,com.sun.star.sheet.XSpreadsheetDocument,com.sun.star.document.XActionLockable,com.sun.star.sheet.XCalculatable,com.sun.star.util.XProtectable,com.sun.star.drawing.XDrawPagesSupplier,com.sun.star.sheet.XGoalSeek,com.sun.star.sheet.XConsolidatable,com.sun.star.sheet.XDocumentAuditing,com.sun.star.style.XStyleFamiliesSupplier,com.sun.star.view.XRenderable,com.sun.star.document.XLinkTargetSupplier,com.sun.star.beans.XPropertySet,com.sun.star.lang.XMultiServiceFactory,com.sun.star.lang.XServiceInfo,com.sun.star.util.XChangesNotifier,com.sun.star.sheet.opencl.XOpenCLSelection}}
>>>

PS Restore LO with:

>>> Lo.close_doc(wb)
>>> Lo.close_office()
from ooodev.utils.lo import Lo
from ooodev.office.calc import Calc

_ = Lo.load_office(Lo.ConnectSocket(headless=True))
wb = Calc.create_doc()

for t in wb.Types:
    print(t.typeName)

Lo.close_doc(wb)
Lo.close_office()

Results:

com.sun.star.container.XChild
com.sun.star.document.XDocumentPropertiesSupplier
com.sun.star.document.XCmisDocument
com.sun.star.rdf.XDocumentMetadataAccess
com.sun.star.document.XDocumentRecovery
com.sun.star.document.XUndoManagerSupplier
com.sun.star.document.XShapeEventBroadcaster
com.sun.star.document.XDocumentEventBroadcaster
com.sun.star.lang.XEventListener
com.sun.star.document.XEventsSupplier
com.sun.star.document.XEmbeddedScripts
com.sun.star.document.XScriptInvocationContext
com.sun.star.frame.XModel3
com.sun.star.util.XModifiable2
com.sun.star.view.XPrintable
com.sun.star.view.XPrintJobBroadcaster
com.sun.star.frame.XStorable2
com.sun.star.frame.XLoadable
com.sun.star.script.XStarBasicAccess
com.sun.star.document.XViewDataSupplier
com.sun.star.util.XCloseable
com.sun.star.datatransfer.XTransferable
com.sun.star.document.XDocumentSubStorageSupplier
com.sun.star.document.XStorageBasedDocument
com.sun.star.script.provider.XScriptProviderSupplier
com.sun.star.ui.XUIConfigurationManagerSupplier
com.sun.star.embed.XVisualObject
com.sun.star.lang.XUnoTunnel
com.sun.star.frame.XModule
com.sun.star.frame.XTitle
com.sun.star.frame.XTitleChangeBroadcaster
com.sun.star.frame.XUntitledNumbers
com.sun.star.lang.XTypeProvider
com.sun.star.uno.XWeak
com.sun.star.util.XNumberFormatsSupplier
com.sun.star.lang.XUnoTunnel
com.sun.star.lang.XTypeProvider
com.sun.star.uno.XWeak
com.sun.star.uno.XAggregation
com.sun.star.sheet.XSpreadsheetDocument
com.sun.star.document.XActionLockable
com.sun.star.sheet.XCalculatable
com.sun.star.util.XProtectable
com.sun.star.drawing.XDrawPagesSupplier
com.sun.star.sheet.XGoalSeek
com.sun.star.sheet.XConsolidatable
com.sun.star.sheet.XDocumentAuditing
com.sun.star.style.XStyleFamiliesSupplier
com.sun.star.view.XRenderable
com.sun.star.document.XLinkTargetSupplier
com.sun.star.beans.XPropertySet
com.sun.star.lang.XMultiServiceFactory
com.sun.star.lang.XServiceInfo
com.sun.star.util.XChangesNotifier
com.sun.star.sheet.opencl.XOpenCLSelection

Then if you wanted to access an interface for example

from com.sun.star.util import XProtectable

sheet = Calc.get_active_sheet(wb)
# get the XProtectable interface
pro = Lo.qi(XProtectable, sheet, True)
# add a password to sheet
pro.protect("foobar")
print(f"Is protected: {pro.isProtected()}")

See Also: Show Sheet

@vib Thanks for the fast support but it’s not what I’m after. Maybe I’m using terminology incorrectly. Your code seems to display the services.
.
As a typical use case, say I wanted to see if the object was the correct type for the following:

classmethod delete_cells(sheet, cell_range, is_shift_left)
  Deletes cell in a spreadsheet
    Parameters: sheet (XSpreadsheet) – Spreadsheet

I want the Return type and nothing else. I could use:

pyuno object (com.sun.star.sheet.XSpreadsheetDocument)

It should be consistent with the docs:

static create_doc(loader: com.sun.star.frame.XComponentLoader)→ XSpreadsheetDocument
  Creates a new spreadsheet document
    ...
    Returns:      Spreadsheet document
    Return type:  XSpreadsheetDocument

It is shown in the output:

pyuno object (com.sun.star.sheet.XSpreadsheetDocument)0x210c4347578{implementationName=ScModelObj

 supportedServices={com.sun.star.sheet.SpreadsheetDocument
com.sun.star.sheet.SpreadsheetDocumentSettings
com.sun.star.document.OfficeDocument}

 supportedInterfaces={com.sun.star.container.XChild
com.sun.star.document.XDocumentPropertiesSupplier
com.sun.star.document.XCmisDocument
com.sun.star.rdf.XDocumentMetadataAccess
com.sun.star.document.XDocumentRecovery
com.sun.star.document.XUndoManagerSupplier
com.sun.star.document.XShapeEventBroadcaster
com.sun.star.document.XDocumentEventBroadcaster
com.sun.star.lang.XEventListener
com.sun.star.document.XEventsSupplier
com.sun.star.document.XEmbeddedScripts
com.sun.star.document.XScriptInvocationContext
com.sun.star.frame.XModel3
com.sun.star.util.XModifiable2
com.sun.star.view.XPrintable
com.sun.star.view.XPrintJobBroadcaster
com.sun.star.frame.XStorable2
com.sun.star.frame.XLoadable
com.sun.star.script.XStarBasicAccess
com.sun.star.document.XViewDataSupplier
com.sun.star.util.XCloseable
com.sun.star.datatransfer.XTransferable
com.sun.star.document.XDocumentSubStorageSupplier
com.sun.star.document.XStorageBasedDocument
com.sun.star.script.provider.XScriptProviderSupplier
com.sun.star.ui.XUIConfigurationManagerSupplier
com.sun.star.embed.XVisualObject
com.sun.star.lang.XUnoTunnel
com.sun.star.frame.XModule
com.sun.star.frame.XTitle
com.sun.star.frame.XTitleChangeBroadcaster
com.sun.star.frame.XUntitledNumbers
com.sun.star.lang.XTypeProvider
com.sun.star.uno.XWeak
com.sun.star.util.XNumberFormatsSupplier
com.sun.star.lang.XUnoTunnel
com.sun.star.lang.XTypeProvider
com.sun.star.uno.XWeak
com.sun.star.uno.XAggregation
com.sun.star.sheet.XSpreadsheetDocument
com.sun.star.document.XActionLockable
com.sun.star.sheet.XCalculatable
com.sun.star.util.XProtectable
com.sun.star.drawing.XDrawPagesSupplier
com.sun.star.sheet.XGoalSeek
com.sun.star.sheet.XConsolidatable
com.sun.star.sheet.XDocumentAuditing
com.sun.star.style.XStyleFamiliesSupplier
com.sun.star.view.XRenderable
com.sun.star.document.XLinkTargetSupplier
com.sun.star.beans.XPropertySet
com.sun.star.lang.XMultiServiceFactory
com.sun.star.lang.XServiceInfo
com.sun.star.util.XChangesNotifier
com.sun.star.sheet.opencl.XOpenCLSelection}}

Here is an example from the openpyxl library:

>>> type(wb)
<class 'openpyxl.workbook.workbook.Workbook'>

Youre compare apples with bananas, openpyxl runs without an excel-installation, and read|writes .xls-files

ooodev depends on an existing Libreofficeinstallation and it must run Libreoffice (maybe in Background)
Its at least a wrapper-library to the api, compareable to the ugly »script-forge-service-hell« but far better!

Note that if your expectation is that the object returned by that call will have exactly that type, you are wrong. The library works as a wrapper around UNO API (as @karolus mentioned); and as such, you get not native Python objects, but some wrappers over UNO type system. When such a wrapper tells you that it “returns an XSpreadsheetDocument”, it refers to any object that implements the XSpreadsheetDocument interface. And if you need to check if the object “is XSpreadsheetDocument”, you are expected to do that using methods of UNO (or of that wrapper, if they provide them).

If you were using a strongly-typed language, you would use a call to queryInterface method of XInterface (the root of all UNO interfaces hierarchy). No idea what people use in Python for that.

Huh? I realise a banana will not have apple seeds, you skin it like a cat, and now I understand the type is like house.
.
I have another object called widget. Do I need to use the Cluedo approach to see what it contains?

It didn’t, that was what I was after.

I am the author of ODEV and I agree with @mikekaganski .

I just want to add. When ODEV returns an object with a stated type such as XSpreadsheetDocument then you can be sure it indeed has all the properties and methods of said interface.

This is done through queryInterface via the Lo.qi() method.

Althought not strictly necessary in python. ODEV uses Lo.qi() very liberally.
This gives amazing typing support for all the API types in the LibreOffice API, thanks to ooouno and types-unopy, which I also authored.

ODEV general philosophy around LibreOffice API types is always work with an interface. This makes life a lot more sane when working with the LibreOffice API in python. It will act and feel much like strongly type objects.

1 Like

That is the object interfaces. How can object services and whatever the rest is:

Use Info class

from ooodev.utils.lo import Lo
from ooodev.office.calc import Calc
from ooodev.utils.info import Info

_ = Lo.load_office(Lo.ConnectSocket(headless=True))
wb = Calc.create_doc()
Info.show_services("Spreadsheet document", wb)

if Info.support_service(wb, "com.sun.star.sheet.SpreadsheetDocument"):
    print("Is a SpreadsheetDocument")
else:
    print("Not a SpreadsheetDocument")

Lo.close_doc(wb)
Lo.close_office()

Results:

Spreadsheet document Supported Services (3)
'com.sun.star.document.OfficeDocument'
'com.sun.star.sheet.SpreadsheetDocument'
'com.sun.star.sheet.SpreadsheetDocumentSettings'

Is a SpreadsheetDocument
1 Like