“I want to put a ding in the universe.” Steve Jobs
Top 5 Questions
Before we dive into more details, let’s answer some simple questions. For sure the below is applicable to many similar products. However, the main difference is that some other products might be “selling” other services. It is a typical “hook, line and sinker” scenario. And fair enough, it’s business after all. The Jam.py does not do that. The source code is yours, and it is very well structured. A joy to dig in, and I think Steve would be pleased. Try it. Give it a go.
1. What is Jam.py?
Jam.py is a Rapid Application Development framework. The word rapid should be stressed.
2. Why using Jam.py?
If you are already working with the databases, then Jam.py is a no-brainier.
The development tool is free. No need for anything more then a browser.
Leverage the existing skill-set. With some Python and JS experience, you’ll be productive in no time.
Simple infrastructure, especially for developers.
Deployment complexity is greatly reduced. Jam.py itself is only a few megabytes in size.
3. Why not to use Jam.py?
If not using databases, then it probably doesn’t make sense to use Jam.py.
4. Does it scale?
Yes. That is absolutely true with containers as well.
5. What can I use it for?
Data-centric application – anything to do with the database, for example reporting, CRUD.
Hope the above five questions sparked some interest. Nothing wrong with comparing Jam.py with for example Oracle Apex.
One of the first thing to understand is the Jam.py terminology: the difference between Catalogs (Catalogues), Journals and Details Groups.
Excellent Article by Marco Fioretti @ Linux Magazine:
We will reference the above article:
Every Jam.py interface, or project, is structured as a tree of tasks that are organized in groups. You may create custom groups if you like; however, at least for your first Jam.py projects, I strongly suggest that you stick with the default task tree, which consists of four groups called Catalogs, Journals, Details, and Reports.
Catalogs are tables that store actual records, like the inventory of a store or the students of some school.
Once tables are created in Catalogs, they can’t be moved to some other group that easily. There is a special utility that does that. In a newer Jam.py version, moving the tables is enabled by default, no need for any utility.
Journals store information about events or transactions pertaining to the records in the Catalogs – such as invoices or purchase orders.
Journals are groups of tables that depend on some other tables, namely Catalogs and Details tables. This are the Master tables in database Master-Details scenario, or General Ledger tables, for example in Accounting. Journals table should contain at least one Details table, and if it does not, it probably is a Catalogs table and not a Journals table. One Journals table can contain as many Details tables as needed. Journals table is using Catalogs tables as a source for data lookups, for example a Customer data like Name, Surname, if this data exist in the Catalogs Customers table.
The same calculations and location principles apply as for Catalogs.
Details store detailed information pertaining to the records in the Journals – such as invoices items details or purchase orders items details.
Details are group of tables used only by Journals tables. This are special tables with extended functionality by the default, since extra fields are added every time a Details table is created. The extra fields are used to identify the owner record in the Journals tables. This enables Jam.py to find information much quicker then not using extra fields. It is possible to use Details with no extra fields to find exactly the same information by the code. For example, when Importing tables from some Legacy system, there would be no such extra field. The solution is to use code for some otherwise missing functionality, which is enabled automatically if used native Jam.py Details.
The same calculations and location principles apply as above.
Reports are reports based on OpenDocument templates, more specifically Calcs ods files.
Professional look of reports is developed visually in LibreOffice (LO) Calcs. It is similar look and feel to any other Spreadsheet software. The LO enables us to use graphics, for example as the Company Logo. It is even possible to insert images from the database itself (with watermark, if needed).
The LibreOffice must be installed on the server OS level which is hosting Jam.py. The containerised LO images do exist on the Internet, if needed to use for the Jam.py container.
Need more Groups?
It is possible to rename any existing Item, or delete or make them invisible when accessing the Application.
Now that we know the Jam.py terminology, it is good to start thinking about what we want to do. We might completely ignore the default Item Groups and make some new ones. Or, we can have only one single Group and create everything in there. However, that would not be nicely organized, due to:
Item Groups are represented by the drop-down menu automatically. Hence, there might be a need for HR, Payroll, General Ledger and Assets Groups, to name a few for a Financial System. The drop-down menu would contain many items (tables), for each Group.
Item Groups are Ordered in any order. In each Group, the items are also ordered.
All of the above happens with no programming.
Journal/Detail (or Master/Child) scenario
As mentioned, Details Group is used to quickly identify what the Detail (Child), is for the Journal (Master), tables. However, there is more in that. Jam.py can automatically join two or more tables to Master as Details only if tables are available in Details Group. Hence, if there is no Details group, with no tables in it, Jam.py can not build the Master/Child relation automatically.
There are a number of Design decisions to make, namely what is the Authentication method the Application will use, the need for Users Registration and password reset, or forgotten password mechanism, default Language or translations, Business Logic and what not.
Built in Authentication
Jam.py has a built in Authentication based on Users and Roles tables within admin.sqlite database. This method works fine for smaller Applications or Proof of Concept (PoC). However, for larger implementation it might be needed to extend the Users/Roles table for the Application specific requirements. There might be also a requirement to store the two mentioned tables outside the admin.sqlite database for improved security by using some other database other then SQLite3. To copy Users/Roles from a built in database to some other Application (e.g. from Development to Test and Prod), export/import of SYS_USERS and SYS_ROLES tables would be needed. All Administrator accounts accessing the Builder interface use built in database.
Non built in Authentication
To extend the Authentication with the Application database and Users/Roles tables is easy. Please consult the official Jam.py Documentation how to do that. The benefits for doing it is the ability to use the database backup or export, which will contain all information specific to the Application, in one or more backup/export files. There is no need to export/import SYS_USERS/SYS_ROLES tables, unless there are a large number of Administrator accounts who are accessing the Builder interface.
With non built in Authentication, the Application can, as an option, use a custom Python password hashing within the Task/Server Module. It is also possible to develop custom password complexity, or password lifetime, which does not exist with build in method.
LDAP (Active Directory) Authentication
LDAP is supported by Jam.py v5. LDAP or Active Directory Authentication is fairly straight forward, and it is possible to use a specific LDAP (AD), branch (or AD Groups), where the Jam.py Users exist. The Application will still use built in or non built in database for storing Users/Roles.
The Python Business Logic (BL) can be developed within the Task/Server Module.
For example, if the User does not exist in the Application database, it can be created with Python BL and some Role can be assigned for the User. Otherwise, the User accessing the Application should be created first manually in the Application with the specific Role assigned. It is worth mentioning that LDAP or AD is using password to Authenticate the User, and it does not contain Roles information in the LDAP tree, unless LDAP is extended to contain Roles for Jam.py.
Please refer to more info in here: https://groups.google.com/g/jam-py/c/Q2iqvSA1zTM/m/o8HKxhvSCgAJ
It is worth using SSL with all connection to LDAP or AD.
SAML or SSO Authentication
SAML will be supported in newer major versions other then v5. SAML depends on the DNS service and the SSL Certificates issued for the Application name. It is a large implementation for mostly commercial environment.
Please visit Demo Application in here: http://auth.jampyapplicationbuilder.com
For username/password and more information plese visit: https://groups.google.com/g/jam-py/c/1qciSkILloU/m/JfRncz89BQAJ
The SAML authentication code is not publicly available at this time of writing. The code is tested with MS Azure, Shibboleth and JumpCloud. MS Graph should also work.
OAuth2, OpenID or SiteMinder (CA) Authentication
Similar to SAML, it is possible to develop other Authentication mechanisms. SiteMinder is supported by Apache.
MFA or Two Factor Authentication
Instead of using LDAP or SAML, the Application might consume Multi Factor Authentication, with Google Authenticator, FreeOTP or similar software.
Please refer to more info in here: https://groups.google.com/g/jam-py/c/Nisyemcx6Vc/m/d6m7A4WSDQAJ
User Registration Form
Instead of manually creating the Users, regardless of Authentication method, the Application might use a Registration Form for initial User creation. the default Role might be assigned for the User by Business Logic (BL).
Please consult the official Jam.py Documentation how to create a Registration Form.
Forgotten Password Method
For the Application Authenticated Users it might be worth to provide the Forgotten Password method by email. Jam.py already has Change Password method explained in the official documentation. However, Forgotten Password method depends on multitude dependencies, namely sending emails from the Application, and SSL, to name a few.
Please refer to more info in here: https://groups.google.com/g/jam-py/c/SYn2R0ILy74/m/Y5YMzUsSCAAJ