3. References

3.1. browse

Universal browser

This module provides a browser in 2 flavours: as a program to use in a Terminal, or as a Python function that can be used in other software. The underlying code is based on the standard python module webbrowser. With webbrowser module itself, you can already open a URL as follows in a command line interface:

python -m webbrowser -t "http://www.python.org"

However, with browse, you can simply type:

browse http://www.python.org

It does not seem to be a big improvments but it is a bit more flexible. First, there is no need to enter “http://” : it will be added if missing and if this is not a local file.:

browse docs.python.org
browse http://docs.python.org --verbose

Similarly, you can open an image (it uses the default image viewer):

browse image.png

Or a txt file (or any document provided there is a default executable to open it). It works like a charm under Linux. Under MAC, it uses the open command so this should also work.

When invoking browse, under MacOSX, it actually tries to call open first and then calls webbrowser, if unsuccessful only. Note tested under Windows but uses webbrowser is used and works for open HTML document and URLs.

You can also look at a directory (starts nautilus under Fedora):

browse ~/Pictures

See more examples below.

The interest of browse is that it can also be used programmatically:

from easydev.browser import browse
# open an image with the default image viewer:
browse("image.png")
# or a web page
browse("http://www.uniprot.org")

There is also an alias onweb:

from easydev import onweb

3.2. chunks

split_into_chunks(items, maxchunks=10)[source]

Split a list evenly into N chunks

>>> from easydev import split_into_chunks
>>> data = [1,1,2,2,3,3]
>>> list(split_into_chunks(data, 3))
[[1, 2], [1, 3], [2, 3]]

3.3. codecs

various type convertors (e.g., list to string)

list2string(data, sep=',', space=True)[source]

Transform a list into a string

Parameters:
  • data (list) – list of items that have a string representation. the input data could also be a simple object, in which case it is simply returned with a cast into a string

  • sep (str) – the separator to be use

>>> list2string([1, 2]
"1, 2"
>>> list2string([1, 2], sep=;)
"1; 2"
>>> list2string([1, 2], sep=;, space=False)
"1;2"
>>> list2string(1, sep=;, space=False)
"1"

Note

the cast is performed with str()

to_list(data, verbose=True)[source]

Transform an object into a list if possible

Parameters:

data – a list, tuple, or simple type (e.g. int)

Returns:

a list

  • if the object is list or tuple, do nothing

  • if the object is not a list, we assume this is a primitive type and a list of length 1 is returned, the item being the parameter provided.

>>> from easydev import transform_to_list
>>> to_list(1)
[1]
>>> to_list([1,2])
[1,2]
tolist(data, verbose=True)[source]

alias to easydev.codecs.to_list()

3.4. config

class CustomConfig(name, verbose=False)[source]

Base class to manipulate a config directory

property user_config_dir

return directory of this configuration file

class DynamicConfigParser(config_or_filename=None, *args, **kargs)[source]

Enhanced version of Config Parser

Provide some aliases to the original ConfigParser class and new methods such as save() to save the config object in a file.

>>> from easydev.config_tools import ConfigExample
>>> standard_config_file = ConfigExample().config
>>> c = DynamicConfigParser(standard_config_file)
>>>
>>> # then to get the sections, simply type as you would normally do with ConfigParser
>>> c.sections()
>>> # or for the options of a specific sections:
>>> c.get_options('General')

You can now also directly access to an option as follows:

c.General.tag

Then, you can add or remove sections (remove_section(), add_section()), or option from a section remove_option(). You can save the instance into a file or print it:

print(c)

Warning

if you set options manually (e.G. self.GA.test =1 if GA is a section and test one of its options), then the save/write does not work at the moment even though if you typoe self.GA.test, it has the correct value

Methods inherited from ConfigParser are available:

# set value of an option in a section
c.set(section, option, value=None)
# but with this class, you can also use the attribute
c.section.option = value

# set value of an option in a section
c.remove_option(section, option)
c.remove_section(section)
add_option(section, option, value=None)[source]

add an option to an existing section (with a value)

>>> c = DynamicConfigParser()
>>> c.add_section("general")
>>> c.add_option("general", "verbose", True)
get_options(section)[source]

Alias to get all options of a section in a dictionary

One would normally need to extra each option manually:

for option in config.options(section):
    config.get(section, option, raw=True)#

then, populate a dictionary and finally take care of the types.

Warning

types may be changed .For instance the string “True” is interpreted as a True boolean.

See also

internally, this method uses section2dict()

read(filename)[source]

Load a new config from a filename (remove all previous sections)

save(filename)[source]

Save all sections/options to a file.

Parameters:

filename (str) – a valid filename

config = ConfigParams('config.ini') #doctest: +SKIP
config.save('config2.ini') #doctest: +SKIP
section2dict(section)[source]

utility that extract options of a ConfigParser section into a dictionary

Parameters:
  • config (ConfigParser) – a ConfigParser instance

  • section (str) – the section to extract

Returns:

a dictionary where key/value contains all the options/values of the section required

Let us build up a standard config file: .. code-block:: python

>>> # Python 3 code
>>> from configparser import ConfigParser
>>> c = ConfigParser()
>>> c.add_section('general')
>>> c.set('general', 'step', str(1))
>>> c.set('general', 'verbose', 'True')

To access to the step options, you would write:

>>> c.get('general', 'step')

this function returns a dictionary that may be manipulated as follows:

>>> d_dict.general.step

Note

a value (string) found to be True, Yes, true, yes is transformed to True

Note

a value (string) found to be False, No, no, false is transformed to False

Note

a value (string) found to be None; none, “” (empty string) is set to None

Note

an integer is cast into an int

3.5. console

Format colored consoled output. Modified from sphinx.util.console

black(text)
blue(text)
bold(text)
brown(text)
color_terminal()[source]

Does terminal allows coloring

Returns:

boolean

darkblue(text)
darkgray(text)
darkgreen(text)
darkred(text)
faint(text)
fuchsia(text)
get_terminal_width()[source]

Returns the current terminal width

green(text)
lightgray(text)
purple(text)
red(text)
reset(text)
standout(text)
teal(text)
term_width_line(text)[source]

prints pruned version of the input text (limited to terminal width)

Parameters:

text (str) –

Return str text:

turquoise(text)
underline(text)
white(text)
yellow(text)

3.6. decorators

Handy decorators

ifpandas(func)[source]

check if pandas is available. If so, just return the function, otherwise returns dumming function that does nothing

ifpylab(func)[source]

check if pylab is available. If so, just return the function, otherwise returns dumming function that does nothing

requires(requires, msg='')[source]

Decorator for class method to check if an attribute exist

>>> from easydev.decorators import requires
>>> class Test(object):
...     def __init__(self):
...         self.m = 1
...         self.x = 1
...     @requires(['m','x'], "set the m attribute first")
...     def printthis(self):
...         print(self.m+self.x)
>>> t = Test()
>>> t.printthis()
2

3.7. dependencies

get_dependencies(pkgname)[source]

Return dependencies of a package as a sorted list

Parameters:

pkgname (str) – package name

Returns:

list (empty list if no dependencies)

3.8. doc

Module related to documentation

underline(text, symbol='=')[source]

Underlines a string with a specific character

Parameters:
  • text (str) – the text to underline

  • symbol (str) – the character to be used to underline the text

Returns:

underlined text.

>>> print(underline("test"))
test
====

3.9. easytest

class TempFile(suffix='', dir=None)[source]

A small wrapper around tempfile.NamedTemporaryFile function

f = TempFile(suffix="csv")
f.name
f.delete() # alias to delete=False and close() calls
delete()[source]
property name
assert_list_almost_equal(first, second, places=None, deltas=None)[source]

Combined version nose.tools.assert_almost_equal and assert_list_equal

This function checks that 2 lists contain identical items. The equality between pair of items is checked with assert_almost_equal function, which means you can check for the places argument

Note

there may be already some tools to check that either in nosetests or unittest but could not find.

>>> from easydev.easytest import assert_list_almost_equal
>>> assert_list_almost_equal([0,0,1], [0,0,0.9999], places=3)
>>> assert_list_almost_equal([0,0,1], [0,0,0.9999], deltas=1e-4)
trysetattr(this, attrname, value, possible)[source]

A common test pattern: try to set a non-writable attribute

class A(object):
    def __init__(self):
        self._a = 1
        self._b = 2
    def _get_a(self):
        return self._a
    def _set_a(self, value):
        self._a = value
    a = property(_get_a, _get_b)
    def _get_b(self):
        return self._b
    b = property(_get_b)

>>> o = A()
>>> trysetattr(A, "a", 1, possible=True)
>>> trysetattr(A, "b", 1, False)
AssertionError

3.10. logging_tools

class Logging(name='root', level='WARNING', text_color='blue')[source]

logging utility.

>>> l = Logging("root", "INFO")
>>> l.info("test")
INFO:root:test
>>> l.level = "WARNING"
>>> l.info("test")
critical(msg)[source]
debug(msg)[source]
error(msg)[source]
info(msg)[source]
property level
property name
warning(msg)[source]

3.11. Options

class SmartFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]

Formatter to be used with argparse ArgumentParser

When using the argparse Python module one can design standalone applications with arguments (e.g; –help, –verbose…)

One can easily define the help as well. However, The help message is wrapped by ArgumentParser, removing all formatting in the process. The reason being that the entire documentation is consistent.

Sometines, one want to keep the format. This class can be used to do that.

Example:

import argparse
from easydev import SmartFormatter
class Options(argparse.ArgumentParser):
def  __init__(self, prog="sequana"):
    usage = "blabla"
    description="blabla"
    super(Options, self).__init__(usage=usage, prog=prog,
        description=description,
        formatter_class=SmartFormatter)
add_argument(action)
add_arguments(actions)
add_text(text)
add_usage(usage, actions, groups, prefix=None)
end_section()
format_help()
start_section(heading)

3.12. paths

Utilities to ease access to share data paths

get_package_location(package)[source]

Return physical location of a package

get_share_file(package, datadir, filename)[source]

Creates the full path of a file to be found in the share directory of a package

get_shared_directories(package, datadir='data')[source]

Returns all directory paths found in the package share/datadir directory

Parameters:

datadir (str) – scans package/share/<datadir> where datadir is “data” by default. If it does not exists, the list returned is empty.

>>> from easydev import get_shared_directories
>>> shared_directories = get_shared_directories("easydev", "themes")
>>> len(shared_directories)>=2
True
get_shared_directory_path(package)[source]

Returns the share directory path of an installed package

sharedir = get_shared_directory_path("easydev")
gsf(package, datadir, filename)[source]

3.13. progressbar

A progress bar copied and adapted from pyMC code (dec 2014)

class Progress(iters, interval=None)[source]

Generic progress bar for python, IPython, IPython notebook

from easydev import Progress
pb = Progress(100, interval=1)
pb.animate(10)
animate(i)[source]
property elapsed
class TextProgressBar(iterations, printer, width=40, interval=None)[source]

Use Progress

animate(i, dummy=None)[source]
bar(percent)[source]
property elapsed
progbar(i)[source]
progress_bar(iters, interval=None)[source]

A progress bar for Python/IPython/IPython notebook

Parameters:
  • iters (int) – number of iterations (steps in the loop)

  • interval – number of intervals to use to update the progress bar (20 by default)

from easydev import progress_bar
pb = progress_bar(10)
for i in range(1,10):
    import time
    time.sleep(0.1)
    pb.animate(i)

3.14. sphinx themes

Common tools to ease access to a easydev sphinx themes.

get_path_sphinx_themes()[source]

Returns the path where the sphinx themes can be found

>>> from easydev import sphinx_themes
>>> themes_path = sphinx_themes.get_path_sphinx_themes()
get_sphinx_themes()[source]

Returns the sphinx themes found in easydev

>>> from easydev import sphinx_themes
>>> themes = sphinx_themes.get_sphinx_themes()
>>> "standard" in themes
True

3.15. timer

A convenient timer

class Timer(times)[source]

Timer working with with statement

times = []
with Timer(times):
    # do something
    import time
    time.sleep(0.1)
with Timer(imes):
    # do something else
    time.sleep(0.2)

3.16. tools

toolkit to ease development

class AttrDict(**kwargs)[source]

dictionary-like object that exposes its keys as attributes.

When you have dictionary of dictionaries with many levels e.g.:

d = {'a': {'a1': {'a2': 2}}}

to get/set a values, one has to type something like:

d['a']['a1']['a2'] = 3

The AttrDict allows the dictionary to work as attributes:

ad = AttrDict(**d)
ad.a.a1.a2 = 3

You can now add values as attribute, or with [‘key’] syntax

>>> from easydev import AttrDict
>>> a = AttrDict(**{'value': 1})
>>> a.value
1
>>>
>>> a.unit = 'meter'
>>> sorted(a.keys())
['unit', 'value']

If you need to add new simple values after the creation of the instance, just use the setter:

>>> d['newa'] = 2
>>> d.newa = 2  # equivalent to the statement above

but if you want to set a dictionary (whichever recursive level), use the update() method:

>>> d.update({'newd': {'g': {'h':2}}})
>>> d.newd.g.h
2

Note that if you use the setter for a value that is a dictionary, e.g.:

ad.a = {'b':1}

then a is indeed a dictionary.

from_json(filename)[source]

does not remove existing keys put replace them if already present

to_json(filename=None)[source]
update(content)[source]

See class/constructor documentation for details

Parameters:

content (dict) – a valid dictionary

class DevTools[source]

Aggregate of easydev.tools functions.

check_exists(filename)[source]

Raise error message if the file does not exists

check_param_in_list(param, valid_values)[source]

wrapper around easydev.check_param_in_list()

check_range(value, a, b)[source]

wrapper around easydev.check_range()

list2string(query, sep=',', space=False)[source]

see easydev.tools.list2string()

mkdir(dirname)[source]

Create a directory if it does not exists; pass without error otherwise

mkdirs(dirname, mode=511)[source]
shellcmd(cmd, show=False, verbose=False, ignore_errors=False)[source]

See shellcmd()

swapdict(d)[source]

wrapper around easydev.swapdict()

to_json(dictionary)[source]

Transform a dictionary to a json object

to_list(query)[source]

Cast to a list if possible

‘a’ ->[‘a’] 1 -> [1]

checkParam(param, valid_values)[source]

Warning

deprecated since 0.6.10 use check_param_in_list() instead

check_param_in_list(param, valid_values, name=None)[source]

Checks that the value of param is amongst valid

Parameters:
  • param – a parameter to be checked

  • valid_values (list) – a list of values

check_param_in_list(1, [1,2,3])
check_param_in_list(mode, ["on", "off"])
check_range(value, a, b, strict=False)[source]

Check that a value lies in a given range

Parameters:
  • value – value to test

  • a – lower bound

  • b – upper bound

Returns:

nothing

>>> from easydev.tools import check_range
>>> check_range(1,0, 2)
execute(cmd, showcmd=True, verbose=True)[source]

An alias to run system commands using pexpect.

Parameters:
  • cmd

  • showcmd

  • verbose

mkdirs(newdir, mode=511)[source]

Recursive creation of a directory

Source:

matplotlib mkdirs. In addition, handles “path” without slashes

make directory newdir recursively, and set mode. Equivalent to

> mkdir -p NEWDIR
> chmod MODE NEWDIR
precision(data, digit=2)[source]

Round values in a list keeping only N digits precision

>>> precision(2.123)
2.12
>>> precision(2123, digit=-2)
2100
shellcmd(cmd, show=False, verbose=False, ignore_errors=False)[source]

An alias to run system commands with Popen.

Based on subprocess.Popen.

Parameters:
  • cmd (str) – the command to call

  • show (bool) – print the command

  • verbose (bool) – print the output

Returns:

the output as a string

swapdict(dic, check_ambiguity=True)[source]

Swap keys for values in a dictionary

>>> d = {'a':1}
>>> swapdict(d)
{1:'a'}
touch(fname, times=None)[source]

Touch a file (like unix command)

3.17. url

Utilities related to the web

isurl_reachable(url, timeout=10, path='/')[source]

Checks if an URL exists or nor

Parameters:
  • url (str) – the url to look for

  • path (str) – Used in request.request at the url path following the domain name. For instance, www.ensembl.org is the site url but actually we want to check this full url www.ensembl.org/biomart/martview

Returns:

True if it exists

Changed in version 0.9.30.

3.18. multicore

class MultiProcessing(maxcpu=None, verbose=False, progress=True)[source]

Class to run jobs in an asynchronous manner.

You would use this class to run several jobs on a local computer that has several cpus.

t = MultiProcessing(maxcpu=2)
t.add_job(func, func_args)
t.run()
t.results[0] # contain returned object from the function *func*.

Warning

the function must be a function, not a method. This is inherent to multiprocess in the multiprocessing module.

Warning

the order in the results list may not be the same as the list of jobs. see run() for details

Parameters:
  • maxcpu – default returned by multiprocessing.cpu_count()

  • verbose – print the output of each job. Could be very verbose so we advice to keep it False.

  • progress – shows the progress

add_job(func, *args, **kargs)[source]

add a job in the pool

reset()[source]

remove joves and results

run(delay=0.1, verbose=True)[source]

Run all the jobs in the Pool until all have finished.

Jobs that have been added to the job list in add_job() are now processed in this method by using a Pool. Here, we add all jobs using the apply_async method from multiprocess module.

In order to ensure that the jobs are run sequentially in the same order as in jobs, we introduce a delay between 2 calls to apply_async (see http://docs.python.org/2/library/multiprocessing.html)

A better way may be t use a Manager but for now, this works.