how to programmatically control zope?
hello, would someone please point me to the right direction? what is the preferred way to control a zope server programmatically? i need to be able to administer my zope instance from a script. add users, change permissions, create new sites, add objects to the sites. there is webdav, xml-rpc, what else? which one is the right way to do it? i am a newbie i hope this is not a frequent question, at least i did not find an answer in the documentation... thanks konstantin
akonsu wrote:
hello, would someone please point me to the right direction? what is the preferred way to control a zope server programmatically? i need to be able to administer my zope instance from a script. add users, change permissions, create new sites, add objects to the sites. there is webdav, xml-rpc, what else?
Interactively control/inspect/play with the server: <ZOPE_INSTANCE>/bin/zopectl debug Run a script on the server: <ZOPE_INSTANCE>/bin/zopectl run <myscript.py> [args...] There are a few tricks however: 1/ You can't run zopectl debug or zopectl run while you instance is running (as it locks the ZODB). The solution here is to set up a zeo instance (this is really easy), and have 2 zope instances, one serving the web requests, the other being used for debug/run 2/ changes made from the debug interactive shell or a script needs to be explicitely commited. The idiom is: # ... your code here get_transaction.commit() app._p_jar.sync() # app is the root zope object 3/ When accessing your zope server this way, you have the default Anonymous role. If you need Admin privileges (which may well be the case !-), you have to 'log in' by code. Here's a snippet I stoled from I-Can't-Remember-Where-But-Thanks-Anyway(tm) : from AccessControl.SecurityManagement import newSecurityManager def login(app, username): acl = app.acl_users user = acl.getUserById(username) assert user is not None user = user.__of__(acl) newSecurityManager(None, user) login(app, "myadminlogin") 4/ Some Products or methods may need a REQUEST object, which is not provided by default. Here's a way to simulate one: from os import environ from sys import stdin, stdout from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.BaseRequest import RequestContainer from ZPublisher import Publish from thread import get_ident def makerequest(app, stdout=stdout): # copy/hacked from Testing.makerequest resp = HTTPResponse(stdout=stdout) environ['SERVER_NAME']='foo' environ['SERVER_PORT']='80' environ['REQUEST_METHOD'] = 'GET' req = HTTPRequest(stdin, environ, resp) # first put the needed values in the request req['HTTP_ACCEPT_CHARSET'] = 'latin-15' req['HTTP_ACCEPT_LANGUAGE'] = 'fr' # etc, just fill what you need in the request # then store the request in Publish._requests # with the thread id id = get_ident() Publish._requests[id] = req # ok, let's wrap and return return app.__of__(RequestContainer(REQUEST = req)) app = makerequest(app) Most - if not everything - of what you do via the ZMI can be done by code. Reading the ZMI and the base Products source code may be a good way to learn the API.
which one is the right way to do it?
Depends on your needs.
i am a newbie i hope this is not a frequent question, at least i did not find an answer in the documentation...
This is usually not what newbies starts with !-) And I'm afraid that Zope's documentation is not always that helpful to newbies - not that it's that bad, but documentation, being freely contributed, is not always the strongest point of OSS projects, and Zope is quite a complex application anyway, so it's not easy to document. There again, it's mostly "Use The Code, Luke". HTH -- Bruno Desthuilliers Développeur bruno@modulix.org
akonsu wrote:
hello, would someone please point me to the right direction? what is the preferred way to control a zope server programmatically? i need to be able to administer my zope instance from a script. add users, change permissions, create new sites, add objects to the sites. there is webdav, xml-rpc, what else?
Here's an overview of web-based techniques that might be useful... http://www.plope.com/Books/2_7Edition/ScriptingZope.stx#1-9 but I prefer doing as Bruno does:
Interactively control/inspect/play with the server: <ZOPE_INSTANCE>/bin/zopectl debug
Run a script on the server: <ZOPE_INSTANCE>/bin/zopectl run <myscript.py> [args...]
yep, I like working that way, and Bruno's introduction is excellent. One clarification however:
1/ You can't run zopectl debug or zopectl run while you instance is running (as it locks the ZODB). The solution here is to set up a zeo instance (this is really easy), and have 2 zope instances, one serving the web requests, the other being used for debug/run
That's a bit misleading. With ZEO, you don't need two full instances (by which i mean directories containing their own etc, bin, var, and log subdirectories). You can run the Zeo server AND one Zope server out of a single instance home at the same time; and since your zopectl scripts won't normally involve starting up on a tcp/ip port, you can run those from the same instance too. I do it all the time. Example (for any unix-like environment): cd MyInstanceHome ../bin/zeoctl start # ZEO is now running in the background. ../bin/zopectl start # Zope is now running in the background, connected to ZEO. ../bin/zopectl run myscript.py & # I'm now running a script via zopectl in the background. # This can run at the same time as Zope, because it runs as # a separate process and talks to Zeo, which accepts many clients # at once. ../bin/zopectl debug # I am now interacting with ZEO via a python shell. # Again, this is a separate process connecting to Zeo so I can do this # as many times as I want simultaneously. It's only when you want to run multiple Zope server processes on multiple ports simultaneously that you actually need to set up multiple instance homes. -PW
Paul Winkler wrote: (snip)
yep, I like working that way, and Bruno's introduction is excellent.
<blush>Thanks</blush>
One clarification however:
1/ You can't run zopectl debug or zopectl run while you instance is running (as it locks the ZODB). The solution here is to set up a zeo instance (this is really easy), and have 2 zope instances, one serving the web requests, the other being used for debug/run
That's a bit misleading. With ZEO, you don't need two full instances (by which i mean directories containing their own etc, bin, var, and log subdirectories). You can run the Zeo server AND one Zope server out of a single instance home at the same time; and since your zopectl scripts won't normally involve starting up on a tcp/ip port, you can run those from the same instance too. I do it all the time.
Woops ! Seems obvious when explained, but I missed that point. Doh :( Thanks Paul, this will simplify my sandbox setup scripts !-) -- Bruno Desthuilliers Développeur bruno@modulix.org
Hi. This discussion has really helped me with my question about running asynchronous methods also since these kinds of requests could be cronned at the very least. But what about triggering this kind of script from the running zope instance. Is this possible? What I am hoping to accomplish is when a user uploads a file it triggers the long-running script - the one I want to inject into ZEO (and gives the user immediate feedback) so they are not waiting for the process to complete. At the end of the long running process, I want to send them an email advising that the process was successful. I am just setting up ZEO for first time today. I am anxious to give something like this a try. Many thanks. Regards, David On Friday, September 16, 2005, at 12:28 PM, Paul Winkler wrote:
cd MyInstanceHome ../bin/zeoctl start # ZEO is now running in the background. ../bin/zopectl start # Zope is now running in the background, connected to ZEO. ../bin/zopectl run myscript.py & # I'm now running a script via zopectl in the background. # This can run at the same time as Zope, because it runs as # a separate process and talks to Zeo, which accepts many clients # at once.
David Pratt wrote:
Hi. This discussion has really helped me with my question about running asynchronous methods also since these kinds of requests could be cronned at the very least. But what about triggering this kind of script from the running zope instance. Is this possible?
Two solutions a priori: - call an external method that launch a thread that do the job - fork and launch the script as a new process with os.execXXX You'll find documentations about threads and os.execXX in the Python's manual. Now there can be Zope-specific gotchas, but there I can't help you. -- Bruno Desthuilliers Développeur bruno@modulix.org
Hi Bruno. Many thanks you for your reply. Yes, I have been looking at this more. With the help of Ron a few days back I am going to try a signaling process working with a daemon that uses a queue. So I am hoping for user to get response so zope thread is freed up, an asynchronous python method / daemon gets signal to run if not already running, job gets added to queue and jobs run queue is empty (then daemon goes to sleep). Regards, David On Wednesday, September 21, 2005, at 10:13 AM, bruno modulix wrote:
David Pratt wrote:
Hi. This discussion has really helped me with my question about running asynchronous methods also since these kinds of requests could be cronned at the very least. But what about triggering this kind of script from the running zope instance. Is this possible?
Two solutions a priori: - call an external method that launch a thread that do the job - fork and launch the script as a new process with os.execXXX
You'll find documentations about threads and os.execXX in the Python's manual. Now there can be Zope-specific gotchas, but there I can't help you.
-- Bruno Desthuilliers Développeur bruno@modulix.org _______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
participants (4)
-
akonsu -
bruno modulix -
David Pratt -
Paul Winkler