Start reading at base.py, class BaseHandler. BaseHandler inherits from Tornado’s Request handler. BaseHandler has some more methods that get self and call super. These are extended methods of Tornado’s requestHandler.
(particularly relevant files are in bold)
- Folder: Web
- __init__: make_app creates the application and connectes the URLs to the respective views and API endpoints.
- api: API responses. Change data via commands. Data as well as commands are pulled via the functionality in
database.py
- base: Start reading here Defines the Application class and the web response baseclass (BaseHandler), both inheriting from the respective Tornado classes.
- export
- views: Views seem to use the BaseHandler (in
base.py
) but not the API.
- __init__
- convert
- database: Datatypes (as classes) and
Command
s to change the data. The commands are mainly used by the responses in api.py. - export: different kinds of export-to-file code
- extract: used by export to get highlighted segments for the exported files
- import_codebook
- main: Setup the application, create the application (makeApp), load the start the tornado web framework event loop.
- utils
- validate: Contains general validation function for different datatypes, among them user identification (used by
database.py
code a lot)
- Main is called.
- Main creates a
config
dict that configures the app it creates via make_app. - A webbrowser is opened (if you run it locally, that is) on a localhost:xxxx/ address (and a token)
- The webbrowser accessing / creates a get-Request to the / route which matches to the index view which is called then.
- You see the "Here are your projects:" screen (if you run taguette locally, that is)
- The browser requests a url
- If that URL was bound to a view in web/__init__:makeApp(…), it will call that view (which code is in web/view.py)
- For a normal page view, the get request handler of the view is called…
- …and then, usually at the end of the handler, the self.render(…) function of the view baseclass (as defined in the Tornado Framework)
- …
- If that URL was bound to an API response in web/__init__:makeApp(…), it will use the request handler (as defined in web/api.py)…
- …the request handler can have several methods for different crud actions (patch, delete, post…). The handler corresponding to the request is used…
- …which ends in sending a JSON (usually post, get), a finish (usually patch, delete) or an error-JSON.
Clients long poll on the url /events. This API-url is managed by api.py’s ProjectEvents class. It observes the project and gets notified on on changes. When a change is done, all clients get an event object handled in the client side JS. A coorsponding function is called, doing the change.
TODO: How does taguette deal with conficting operations by different users? E.g. both try to edit the same tag’s title, a person deletes a document that another was tagging etc.
The interactivity beyond changing views by clicking links is realized with Javascript in static/js/taguette.js. The javascript manages long-polling the server and calling the API based on user actions.
There are some idiosyncracies in how the Javascript is used. All custom JavaScript code is in one file, there is currently no modularization. Functions are trigged by <a href="javascript:myFunction()"
links – this has become very unusual.
Usually a front end framework like vue, react or riot would be employed to handle interactions and seperation of font-end-javascript concerns and communicate directly with the API. The web socket/long poll handling would be seperated from the UI code.
- Taguette Repository, obviously
- Taguette Architecture. It does mention the frameworks used and where the frontend is defined, but is not very helpful in understanding how the core python code works.
- Tornado Documentation Tornado is the python web framework taguette builds upon.