This page describes the TCL interface to BioCoRE. For general
information about programming with BioCoRE, please go to our
Programming With BioCoRE page.
Files. These are the latest released versions of the API:
The actual API
Testing File. Most of the
examples below are from this file
Package file allows TCL to easily find the
file it needs
Helper procedures that don't directly
talk to the BioCoRE server, but use the BioCoRE api calls. These include
things like Tk window frontends to some of the API calls.
TCL Version of the Control Panel Alpha version
of a Control Panel written in TCL. This isn't very robust at this
point, and it requires you to have valid session information in
your .biocoreSession file (normally you populate this file by logging
in via the Java Control Panel) But, the concepts are covered and can
be used to implement more robust solutions.
Quick Jump. I want to:
The API is provided as a BioCoRE package and is available for
download. The package requires http
, and if you have
tls
it will use https for communication. We recommend the
installation of the tls
package.
First, the user of your program must register with a BioCoRE server.
This is done via the standard BioCoRE web interface, or, a guest account
can be created with the API.
Connecting to BioCoRE
There are multiple ways to get your TCL code talking to the BioCoRE
server as a BioCoRE user.
- If the user logs in via the Web Start version of the Control Panel,
it is pretty easy. You can just call the initDefault procedure.
Check out the biolog code
example.
package require biocore 1.15
puts "Testing biocore_initDefault"
set anyErrors [::biocore::initDefault ]
if { [string length $anyErrors] > 0} {
puts stderr $anyErrors
} else {
# user values have been set. It would be wise to call
# verify here to make sure.
}
|
- There is a login TCL procedure. For versions of the API before
1.17 you MUST have TLS installed to use the procedure. (The server
won't allow nonsecure connections for
login, so you MUST have TLS to allow the secure connections) Starting
with API version 1.17, encryption is used to send the password to the
server, so it can be safely used to log into the BioCoRE server.
The login procedure returns the user ID of the user, although that
isn't being used for anything right now.
If the user has not logged in, the following code will get the user
logged in. Note, if you have the biocoreHush variable set, and do NOT
have TLS, this procedure call will fail with an error of Invalid User.
The login method requires version 1.15 of the biocore package.
package require biocore 1.15
::biocore::UserInfo ui
puts "Testing biocore_login"
# get the user name
puts "User Name?"
gets stdin strUserName
# get the password
puts "Password (will show plaintext in terminal window)?"
gets stdin strPassword
if [catch {eval ::biocore::ui configure [::biocore::login $strUserName \
$strPassword ]} errmsg] {
# if we make it in here, we had an error thrown
puts "Error: $errmsg"
} else {
# we got a response. We need to print it out
puts "Login successful."
puts "Session: '$::biocore::Session'"
puts "User Id: '[::biocore::ui cget Id]'"
}
|
The login procedure will cause a session file to be written to the
user's home directory. Specifically, a directory called .biocore
is written in the user's home directory, and a file called
.biocoreSession
is written to that directory that contains
information about the user's current session. On Unix and derivatives,
the home directory concept should be easy to understand. On Windows,
TCL seems to typically use the user's Documents & Settings folder
or something similar. You might have to look around to discover the
exact location.
- If the user logs in via the web without the Web Start version of the
Control Panel... By clicking on the Utilities link in the bottom left
hand corner of the screen they will be presented with the Utilities
menu.
An option near the end of that menu is
API Connection Information
. Clicking on this will present
a table that looks something like:
URL: https://biocore-s.ks.uiuc.edu/biocore/
Session ID: 3EFC480542F5781751C1453EB999AE98
Project list. Choose the ID associated with the project that
you are working on:
All User Test Project 1
Project X 2
Project Y 27
Project Z 93
The URL, Session ID, and project ID are all values that you will need.
For the purposes of the following code, we will assume that the TCL
variable strUrl
has been set to the URL value given above,
the TCL variable strSession
has been set to the session id
given above (except for documentation about the login procedure), and
the TCL variable strProject
has been set to the number
corresponding to the user's desired project given above.
In the program you are writing you might be able to save some of
the above values for the user IF they only ever login to one BioCoRE
server. If they use multiple BioCoRE servers they will need to enter
this information everytime. The URL and the project IDs are unlikely
to change. The session id, however, will change each time they log
in.
The following code will initialize the BioCoRE API with the information
that it needs to connect to the BioCoRE server assuming the user has
already logged in.
package require biocore 1.15
# set the URL
set ::biocore::URL $strUrl
# Are you behind a proxy? If so, uncomment the following line
# ::biocore::setProxy $strProxyHost $iProxyPort
# set the Session
set ::biocore::Session $strSession
# set the Project
set ::biocore::Project $strProject
|
When the biocore TCL package is accessed for the first time it will
print out a line to STDOUT giving the version number and the URL for
BioCoRE. Additionally, if the user doesn't have TLS in their version
of TCL it will print a warning line stating this.
We have provided to way to turn this printing off, but we suggest leaving
the printing enabled. If you wish to turn it off, give the variable
biocoreHush
a value before using the package and it won't
print these two lines to STDOUT.
Determining if a user has a valid BioCoRE Session
If you want to determine whether or not the BioCoRE server thinks that
a user has a valid session id and project id, you can do:
package require biocore 1.15
puts "Testing biocore_verify"
if [catch {set i [::biocore::verify ]} errmsg] {
# if we make it in here, we had an error thrown
puts "Error: $errmsg"
} else {
# we got a response. We need to print it out
puts "User is valid $i"
}
|
Reset A User's BioCoRE Password
A user's password can be reset to a random password. This is used
in cases where a user has forgotten their password.
package require biocore 1.20
puts "Testing biocore_resetPassword"
# get the user name
puts "User Name?"
gets stdin strUserName
if {[catch {::biocore::resetPassword $strUserName } errmsg]} {
# if we make it in here, we had an error thrown
global errorInfo errorCode
puts "Error in resetPassword: <$errmsg> <$errorInfo> <$errorCode>"
} else {
# everything worked
puts "Password Reset Successful. Check Your Email."
}
|
Change A User's BioCoRE Password
A user's password can be changed to a new password. This is used when
a user knows their password, but wants to change it to something new.
As you can see from the sample code below, the changePassword procedure
takes an old and a new password. It is suggested that the programmer
verify that the new password is correct (typically by having the user
enter it twice).
package require biocore 1.20
puts "Testing biocore_changePassword"
# get the old password
puts "Old Password? (will show plaintext in terminal window)"
gets stdin strOld
puts "New Password?"
gets stdin strNew1
puts "New Password (confirm)?"
gets stdin strNew2
if { [string compare $strNew1 $strNew2] == 0 } {
if {[catch {::biocore::changePassword $strOld $strNew1 } errmsg]} {
# if we make it in here, we had an error thrown
global errorInfo errorCode
puts "Error in changePassword: <$errmsg> <$errorInfo> <$errorCode>"
} else {
# Looks like things went ok
puts "Password Changed successful."
}
} else {
puts "Two new passwords don't match."
}
|
Getting a list of BioCoRE projects in which a user is enrolled
You can retrieve a list of project names along with their associated
BioCoRE project ids.
package require biocore 1.15
puts "Testing biocore_getProjectList"
# get the list
if [catch { set projectList [::biocore::getProjectList] } errmsg] {
# if we make it in here, we had an error thrown
puts "Error: $errmsg"
} else {
# we got a response. We need to print it out
puts " Id Project"
puts "---- -------"
foreach { name id } $projectList {
puts "[format %3i $id] $name"
}
}
|
Get a list of projects that a user is eligible to join
getEligibleProjects will return a list of projects that a user is eligible
to join. These can then be displayed in lists/windows/etc. Presumably,
this would be followed by a call to joinProject.
package require biocore 1.16
puts "Testing biocore_getEligibleProjects"
# get the list
if {[catch { set projectList [::biocore::getEligibleProjects] } errmsg]} {
# if we make it in here, we had an error thrown
global errorInfo errorCode
puts "getEligibleProjects Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
# we got a response. We need to print it out
puts $projectList
puts "Time id [format %18s title] [format %40s description] isPublic userInvited creatorid altproject publicareas defaulttab"
puts "---- -------"
foreach { ti p t d i in ci ap pa dt } $projectList {
puts "$ti [format %3i $p] [format %18s $t] [format %40s $d] $i $in $ci
$ap $pa $dt"
}
}
|
Join a project that a user is eligible to join
Given a project id, add this user to the project. The project must either
be a public project, or the user must have been invited to the project.
package require biocore 1.16
puts "Project id to join?"
gets stdin iId
if {[catch {::biocore::joinProject $iId } errmsg]} {
# if we make it in here, we had an error thrown
global errorInfo errorCode
puts "joinProject Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts "Joined project $iId"
} ; # end the else on not having an error in the API request
|
Getting a list of BioCoRE Notebook entries
Using the API you can retrieve an index of entries that have been
posted to the BioCoRE notebook.
The following code will demonstrate how to do this. BioCoRE Notebook
entries are stored according to "type". The regular user message
list (what you normally see when you choose the Message Board in
BioCoRE) is type 0. The list of saved VMD states is type 2. The list
of BioLog messages is 4. So, if
you wish to retrieve the list of regular user message board messages,
iType
would be 0.
The code also prints out each entry.
package require biocore 1.15
::biocore::NotebookEntryInfo nei
puts "Testing biocore_getNotebookEntryList"
puts "Message type (0 for normal notebook msg; 4 for biolog messages)?"
gets stdin iType
if [catch {set neiList [::biocore::getNotebookEntryList $iType 0 \
0 ]} errmsg] {
# if we make it in here, we had an error thrown
puts "Error: $errmsg"
} else {
# we got a response. We need to print it out
set iNumEntries [llength $neiList]
puts "Number of Notebook Entries: '$iNumEntries'"
# now we loop over the entries
for {set iCount 0} {$iCount < $iNumEntries} {incr iCount} {
eval ::biocore::nei configure [lindex $neiList $iCount]
if { [::biocore::nei cget Id] == -1 } {
puts "This entry has been deleted"
} else {
puts "Id: [::biocore::nei cget Id], Time: '[::biocore::nei cget Time]', "
puts "User: '[::biocore::nei cget User]', Title: '[::biocore::nei cget Title]', "
puts "Desc: '[::biocore::nei cget Description]'"
}
}
}
|
Getting a single Notebook entry
The above procedure will return a list of IDs of individual messages.
The id of a desired message can be used to retrieve the message itself.
package require biocore 1.15
::biocore::NotebookEntry ne
puts "Message id?"
gets stdin iMsgId
if [catch {eval ::biocore::ne configure [::biocore::getNotebookEntry \
$iMsgId ]} errmsg] {
# if we make it in here, we had an error thrown
puts "Error: $errmsg"
} else {
# we got a response. We need to print it out
::biocore::ne print
}
|
Saving a BioCoRE Notebook entry
You can save a new entry to the Notebook also. If you want, you can
upload an image or something else along with the notebook message. If
you have an image called plot.jpg you can reference this file in
your notebook entry text by saying:
<IMG SRC="<<<notebookAttach plot.jpg>>>">
package require biocore 1.22
::biocore::NotebookEntry ne
puts "title?"
gets stdin strTitle
::biocore::ne configure Title $strTitle
# NOTE: Description isn't yet supported on the server side. This
# requires us to change a database table to add a new column, etc
# and this hasn't been done yet
puts "description?"
gets stdin strDesc
::biocore::ne configure Description $strDesc
puts "Message type (0 for normal notebook msg; 4 for BioLog msg)?"
gets stdin iType
::biocore::ne configure Type $iType
puts "Are you going to upload a file with this entry? (1 for yes, 0 for no)"
gets stdin iUpload
if { $iUpload == 1} {
puts "Local filename that you are going to upload"
gets stdin strLocalName
::biocore::ne configure FileUploadName $strLocalName
set ind [string last "/" $strLocalName]
incr ind
set XXXX [string range $strLocalName $ind end]
puts "Put <<<notebookAttach $XXXX>>> anywhere you want the file URL to be"
}
puts "Number of lines in body (purely for ease of testing)?"
gets stdin iNum
set count 0
set strMsg ""
puts "Enter the message"
for {set iCount 0} {$iCount < $iNum} {incr iCount} {
gets stdin strLine
append strMsg "$strLine\n"
}
::biocore::ne configure Text $strMsg
# print out the message to be sent, just for verification
puts "\n---\nTitle: '[::biocore::ne cget Title]'"
puts "Description: '[::biocore::ne cget Description]'"
puts "Type: '[::biocore::ne cget Type]'"
puts "FileUpload: '[::biocore::ne cget FileUploadName]'"
puts "Text: '[::biocore::ne cget Text]'"
if {[catch {set iRetVal [::biocore::saveNotebookEntry ::biocore::ne ]} \
errmsg]} {
global errorInfo errorCode
puts "saveNotebookEntry Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts "iRetVal was $iRetVal"
}
|
Deleting a BioCoRE Notebook entry
You can delete a BioCoRE Notebook entry, given its ID. The server
will not allow this if the user doesn't have permission to do so.
package require biocore 1.15
puts "Testing biocore_deleteNotebookEntry"
puts "Notebook entry id to delete?"
gets stdin iId
if [catch [::biocore::deleteNotebookEntry $iId ] errmsg] {
# if we make it in here, we had an error thrown
puts "deleteNotebookEntry Error: $errmsg"
} else {
puts "Notebook entry deleted"
} ; # end the else on not having an error in the API request
|
Getting the content of a BioCoRE BioFS directory
You can get information about a directory in the BioFS. Directories
are identified by an id number. Directory ID 0 is the top level
directory for a user. It has, as children, all of the directories that
a user can access. Directory ID -1 is the user's special private
directory that no one else can access.
package require biocore 1.15
::biocore::BiofsDirectory biofsDir
puts "Directory id to retrieve?"
gets stdin iId
if [catch {eval ::biocore::biofsDir configure \
[::biocore::getBiofsDirectory $iId 0]} errmsg] {
# if we make it in here, we had an error thrown
puts "getBiofsDirectory Error: $errmsg"
} else {
# we got a response. We need to print it out
puts "Directory name: '[::biocore::biofsDir cget Name]'"
set deList [::biocore::biofsDir cget Entries]
set iNumEntries [llength $deList]
puts "Number of Dir Entries: '$iNumEntries'"
# now we loop over the entries
for {set iCount 0} {$iCount < $iNumEntries} {incr iCount} {
::biocore::BiofsDirectoryEntry bioDE
eval ::biocore::bioDE configure [lindex $deList $iCount]
# do we have a directory, or a file?
if { [::biocore::bioDE cget Type] == 0 } {
::biocore::bioDE printDir
} else {
::biocore::bioDE printFile
} ; # end the else
} ; # end the for loop over the directory entries
} ; # end the else on not having an error in the API request
|
Getting a particular BioCoRE BioFS file
Once you have the ID for a BioFS file that you want, you can use the
API to save the file to a filename on your local filesystem.
package require biocore 1.15
puts "Testing biocore_getBiofsFile"
puts "File id to retrieve"
gets stdin iId
puts "Local filename to save to"
gets stdin strLocalName
if [catch [::biocore::getBiofsFile $iId $strLocalName] errmsg] {
# if we make it in here, we had an error thrown
puts "getBiofsFile Error: $errmsg"
} else {
puts "File downloaded to $strLocalName"
} ; # end the else on not having an error in the API request
|
Uploading a file to the BioCoRE BioFS
Once you have the directory ID for the BioFS directory where you want
to upload a file,you can use the putBiofsFile
procedure in
the API to upload a file on your local filesystem to the BioFS. This
procedure requires http package 2.2+ to be successful.
package require biocore 1.15
puts "Testing biocore_putBiofsFile"
puts "Directory id to place file in?"
gets stdin iDirId
puts "Local filename to send?"
gets stdin strLocalName
puts "Name file will be given in BioFS?"
gets stdin strRemoteName
if [catch [::biocore::putBiofsFile $iDirId $strLocalName \
$strRemoteName] errmsg] {
# if we make it in here, we had an error thrown
puts "putBiofsFile Error: $errmsg"
} else {
puts "File $strLocalName uploaded to $strRemoteName"
} ; # end the else on not having an error in the API request
|
Deleting a file from the BioCoRE BioFS
Files can be deleted from the BioFS.
package require biocore 1.15
puts "Testing biocore_delBiofsFile"
puts "File id to delete?"
gets stdin iId
if [catch [::biocore::delBiofsFile $iId ] errmsg] {
# if we make it in here, we had an error thrown
puts "delBiofsFile Error: $errmsg"
} else {
puts "File deleted"
} ; # end the else on not having an error in the API request
|
Deleting a directory from the BioCoRE BioFS
Directories can be deleted from the BioFS. They must be empty to
be deleted. So, if you need to, you will need to use other API
methods to retrieve current contents and delete contents before
the entire directory can be removed.
package require biocore 1.15
puts "Testing biocore_delBiofsDirectory"
puts "Directory id to delete? (must already be empty)"
gets stdin iId
if [catch [::biocore::delBiofsDirectory $iId ] errmsg] {
# if we make it in here, we had an error thrown
puts "delBiofsDirectory Error: $errmsg"
} else {
puts "Directory deleted"
} ; # end the else on not having an error in the API request
|
Creating a new directory in the BioCoRE BioFS
To create a new directory in the BioFS you need to know the ID of
the directory in which you wish to place the new directory.
package require biocore 1.15
puts "Testing biocore_createBiofsDirectory"
puts "Directory id where the new directory should go?"
gets stdin iId
puts "New Directory Name?"
gets stdin strNewName
if [catch [::biocore::createBiofsDirectory $iId $strNewName] errmsg] {
# if we make it in here, we had an error thrown
puts "createBiofsDirectory Error: $errmsg"
} else {
puts "New directory created"
} ; # end the else on not having an error in the API request
|
Getting the list of jobs that the BioCoRE server can run
BioCoRE job types are identified by a short name. Each job type may use
the job parameters in particular ways, or ignore some values. This call
returns a list of job type names. These are currently NAMD
and Generic
package require biocore 1.15
puts "Testing biocore_getJobTypes"
if [catch {set jobTypeList [::biocore::getJobTypes ]} errmsg] {
# if we make it in here, we had an error thrown
# This shouldn't ever happen
global errorInfo
global errorCode
puts "getJobTypes Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts "-------------"
set i 0
foreach { name } $jobTypeList {
set i [ expr $i + 1 ]
puts "$i:$name"
}
puts "-------------"
}
Get the accounts the user has defined which can run this type of job
This method will return a list of two-item lists. Each item contains the
account id and user-defined name for one of the user's accounts which
is able to run a job of the specified job type.
package require biocore 1.15
puts "Testing biocore_getAccountsForJob"
if [catch {set jobTypeList [::biocore::getAccountsForJob $jobType ]} errmsg] {
# if we make it in here, we had an error thrown
# This shouldn't ever happen
global errorInfo
global errorCode
puts "getAccountsForJob Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts " Id Name"
puts "---- -------"
foreach { name } $jobTypeList {
puts "[format %3i [lindex $name 0]] [lindex $name 1]"
}
puts "-------------"
}
Get the available queues for a particular account id
The getQueuesForAccount method returns the list of account names and
descriptions for a particular account id.
package require biocore 1.15
puts "Testing getQueuesForAccount $account"
if {[catch {set queueList [::biocore::getQueuesForAccount \
$account ]} errmsg]} {
# if we make it in here, we had an error thrown
# This shouldn't ever happen
global errorInfo errorCode
puts "getQueuesForAccount Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts " Name Desc"
puts "----- -------"
foreach { name } $queueList {
puts "[lindex $name 0] [lindex $name 1]"
}
puts "-------------"
}
}
Run a job
The BioCoRE server will submit a job specified by the parameters
that get passed in.
package require biocore 1.15
puts "Testing biocore_submitJob"
set jobType "Generic"
set accountId 12
set projectId 3
set jobName "MyJob"
set jobDesc "The description"
set workDir "sim1/run1"
set cmd "~/bin/my_sim"
set cmdParams "infile1 infile2 outfile1 outfile2"
set stdoutFile ""
set stderrFile ""
set queueName ""
set projToCharge ""
set numProcs ""
set cpuTime ""
set memory ""
set inputFileList { "/myproj/file1" "/myproj/file2" }
set outputFileList { "outfile1" "outfile2" }
if [catch {set result [::biocore::runJob \
"$jobType" \
"$accountId" \
"$projectId" \
"$jobName" \
"$jobDesc" \
"$workDir" \
"$cmd" \
"$cmdParams" \
"$stdoutFile" \
"$stderrFile" \
"$queueName" \
"$projToCharge" \
"$numProcs" \
"$cpuTime" \
"$memory" \
"$inputFileList" \
"$outputFileList" ] } errmsg] {
# if we make it in here, we had an error thrown
global errorInfo
global errorCode
puts "submitJob Error: <$errmsg> <$errorInfo> <$errorCode>"
} else {
puts "Job id is $result"
}
Get the status of a BioCoRE job
The getJobStatus method returns the status of a job running in BioCoRE
package require biocore 1.15
# check the job status 10 times, then return. The return codes are
# listed in the java code in collab.jobManagement.Job.java, but
# the important ones are SUBMITTED=2, RUNNING=3, RETRIEVING=10
# COMPLETE=4, KILLED=5
set done 0
for {set i 0} { $i<10 && $done==0 } {incr i} {
if {[catch {set status [::biocore::getJobStatus $jobid] } errmsg ]} {
# if we make it in here, we had an error thrown
global errorInfo errorCode
puts "submitJob Error: <$errmsg> <$errorInfo> <$errorCode>"
break
}
puts "Job status is $status"
after 5000
}
Logging a user out of BioCoRE
The biocore logout method can be used to log a user out of BioCoRE.
Note that this will completely log a user out.
If the user has other Control Panels, etc., running they will be closed.
package require biocore 1.15
puts "Testing biocore_logout"
if [catch {set i [::biocore::logout ]} errmsg] {
# if we make it in here, we had an error thrown
# This shouldn't ever happen
puts "Error: $errmsg"
} else {
puts "User logged out."
}
|
Feedback
The BioCoRE team welcomes any comments, questions, or
suggestions that you might have concerning our software! Please email us or fill out our feedback form.
|
|