News

1st December 2014 by aegeuana_sjp_admin

PyFileMaker – Integrating Python and Filemaker

PyFileMaker is a Python Library that makes it possible to work with FileMaker‘s XML API. You can use the Filemaker XML API to query a FileMaker database, create records, modify records, execute scripts and more.
During the creation of web applications there is often a need to use third party services or programs. One of them is FileMaker. FileMaker is a cross-platform relational database application. It contains a GUI layer that allows a user to easily create different relations between tables, create bespoke layouts, and easily run reports on the go. FileMaker is used as a database as it contains built-in server (which is SQL based, and to which you can actually execute direct SQL Queries if you want to!).
It also allows you to run a PHP server which is powerful but also quite inefficient and sluggish at times. To connect to FileMaker we can use the provided XML API instead, and that is what PyFileMaker is doing.

Functions already implemented

PyFileMaker has a lot of functions to work with already implemented. Some of these include:

  • Getting objects from db
  • Saving objects to db
  • Finding records
  • Sorting a query
  • Displaying meta data for particular layouts

When we’ve started working with the PyFileMaker library we noticed a few missing parts that are desperately needed:

  • No compatibility with FileMaker 13
  • Unable to execute scripts with/without parameters
  • Executing scripts in a chain with insert operations
  • Fetching files

In that situation one thing you can do is to extend the old library, write your own functions and integrate it together.
It turns out we can easily integrate PyFileMaker with FileMaker 13 and use then add in extra functionality that doesn’t exist in the original PyFileMaker Library.
All the standard functions work in the same way:
[code language=”python”]
from PyFileMaker import FMServer
fm = FMServer(‘login:password@filemaker.server.com’)
fm.getDbNames()
[‘dbname’,’anoterdatabase’]
fm.setDb(‘dbname’)
fm.getLayoutNames()
[‘layoutname’,’anotherlayout’]
fm.setLayout(‘layoutname’)
[/code]

New functionality

To execute the code below remember to specify a proper database and layout.

Execute scripts

The FileMaker API allows you to execute scripts. We can execute them in two ways: with or without parameters. We can send a parameter as a string separated by a special character that can be parsed from the FileMaker script that is being executed (this can be done by a simple replace statement in the Get(ScriptParameters) method on a FileMaker script and replacing the designated character eg: | with a carriage return character, which will then recognise each parameter as a value for GetValues()).
[code language=”python”]
# execute script without parameters
resp = fm.doScript(‘script_name’)
# execute script with parameters
parameters = "first|second|third"
resp = fm.doScript(‘script_name’, params=parameters)
[/code]

Retrieve files

We can retrieve files from the Filemaker Server as a binary stream. To do this we need to point to the container field of the object and query its content.
Each object that contains a container field also contains a pre-generated  query (returned by FileMaker) to retrieve its content. We can easily find it by displaying all the fields for that given object:
[code language=”python”]
container_field = fm.doFind(id="10")
container_field
MODID = ’10’
RECORDID = ‘9791’
creation_timestamp = ‘2014-06-25 16:25:05′
id = ’37’
number = ‘199’
email = ‘some@email.co.uk’
title = ‘Rambo II’
from_ts = ‘2014-06-25 00:00:00’
ooh_zip = ‘/fmi/xml/cnt/data.zip?-db=DATABASE&-lay=layout&-field=ooh_zip&-recid=114’
status = ‘Complete’
[/code]
In this case we need the `ooh_zip` field.
[code language=”python”]
file_name, file_extension, file_binary = fm_server.getFile(container.ooh_zip)
[/code]

Execute script after another command

The doScriptAfter Method is taking the following arguments:

  1. Filemaker XML API Method
  2. Method arguments as kwargs(dict formatted)
  3. Filemaker Script name
  4. Filemaker Script arguments (optional)

[code language=”python”]
resp = fm.doScriptAfter(fm_server.doNew, {
‘first_name’: ‘Foo’,
‘last_name’: ‘Bar’,
‘ip’: user_ip,
‘action’: ‘Download’
},
‘script_name’,
‘script_params’
)
[/code]

 Summary

Since sometimes you can’t avoid working with third party applications such as FileMaker, you need to use something that is able to satisfy your requirements. If there is nothing currently available then it is probably a good idea to extend the functionality and just share your work and ideas with the community.
Hope this helps somebody!
The lib can be found on:

Leave a Reply

Your email address will not be published. Required fields are marked *