What | jimhttp |
Where | https://github.com/dbohdan/jimhttp |
Description | A web microframework meant to be like Sinatra and Flask written in pure Jim Tcl. Provides a rough implementation of the HTTP protocol as well as routing, templates, JSON generation and parsing, an HTML DSL and persistent storage powered by SQLite3. |
Platforms | Likely all supported by Jim Tcl's aio. |
Prerequisites | The HTTP server itself requires Jim Tcl 0.76 or later. The majority of the components runs on either Jim Tcl 0.76 or later or Tcl 8.5 or later. |
Updated | 2018-04-06 |
License | MIT |
Components edit
See
https://github.com/dbohdan/jimhttp#components for what is included in the framework.
Code examples edit
http.tcl
source http.tcl
::http::add-handler GET /hello/:name/:town {
::http::respond [::http::make-response \
"Hello, $routeVars(name) from $routeVars(town)!"]
}
::http::start-server 127.0.0.1 8080
json.tcl
# This produces the output
# {"a": "123", "b": 123, "c": [123, 456], "d": "true", "e": true}
source json.tcl
puts [::json::stringify {
a 123
b 123
c {123 456}
d true
e true
} 0 {
a string
c {N* number}
d string
}]
Discussion edit
ekd123 - 2014-09-30 08:04:39Will there be a "tclhttp" written in Tcl?
dbohdan 2014-09-30: It's not a goal for me for now (especially since there are already web frameworks for Tcl) but I would welcome a compatibility patch that makes the code work in both. Porting should be pretty straightforward except for the use of static variables (though static variables can be emulated with namespaces, e.g, by mapping variable
varName to
$procName::$varName).
aspect 2014-10-01: I just spent an hour or so trying to shim this to run under Tcl (as a Jim learning exercise - nothing more), and while I didn't succeed it certainly looks feasible. A
jimshim package would have to do a couple of things:
- shim set and proc to create the namespace if it doesn't already exist
- simulate statics as dbohdan describes above
- extend proc to support TIP#288+ styled arglists, with optional args in the middle. I have a package which approaches this, if anyone's interested.
- qualify namespaces appropriately -- namespaces in jimhttp aren't explicitly rooted in ::, though it looks like that's how they function
- do array<->dict binding a la tie to support jim's dict(subscript) notation
- do a little bit of magic to support the pattern global ns::x; set ns::x. The relative qualified names may make it tricky
- provide a compatibility wrapper around sqlite3 - just sqlite3.open and the query method are sufficient for jimhttp
- provide a compatibility wrapper around socket -server
- provide a stdout command which is almost exactly an alias to fconfigure stdout.
That might be all that's needed. Some (all?) of these are quite trivial edits to the code as it is, but a shim to run it unmodified would be quite nice. Appropriate wrappers for
socket and
sqlite3 should be trivial in
TclOO. If anyone's motivated enough to make a page for
Jim Shim and start building a package, I'm happy to contribute what I have so far ... though I have no direct use for it right now, and no real experience with Jim, so quality and support from my end should not be relied upon ;-).
Worth noting: several of jimhttp's modules run perfectly on Tcl without modification. It might be more fun to pull those out and use them with
Wibble or
Woof! or
Rivet or
Wub or
H. I think that's all the most popular Tcl HTTP stacks today?
dbohdan 2014-10-02: Interesting! I like the idea of a Jim compatibility shim. It could even be a starting point for something like Python's
six;
six is a Python package that, when imported, provides the same standard library API in Python versions 2.x and 3.x, which by themselves have incompatibilities. Obviously, something like that would be a larger undertaking and harder to implement. As a bonus it could, e.g, help establish a dominant format for statics in Tcl (I am not aware of one). I can not work on such a compatibility project myself right, so if anyone else wants to the idea is up for grabs. :-) For now I have made plans to look into writing a shim based on your analysis that provides just the functionality that jimhttp uses with minimal changes to jimhttp itself.
I pushed a update today that roots all namespaces used in jimhttp in the global namespace. It doesn't matter for Jim but should make Tcl compatibility easier and there was really no reason not to (except maybe slightly uglier-looking code because of all the double colons). As for
socket -server, I have a wrapper from an earlier project parts of which became the basis for jimhttp:
if {[catch {info tclversion}]} {
set interpreter Jim
} else {
set interpreter Tcl
package require struct
interp alias {} lmap {} struct::list mapfor
}
puts "Running in $interpreter."
# [...]
proc start-server {ipAddr port} {
global interpreter
if {$interpreter eq "Tcl"} {
proc accept {channel clientaddr clientport} {
chan event $channel readable [
list serve $channel $clientaddr $clientport
]
}
socket -server accept -myaddr $ipAddr $port
} else {
global s
set s [socket stream.server $ipAddr:$port]
$s readable {
set client [$s accept addr]
serve $client {*}[split $addr :]
}
}
vwait done
}
json.tcl,
html.tcl and
template.tcl work in Tcl 8.5 if you create the namespace beforehand with something like
proc source-x filename { namespace eval [file rootname $filename] {}; source $filename }; source-x html.tcl;. You may find
json.tcl interesting for implementing both decoding and encoding JSON arrays as number-keyed dictionaries as suggested in
https://core.tcl-lang.org/tcllib/tktview?name=2967134fff. You'll also need a
+ proc for
json.tcl.
Thanks for pointing out
H to me; I didn't know about it. The question of popular Tcl HTTP stacks (or more narrowly, web application frameworks) is something I started researching recently. Unfortunately, I couldn't find any up-to-date comparison of them. So far I've made the wiki page
web framework that I hope might fulfill this role in the future and have filled in some details; however, nothing can replace actual experience with the stacks themselves. While there is overlap here with the HTTP server category the scope of a modern web application framework is^W makes it its own distinct thing with some functionality expected that wouldn't necessarily be in a "normal" web server.
aspect: The
web framework page is timely.
H is Colin's recent effort to strip down
Wub to essentials, as apparently some folks (myself included) found the whole package a bit much to digest. As you'll see from the examples, it's very easy to use, though some of the modules still need a bit of de-Wubification. There's been quite a bit of activity on the
Tcl'ers chat of late with folks using these frameworks for websites and HTTP services - I'd recommend asking on there if you want to learn more. Alternatively, chatters are likely to see this activity in recent changes and pipe in with more detail :-).
dbohdan 2014-10-03: I'd be glad to see others chime in. To make the most of their contributions we'll probably need to improve the "schema" of that table. The formatless "description" column makes contributing facts that could help differentiate the frameworks harder than it should be.
See also edit