Pyblish 1.3 Released


#1

http://forums.pyblish.com/uploads/default/original/1X/57ea12059d1c8620fcbdf6f7c73530cf3a63286f.gif

Previous releases

Summary of new features.

Management

Core

GUI

  • Collectors visible during processing (See animation above)
  • More feedback Read more



Overview

This release marks a significant overhaul of the underlying logic of Pyblish. The change is fully backwards compatible and will continue to support the prior ways of working until the next major version change (2.0), but users are recommended to transition and will likely find the change an improvement.

Say hello to ContextPlugin and InstancePlugin.

import pyblish.api

class MyCollector(pyblish.api.ContextPlugin):
    order = pyblish.api.CollectorOrder

    def process(self, context):
        ...

class MyValidator(pyblish.api.InstancePlugin):
    order = pyblish.api.ValidatorOrder

    def process(self, instance):
        assert ...

Like before, these process either the current Context or Instance, unlike before this distinction is made upfront and not decided upon based on the argument signature.




What has changed?

Leaving the details of this change to the two links provided above, here’s the gist of it. The workflow and mindset of the developer remains the same, but implementation differs in that the superclasses no longer behave differently based on their argument signature.

As you (may not) know, process(self, context) behaves differently from process(self, context, instance). This behaviour was confusing and led to a lot of odd corner cases that were difficult to debug.

Instead, the superclass - ContextPlugin or InstancePlugin - now determines a fixed behaviour for your plug-ins, where their ordering is instead based solely on the order attribute and CVEI provided as named integers, such as pyblish.api.CollectorOrder.

class MyCollector(pyblish.api.ContextPlugin):
  order = pyblish.api.CollectorOrder

  def process(self, context):
    ...

class MyValidator(pyblish.api.InstancePlugin):
  order = pyblish.api.ValidatorOrder

  def process(self, instance):
    ...



Installation

Whether you are installing anew or updating, it is recommended that you install from scratch.

For Windows, download and run the installer or install via the command-line.
For Linux, OSX or to install via the command-line, see manual installation instructions here.
If you run into any issues, feel free to post below.




Callbacks

This new feature enables developers to listen for events taking place throughout Pyblish and surrounding applications, such as the GUI.

import pyblish.api

def on_published(context):
  has_error = any(result["error"] is not None for result in context.data["results"])
  print("Publishing %s" % ("finished" if has_error else "failed"))

pyblish.api.register_callback("published", on_published)

Thanks to this change, you will now find the toggled state in the GUI properly reflected in the physical instance within your plug-ins; meaning you can now make considerations based on their visual state!

To try it out, have a play with this example, printing the current state from the GUI.

import pyblish.api
import pyblish_integration

class MyCollector(pyblish.api.ContextPlugin):
    order = pyblish.api.CollectorOrder

    def process(self, context):
        context.create_instance("myInstance1")
        context.create_instance("myInstance2")
        count["#"] += 1

class MyValidator(pyblish.api.ContextPlugin):
    order = pyblish.api.ValidatorOrder

    def process(self, context):
        for instance in context:
            print("%s['publish']: %s" % (instance.data["name"], instance.data.get("publish", True)))

pyblish.api.register_plugin(MyCollector)
pyblish.api.register_plugin(MyValidator)

pyblish_integration.show()

For a list of supported events, see here.

Also have a look at the new chapters in Pyblish by Example




Transition Guide

In general, you can simply replace your superclass with the new superclass; either ContextPlugin or InstancePlugin, depending on whether your argument signature contained context or instance respectively.

There is one corner case.

I have both instance and context in my signature.

If so, subclass from InstancePlugin and remove context and instead get the context via instance.context.

def process(self, instance):
  context = instance.context

The plug-in will continue to behave exactly as before.




More changes

  • Simplified CLI
  • Retired vendors
  • Retired file-based configuration
  • Deprecation

Simplified CLI

The command-line interface no longer provides options for file-based configuration and data.

$ pyblish publish

Storing a file called data.yaml in the current working directory when running this command caused the contained dictionary of data to be appended to the Context. This no longer happens.

Additionally, storing a file called config.yaml with plug-in paths would cause the contained paths to be appended to the PYBLISHPLUGINPATH when running the above command. This no longer happens.

Retired Vendors

nose, yaml and coverage are no longer included in this release. If you in depend on them (you shouldn’t) then you will have to install them locally henceforth.

nose and coverage was retired due to incompatibility with the forthcoming Python 3 support, and yaml due to no longer having support for file-based configuration.

Retired file-based configuration

At the dawn of Pyblish, plug-in paths were registered by editing a configuration file and storing it in your local home directory. The practice quickly grew cumbersome, as it was difficult to enable networked installs and varying the configuration based on various factors, such as project, software or user.

Instead, environment variables were introduced to take on the weight, and they have been in use ever since.

Hopefully, this deprecation should not affect you and if it does then you find much greater flexibility in instead customising environment variables.

If you still have need for this feature, now is the time to speak up.

Deprecation

Some internal details mostly relevant to developers of Pyblish or software that somehow uses Pyblish to function have changed and are facing deprecation.

  • pyblish.logic.process
  • Services

process was previously used to determine what plug-in to run next and when to stop. But this practice proved too inflexible when it came to the GUI that needed direct control over this particular aspect.

In its place, there is now pyblish.logic.Iterator which simply provides the next pair of items to process, without actually processing them. For your own GUIs, this should prove more flexible, at the cost of having to implement more logic on your own.

See pyblish.util.publish() or pyblish-qml for examples of how to do that.

Services are also deprecated. Their primary reason for existing was to facilitate dependency injection which is no longer needed thanks to the much simplified ContextPlugin and InstancePlugin classes.

If you have need for them, now is the time to speak up.




FAQ

With the change from pyblish to pyblish-base, you may be wondering…

Will the import path change?

No, you will still import like this:

import pyblish.api

The name pyblish-base is only visible and relevant on GitHub.

Can I still install via pip?

Yes, installation remains unchanged.

$ pip install pyblish

#2

#3

Thank you @marcus
nice features

i’m implementing 1.3.1 for our Studio and start writing plugins with new syntax.
i will share problems i have
good luck!


#4

Just wanted to drop in that this release feels silky smooth. The GUI feels nice and fast. Great updates!


#5

Thanks guys, good to hear!

I’ve just pushed an update, 1.3.2, with a bugfix (#243), see conversation here and issue here.

pyblish-win is currently baking also and should be ready within a few mins.


#6

I tried updating by running update.bat. No errors occurred and it stated some file removal and changes yet it doesn’t seem to be updated. The GUI and pyblish-base module state the version number of 1.3.1. Is that expected?

Maybe you didn’t bump the version? Or is update.bat not expected to work like that?

EDIT: Nevermind, seems to be just that pyblish-win isn’t updated on github.
EDIT2: Well, actually… i’m not getting it updated in such a way that the GUI shows 1.3.2 Haha, probably doing something wrong?


#7

Hm, odd. I must have missed pushing the update to pyblish-win. :S

I’ll have a look at this tonight; the only updated repository is pyblish-qml, as a workaround until then you can pull from this manually.


#8

Any tips on that update? Is it just matter of running the update.bat? Asking because it didn’t work for me yesterday. :wink:


#9

I’ve updated pyblish-win now, turns out I had missed pushing, sorry about that!

About updating, I’ve got an idea for how to simplify this and will have a look at this next; for now, the safest thing to do, is remove pyblish-win completely, and re-clone and run install.bat again.

The next time, update.bat will behave more predictably.


#10

Hey @marcus for updating
but it is better to update it with less files taransfer, not remove and clone again.

because it is frustrating, for time i mean, especially for me that internet speed is slow.
btw, i hope we can have a good updating system in next releases.


#11

and another question is that is it possible to leave new feature (ContextPlugin and IntancePlugin) and back to old features?
i mean maintaining backward compatibility and back to it in version 2 again?
make sense?


#12

Yes, you are right @Mahmoodreza_Aarabi, for someone with low bandwidth, that PyQt download can get rather intense.

The old features will remain supported until Pyblish 2.0, you can use whichever suits you best, so long as you are prepared for their complete removal once we hit 2.0.


#13

I will use the new syntax, because i want to use it from now, long time


#14

EDIT: Nevermind this error.

Just tried updating again and seem to be getting this:

# Traceback (most recent call last):
#   File "P:\pipeline\dev\git\pyblish-win\lib\pyblish\modules\pyblish-rpc\pyblish_rpc\service.py", line 119, in _dispatch
#     return func(*params)
#   File "P:\pipeline\dev\git\pyblish-win\lib\pyblish\modules\pyblish-rpc\pyblish_rpc\service.py", line 97, in process
#     action=action)
#   File "P:\pipeline\dev\git\pyblish-win\lib\pyblish\modules\pyblish-base\pyblish\plugin.py", line 414, in process
#     return __explicit_process(plugin, context, instance, action)
#   File "P:\pipeline\dev\git\pyblish-win\lib\pyblish\modules\pyblish-base\pyblish\plugin.py", line 430, in __explicit_process
#     "Cannot process an InstancePlugin without an instance. This is a bug")
# AssertionError: Cannot process an InstancePlugin without an instance. This is a bug

Will try to re-install and investigate some more.

Actually. Nevermind.

This particular error seems to have come from having a InstancePlugin collector that tried to process the context.


Is the GUI still supposed to show 1.3.1?


#15

The GUI is currently showing you the version of pyblish-base. It should be updated to show you the version of pyblish. It’s on my list of todo’s.


[solved] InstancePlugin not running as Collector?
ContextPlugin running when instance of family not present
#16

Maybe this will help others:

For now this file pyblish-win\lib\pyblish\VERSION should hold the correct version number that could be used to identify whether you are on 1.3.2 as opposed to 1.3.1.


#17