Advanced Gry topics.¶
The following, more advanced features of Gry will require an understanding of how Pygrister works, and/or some Python skills.
Data type converters.¶
Pygrister converters can be very helpful
in gry, especially in writing operations, because it’s difficult
to express anything other than strings in the command line.
If you want to include converters in your gry workflow, you must add
a Python module named cliconverters.py in your current directory
(in fact, you can put the file anywhere in your Python path, since gry
will attempt to import it).
Standalone version: In the standalone bundle, you may also drop your
cliconverters.py in the top-level directory of the bundle, ie next to the
“gry.exe” and readme files. You will find a stub module there, for you
to open and edit.
Inside the file, write your converter functions as you need.
You must, however, name the final converter dictionaries cli_out_converters
and cli_in_converters. These converters will be imported and applied
to your gry call.
Passing additional arguments to Requests.¶
In Pygrister, you may set
GristApi.apicaller.request_options to a dictionary in order to pass
optional arguments, not otherwise used by Pygrister, to the underlying
Requests call. You can’t do this in Gry, as you don’t have direct access
to the GristApi class.
If you need to pass arguments to Requests, just drop a gryrequest.json
file in your current directory. This file will be parsed at runtime,
and its content will be feeded to GristApi.apicaller.request_options
as it is. For instance,
{
"timeout": 15,
"verify": false,
"allow_redirects": true
}
See the Requests documentation for the available options.
Standalone version: In the standalone bundle, gryrequest.json must
be located in the top-level folder of the bundle. You will find a stub there,
for you to open and edit.
Please note that the Gry-specific GRIST_GRY_TIMEOUT configuration
may also be used to set a timeout for the Requests call. This is meant
as a shortcut, since a timeout is almost always wanted. If a timeout is
all you need, just set the config key. For anything more than this,
you’ll need a separate gryrequest.json file. If a timeout setting
is found in both places, gryrequest.json will take precedence
(if in neither place, Gry will default to 60 seconds anyway).
The gry conf command will output both the current Gry settings, and
any Requests additional arguments you may have set.
The gry Python shell.¶
Entering the gry python command gives you access to a patched Python shell,
complete with a pre-loaded Pygrister environment. Inside, the gry variable
is an instance of pygrister.GristApi: its configuration is the same of the
gry cli tool, at the moment of starting the Python shell:
% gry python
This is Python <...> on <...>, and Pygrister <...>
Here, "gry" is a ready-to-use, pre-configured GristApi instance.
>>> gry
<GristApi instance at 0x....>
>>> gry.configurator.config
{... <the same config of the gry tool> ...}
>>> gry.see_doc() # etc. etc.
...
>>> exit()
This is meant as a quick way to switch to a more powerful tool when you need
to express an API call too sophisticated for gry to handle.
Type exit() to return to your system command line.
If you add the --idle option, an Idle window will open instead, provided that
you have Idle installed on your system.
(More specifically: all Gry will do, is to invoke python or python -m idlelib
from your system shell. If it doesn’t work for you, perhaps because you don’t have
Python in your path or whatever, the gry command will fail too.)
Be aware that you can change your configuration in the Gry Python shell
between api calls, as gry, here, is just a regular GristApi instance:
nothing stops you from invoking gry.reconfig({...}) or
gry.update_config({...}). However, you will return to the previous,
“regular” Gry configuration as soon as you leave the Gry Python shell.
Caveat and limitations.¶
There is a limit to what can be expressed from the command line, without over-complicating the syntax. For this reason, Gry does not map a few APIs, and does not include a few options.
Several APIs allow for writing many instances of a “thing” in a single call: in Gry, it’s always one thing at a time. For instance, you can add multiple tables to a document with
GristApi.add_tables, and multiple columns to a table withGristApi.add_cols: the Gry equivalentsgry table newandgry col neware limited to one object at a time.Filters in search APIs are difficult to write in the command line: Gry does not provide filter options for user, attachment and record listing (for the latter, an sql query is recommended instead). Unfortunately,
GristApi.search_usersis also basically a filter, therefore Gry is not implementing it at the moment.Nested structures such as record, columns, etc. are difficult to express as well: Gry will offer only a simplified version for adding/updating records and columns.
The two
GristApi.add_update_*APIs (for columns and records) are just too complicated for Gry, as it isGristApi.bulk_user.
Some of these may be implemented in the future. In any case, remember:
if you hit a construct that you cannot express in Gry, just type
gry python to open a Python shell, pre-loaded with a working GristApi
instance, and let Pygrister take over from there.
Finally, keep in mind that gry, being written in Python, is slow:
every time you enter a gry command, the Python interpreter must be loaded
(and then some) before your command is parsed and executed.
In normal, interactive usage you won’t even notice (because the real bottleneck
will be the network latency anyway). However, think twice before, say,
queuing many gry commands in a script. If you want to load 100 records
into a table, something like this
>>> records = [[...], [...], ...]
>>> grist = GristApi()
>>> for record in records:
... _ = grist.add_record(...)
can be fast, while the equivalent
#!/bin/bash
gry rec new ... -q
gry rec new ... -q
...
will be very slow.