Plone / Python : zc.async problems with Plone on Ubuntu - python

I have integrated collective.documenviewer on my plone website. This is used for viewing PDF and other office files online.
One of the optional add-on products is plone.app.async which in turn uses zc.async. Now, the installation went well without errors. But when I save a file, an error is generated that I can't figure out: Below is the error:
2012-08-29T12:52:03 ERROR collective.documentviewer Error using plone.app.async with collective.documentviewer. Converting pdf without plone.app.async...
Traceback (most recent call last):
File "/home/frank/apps/myplonesite/plone/eggs/collective.documentviewer-2.2a1-py2.7.egg/collective/documentviewer/async.py", line 143, in queueJob
runner = JobRunner(object)
File "/home/frank/apps/myplonesite/plone/eggs/collective.documentviewer-2.2a1-py2.7.egg/collective/documentviewer/async.py", line 50, in __init__
self.queue = self.async.getQueues()['']
File "/home/frank/apps/myplonesite/plone/eggs/plone.app.async-1.2-py2.7.egg/plone/app/async/service.py", line 100, in getQueues
return self._conn.root()[KEY]
File "/home/frank/apps/myplonesite/plone/../../python27/lib/python2.7/UserDict.py", line 23, in __getitem__
raise KeyError(key)
KeyError: 'zc.async'
These are the versions that I am using:
plone.app.async = 1.2
zc.async = 1.5.4
How do I do away with the KeyError issue ?
UPDATE: Below is my buildout
[buildout]
newest = false
allow-picked-versions = false
index = http://dist.candid.org/candid
extends =
versions.cfg
parts =
lxml
svneggs
svnproducts
zeo
instance
worker
paster
plonesite
versions = versions
find-links =
http://dist.candid.org/candid
develop =
../src/candid.main
../src/ploned.ui
../src/z3c.traverser
../src/repoze.whooze
../src/marginalia
../src/ore.alchemist
../src/alchemist.ui
../src/alchemist.catalyst
../src/alchemist.traversal
../src/alchemist.security
../src/portal.auth
eggs =
Plone
Products.PloneHelpCenter
Products.LinguaPlone
candid
alchemist.ui
alchemist.catalyst
alchemist.traversal
alchemist.security
ploned.ui
candidcms.plonepas
candidcms.policy
candidcms.theme
psycopg2
Products.Scrawl
collective.contacts
collective.tabr
candidcms.workspaces
lotr.repository
archetypes.multifile
Products.ATVocabularyManager
collective.dynatree
collective.portlet.explore
z3c.json
collective.js.jqueryui
python-cjson
collective.plonetruegallery
lotr.templates
portal.auth
Products.PloneFormGen
quintagroup.pfg.captcha
collective.documentviewer
five.intid
plone.app.async
zcml =
candidcms.plonepas
candidcms.policy
candidcms.theme
candid.portal
candidcms.workspaces
archetypes.multifile
lotr.templates
collective.contacts
collective.tabr
collective.portlet.explore
[instance]
recipe = plone.recipe.zope2instance
user = uadmin:uadmin
eggs =
${buildout:eggs}
Products.CMFPlone
Paste
PasteScript
PasteDeploy
repoze.tm2
repoze.retry
repoze.who
zcml =
${buildout:zcml}
zcml-additional =
<include package="plone.app.async" file="single_db_instance.zcml" />
environment-vars =
ZC_ASYNC_UUID ${buildout:directory}/var/instance-uuid.txt
products =
${svnproducts:location}
# !+XAPIAN PATH(mn, apr-2012) hardcoded path to candid xapian installation
# temporary fix because plone uses the 'candid.portal' package which is in the
# candid.main package. Once the candid.portal package is factored out this entry
# should be removed.
extra-paths =
../parts/xapian/lib/python
[lxml]
recipe = z3c.recipe.staticlxml
egg = lxml
force = false
build-libxslt = true
build-libxml2 = true
libxslt-url = http://candid-portal.googlecode.com/files/libxslt-1.1.24.tar.gz
libxml2-url = http://candid-portal.googlecode.com/files/libxml2-2.6.32.tar.gz
[svnproducts]
recipe = infrae.subversion
urls =
http://candid-portal.googlecode.com/svn/plone.products/CandidHelpCenter/branches/plone4 CandidHelpCenter
[svneggs]
recipe = infrae.subversion
as_eggs = true
urls =
http://candid-portal.googlecode.com/svn/plone.products/candidcms.plonepas/trunk/ candidcms.plonepas
http://candid-portal.googlecode.com/svn/plone.products/candidcms.policy/trunk/ candidcms.policy
http://candid-portal.googlecode.com/svn/plone.products/candidcms.theme/trunk/ candidcms.theme
http://candid-portal.googlecode.com/svn/plone.products/candidcms.workspaces/trunk/ candidcms.workspaces
http://lotr.googlecode.com/svn/lab/apps/lotr.repository/ lotr.repository
http://lotr.googlecode.com/svn/trunk/products/lotr.templates/ lotr.templates
[paster]
recipe = zc.recipe.egg
eggs = ${instance:eggs}
# !+XAPIAN PATH(mn, apr-2012) hardcoded path to candid xapian installation
extra-paths =
../parts/xapian/lib/python
scripts = paster
[zeo]
recipe = plone.recipe.zeoserver
file-storage = ${buildout:directory}/var/filestorage/Data.fs
blob-storage = ${buildout:directory}/var/blobstorage
eggs = ${instance:eggs}
[worker]
recipe = plone.recipe.zope2instance
user = ${instance:user}
eggs = ${instance:eggs}
zcml = ${instance:zcml}
zserver-threads = 2
debug-mode = on
verbose-security = on
zeo-client = true
blob-storage = ${zeo:blob-storage}
shared-blob = on
eggs = ${instance:eggs}
zcml-additional =
<include package="plone.app.async" file="single_db_worker.zcml" />
environment-vars =
ZC_ASYNC_UUID ${buildout:directory}/var/worker-uuid.txt
[plonesite]
recipe = collective.recipe.plonesite
site-id = plone
admin-user = uadmin
instance = instance
profiles-initial =
Products.CMFPlone:dependencies
Products.CMFPlone:plone-content
lotr.repository:default
candidcms.policy:default
candidcms.theme:default
collective.dynatree:default
candidcms.workspaces:default
lotr.templates:default
Products.FacultyStaffDirectory:default
Products.PlonePopoll:default
Products.PloneFormGen:default
quintagroup.pfg.captcha:default
collective.documentviewer:default
products-initial =
Products.CMFPlone
archetypes.multifile
candidHelpCenter
LinguaPlone
collective.plonetruegallery
collective.tabr
Products.PloneFormGen
quintagroup.pfg.captcha

This would happen if the queues for plone.app.async have not been set up. plone.app.async & zc.async are (over)complicated and actually do require you reading the README ;)
You should have a look at the instructions provided with plone.app.async at their pypi page, in particular the buildout configuration.
Unless you include the necessary zcml (for your "normal", as well as your "worker" instance) your queues will not be setup.

This looks like an issue with collective.documentviewer. I am the author and actually think I fixed this at some point. What version are you running?

Related

All my poetry commands fail with 'The Poetry config is invalid'

I am working on macOS Monterey version 12.6 running Python 3.9.9 with Poetry 1.2.1. I'm trying to install all dependancies for my project from pyproject.toml with 'poetry install' ,and I keep getting the message
The Poetry config is invalid:
- [description] ' Tombstone is basically composed of a web server process (apiv2 web\n
server) and a celery worker process\n
(aiworker) for running async/background tasks outside\n
of a web request context.\n'
does not match '^[^\n]*$'
This doesn't give me much to go off of as far as debugging is concerned. The description is just line 4 of my pyproject.toml.
I have tried to uninstall Poetry and reinstall using Homebrew. I have also tried acting moving the poetry config to a different location inside my system, but I keep getting this error.
Here is the pyproject.toml:
[tool.poetry]
authors =
description = """
Tombstone is basically composed of a web server process (apiv2 web
server) and a celery worker process
(aiworker) for running async/background tasks outside
of a web request context.
"""
name = "tombstone"
version = "1.0.0"
[[tool.poetry.source]]
name = "tombstone-common-package"
secondary = true
url =
[tool.poetry.dependencies]
Python = ">=3.9,<3.10"
analytics-python = "1.3.1"
arpeggio = "1.10.2"
auth0-python = "3.16.0"
awscli = "1.19.106"
billiard = "3.6.4.0"
boto3 = "1.17.106"
cachecontrol = "0.12.8"
celery = {extras = ["redis", "zstd"], version = "4.4.7"}
celery-slack = "0.4.1"
cffi = "1.15.0"
click = "7.1.2"
dask = "2021.10.0"
distributed = "2021.10.0"
factory-boy = "3.2.1"
faiss-cpu = {version = "1.7.1.post3", markers = "sys_platform == 'darwin' or platform_machine == 'aarch64'"}
faiss-gpu = {version = "1.7.1.post2", markers = "sys_platform == 'linux' and platform_machine == 'x86_64'"}
faker = "8.2.1"
Flask = "2.0.2"
flask-admin = "1.5.8"
flask-caching = "1.10.1"
flask-cors = "3.0.10"
flask-jwt = "0.3.2"
Flask-RESTful = "0.3.9"
flask-restful-swagger-2 = "0.35"
flask-restplus = "0.13.0"
flask-sqlalchemy = "2.5.1"
flower = "0.9.4"
fs = "2.4.13"
fs-s3fs = "1.1.1"
gensim = "4.1.2"
google-auth = "2.3.3"
grpcio = "1.34.1"
gunicorn = "20.1.0"
joblib = "1.1.0"
json-log-formatter = "0.4.0"
marshmallow = "3.14.0"
marshmallow-sqlalchemy = "0.26.1"
matplotlib = "3.4.3"
networkx = "2.6.3"
nltk = "3.6.5"
numba = "0.54.1"
numpy = "1.19.5"
openpyxl = "3.0.9"
packaging = "20.9"
pandas = "1.2.5"
pika = "1.2.0"
prometheus-client = "0.12.0"
prometheus-flask-exporter = "0.18.5"
psycopg2-binary = "2.9.1"
pyarrow = "4.0.1"
pydash = "4.9.3"
pyjwt = "1.4.2"
python-dateutil = "2.8.2"
python-dotenv = "0.19.1"
python-jose = "3.3.0"
pytz = "2021.3"
pyyaml = "5.4.1"
requests = "2.26.0"
s3fs = "0.6.0"
scikit-learn = "1.0.1"
scipy = "1.7.1"
sendgrid = "6.8.3"
seqeval = "1.2.2"
simplejson = "3.17.5"
smart-open = "5.1.0"
sqlalchemy = "1.4.26"
tabulate = "0.8.9"
tensorboard = "2.7.0"
tensorflow = {version = "2.5.1", markers = "platform_machine == 'x86_64'"}
tombstone-common = "0.0.7"
tzlocal = "2.1"
# Tests dependecies. Currently, poetry doesn't support dependency groups in the
# requirements, so we need to use the extras feature. If adding a new test
# dependency REMEMBER TO ADD an entry on [tool.poetry.extras]
bandit = {version = "1.7.0", optional = true}
coverage = {version = "5.5", optional = true}
flake8 = {version = "3.9.2", optional = true}
flake8_formatter_junit_xml = {version = "0.0.6", optional = true}
pylint = {version = "2.8.3", optional = true}
pylint_junit = {version = "0.3.2", optional = true}
pytest = {version = "6.2.5", optional = true}
pytest-cov = {version = "2.12.1", optional = true}
pytest-factoryboy = {version = "2.1.0", optional = true}
pytest-flask = {version = "1.2.0", optional = true}
pytest-flask-sqlalchemy = {version = "1.0.2", optional = true}
pytest-html = {version = "3.1.1", optional = true}
pytest-mock = {version = "3.6.1", optional = true}
pytest-test-groups = {version = "1.0.3", optional = true}
pytype = {version = "2021.10.25", optional = true}
safety = {version = "1.10.3", optional = true}
easypost = "^5.1.3"
marshmallow-dataclass = "8.1.0"
ddtrace = "^1.0.0"
blinker = "^1.4"
mapbox = "^0.18.0"
geopy = "^2.2.0"
[tool.poetry.extras]
# Currently, poetry doesn't support dependency groups in the requirements, so we
# need to use the extras feature. Keep an eye on poetry 1.2 that will implement
# this feature
tests = [
"bandit",
"coverage",
"flake8",
"flake8_formatter_junit_xml",
"pylint",
"pylint_junit",
"pytest",
"pytest-cov",
"pytest-factoryboy",
"pytest-flask",
"pytest-flask-sqlalchemy",
"pytest-html",
"pytest-mock",
"pytest-test-groups",
"pytype",
"safety",
]
[tool.poetry.dev-dependencies]
# Add here the dependencies for local development
autopep8 = "1.5.7"
flask-shell-ptpython = "1.0.2"
honcho = "1.1.0"
ipython = "7.20.0"
pip-check-reqs = "2.1.1"
prompt-toolkit = "3.0.21"
pyspellchecker = "0.6.2"
pytest-watch = "4.2.0"
setuptools = "51.0.0"
wheel = "0.36.2"
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core>=1.0.0"]
A multi-line string is not valid for the description field. The error message does not match '^[^\n]*$' is telling you that it is not valid for the value to contain any newline characters.

How do you delete a virtual disk with pyvmomi

I am trying to write a Python program using the pyvmomi library to "erase" a virtual hard drive associated with a VM. The way this is done manually is to remove the virtual disk and create a new virtual disk with the same specs. I am expecting that I will need to do the same thing with pyvmomi so I have started down that path. My issue is that I can use ReconfigVM_Task to remove the virtual drive but that leaves the VMDK file itself.
I originally tried using DeleteVStorageObject_Task (since DeleteVirtualDisk_Task is deprecated) to remove the virtual disk file but that requires the ID of the object (the VMDK file) which I am unable to find anywhere. Theoretically that's available from the VirtualDisk property vDiskId but that is null. In further research it seems to only be populated for first class disks.
So I am instead trying to delete the VMDK file directly using DeleteDatastoreFile_Task but when I do that I end up with a XXXX-flat.vmdk file in the datastore so it seems to not actually delete the file.
Any idea on where I'm going wrong here or how to better do this? The VMWare SDK documentation for pyvmomi is...lacking.
Thanks!
You'll have to perform a ReconfigVM_Task operation. The keypoint for this is that the file operation should be destroy. Here's the raw output from performing the operation in the UI:
spec = vim.vm.ConfigSpec()
spec_deviceChange_0 = vim.vm.device.VirtualDeviceSpec()
spec_deviceChange_0.fileOperation = 'destroy'
spec_deviceChange_0.device = vim.vm.device.VirtualDisk()
spec_deviceChange_0.device.shares = vim.SharesInfo()
spec_deviceChange_0.device.shares.shares = 1000
spec_deviceChange_0.device.shares.level = 'normal'
spec_deviceChange_0.device.capacityInBytes = 8589934592
spec_deviceChange_0.device.storageIOAllocation = vim.StorageResourceManager.IOAllocationInfo()
spec_deviceChange_0.device.storageIOAllocation.shares = vim.SharesInfo()
spec_deviceChange_0.device.storageIOAllocation.shares.shares = 1000
spec_deviceChange_0.device.storageIOAllocation.shares.level = 'normal'
spec_deviceChange_0.device.storageIOAllocation.limit = -1
spec_deviceChange_0.device.storageIOAllocation.reservation = 0
spec_deviceChange_0.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
spec_deviceChange_0.device.backing.backingObjectId = ''
spec_deviceChange_0.device.backing.fileName = '[kruddy_2TB_01] web01/web01_2.vmdk'
spec_deviceChange_0.device.backing.split = False
spec_deviceChange_0.device.backing.writeThrough = False
spec_deviceChange_0.device.backing.datastore = search_index.FindByUuid(None, "datastore-14", True, True)
spec_deviceChange_0.device.backing.eagerlyScrub = True
spec_deviceChange_0.device.backing.contentId = 'e26f44020e7897006bec81b1fffffffe'
spec_deviceChange_0.device.backing.thinProvisioned = False
spec_deviceChange_0.device.backing.diskMode = 'persistent'
spec_deviceChange_0.device.backing.digestEnabled = False
spec_deviceChange_0.device.backing.sharing = 'sharingNone'
spec_deviceChange_0.device.backing.uuid = '6000C292-7895-54ee-a55c-49d0036ef1bb'
spec_deviceChange_0.device.controllerKey = 200
spec_deviceChange_0.device.unitNumber = 0
spec_deviceChange_0.device.nativeUnmanagedLinkedClone = False
spec_deviceChange_0.device.capacityInKB = 8388608
spec_deviceChange_0.device.deviceInfo = vim.Description()
spec_deviceChange_0.device.deviceInfo.summary = '8,388,608 KB'
spec_deviceChange_0.device.deviceInfo.label = 'Hard disk 2'
spec_deviceChange_0.device.diskObjectId = '148-3000'
spec_deviceChange_0.device.key = 3000
spec_deviceChange_0.operation = 'remove'
spec.deviceChange = [spec_deviceChange_0]
spec.cpuFeatureMask = []
managedObject.ReconfigVM_Task(spec)
Kyle Ruddy got me pointed in the right direction. Here's a code snippit showing how I made it work for future people searching for information on how to do this:
#Assuming dev is already set to the vim.vm.device.VirtualDisk you want to delete...
virtual_hdd_spec = vim.vm.device.VirtualDeviceSpec()
virtual_hdd_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy
virtual_hdd_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
virtual_hdd_spec.device = dev
spec = vim.vm.ConfigSpec()
spec.deviceChange = [virtual_hdd_spec]
WaitForTask(vm.ReconfigVM_Task(spec=spec))
The API documentation for this is at https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.device.VirtualDeviceSpec.html

VTK changes for "GetImage" and "Update"

I'm trying to get into Extension programming in 3DSlicer using Python.
There is a tutorial online. Unfortunately there is a problem with the third example script "HelloSharpen". I did the exact same thing they did but I get this error:
Traceback (most recent call last):
File "C:/Users/johan/Desktop/HelloPythonSlicer4/helloPython/code/HelloSharpen.py", line 105, in onApply
laplacian.SetInput(inputVolume.GetImageData())
AttributeError: 'vtkImagingGeneralPython.vtkImageLaplacian' object has no attribute 'SetInput'
I solved this by changing laplacian.SetInput(inputVolume.GetImageData()) to laplacian.SetInputData(inputVolume.GetImageData()) because I read that they changed this in the newer versions of VTK.
However when I try to run this a new error comes up:
Traceback (most recent call last):
File "C:/Users/johan/Desktop/HelloPythonSlicer4/helloPython/code/HelloSharpen.py", line 107, in onApply
laplacian.GetOutput().Update()
AttributeError: 'vtkCommonDataModelPython.vtkImageData' object has no attribute 'Update'
It seems that laplacian.GetOutput().Update() is causing problems so
I tried to find something on the Internet if they also changed this in the newer versions of VTK but I couldn't find anything. I tried to change this into "UpdateData" but this doesn't work.
Do you know if they also changed this and if yes, do you know what I should replace this with?
Here is the full code for "HelloSharpen":
from __main__ import vtk, qt, ctk, slicer
#
# HelloSharpen
#
class HelloSharpen:
def __init__(self, parent):
parent.title = "Hello Python Part D - Sharpen"
parent.categories = ["Examples"]
parent.dependencies = []
parent.contributors = ["Jean-Christophe Fillion-Robin (Kitware)",
"Steve Pieper (Isomics)",
"Sonia Pujol (BWH)"] # replace with "Firstname Lastname (Org)"
parent.helpText = """
Example of scripted loadable extension for the HelloSharpen tutorial.
"""
parent.acknowledgementText = """
This file was originally developed by Jean-Christophe Fillion-Robin, Kitware Inc.,
Steve Pieper, Isomics, Inc., and Sonia Pujol, Brigham and Women's Hospital and was
partially funded by NIH grant 3P41RR013218-12S1 (NAC) and is part of the National Alliance
for Medical Image Computing (NA-MIC), funded by the National Institutes of Health through the
NIH Roadmap for Medical Research, Grant U54 EB005149.""" # replace with organization, grant and thanks.
self.parent = parent
#
# qHelloPythonWidget
#
class HelloSharpenWidget:
def __init__(self, parent = None):
if not parent:
self.parent = slicer.qMRMLWidget()
self.parent.setLayout(qt.QVBoxLayout())
self.parent.setMRMLScene(slicer.mrmlScene)
else:
self.parent = parent
self.layout = self.parent.layout()
if not parent:
self.setup()
self.parent.show()
def setup(self):
# Collapsible button
self.laplaceCollapsibleButton = ctk.ctkCollapsibleButton()
self.laplaceCollapsibleButton.text = "Sharpen Operator"
self.layout.addWidget(self.laplaceCollapsibleButton)
# Layout within the laplace collapsible button
self.laplaceFormLayout = qt.QFormLayout(self.laplaceCollapsibleButton)
#
# the volume selectors
#
self.inputFrame = qt.QFrame(self.laplaceCollapsibleButton)
self.inputFrame.setLayout(qt.QHBoxLayout())
self.laplaceFormLayout.addWidget(self.inputFrame)
self.inputSelector = qt.QLabel("Input Volume: ", self.inputFrame)
self.inputFrame.layout().addWidget(self.inputSelector)
self.inputSelector = slicer.qMRMLNodeComboBox(self.inputFrame)
self.inputSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" )
self.inputSelector.addEnabled = False
self.inputSelector.removeEnabled = False
self.inputSelector.setMRMLScene( slicer.mrmlScene )
self.inputFrame.layout().addWidget(self.inputSelector)
self.outputFrame = qt.QFrame(self.laplaceCollapsibleButton)
self.outputFrame.setLayout(qt.QHBoxLayout())
self.laplaceFormLayout.addWidget(self.outputFrame)
self.outputSelector = qt.QLabel("Output Volume: ", self.outputFrame)
self.outputFrame.layout().addWidget(self.outputSelector)
self.outputSelector = slicer.qMRMLNodeComboBox(self.outputFrame)
self.outputSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" )
self.outputSelector.setMRMLScene( slicer.mrmlScene )
self.outputFrame.layout().addWidget(self.outputSelector)
self.sharpen = qt.QCheckBox("Sharpen", self.laplaceCollapsibleButton)
self.sharpen.toolTip = "When checked, subtract laplacian from input volume"
self.sharpen.checked = True
self.laplaceFormLayout.addWidget(self.sharpen)
# Apply button
laplaceButton = qt.QPushButton("Apply")
laplaceButton.toolTip = "Run the Laplace or Sharpen Operator."
self.laplaceFormLayout.addWidget(laplaceButton)
laplaceButton.connect('clicked(bool)', self.onApply)
# Add vertical spacer
self.layout.addStretch(1)
# Set local var as instance attribute
self.laplaceButton = laplaceButton
def onApply(self):
inputVolume = self.inputSelector.currentNode()
outputVolume = self.outputSelector.currentNode()
if not (inputVolume and outputVolume):
qt.QMessageBox.critical(
slicer.util.mainWindow(),
'Sharpen', 'Input and output volumes are required for Laplacian')
return
# run the filter
laplacian = vtk.vtkImageLaplacian()
laplacian.SetInputData(inputVolume.GetImageData())
laplacian.SetDimensionality(3)
laplacian.GetOutput().Update()
ijkToRAS = vtk.vtkMatrix4x4()
inputVolume.GetIJKToRASMatrix(ijkToRAS)
outputVolume.SetIJKToRASMatrix(ijkToRAS)
outputVolume.SetAndObserveImageData(laplacian.GetOutput())
# optionally subtract laplacian from original image
if self.sharpen.checked:
parameters = {}
parameters['inputVolume1'] = inputVolume.GetID()
parameters['inputVolume2'] = outputVolume.GetID()
parameters['outputVolume'] = outputVolume.GetID()
slicer.cli.run( slicer.modules.subtractscalarvolumes, None, parameters, wait_for_completion=True )
selectionNode = slicer.app.applicationLogic().GetSelectionNode()
selectionNode.SetReferenceActiveVolumeID(outputVolume.GetID())
slicer.app.applicationLogic().PropagateVolumeSelection(0)
TL;DR Change laplacian.GetOutput().Update() to laplacian.Update().
Explanation:
As per this link, there was a major change introduced in VTK 6. In summary, newer versions of VTK have separated algorithms and the data in two different class hierarchies. In newer versions of VTK, the Update() function can be called only on objects which have been derived from the vtkAlgorithm class. You can look at the inheritance diagram of vtkImageLaplacian here and it is indeed derived from vtkAlgorithm class. So laplacian.Update() will work.
As the name suggests vtkImageData is a data object. laplacian.GetOutput() returns a vtkImageData object and that's why you cannot call Update() function on it and therefore you get the error.

py2exe SytaxError: invalid syntax (asyncsupport.py, line22) [duplicate]

This command works fine on my personal computer but keeps giving me this error on my work PC. What could be going on? I can run the Char_Limits.py script directly in Powershell without a problem.
error: compiling 'C:\ProgramData\Anaconda2\lib\site-packages\jinja2\asyncsupport.py' failed
SyntaxError: invalid syntax (asyncsupport.py, line 22)
My setup.py file looks like:
from distutils.core import setup
import py2exe
setup (console=['Char_Limits.py'])
My file looks like:
import xlwings as xw
from win32com.client import constants as c
import win32api
"""
Important Notes: Header row has to be the first row. No columns without a header row. If you need/want a blank column, just place a random placeholder
header value in the first row.
Product_Article_Number column is used to determine the number of rows. It must be populated for every row.
"""
#functions, hooray!
def setRange(columnDict, columnHeader):
column = columnDict[columnHeader]
rngForFormatting = xw.Range((2,column), (bttm, column))
cellReference = xw.Range((2,column)).get_address(False, False)
return rngForFormatting, cellReference
def msg_box(message):
win32api.MessageBox(wb.app.hwnd, message)
#Character limits for fields in Hybris
CharLimits_Fields = {"alerts":500, "certifications":255, "productTitle":300,
"teaserText":450 , "includes":1000, "compliance":255, "disclaimers":9000,
"ecommDescription100":100, "ecommDescription240":240,
"internalKeyword":1000, "metaKeywords":1000, "metaDescription":1000,
"productFeatures":7500, "productLongDescription":1500,"requires":500,
"servicePlan":255, "skuDifferentiatorText":255, "storage":255,
"techDetailsAndRefs":12000, "warranty":1000}
# Fields for which a break tag is problematic.
BreakTagNotAllowed = ["ecommDescription100", "ecommDescription240", "productTitle",
"skuDifferentiatorText"]
app = xw.apps.active
wb = xw.Book(r'C:\Users\XXXX\Documents\Import File.xlsx')
#identifies the blanket range of interest
firstCell = xw.Range('A1')
lstcolumn = firstCell.end("right").column
headers_Row = xw.Range((1,1), (1, lstcolumn)).value
columnDict = {}
for column in range(1, len(headers_Row) + 1):
header = headers_Row[column - 1]
columnDict[header] = column
try:
articleColumn = columnDict["Product_Article_Number"]
except:
articleColumn = columnDict["Family_Article_Number"]
firstCell = xw.Range((1,articleColumn))
bttm = firstCell.end("down").row
wholeRange = xw.Range((1,1),(bttm, lstcolumn))
wholeRangeVal = wholeRange.value
#Sets the font and deletes previous conditional formatting
wholeRange.api.Font.Name = "Arial Unicode MS"
wholeRange.api.FormatConditions.Delete()
for columnHeader in columnDict.keys():
if columnHeader in CharLimits_Fields.keys():
rng, cellRef = setRange(columnDict, columnHeader)
rng.api.FormatConditions.Add(2,3, "=len(" + cellRef + ") >=" + str(CharLimits_Fields[columnHeader]))
rng.api.FormatConditions(1).Interior.ColorIndex = 3
if columnHeader in BreakTagNotAllowed:
rng, cellRef = setRange(columnDict, columnHeader)
rng.api.FormatConditions.Add(2,3, '=OR(ISNUMBER(SEARCH("<br>",' + cellRef + ')), ISNUMBER(SEARCH("<br/>",' + cellRef + ")))")
rng.api.FormatConditions(2).Interior.ColorIndex = 6
searchResults = wholeRange.api.Find("~\"")
if searchResults is not None:
msg_box("There's a double quote in this spreadsheet")
else:
msg_box("There are no double quotes in this spreadsheet")
# app.api.FindFormat.Clear
# app.api.FindFormat.Interior.ColorIndex = 3
# foundRed = wholeRange.api.Find("*", SearchFormat=True)
# if foundRed is None:
# msg_box("There are no values exceeding character limits")
# else:
# msg_box("There are values exceeding character limits")
# app.api.FindFormat.Clear
# app.api.FindFormat.Interior.ColorIndex = 6
# foundYellow = wholeRange.api.Find("*", SearchFormat=True)
# if foundYellow is None:
# msg_box("There are no break tags in this spreadsheet")
# else:
# msg_box("There are break tags in this spreadsheet")
Note:
If you are reading this, I would try Santiago's solution first.
The issue:
Looking at what is likely at line 22 on the github package:
async def concat_async(async_gen):
This is making use of the async keyword which was added in python 3.5, however py2exe only supports up to python 3.4. Now jinja looks to be extending the python language in some way (perhaps during runtime?) to support this async keyword in earlier versions of python. py2exe cannot account for this language extension.
The Fix:
async support was added in jinja2 version 2.9 according to the documentation. So I tried installing an earlier version of jinja (version 2.8) which I downloaded here.
I made a backup of my current jinja installation by moving the contents of %PYTHONHOME%\Lib\site-packages\jinja2 to some other place.
extract the previously downloaded tar.gz file and install the package via pip:
cd .\Downloads\dist\Jinja2-2.8 # or wherever you extracted jinja2.8
python setup.py install
As a side note, I also had to increase my recursion limit because py2exe was reaching the default limit.
from distutils.core import setup
import py2exe
import sys
sys.setrecursionlimit(5000)
setup (console=['test.py'])
Warning:
If whatever it is you are using relies on the latest version of jinja2, then this might fail or have unintended side effects when actually running your code. I was compiling a very simple script.
I had the same trouble coding in python3.7. I fixed that adding the excludes part to my py2exe file:
a = Analysis(['pyinst_test.py'],
#...
excludes=['jinja2.asyncsupport','jinja2.asyncfilters'],
#...)
I took that from: https://github.com/pyinstaller/pyinstaller/issues/2393

Python-UNO bridge: change PDF export options

I'm trying to generate a PDF from an odt file using Python and the OpenOffice UNO bridge.
It works fine so far, the only problem i'm facing are the export options.
By default, OO is using the existing PDF export settings (the one used the last time, or the default if the first time). But I need set these settings manually, for example "UseTaggedPDF" has to be true.
This is part of the code where i export the PDF:
try:
properties=[]
p = PropertyValue()
p.Name = "FilterName"
p.Value = "writer_pdf_Export"
properties.append(p)
p = PropertyValue()
p.Name = "UseTaggedPDF"
p.Value = True
properties.append(p)
document.storeToURL(outputUrl, tuple(properties))
finally:
document.close(True)
The PDF is generated but not tagged. What's wrong with this?
Finaly found the solution on http://www.oooforum.org/forum/viewtopic.phtml?t=70949
try:
# filter data
fdata = []
fdata1 = PropertyValue()
fdata1.Name = "UseTaggedPDF"
fdata1.Value = True
fdata.append(fdata1)
fdata.append(fdata1)
args = []
arg1 = PropertyValue()
arg1.Name = "FilterName"
arg1.Value = "writer_pdf_Export"
arg2 = PropertyValue()
arg2.Name = "FilterData"
arg2.Value = uno.Any("[]com.sun.star.beans.PropertyValue", tuple(fdata) )
args.append(arg1)
args.append(arg2)
document.storeToURL(outputUrl, tuple(args))
finally:
document.close(True)

Categories