An Introduction to python-fmrest (dotfmp demo)

python-fmrest is a wrapper around the FileMaker Data API.

No need to worry about manually requesting access tokens, setting the right http headers, parsing responses, ...

Use cases

Some things you may use the python-fmrest library for:

  • Build a backend for a web app that works with FileMaker data
  • Use python-fmrest together with a rest framework to build your own data API as middleware
    (so that you don't expose the whole FM data API to a third party, but only allowed endpoints/actions)
  • Explore your FileMaker data with data analysis tools from the Python ecosystem
  • Anything else you could do in the past with the CWP/XML API

Installation (get you up and running quickly)

If you haven't worked with Python and Virtualenvs before:

  • brew install python3
    • No brew? /usr/bin/ruby -e "$(curl -fsSL")
  • pip3 install virtualenv

If you have worked with Python and Virtualenvs before, or after executing the steps above:

  • virtualenv venv --python=`which python3`
  • source venv/bin/activate
  • pip install python-fmrest

The demo setup

  • FileMaker Server 17, with Data API enabled, in a VM
  • Hosted Database called "Planets"
    • incl. account with fmrest extended privilege
  • Example code running in a Jupyter Notebook with a Python 3.6 kernel
    • Not necessarily needed, but nice for exploration and presentation (mixing code and annotations)
  • Installed python-fmrest library

Import module

In [ ]:
import fmrest

In [ ]:

Create server instance

In [ ]:
fms = fmrest.Server(
    # if you are testing without cert/domain you may need the parameter verify_ssl=False here.

This gives you a server instance which provides all further methods to interact with the Data API.

In [ ]:


Obtain a token from FMS:

In [ ]:

Get records and access field and portal data

List all records from the Planets table

In [ ]:
planets = fms.get_records()
for planet in planets:
    print(f'{}, {planet.record_id}, {}')

In [ ]:
type(planets), planets

Look at (some of) the moons of Jupiter (list records of a portal)

In [ ]:
record = fms.get_record(5, portals=[{'name': 'moons', 'limit': 5}])

portal = record['portal_moons']
record, portal

Fetching a record always gives you a Record instance. The portal rows, however, are returned as a Foundset.

In [ ]:
for row in portal:

You can inspect what fields are available:

In [ ]:

In [ ]:

In [ ]:

And access the value by attribute or key:

In [ ]:, record['atmosphere']

So far we have seen Server, Foundset, Record. These are the main classes you need to be aware of when working with the library.

Find records

In [ ]:
find_request = [{'name': 'Earth'}, {'name': 'Jupiter'}]
foundset = fms.find(query=find_request)

earth = foundset[0]

Edit a record

In [ ]: = 'Blue Dot'

In [ ]:

Handle outdated record values:

In [ ]:
# change back = 'Earth'
fms.edit(earth, validate_mod_id=False)

Create a record

In [ ]:
pluto = fms.create_record({'name': 'Pluto', 'id': 9})

Delete a record

In [ ]:

Performing scripts (new in v17)

In [ ]:
        'after': ['say_hello', 'dotfmp']

In [ ]:

Uploading container data (new in v17)

In [ ]:
with open('../scratch/dotfmp_logo.png', 'rb') as image:
    result = fms.upload_container(3, 'image', image) # upload dotfmp logo into field with name "image" of record 3

Now retrieve the image again:

In [ ]:
earth = fms.get_record(3)

In [ ]:
name, type_, length, response = fms.fetch_file(earth.image)
name, type_, length

In [ ]:
from IPython.display import Image


In [ ]:
find_request = [{'name': 'something that doesn\'t exist'}]
foundset = fms.find(query=find_request)

Foundset into DataFrame

Turn Foundset into a Pandas DataFrame to do statistical analyses on your dataset, work with missing data, reshape/pivot, perform joins/merges, plot with matplotlib, export, etc.

In [ ]:
foundset = fms.get_records()
df = foundset.to_df()
df.loc[:, df.columns != 'image']

In [ ]:
df[['name', 'atmosphere', 'rings', 'confirmed_moons', 'mass']].set_index('name').T

In [ ]:

... or plot some data with matplotlib

In [ ]:
%matplotlib notebook
df.plot(x='name', y='confirmed_moons')

... or export the data in a different format

In [ ]:
path = 'data.csv'
df.to_csv(path, sep=";", index=False)
from IPython.display import FileLink

Read about Pandas here:

More on python-fmrest

More on me

Any questions? Ask now or later.