Gramex 1.89 supports case-insensitive search, distributed user logs, feature usage reports, and complexity reports.
FormHandler filters has 2 new operators *=
and !*=
that match case-insensitively.
?Name*=united matches “united” in any case, e.g. “United” and “UNITED”
ID | Name | Continent | … |
---|---|---|---|
ARE | United Arab Emirates | Asia | … |
GBR | United Kingdom | Europe | … |
USA | United States North | America | … |
Similarly, ?Name!*=united skips “united” in any case, e.g. “United” and “UNITED”
This currently works for in-memory data frames as well as all SQLAlchemy databases, but not yet for MongoDB, InfluxDB and ServiceNow.
When a user logs in or out, Gramex logs the event to a user log store. This is useful for auditing, reporting, and debugging.
Earlier, this was stored as logs/user.csv
under $GRAMEXDATA.
But this could not be shared across multiple machines.
Now, this is stored in a database. The default database is sqlite:///$GRAMEXDATA/auth.user.db
and the default table is userlog
. You can change these in gramex.yaml
:
storelocations:
userlog:
url: postgresql://$USER:$PASS@server/db
# url: mysql+pymysql://$USER:$PASS@server/db
# ...
table: userlog
You can set the columns to log with any key in request logging. Below is the default.
storelocations:
userlog:
columns:
# You MUST add these 3 columns
event: TEXT # Type of event: login/logout/fail
datetime: TEXT # Time of event, ISO8601 encoded (YYYY-MM-DD HH:MM:SSZ)
user: TEXT # User ID (e.g. user name or email address, depending on handler)
# You can change / update any of these
port: INTEGER # Port on which Gramex is running
uri: TEXT # URL where the user logged in
name: TEXT # Name of the handler
class: TEXT # Class of the handler (e.g. SimpleAuth, GoogleAuth, etc)
ip: TEXT # IP address of the client
browser: TEXT # Browser name
# request.method: TEXT
# env.HOME: TEXT
Run gramex features
on any Gramex app to list the features used.
Here’s an example:
$ gramex features
type feature count
0 MS CaptureHandler 2
1 MS ComicHandler 1
2 MS FileHandler 67
...
18 KWARG Access Control 53
19 KWARG Security 12
...
27 SVC Microservice 2
28 SVC Import 0
...
41 ERR-MS handlerutil.CustomHandler 1
42 ERR-MS handlerutil.SetupHandler 1
The columns are:
type
: The type of feature. One of MS
(microservice), KWARG
(configuration), SVC
(service).
ERR-MS
indicates a custom or missing microservicefeature
: The name of the featurecount
: The number of times the feature is usedYou can render the output in different formats:
--format=table
prints a table (default)--format=csv
prints a CSV file--format=json
prints a JSON filePass multiple folders, e.g. gramex features /project1/ /project2/
, to sum features used across folders.
Run gramex complexity
on any Gramex app to measure the
Cyclomatic Complexity
of the code.
Here’s an example:
$ gramex complexity
py js gramex
0 121 345 2782
The columns are:
py
: Python code complexityjs
: JavaScript code complexitygramex
: Complexity of the Gramex codebase used by the projectThis is useful to see what % of the code re-uses Gramex code, and what % is custom code.
Put another way, without Gramex, the project would have a complexity of 122 + 345 + 2,782 = 3,249.
Gramex reduces 2,782 / 3,249 = 86% of the code.
Gramex 1.89 is backward compatible with previous releases unless the release notes say otherwise. We ensure this with automated tests.
Every Gramex release is tested for security vulnerabilities using the following tools.
The Gramex code base has: