Talking to JuliaBase¶
You have a measurement or processing setup, and you have access to the program(s) that run this setup? This is the ideal situation to make a direct, bi-directional connection between your experimental setup and the central JuliaBase server. This has many benefits:
You can assure that only people authorised for this apparatus can log in your program.
You can assure that the header data in your data files is correct, in particular operator name and sample name.
Each run is immediately available in the central database.
Operators needn’t enter each run into the browser, which is inconvenient and error-prone.
Operators can pick the affected sample(s) comfortably from a list instead of typing the sample names explicitly.
If a run is connected with a task, this task can automatically updated.
This chapter is intended as a gentle introduction to how to realise this.
The big picture¶
JuliaBase is written in the Python programming language. This is also true for the Remote Client, which is a Python library that you can install on any lab or office computer and use it to talk to the central JuliaBase server.
However, you needn’t use Python to communicate with JuliaBase. This is just the most natural way. But JuliaBase’s source code includes bindings to Delphi, Visual Basic, and LabVIEW. Further bindings can be added very easily once the demand is there.
Such a binding works by calling the Python interpreter in the background. This indirection causes a very slight performance loss. Moreover, you need to install a Python interpreter. However, the simplicity and maintainability of this approach make up for it.
Installation¶
First, make sure that Python is installed on your computer.
Then, install the remote client package (which is an adaption of the original JuliaBase client to your institute or
group). Ask your local JuliaBase guru for how to do this. Ideally, it is
available in a shared directory, so that you don’t have to do anything. You
should make sure that the remote client package’s directory is in the
PYTHONPATH. In the following, I call the adapted module
jb_institute_inm
; your name with probably be different.
Basic usage¶
The next steps differ depending on the programming language you use. The basic principle is always the same, though: You log in on server with user name and password, execute commands that read from or write to the database, and log out.
In all non-Python languages, however, you cannot give the commands directly.
Instead, you build a string that contains the Python commands and pass it to
a special function called execute_jb
or similar.
Python¶
In our example code, we read the data of sample “14-JS-1” and then change its current location:
from jb_remote_inm import *
setup_logging("file")
login("juliabase", "12345")
sample = Sample("14-JS-1")
sample.current_location = "main lab"
sample.edit_description = "location changed"
sample.submit()
logout()
Visual Basic¶
The Visual Basic binding in remote_client/visual_basic/juliabase.vb
can
be used like the following:
Imports System
Imports Juliabase
Public Module ModuleMain
Sub Main()
JB_Module_Name = "jb_remote_inm"
Execute_JB("juliabase", "12345",
"sample = Sample('14-JS-1');" &
"sample.current_location = 'main lab';" &
"sample.edit_description = 'location changed';" &
"sample.submit()")
End Sub
End Module
Delphi¶
For Delphi, in order to achieve the same as in the previous sections, you say
program juliabase_example;
{$APPTYPE CONSOLE}
uses
SysUtils, juliabase;
begin
jb_module_name := 'jb_remote_inm';
execute_jb('juliabase', '12345',
'sample = Sample("14-JS-1");' +
'sample.current_location = "main lab";' +
'sample.edit_description = "location changed";' +
'sample.submit()');
end.
The necessary unit can be found in remote_client/delphi/juliabase.pas
.
LabVIEW¶
The LabVIEW virtual instrument “execute jb.vi” in
remote_client/labview/juliabase.llb
is very different from the other
bindings for obvious reasons, but the general method is the same: You pass
login, password, and the module name in a data structure called “settings” to
the VI, and the result of the Python process is returned:
Getting data in non-Python languages¶
In the non-Python languages, you don’t have direct access to the results of the
commands. Instead, you may use Python’s print()
to send data to the
standard output, which in turn is the return value of the execute_jb
function. Then, you can extract the original data from this value. For
example in Delphi, you may write:
topic := execute_jb('juliabase', '12345', 'print(Sample("14-JS-1").topic)');
Then, topic
contains the topic of the sample. Note that topic
is a string. If you need other data types, you have to convert the result
string yourself.
For more complex return values, this conversion can be cumbersome. In
languages with JSON support, there is a convenience function defined in the
remote client called as_json()
. It can be used
instead of print()
. It prints its argument in JSON format to standard
output. The LabVIEW example above demonstrates the usage of this function
in the second VI call.
The test server¶
Your institution may provide a test server for easier developing. This way,
you do not manipulate valuable data on the production server. You choose the
test server by passing testserver=True
to the login()
function:
login("juliabase", "12345", testserver=True)
In non-Python languages, you pass the same parameter to the execute_jb
function.
Error handling¶
If something goes wrong while executing the commands, an exception is raised. If it is a JuliaBase-related error, this is a special exception class:
language |
exception class name |
error code attribute name |
---|---|---|
Python |
JuliaBaseError |
error_code |
Visual Basic |
JuliabaseException |
code |
Delphi |
EJuliaBaseError |
ErrorCode |
Moreover, the error message is stored in the exception attribute typical of the respective language.
If the error is not JuliaBase-related (for example, a syntax error), the language-typical basic exception class is raised, containing a proper error message.
As usual, in LabVIEW, things are slightly different. If an error occurs, it is set in the error output of the VI. Error numbers greater than 6000 indicate JuliaBase errors. The error message contains the details.
Error pages in the browser¶
In case of JuliaBase errors, non-Python languages may open a browser
automatically showing a detailed problem description. You may turn off this
behaviour by setting the global variable jb_open_error_page_in_browser
to false
.
About passwords¶
Passwords are sensitive data. Never store them on the disk. Assure that they never appear anywhere on the screen (use the •••• display). Let the user input their password, store it in a variable, and use it to login to JuliaBase – that’s all.
How do I …¶
… check whether the user is known to JuliaBase?¶
You login the user with the user name and password they give and check whether this raises a JuliaBase exception with error code 4. If it does, the user name and/or the password is wrong.
In Python:
try:
login(username, password)
except JuliaBaseError as error:
if error.error_code == 4:
print("Login and/or password is wrong!")
In Visual Basic:
Try
Execute_JB(login, password, "")
Catch e As JuliabaseException:
If e.code = 4 Then
MessageBox.Show("Login and/or password is wrong!")
End If
End Try
… check whether the user is allowed to use my setup?¶
You retrieve the permissions
attribute of a
User
instance. Then, you check whether the
“add” permission occurs in this attribute.
In Python:
permissions = User(username).permissions
if "institute.add_pdsmeasurement" not in permissions:
print("You are not authorised to make PDS measurements!")
In Visual Basic:
Dim result As String
result = Execute_JB(login, password, "print(User('" & username & "').permissions)")
If result.IndexOf("'institute.add_pdsmeasurement'") = -1 Then
MessageBox.Show("You are not authorised to make PDS measurements!")
End If
… check whether a sample exists?¶
You retrieve the sample and check whether this raises an exception with error code 2. If it does, a sample with that name was not found.
In Python:
try:
Sample(sample_name)
except JuliaBaseError as error:
if error.error_code == 2:
print("A sample with this name does not exist!")
In Visual Basic:
Try
Execute_JB(login, password, "Sample('" & sample_name & "')")
Catch e As JuliabaseException:
If e.code = 2 Then
MessageBox.Show("A sample with this name does not exist!")
End If
End Try
… add a new process?¶
You instantiate the process class, set sample ID, operator, timestamp, and the
process-specific attributes, and call the submit()
method of the
process instance.
In Python:
pds_measurement = PDSMeasurement()
pds_measurement.sample_id = Sample(sample_name).id
pds_measurement.operator = username
pds_measurement.timestamp = datetime.datetime.now()
pds_measurement.number = next_number
pds_measurement.apparatus = "pds1"
pds_measurement.raw_datafile = filepath
pds_measurement.submit()
In Visual Basic:
Execute_JB(login, password,
"pds_measurement = PDSMeasurement();" &
"pds_measurement.sample_id = Sample('" & sample_name & "').id;" &
"pds_measurement.operator = '" & login & "';" &
"pds_measurement.timestamp = '" & Format(Now, "yyyy-MM-dd HH:mm:ss") & "';" &
"pds_measurement.number = " & next_number & ";" &
"pds_measurement.apparatus = 'pds1';" &
"pds_measurement.raw_datafile = '" & filepath & "';" &
"pds_measurement.submit()")
In order to know which instance attributes you need to set and how, look for documentation in the Python remote client module, or ask your local JuliaBase guru.