[PEAK] ZConfig question

Roché Compaan roche at upfrontsystems.co.za
Tue Jul 27 14:41:13 EDT 2004

* Phillip J. Eby <pje at telecommunity.com> [2004-07-27 18:22]:
> At 01:50 PM 7/27/04 +0200, Roché Compaan wrote:
> >How do I do I the following in a peak ini file:
> >
> >SCHEMA = "/home/roche/work/jack/schema.xml"
> >config_file_name = "/home/roche/work/jack/jack.conf"
> >
> >schema = ZConfig.loadSchema(SCHEMA)
> >cfg, nil = ZConfig.loadConfig(schema, config_file_name)
> >
> >In other words, how do I load the schema file, parse the config file 
> >and  assign the output to a configuration root?
> The recommended approach:
>     #!peak runIni
>     [peak.naming.factories]
>     myapp.schema = naming.Reference(
>         'zconfig.schema', ['file:///home/roche/work/jack/schema.xml'])
>     [peak.running]
>     app = naming.Reference('myapp.schema', 
> ['file:///home/roche/work/jack.conf'])

First time I see 'naming.Reference' in action.

> Then, './myapp.ini' will attempt to invoke the root object of the ZConfig 
> file.
> 'naming.Reference' takes a factory name and a list of addresses.  The 
> factory name refers to either an entry in 'peak.naming.factories', or if it 
> doesn't exist there, an object/class to be imported.  'zconfig.schema' is a 
> predefined factory that loads ZConfig schemas, which are then usable as 
> factories themselves.
> So what the above does is to first say, "when you have a Reference with a 
> factory of 'myapp.schema', use this ZConfig schema to load it."  And then 
> it says, "when somebody runs this .ini file, use this reference to a file 
> with a particular schema as the application object."
> If you didn't want the config file root to become the application itself, 
> you can of course use the 'naming.Reference' any place you would put the 
> actual object in your .ini file.  For example, if you wanted the ZConfig 
> object to be a named service (accessible via property name, but only one 
> copy created/loaded per service area):
>     [Named Services]
>     myapp.config = naming.Reference('myapp.schema', 
> ['file:///home/roche/work/jack.conf'])
> You can also use [Named Services] to define the factory, so that the schema 
> will only be loaded once:

I don't understand why it will only get loaded once? How is it different
than to putting the factory in the peak.naming.factories section?

>     [Named Services]
>     peak.naming.factories.myapp.schema = naming.Reference(
>         'zconfig.schema', ['file:///home/roche/work/jack/schema.xml'])
> Finally, it should also be noted that instead of 'naming.Reference()', you 
> can use 'ref:' URLs, as in:
>     [Named Services]
>     peak.naming.factories.myapp.schema = naming.LinkRef(
>         'ref:zconfig.schema at file:///home/roche/work/jack/schema.xml')
>     myapp.config = 
> naming.LinkRef('ref:myapp.schema at file:///home/roche/work/jack.conf')

I noticed 'LinkRef' in peak.ini, but my URL omitted 'ref:'. I copied
what is done with the 'EventDriven' shortcut. To be clear, how is
"naming.LinkRef('ref:myapp.schema at ....')" different to
"naming.LinkRef('myapp.schema at ...')"?

> As you can see, though, this gains you little in this context, since you 
> still need to create a LinkRef so the URL can be looked up.

But it is aesthetically pleasing to see everything as an URL ;-)

> But the URL 
> syntax is handy for doing things like 
> 'self.lookupComponent("ref:myapp.schema at somewhere")' or 
> 'binding.Obtain("ref:myapp.schema at somewhere")'.
> Incidentally, whether you use 'naming.Reference()' or the 'ref:' URL 
> scheme, you can use other URL schemes besides 'file:' as addresses.  For 
> example, you can use 'pkgfile', which lets you refer to a file contained 
> inside a Python package directory, and you can even use http or ftp should 
> you have the need.

Yes, I replaced the absolute filename with "pkgfile:jack/schema.xml":

     peak.naming.factories.myapp.schema = naming.LinkRef(
         'ref:zconfig.schema at pkgfile:jack/schema.xml')

> In fact, you can use any peak.naming address that 
> resolves to an object that can be adapted to 'naming.IStreamFactory', and 
> it will be usable for loading ZConfig schemas and ZConfig configuration 
> files.
> Last, but not least, in case you want to create your own kinds of factories 
> that can do this sort of thing, the interface you need to implement is 
> 'naming.IObjectFactory'.  One example of how to do this is found in the 
> peak.config.load_zconfig module, but there are others elsewhere.

Thanks, I'll remember that.

Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za

More information about the PEAK mailing list