python-fmrest compatibility with the new FileMaker 17 Data API

21 minute read

A few hours ago FileMaker 17 was released, and with it an updated Data API, which is now finally out of trial phase.

Depending on your situation and if you have used the Data API in v16, there’s good and bad news. The bad news is that all API paths have been renamed, response formats have changed, authentication works a little different, and a few other little changes here and there. The good news is: if you have been using my python-fmrest wrapper library, little to no adjustments are necessary to make your existing app compatible with FileMaker 17 😎. If you have not used the library but have an app that you need to update, you might still be interested in reading a bit further to get a summary of the changes.

Breaking changes in the library

The breaking changes in the latest version of python-fmrest are:

  • The portal parameter range in the get_record method is now called limit (in both the wrapper and the official API)
  • The parameter range_ for the get_records method is now called limit
  • The parameter range_ for the find method is now called limit
  • get_records now has a sort parameter; watch out if you didn’t use named parameters before
  • set_globals now needs fully qualified field names as the layout is not passed in anymore
  • data_sources is now a parameter of the Server class. Passing in a list of data sources was not available in v16. If you didn’t use positional arguments for instantiating your server, you don’t need to worry about this. See below for more info.

If you haven’t worked with these methods/parameters, you can install the new python-fmrest version and everything should “just work” with FMS v17.

Note: v16 is not supported anymore by this new version of the library as the Data API will automatically be terminated in September 2018. If you still need to work with v16, please use this tagged release from GitHub.

Other changes and new features

There have been a lot of other changes and extensions to the wrapper library, but notable are the following:

  • The Data API now finally returns numbers in a number type and you will see this change reflected by the library as well.
  • If you have used the type_conversion parameter for automatic type detection/conversion, you may not need to anymore. If you are working with dates, you may still find it helpful, so it continues to be in the library.
  • With the upload_container method you can now upload binary data into container fields. See example here: uploading_container_data.ipynb
  • You can now specify a sort parameter for get_records
  • You do not need to specify a “start layout” for logging in anymore. However, you can still set it when instantiating the Server class, so that you have it ready for subsequent requests. Like before, you can always change the layout by doing something like fms.layout = 'new_layout'.
  • All examples have been updated. Head over to GitHub to see how the new and old functions work.
  • I implemented the new scripting functionality for all supported calls: find(), get_records(), get_record(), edit_record(), delete_record(), create_record(). Pass a scripts object via the new scripts parameter like so: {'prerequest': ['my_script', 'my_param']}. See example here: performing_scripts.ipynb.
  • The script result can be accessed via the new last_script_result property of the Server class. It looks like this:
{
 'after': [3, None],
 'prerequest': [0, 'Output prerequest'],
 'presort': [0, 'Output presort']
}

Note: The script result will be None if the script exits without an Exit Script[] or with an empty Exit Script[]. An empty string will also return None as the return value. This is due to the fact, that the API gives no indication whether your script exited with an empty result or simply didn’t have a script result. Also be aware that the script result will never contain the result of a previous script call from inside the called script (as Get(ScriptResult) in FileMaker Pro would do).

Script results are always returned as string. Even if your actual return value is a Number or a Date or Time, …. This is not due to python-fmrest’s handling but due to the fact, that the API only gives back strings (just like it was the case for field data in v16. Let’s hope this will change in future versions).

For script errors it is clear that they are ints, so they will be automatically converted to int by the library.

  • find(), get_record() and get_records() now have a new parameter layout. It allows you to set the response (!) layout. Let’s say you want to search via a related field that sits in a portal, but are only interested in the parent records as response data. Then you can have a simple layout (without the portal) and limit the number of fields and data being returned.
  • You can now pass a list of data_sources when instantiating the Server. This makes sense if you need to be authenticated to multiple database files for a request. An example could be: [{'database': 'SecondDataSource', 'username': 'admin2', 'password': 'admin2'}]. See an example here: multiple_data_sources.ipynb
  • create_record() and edit_record() now take a portal parameter. You can specify the portal records that should be created with the create_record request. For example:
record_id = fms.create_record(
    {'name': 'David'},
    portals={
        'my_portal_name': [
            {'myTO::name': 'name 1', 'myTO::name2': 'name 2'},
            {'myTO::name': 'second record name 1'}
        ]
    }
)

(For edit_record you can specify the recordId to change existing records. If it is not specified, a new record will be created)

General changes of the Data API

If you haven’t used my library and need to change your existing code, you may find the following points helpful.

  • Authentication is now handled via HTTP Basic Auth for login. In subsequent requests you need to set Bearer as the Authorization type in the Authorization HTTP header, followed by the obtained session token.
  • API paths have been renamed. You can find the new paths in my const.py (link) file.
  • The returned json data now has a different structure. Generally, you can find a response (contains the record/field data, token, script errors, script results) and a messages key in the returned data. Here is an example:
{
    "response": { "token": <the token> },
    "messages":[{"code":"0","message":"OK"}]
}
  • Editing Records and setting globals now use HTTP PATCH instead of PUT

As always: if you find bugs, see any possible improvements, or need help, please open an issue on GitHub.

Like to comment? Feel free to send me an email or reach out on Twitter.

Did this or another article help you? If you like and can afford it, you can buy me a coffee (3 EUR) ☕️ to support me in writing more posts. In case you would like to contribute more or I helped you directly via email or coding/troubleshooting session, you can opt to give a higher amount through the following links or adjust the quantity: 50 EUR, 100 EUR, 500 EUR. All links redirect to Stripe.