Gramex 1.75 includes a ServiceNow connector for FormHandler, and the ability to update data in MongoDB.
FormHandler supports the servicenow://
URL to read from ServiceNow tables.
For example:
url:
servicenow:
pattern: /$YAMLURL/servicenow
handler: FormHandler
kwargs:
url: "servicenow://user:password@hostname.com/table/incident"
To use this, get REST API access ServiceNow account and query the tables.
Note: Only read access is provided. Write-back is not supported.
Thanks @radheyakale
Gramex 1.70 introduced read access to MongoDB. This release enables write-back.
In the FormHandler configuration, add an id:
column. For PUT and DELETE operations, this is used to identify the record to delete.
url:
mongo:
pattern: /$YAMLURL/mongo
handler: FormHandler
kwargs:
url: mongodb://localhost:27017
database: testdatabase
collection: testcollection
id: name
xsrf_cookies: false # Optional
Now, the following operations work:
curl -X POST localhost:9988/mongo -d 'name=value&key=value' # Add a record
curl -X PUT localhost:9988/mongo -d 'name=value&key=value2' # Update the record
curl -X DELETE localhost:9988/mongo -d 'name=value' # Delete the record
Thanks @radheyakale
To help developers debug Gramex issues better, gramex -V
now prints more diagnostics:
$ gramex -V
Gramex version: 1.75.1
Gramex path: d:\gramex\gramex
Python version: 3.7.3
Python path: D:\anaconda\3.7\python.exe
This particularly helps identify:
All auth handlers support an ensure_single_session
action that logs the user out from all other sessions.
But Gramex would log all users out, not just the logged in user. This bug went undetected due to poor test coverage (and the author’s stupidity).
Now, Gramex only logs out the user who logged in from other sessions.
Gramex auto-reloads the gramex.yaml
configuration whenever it’s changed. This is useful for fast
debugging – you don’t need to manually restart Gramex. This works even if the YAML is invalid.
But if the configuration is invalid (e.g. you specified handler: NonexistentHandler
),
Gramex would never reload gramex.yaml
configurations again
Now, even if there’s any incorrect configuration, Gramex reports an error and reloads on the next change.
FileHandler directory listing lets you specify an
index_template:
But it was hard to try different designs for the template – you needed
to restart Gramex every time index_template
changed.
Now, if the index_template
file changes, Gramex automatically reloads it. It’s much faster to
iterate and create new index templates.
Gramex stores session data in a JSON file store, by default. This is fast and persistent (though it doesn’t share session data across multiple Gramex instances.)
When a user logs in, the page they should be redirected back to is stored along with the session. But if Gramex restarts, this information is lost.
This is now resolved. Gramex keeps track of all changes in session information and saves it.
gramex.yaml
supports computed variables. This lets you change
the configuration based on the environment.
For example, you could define $DB_URL
that connects to a different databases based on the OS.
variables:
DB:
function: 'sqlite:///...' if os.name == 'nt' else 'mysql:///'
But if this was defined inside a local Python file (e.g. my_module.py
below),
it raised a NameError: name ... is not defined
on startup.
variables:
DB:
function: my_module.get_db_url()
Now, Gramex checks local Python modules for functions and loads them as required.
Earlier, when we stop a Gramex Windows service from services.msc
or via gramex service stop
,
it would not stop the service.
This was because gramex.shutdown()
internally did not allow shutting down from an external thread,
which was used in the Windows Service.
Now, the Windows Service shuts down gracefully.
Gramex 1.75 is backward compatible with previous releases unless the release notes say otherwise. Automated builds test this.
Every Gramex release is tested for security vulnerabilities using the following tools.
The Gramex code base has:
See the Gramex installation and upgrade instructions.
Note: Gramex 1.75 does not work with Python 3.8 or 3.9. Use Python 3.7.