Package: openflexure-microscope-client
A Python client for the OpenFlexure Microscope.TheOpenFlexure Microscopeis most often controlled by two pieces of software - theOpenFlexure Microscope Server, which is written in Python and runs on the embedded Raspberry Pi, andOpenFlexure Connectwhich is a graphical interface written in Electron, that can be run either on the Raspberry Pi, or on another computer via a network connection.  However, if you want to write your own scripts to perform particular experiments or protocols, it's useful not to have to embed these into the theOpenFlexure Microscope Serveror package them up as plugins.  This library exists to make it easy to control your microscope from a simple Python script that can run either on the Raspberry Pi, or over the network.  I particularly like to use it from aJupyternotebook on my laptop, because it allows me to plot graphs and display images as I go.InstallationThis module can be installed withpip install openflexure-microscope-client, or by cloning the repository and runningpoetry install.UsageConnect to your microscopeYou can connect to the microscope either by specifying a hostname or IP address, or using mDNS.  If your network is relatively simple, and if you can see your microscope in the "nearby devices" section ofConnect, then mDNS is a zero-faff way of connecting to your microscope:importopenflexure_microscope_clientasofm_clientmicroscope=ofm_client.find_first_microscope()If your network is more complicated, or you know the address of your microscope, you can connect using the hostname or IP address.  By default, your microscope will declare itself asmicroscope.localthough this also relies on mDNS so if the method above doesn't work,microscope.localmay also not work.microscope=ofm_client.MicroscopeClient("example.host.name")Check the connectionUsually, I run a few commands to check my microscope is working properly:pos=microscope.positionstarting_pos=pos.copy()pos['x']+=100microscope.move(pos)assertmicroscope.position==pospos['x']-=100microscope.move(pos)assertmicroscope.position==starting_pos# Check the microscope will autofocusret=microscope.autofocus()# Acquire an image for sanity-checking tooimage=microscope.grab_image()f,ax=plt.subplots(1,1)ax.imshow(np.array(image))#print(image.metadata)print("Active microscope extensions")forkinmicroscope.extensions.keys():print(k)After running this block, you should see a list of extensions that are currently active, and a picture taken by the microscope.  Given that we just autofocused, this image should be nice and sharp!Basic commandsThere are a few basic commands built in as methods of theMicroscopeClientobject:positionis a property that returns a dictionary with'x','y', and'z'components, giving the position of the stage.get_position_array()returns a 3-elementnumpyarray with the same position in it.move(position)accepts either a 3-element array or a dictionary as returned byposition, and performs an absolute movemove_rel(displacement)performs a relative move (i.e. supplying 0 will not move that axis)capture_image()will take a new image from the camera and return it as aPILimage objectgrab_image()will return the next image the camera sends in its MJPEG preview stream (i.e. it's quicker but lower quality thancapture_image())grab_image_array()returns the image as anumpyarray.autofocus()runs the fast autofocus routine, just like clicking the "autofocus" button inConnectExtensionsTo run methods provided by the microscope extensions, you can use theextensionsdictionary, to makegetorpostrequests:microscope.extensions["your.extension.name"]["link_name"].get()microscope.extensions["your.extension.name"]["link_name"].post_json({"key":"value"})Arguments and documentationThere is not currently much documentation beyond this README for the Python client.  However, the microscope API is pretty well documented.  This is the place to go to find out the details of what each command does, and what the arguments mean, particularly for any of the commands that take apayloadargument; that's converted to JSON and passed directly to the corresponding HTTP POST request.  Currently, there is a static version of the API documentation linked from theserver readthedocs page, or you can access a live interactive version fromhttp://microscope.local:5000/api/v2/docs/swagger-ui, replacingmicroscope.localwith the IP or hostname of your microscope.DevelopmentInstallationThe dependencies are managed using poetry, so once you have cloned the repository, you can set up a virtual environment withpoetry install.TestsThere are some basic tests that can be run usingpytest.  This needs to be within the environment installed above, so usepoetry run pytest.  These mostly need to connect to a microscope; the easiest way to test this automatically is to buildopenflexure-microscope-serverand run it locally - this will create a local dummy microscope server.  Some tests will be skipped because they need microscope hardware, but it should at least verify most of the URLs.  Running the tests requires you to have started that server already - it will not be started automatically.