# 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 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 *

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.

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:
except JuliaBaseError as error:
if error.error_code == 4:


In Visual Basic:

Try
Catch e As JuliabaseException:
If e.code = 4 Then
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
print("You are not authorised to make PDS measurements!")


In Visual Basic:

Dim result As String
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
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.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.