Jump to content

Installing Plugins with External Libraries


Recommended Posts

So far, I've only used stock Python libraries for my plugins, and have distributed them just as vsm files for the users in our company to drop in to their AppData plugins folder.

 

I've now used various 3rd party libraries in standalone Python desktop apps with good results. I would like to start using and bundling 3rd party libraries, and also having a nicer way of all of the required files/packages being placed in the AppData folder, and maybe even the command adding to a workspace (though I'm less concerned about that).

 

However, the below page and links from it seems to suggest that the 'old way' of installing scripts is obsolete...but doesn't seem to clarify what the 'new way' is?

https://developer.vectorworks.net/index.php?title=Vectorworks_Scripting#Installing_Scripts

https://developer.vectorworks.net/index.php?title=VS:Vectorworks_2023_Development

 

I don't want to use the Partner Products thing, as everything I make at the moment is company-specific and needs to be distributed internally here. I would be up for adding things to the Partner Products portal in the future potentially, but not right now.

 

Should I have a go at the methods via the links on that page, or is there a better way I am missing please?

Link to comment

Most of the article that you posted is detailing the Install button in the Third-party plug-ins tab of the Plug-in Manager, which was added several years ago (can't remember the exact version, but it is in VW2019 which is the earliest one I have installed).  I don't know about calling the old method obsolete, as it still works fine, but the Install button and using .zip files is certainly more convenient if you need anything more than the .py plug-in file.

 

As for using outside libraries and ensuring that they are available, the articles you posted don't cover any of that.  The unfortunate thing is that installing outside libraries is an entirely different process, and one that can be difficult to script.  There are methods that I have had some luck with, some being much more hands on than others.  I'll cover them from least hands on to most hands on.

 

1.   Using the Marionette library with VerifyOrGetLib:  The Marionette library has a solution to this that I've used a couple of times with relative success (at least on newer versions of Vectorworks, I could not get it to work on VW2019 because the Python version was too old for any of the libraries I needed).  It basically revolves around using the Marionette.VerifyOrGetLib function and passing in a .whl file.  Below is a code snippet that you might be able to include at the top of your code to install an external library if one is missing, using the GitPython library as an example:

import Marionette

try:
	import git
except:
	git = "https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl"
	bool = Marionette.VerifyOrGetLib("GitPython",git)

 

This will try to import the library, and if it throws an error, it will instead use the Marionette.VerifyOrGetLib function to download it instead.  This will launch a small dialog box asking the user if they want to install the library:

image.png.c1c89b594266376d7911f28e7e679899.png

 

The user will need to press OK for the installation to continue, which will essentially open a terminal window and execute a pip install process for you, but making sure that the files end up in the Python Externals folder of the User Folder.  Keep in mind that the user will need to restart Vectorworks after the process for Python to see the library as installed (may not be a bad idea to include a vs.AlrtDialog() message in the except to remind them).  This has been the most stable way for me.

 

2.  Invoke the pip command from within the script I found a method in this post from @DomC but have never been able to make it work, but also admit that my Python is not the best so I was probably missing something:

 

3.  Use the method found in the Vectorworks Help in the section Manually Installing Python LIbraries:  This method is a bit of a pain in the butt and probably more than you want to ask of most users, but it works.  It's essentially doing the same thing as the Marionette.VerifyOrGetLib method above but manually (assuming you're using Vectorworks 2023 or later).

 

image.thumb.png.7d5d4f8d21ec0fafa600d517c1fd0919.png

 

image.png.6934e8f0996e7f9febcb266b3361f2f1.png

image.png.ff3ae9a1a5c40cc59712cfd5472cdfc3.png

 

image.png.b8fc2b22e4aa7d0271639d04a53072ab.png

 

Again, not scripted or automated, but also not terrible.

  • Like 2
Link to comment

I spent a little more time reading the articles that you posted, the wording is pretty needlessly obtuse and hard to wrap my head around.  What it is initially saying in the Installing Scripts section is that when you create a new script, the script is automatically placed in the proper directory of the User Folder.  In following instances of Vectorworks starting, any plug-in found in that directory is automatically loaded.  None of this is new, and is the way Vectorworks has worked since at least 2010.

 

The Basic Installation just details the use of the Install button of the Plug-in Manager.  The Implementing Installation Script page is a bit more interesting.  It seems that if your .zip file contains an install.py script, that script will be executed when the Install button is pressed.  So, you could have the code snippet I posted above placed in the install.py script so that it only happens on initial installation.  The example file on the page builds a custom directory in the User Library folder and uses the shutil library to copy a provided .vwx file with symbols into that directory as well as copying a custom workspace with the presumed command installed in it.  The More Complicated Installation article demonstrates the use of urllib.request to download a content file from Dropbox, but still doesn't cover the installation of an external library.

  • Like 2
Link to comment
  • 1 month later...

Hi spettitt,

I use the following method for using external libraries:

Call a server API with a Post request. For my personal use I just run a Flask server on my own computer, but I'm sure this can easily be a Python Anywhere free server online or a server on the company network.

 

The functions can just be made using ChatGPT. Inside the vectorworks script I use the following.

def send_post_request(url, data):
	import urllib.request
	import json
	
	# Convert the data dictionary to JSON
	json_data = json.dumps(data).encode('utf-8')
	
	# Create a request object
	req = urllib.request.Request(url, data=json_data, method='POST')
	
	# Set the content type to application/json
	req.add_header('Content-Type', 'application/json')
	
	try:
		# Send the request and get the response
		with urllib.request.urlopen(req) as response:
			# Read and decode the response
			response_data = response.read().decode('utf-8')
			
			# Parse the JSON response
			return json.loads(response_data)
	except urllib.error.URLError as e:
		# print(f"Error: {e.reason}")
		print("error")
		return None

def main():
	url = 'http://localhost:5000/'
	data = {
		# data to send to server
	}

	response = send_post_request(url, data)
	if response:
	 	print(response)

 

The Flask server can just be made using ChatGPT. Just copy the above code into ChatGPT and it will make the appropriate server.

 

Link to comment
  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...