Quickstart¶
Creating New Project¶
Having installed colifrapy, initialize a new project with the Scaffolder by typing into your console:
colifrapy new [name-of-project]
options :
{-a/--author: Author of the project}
{-o/--organization: Organization of the author}
To test your new project, enter your project’s directory and type:
python [name-of-project].py test
It should launch it and output a header and some strings in the console telling you everything is going to be OK.
Command Line Hub¶
[name-of-project].py
A colifrapy project relies on a command line hub extending Colifrapy base class. This is the file you have to call in your shell to launch the program. The duty of this hub is to initialize your tool, analyze the arguments given to it and call upon the relevant controller methods.
In fact, this hub can be compared to a basic router for web frameworks.
This is the hub as generated by the scaffolder
# Dependencies
#=============
from colifrapy import Colifrapy
from model.controller import Controller
# Hub
#======
class NameOfYourProject(Colifrapy):
# From this hub, you can access several things :
# self.settings (Settings Instance)
# self.log (Logger Instance)
# self.opts (Options passed to your hub)
# self.controller (Your Controller)
def launch(self):
# Welcoming visitors
self.log.header('main:title')
# Calling upon the controller
self.controller.test()
# Launching
#===========
if __name__ == '__main__':
# By default, the hub will load config/settings.yml
hub = NameOfYourProject(
controller=Controller,
settings_path='path/to/your/settings.yml'
)
hub.launch()
Note that if you just want to use colifrapy features but don’t want to be tied to its architecture, you can just use this hub which can access any critical utilities as well as any colifrapy Model would.
Settings¶
config/settings.yml
The Settings class is the first class loaded by colifrapy to perform its magic. It will parse your settings.yml file and configure your logger, cacher, arguments and every other configuration you want for your application.
# Basic Informations
version: '[project-name] 0.1.0'
description: 'Description of the program.'
usage: 'How to deal with your program'
arguments:
- [ ['-t', '--test'], {'help' : 'Test', 'type' : 'int'} ]
- [ ['positionnal'] ]
# Logger Settings
logger:
strings: 'config/strings.yml'
flavor: 'default'
# Generic Settings needed by your program
settings:
hello: 'world'
bonjour: 3.4
hash: {'test' : 2}
Also, note that paths are automatically considered by colifrapy either as relative (config/test.yml) or absolute ones (/var/usr/test.yml).
For further information see Settings.
Arguments¶
config/settings.yml[‘arguments’]
Settings Usage¶
Arguments are to be defined as for the python ArgParser class. In fact, the colifrapy Commander class extends the ArgParser one, so if you need complicated things not handled by colifrapy, just use the Commander class like the ArgParser one.
arguments:
- [ ['-t', '--test'], {'help' : 'Test', 'type' : 'int', 'default' : 5} ]
- [ ['-b', '--blue'], {'help' : 'Blue option', 'type' : 'int', 'required' : 'True'} ]
- [ ['some_positionnal_argument'] ]
In the command hub and in your models, you can access the options passed to your commander through self.opts . However, even if those are accessible in models for commodity, only the main hub should use them and one should restrain their usage in models.
Special Arguments¶
Help, Version, Verbose and Settings
As for standard python command line tool, yours will accept three default arguments you should not try to override (verbose is the only one you can override because it is not one of ArgumentParser defaults):
-v/--version (outputting your program's version)
-h/--help (displaying your program's help)
-V/--verbose (overriding settings to enable the logger to display every messages)
--settings (overriding settings file if needed)
Controller¶
model/controller.py
The controller is a class whose goal is to call upon other models. The controller itself is in fact also a colifrapy model and is more a convention that something enforced by colifrapy’s code.
The controller is totally optional and just illustrate a way to organize your code. If you don’t want to follow this logic, just don’t pass a controller to your hub instance.
Controller as generated by the scaffolder
# Dependencies
#=============
from colifrapy import Model
from example_model import ExampleModel
# Main Class
#=============
class Controller(Model):
# Properties
example_model = None
def __init__(self):
self.example_model = ExampleModel()
# Example of controller action
def test(self):
self.log.write('main:controller')
self.example_model.hello()
Model¶
model/example_model.py
Models are the bulk of Colifrapy. You can extend them to access your settings and commands easily.
A standard model is generated for you by the Scaffolder when you create a new project.
Minimalist example of a model usage
from colifrapy import Model
class MyModel(Model):
def test(self):
print self.settings.hello
m = MyModel()
m.test()
>>> 'world'
- Reserved attributes names are:
- cache (access to cache)
- log (access to the logger described hereafter)
- opts (access to the command line options)
- settings (access to the program’s settings)
Logger¶
Basic¶
The logger is the outputting class of colifrapy. It should be loaded with some strings by the settings. If no strings are given, the logger will just output normally the argument strings you give to it.
For full logger documentation, see Logger.
Levels¶
- The logger accepts five levels :
- INFO (green output)
- VERBOSE (cyan output)
- DEBUG (blue output)
- WARNING (yellow ouput)
- ERROR (red output)
- CRITICAL (purple output) –> will throw an exception for you to catch or not
By default, if no level is specified for a message, DEBUG will always be taken.
Strings¶
config/strings.yml
Colifrapy offers to externalize your strings in order to enable you to quickly modify them if needed, or even translate them easily.
The string format used is a mustache-like one, so variables come likewise : {{some_variable}}
Strings given must follow this yaml layout
main:
process:
# String with a variable contained within the mustaches
start: 'Starting corpus analysis (path : {{path}})//INFO'
# Simply write two slashes at the end to specify the level of the message
end: 'Exiting//WARNING'
test_line_break: '\nBonjour'
title: 'Colifrapy'
other_string_category:
test: 'Hello everyone//INFO'
you:
can:
make: 'any levels that you want'
so: 'you can organize your strings however you need.'
Usage¶
This is how you would use the logger in a colifrapy model
from colifrapy import Model
class MyModel(Model):
def test(self):
# Main method
#------------
# Outputting a message
self.log.write('main:process:end')
>>> '[WARNING] :: Exiting'
# Overriding the message level
self.log.write('main:process:end', level='INFO')
>>> '[INFO] :: Exiting'
# Passing variables
self.log.write('main:protocol:start', {'path' : 'test'})
>>> '[INFO] :: Starting corpus analysis (path : test)'
# Variables can be passed to the logger as:
# a hash, a list, a tuple, a single string or integer or float
# Examples
self.log.write('{{variable}}', 'test')
>>> '[DEBUG] :: test'
self.log.write('{{var1}} is {{var2}}', ['python', 'cool'])
>>> '[DEBUG] :: python is cool'
# When yml file is not specified or if message does not match
self.log.write('Test string')
>>> '[DEBUG] :: Test string'
# Named arguments of write
# variables --> mixed
# level --> log level
# Helper methods
#---------------
# Printing a header (yellow color by default)
self.log.header('main:title', [optional]color)
>>> Colifrapy
>>> ---------
# Write methods shorteners
self.log.critical(message, vars)
self.log.error(...)
self.log.warning(...)
self.log.info(...)
self.log.debug(...)
self.log.verbose(...)
Asking for confirmation
from colifrapy import Model
class MyModel(Model):
def test(self):
# Confirmation
#---------------
# 'y' will be taken by default in arg 2
# will return True for y and False for n
response = self.log.confirm('Are you sure you want to continue?')
>>> 'Are you sure you want to continue? (Y/n)'
>>> y --> True
response = self.log.confirm('Are you sure you want to continue?', 'n')
>>> 'Are you sure you want to continue? (y/N)'
>>> n --> False
Getting user input
from colifrapy import Model
class MyModel(Model):
def test(self):
# User Input
#---------------
response = self.log.input('What up ?')
>>> 'What up ?'
>>> 'feeling fine' --> 'feeling fine'
# You can also provide a lambda to the function as second argument
# This lambda will affect the input given
response = self.log.input('What up ?', lambda x: x.upper())
>>> 'What up ?'
>>> 'feeling fine' --> 'FEELING FINE'
Cacher¶
Colifrapy gives you acces, in your hub and models to a caching class able to store data on files for long-term access. There are currently to types of cacher : line and yaml. The first one consist in a text file containing one line read by the cacher while the second archive any python key-value data in a yaml file.
To enable the cacher in the settings.yml file
cache:
kind: 'line'
directory: 'config'
filename: 'last_update.txt'
# Whether you want the cache to be written each time a value is changed
# Defaults to False
auto_write: True
Then in your model
from colifrapy import Model
class MyModel(Model):
def test(self):
# Line Cacher
#-------------
# Setting cache
self.cache.set("test")
# Getting cache
self.cache.get()
>>> "test"
# Yaml Cacher
#-------------
# Setting cache
self.cache.set("one", "red")
self.cache.set("two:deep", "blue")
# Getting cache
self.cache.get("one")
>>> "red"
self.cache.get("two")
>>> {"deep" : "blue"}
self.cache.get("two:deep")
>>> "blue"
self.cache.get
>>> {"two" : "red", {"deep" : "blue"}}
Note that the path separator for deep levels in yaml is always ”:” in Colifrapy.
For full documentation see Cacher.