RSSBus Feed Server uses RSBScript to map content from a connector to a URL. For example, FileOps is a connector that provides operations to get data from a file system, but to transfer this content over HTTP we write a simple script fileList.rsb as shown below.
<rsb:set attr="mask" value="*.rst"/>
<rsb:call op="fileListDir">
<rsb:push/>
</rsb:call>
This allows us to access the content produced from fileListDir in the browser at the URL
http://server/virtual_dir/fileList.rsb. RSBScript not only glues the HTTP request to the underlying connector, but also allows us to manipulate the items produced by the connector. By making small changes to the script above, we can add/remove attributes (rsb:set/rsb:unset keywords), chain items from one operation to another (rsb:pipe keyword), or in general program with feeds produced from the connectors. Today I will demonstrate how we can do similar things using Python.
Although RSSBus Feed Server uses RSBScript by default, it can be extended with language connectors that allow us to work in the language of our choice. PythonOps is one such connector that allows us to write python code to manipulate items and feeds.
The following script written in Python replicates the behavior of the script above.
<rsb:script language="python">
input = {“mask”:”*.rst”}
rsb.call(“fileListDir”,input)
</rsb:script>
The script above first establishes the language using the language parameter of the rsb:script keyword. This is followed by two lines of python, one to create a python dictionary object with the input parameters, and another to call the operation. To communicate with the RSSBus Engine, the python language connector introduces the "rsb" object in the script namespace. Let us look at the methods available in the "rsb" object before we dissect the script.
|
Method |
Description |
|
string get(name) |
The get method gets an input attribute. It can be used to get the attributes specified from the URL line. |
|
set(name, value) |
The set method sets an attribute in the output item. |
|
push([title, description]) |
The push method pushes the current output item to the response. Normally one pushes several items from the script to create a feed. |
|
dict getinput() |
The getinput method returns a python dictionary containing all the input attributes. |
|
list call(operation[,input[,push| PythonFunction]]) |
The call method calls an installed operation and returns a list of dictionaries. The list is the entire feed, each dictionary in the list is an item, and keys in the dictionary are attributes in the item.
The optional parameter input is a dictionary that can be used to specify input parameters. If it is not specified, or if it is None, then the input parameters to the python script are transferred to the called operation.
The optional parameter push is a boolean used to specify if the items produced by the called operation are also simultaneously pushed to the response. It is True by default.
You can also invoke call with the name of a function as the third parameter. This will act as a callback and the function will be called for each item returned from the call. The python function is defined as:
def myOnitem(item): #Note you have to explicitly #push the item from the callback rsb.push()
The item argument to the function is a python dictionary that contains the attributes of the item.
Examples of call:
rsb.call("fileListDir") rsb.call("fileListDir",myinput) rsb.call("fileListDir","myinput,False) rsb.call("fileListDir",myinput,True) rsb.call("fileListDir",null,myOnItem) rsb.call("fileListDir",myinput,myOnItem)
|
From the description above we can see that this python script simply, sets input parameters in a python dictionary, calls an operation, and allows the called operation to push the items to the response. As a next step we will use the methods described above to pipe the results from one operation to another operation. Here is a simple example that calls fileListDir and sends an email (using smtpSendMessage) for each item returned by it.
<!-- Send an email for each file in the directory. -->
<rsb:info desc="Sends an email for each file found in the current directory.">
<input name="from" desc="From address" default="demo@rssbus.com"/>
<input name="mask" desc="File mask" default="*.*"/>
</rsb:info>
<rsb:script language="python">
input = {"mask":rsb.get("mask")}
mail_from = rsb.get("from")
mail_server = "MY_MAIL_SERVER"
mail_to = "MY_EMAIL_ID"
fileListFeed = rsb.call("fileListDir", input, False)
email_body = '''
The file %(file:name)s was accessed on %(file:atime)s.
<p>
Other Details<hr>
Size : %(file:size)s<br>
Creation Time : %(file:ctime)s<br>
'''
for item in fileListFeed:
item["to"] = mail_to
item["from"] = mail_from
item["server"] = mail_server
item["subject"] = item["file:name"]
item["html"] = (email_body)%(item)
rsb.call("smtpSendMessage",item,True)
</rsb:script>
Some points to note in the example above:
- Use of comments: Python comments can be used in the python script section but you can still use XML like comments outside the script section.
- Use of rsb:info: Info provides the metadata to a script and enforces certain rules such as default values, required values, etc.
Using PythonOps you can mix and match results from any of the RSSBus connectors with anything available with the Python library. You can easily create data Feeds that act as simple web services.
Downloads:
RSBScript |
PythonOps