<commit_before>What is Giotto?
===============

Giotto is a python application framework. Not quite a web framework, but it does
include plumbing for deploying applications through a web server.

Giotto's motto is "An application framework for idealists with no deadlines"

This document is a work in progress. Since Giotto is still being conceptualized
and written, this document will change often.

Why?
====

The point of giotto is to avoid writing any controllers. All you write is the
model, and the views. Giotto takes care of the rest.

Write our models once, and reuse them across any controller you want!

Philosophy
==========

* Convention Over Configuration - It may seem like a bummer at first to not be
able to fine-tune configure every aspect of giotto. But in the long run, this
approach is best, as each giotto user does things the same way. Giotto does not
let you shoot yourself in the foot.

* Forward thinking backwards compatability - Giotto will release major versions
that break backwards compatability more often than most projects. For instance,
Giotto 2.x will not be backwards compatable to Giotto 1.x, etc. Point releases will
occur

* Document driven - It is very important that all aspects of giotto are documented
before they are written.

* Giotto should make you do the right thing - It should be very hard to create
complex spaghetti code when using giotto.

* Everything that other frameworks can do, giotto should be able to do - Numerous
times in the development process, giotto's API had radically changed when it has
become known that other frameworks can do things much easier than giotto.

Features
========

* Completely working commandline interface as well as web interface out of the box
* Giotto automatically configures the urls for you. No more dealing with messy regex
based urls to define!

Primitives
==========

When writing model methods, in the function declaration, you can define primitives
which expand to data requested automatically from any controller.

    from giotto import primitives

    def view(data):
        return "logged in as %s" % data['user']

    @bind_controller('http-1.1-get', view)
    @bind_controller('cmd', view)
    def currently_logged_in(user=primitives.LOGGED_IN_USER):
        return {'user': user}

Now when you invoke this function from either the commandline or via http, the
value of `user` will be the currently logged in user. In a http context, the user
will come from a cookie. From the commandline, the currently logged in user will
be extracted from an enviornment variable. How exactly this data is extracted is
a function of the controller module (defined as 'http' and 'cmd' above), and is
configurable.

Example Application:
====================

    from giotto.primitives import RAW_PAYLOAD, LOGGED_IN_USER
    from giotto.exceptions import NotFound, ImproperInput
    from giotto import bind_controller, bind_model, get_invocation

    ###############
    ## Views
    ###############

    def blog_new(blog, errors=None):
        """
        After a blog is created from the command line, return a message
        telling the usser the new blog url.
        """
        url = get_invocation('http-1.1-get', 'view_blog', args={'id': blog.id})
        return "New blog created! see at %s" % url

    def commandline_blog(blog, errors=None):
        """<commit_msg>clarified the explanation of primitives<commit_after>What is Giotto?
===============

Giotto is a python application framework. Not quite a web framework, but it does
include plumbing for deploying applications through a web server.

Giotto's motto is "An application framework for idealists with no deadlines"

This document is a work in progress. Since Giotto is still being conceptualized
and written, this document will change often.

Why?
====

The point of giotto is to avoid writing any controllers. All you write is the
model, and the views. Giotto takes care of the rest.

Write our models once, and reuse them across any controller you want!

Philosophy
==========

* Convention Over Configuration - It may seem like a bummer at first to not be
able to fine-tune configure every aspect of giotto. But in the long run, this
approach is best, as each giotto user does things the same way. Giotto does not
let you shoot yourself in the foot.

* Forward thinking backwards compatability - Giotto will release major versions
that break backwards compatability more often than most projects. For instance,
Giotto 2.x will not be backwards compatable to Giotto 1.x, etc. Point releases will
occur

* Document driven - It is very important that all aspects of giotto are documented
before they are written.

* Giotto should make you do the right thing - It should be very hard to create
complex spaghetti code when using giotto.

* Everything that other frameworks can do, giotto should be able to do - Numerous
times in the development process, giotto's API had radically changed when it has
become known that other frameworks can do things much easier than giotto.

Features
========

* Completely working commandline interface as well as web interface out of the box

* Giotto automatically configures the urls for you. No more dealing with messy regex
based urls to define!

Primitives
==========

Each controller implements a set of 'primitives' that your controller tips can
use without coupling your application to any one controller. Eample:

    class ShowBlogHTTP(GiottoApp):
        name = 'show_blog'
        controller = 'http-get'
        controller_tip = ('id', LOGGED_IN_USER)
        model = Blog.get
        view = HTML('blog.html')

In the above snippet, `LOGGED_IN_USER` is a special 'primitive' object that
represents the currently logged in user. In an HTTP context, this data comes from
a cookie that is set my some authentication middleware. We can subclass this
application, and change the controller:

    class ShowBlogCMD(ShowBlogHTTP):
        controller = 'cmd'
        view = JSON

In this case, `LOGGED_IN_USER` comes from the CMD controller, and is implented
by looking at the enviornment of the commandline where this program is invoked.
The details of how this information gets to the model is an implementation
detail of the controller class, and is of no concern for the model developer.

Example Application:
====================

    from giotto.primitives import RAW_PAYLOAD, LOGGED_IN_USER
    from giotto.exceptions import NotFound, ImproperInput
    from giotto import bind_controller, bind_model, get_invocation

    ###############
    ## Views
    ###############

    def blog_new(blog, errors=None):
        """
        After a blog is created from the command line, return a message
        telling the usser the new blog url.
        """
        url = get_invocation('http-1.1-get', 'view_blog', args={'id': blog.id})
        return "New blog created! see at %s" % url

    def commandline_blog(blog, errors=None):
        """
{'fraction_non_alphanumeric': 0.07385545637777138, 'fraction_numerical': 0.0014396775122372588, 'mean_word_length': 3.923458540042523, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '545083', 'n_tokens_mistral': 1827, 'n_tokens_neox': 1785, 'n_words': 946}