10. Migrating from Karrigell 2.x to 3.y
Although version 3 is a complete rewriting of Karrigell core modules, it is almost fully compatible with previous versions. The two main changes are the way user-defined modules are imported, by a built-in function Import(module_url)
; and the resolution of relative paths in the file system
1 - Configuration
1.1 The configuration files are Python scripts instead of a single .ini file : one for the server, and one for each host. Most configuration options are the same, except that all names have been normalized : lowercase, with underscore between words. For instance, rootDir
becomes root_dir
- but to reduce incompatibility, "old" names will still be recognized
1.2 The only option that can be configured on the command line is the path of the folder of the server configuration script. All other options like the server port are set in the server or host configuration scripts
1.3 the equivalent of "protected" is not yet implemented
2 - Syntax
2.1 Relative file names
-
os.getcwd()
is NOT modified by the framework as in previous versions, because its value is not stable in a multi-threaded environment : you can't rely on it inside scripts - the built-in string
CWD
is the full path of the current script directory - the built-in function
REL(filename)
converts a relative file name to the absolute file name, based on the current script directory - for convenience and compatibility with previous versions, the Python built-ins
open()
andfile()
convert relative path names to absolute path names based on the current script directory
2.2 Imports
- to import Python modules located in the standard distribution, use the usual
import
statement - you can also use
import
for modules located in the directory karrigell/package - for user-defined modules inside the application,
import
can't work reliably in a multi-threaded environment where the value ofsys.path
can be modified by scripts, and because the sharing ofsys.modules
at the interpreter level can lead to confusion on module names. Use the built-in functionImport()
:module = Import(url_to_user_defined_module)
- to make migration simpler, the command-line script karrigell/core/migrate_2_to_3.py will check scripts and report all the cases when
import
is used to import modules outside of the Python distribution currently installed on the computer
2.3 Include
In Karrigell 2.x, with Include(url)
, a relative url was resolved relatively to the full url, including function name in ks scripts, arguments etc
In version 3 the resolution is relative to the script url, regardless of any element following it in the url
For instance, in the script ks_script.ks :
Include("header.html") def myfunc(**kw): Include("info.txt")
When the url host/folder/ks_script.ks/myfunc?arg1=val1 is called, the resolution is relative to the script url host/folder/ks_script.ks. Thus :
- the relative url header.html is resolved to the absolute url host/folder/header.html
- the relative url info.txt is resolved to the absolute url host/folder/info.txt
2.4 Outputs
- when a script is executed, it can give specific values to response headers such as
Content-type, Set-Cookie
etc, and it usually returns data to be printed by the user agent. The HTTP response returned by the server consists of the response line, response headers and data - for this reason,
sys.stdout
can't be used directly inside a script to send the response to the user agent, because the result would be sent BEFORE the response line and headers. The built-in functionprint
can be used for that ; it is internally translated into the built-in functionPRINT()
which can also be used directly :PRINT(data)
is the same asprint data
- internally, this function
PRINT
accumulates data in a buffer ; when the request is completed, the servers sends the response line, then the response headers, and finally the buffer content - to avoid whitespace and line breaks introduced by
print
orPRINT
, use the built-in functionSTDOUT()
2.5 Environment
A built-in dictionary, ENVIRON
, holds the same information as os.environ
for CGI scripts
2.6 User management
The built-in function Logout()
now erases the session cookies and redirects to the requested page (by default, the script where the function is called). In previous versions it returned a string with a link to the logout script
You must replace all lines like :
if Role(): print Logout()
with something like:
if Role(): print '<a href="logout">Logout</a>'
and add a function logout() like this
def logout(): Logout()
3 - Implementation
3.1 Threading server
The default web server, launched by python Karrigell.py, is a multithreaded server, able to serve long-running scripts without blocking other requests
An alternative, multiprocess server also gives excellent performance
3.2 Session management
Sessions are stored on disk, except if the option persistent_session
is set to False
(this will not work reliably in multi-threaded environments : if you need this feature, use the asynchronous or monoprocess versions of the server). The life duration of a session in the session database can be configured
3.3 Data types
HEADERS
and RESP_HEADERS
are instances of email.Message
(behave very much like case-insensitive dictionaries)
4 - Web 2.0
4.1 editarea
The Javascript library EditArea is included, to allow on-line script edition. It is used in the Script Editor in the Administration menu, and in case of error or exception in a script, the Debug button gives access to a page where the script can be edited on line
4.2 jQuery
The lightweight JavaScript libraries jQuery and jQueryFileTree are also included. They are used in the Script Editor application in the Administration menu, to browse files without having to reload the whole page