Package: fades
What is fades?fades is a system that automatically handles the virtualenvs in the
cases normally found when writing scripts and simple programs, and
even helps to administer big projects.fadeswill automagically create a new virtualenv (or reuse a previous
created one), installing the necessary dependencies, and execute
your script inside that virtualenv, with the only requirement
of executing the script withfadesand also marking the required
dependencies.(If you don’t have a clue why this is necessary or useful, I’d recommend you
to read this small text aboutPython and the Management of Dependencies.)The first non-option parameter (if any) would be then the child program
to execute, and any other parameters after that are passed as is to that
child script.fadescan also be executed without passing a child script to execute:
in this mode it will open a Python interactive interpreter inside the
created/reused virtualenv (taking dependencies from--dependencyor--requirementoptions).ContentsWhat is fades?How to use it?Yes, please, I want to readHow to execute the script with fades?How to mark the dependencies to be installed?What if no script is given to execute?Other ways to specify dependenciesAbout different repositoriesHow to control the virtualenv creation and usage?Running programs in the context of the virtualenvHow to deal with packages that are upgraded in PyPIWhat about pinning dependencies?Under the hood optionsSetting options using config filesHow to clean up old virtualenvs?Some command line examplesSome examples using fades in project scriptsWhat if Python is updated in my system?How to install itSimplest wayDependenciesFor others debian and ubuntuUsing pip if you wantMultiplatform tarballCan I try it without installing it?What about Windows?Get some help, give some feedbackHow to develop fades itselfGetting the codeInstall dependenciesHow to run the testsDevelopment processHow to use it?Click in the following image to see a video/screencast that shows most of
fades features in just 5’……or inspectthese several small GIFsthat
show each a particularfadesfunctionality, but please keep also reading
for more detailed information…Yes, please, I want to readWhen you write an script, you have to take two special measures:need to execute it withfades(notpython)need to mark those dependenciesAt the moment you execute the script, fades will search a
virtualenv with the marked dependencies, if it doesn’t exists
fades will create it, and execute the script in that environment.How to execute the script with fades?You can always call your script directly with fades:fades myscript.pyHowever, for you to not forget about fades and to not execute it
directly with python, it’s better if you put at the beggining of
the script the indication for the operating system that it should
be executed with fades…#!/usr/bin/env fades…and also set the executable bit in the script:chmod +x yourscript.pyYou can also execute scripts directly from the web, passing directly the
URL of the pastebin where the script is pasted (most common pastebines are
supported, pastebin.com, gist, linkode.org, but also it’s supported if
the URL points to the script directly):fades http://myserver.com/myscript.pyHow to mark the dependencies to be installed?The procedure to mark a module imported by the script as adependency
to be installed by fadesis by using a comment.This comment will normally be in the same line of the import (recommended,
less confusing and less error prone in the future), but it also can be in
the previous one.The simplest comment is like:import somemodule   # fades
from somepackage import othermodule    # fadesThefadesis mandatory, in this examples the repository is PyPI,
seeAbout different repositoriesbelow for other examples.With that comment,fadeswill install automatically in the virtualenv thesomemoduleorsomepackagefrom PyPI.Also, you can indicate a particular version condition, examples:import somemodule   # fades == 3
import somemodule   # fades >= 2.1
import somemodule   # fades >=2.1,<2.8,!=2.6.5Sometimes, the project itself doesn’t match the name of the module; in
these cases you can specify the project name (optionally, before the
version):import bs4   # fades beautifulsoup4
import bs4   # fades beautifulsoup4 == 4.2What if no script is given to execute?If no script or program is passed to execute,fadeswill provide a virtualenv
with all the indicated dependencies, and then open an interactive interpreter
in the context of that virtualenv.Here is where it comes very handy the-i/--ipythonoption, if that REPL
is preferred over the standard one.In the case of using an interactive interpreter, it’s also very useful to
makefadesto automatically import all the indicated dependencies,
passing the--autoimportparameter.Other ways to specify dependenciesApart of marking the imports in the source file, there are other ways
to tellfadeswhich dependencies to install in the virtualenv.One way is through command line, passing the--dependencyparameter.
This option can be specified multiple times (once per dependency), and
each time the format isrepository::dependency. The dependency may
have versions specifications, and the repository is optional (defaults
to ‘pypi’).Another way is to specify the dependencies in a text file, one dependency
per line, with each line having the format previously described for
the--dependencyparameter. This file is then indicated to fades
through the--requirementparameter. This option can be specified
multiple times.In case of multiple definitions of the same dependency, command line
overrides everything else, and requirements file overrides what is
specified in the source code.Finally, you can include package names in the script docstring, after
a line where “fades” is written, until the end of the docstring;
for example:"""Script to do stuff.

It's a very important script.

We need some dependencies to run ok, installed by fades:
    request
    otherpackage
"""About different repositoriesfadessupports installing the required dependencies from multiples repositories: besides PyPI, you can specify URLs that can point to projects from GitHub, Launchpad, etc. (basically, everything that is supported bypipitself).When a dependency is specified,fadesdeduces the proper repository. For example, in the following examplesfadeswill install requests from the latest revision from PyPI in the first case, and in the second case the latest revision from the project itself from GitHub:-d requests
-d git+https://github.com/kennethreitz/requests.git#egg=requestsIf you prefer, you can be explicit about which kind of repositoryfadesshould use, prefixing the dependency with the special token double colon (::):-d pypi::requests
-d vcs::git+https://github.com/kennethreitz/requests.git#egg=requestsThere are two basic repositories:pypiwhich will makefadesto install the desired dependency from PyPI, andvcs, which will makefadesto treat the dependency as a URL for a version control system site. In the first case, for PyPI, a full range of version comparators can be specified, as usual. Forvcsrepositories, though, the comparison is always exact: if the very same dependency is specified, avirtualenvis reused, otherwise a new one will be created and populated.In both cases (specifying the repository explicitly or implicitly) there is no difference if the dependency is specified in the command line, in arequirements.txtfile, in the script’s docstring, etc.  In the case of marking theimportdirectly in the script, it slightly different.When marking theimportit normally happens that the package itself to be installed has the name of the imported module, and because of that it can only be found in PyPI. So, in the following cases thepypirepository is not only deduced, but unavoidable:import requests  # fades
from foo import bar  # fades
import requests  # fades <= 3But if the package is specified (normally needed because it’s different than the module name), or if a version control system URL is specified, the same possibilities stated above are available: letfadesto deduce the proper repository or mark it explicitly:import bs4  # fades beautifulsoup
import bs4  # fades pypi::beautifulsoup
import requests  # fades git+https://github.com/kennethreitz/requests.git#egg=requests
import requests  # fades vcs::git+https://github.com/kennethreitz/requests.git#egg=requestsOne last detail about thevcsrepository: the format to write the URLs is the same (as it’s passed without modifications) than whatpipitself supports (seepip docsfor more details).Furthermore, you can install from local projects. It’s just fine to use a
dependency that starts withfile:. E.g. (please note the triple slash,
because we’re mixing the protocol indication with the path):fades -d file:///home/crazyuser/myproject/allstars/How to control the virtualenv creation and usage?You can influence several details of all the virtualenv related process.The most important detail is which version of Python will be used in
the virtualenv. Of course, the corresponding version of Python needs to
be installed in your system, but you can control exactly which one to use.No matter which way you’re executing the script (see above), you can
pass a-por--pythonargument, indicating the Python version to
be used just with the number (2.7), the whole name (python2.7) or
the whole path (/usr/bin/python2.7).Other detail is the verbosity offadeswhen telling what is doing. By
default,fadesonly will use stderr to tell if a virtualenv is being
created, and to let the user know that is doing an operation that
requires an active network connection (e.g. installing a new dependency).If you callfadeswith-vor--verbose, it will send all internal
debugging lines to stderr, which may be very useful if any problem arises.
On the other hand if you pass the-qor--quietparameter,fadeswill not show anything (unless it has a real problem), so the original
script stderr is not polluted at all.If you want to use IPython shell you need to callfadeswith-ior--ipythonoption. This option will add IPython as a dependency tofadesand it will launch this shell instead of the python one.You can also use--system-site-packagesto create a venv with access to
the system libs.Finally, no matter how the virtualenv was created, you can always get the
base directory of the virtualenv in your system using the--get-venv-diroption.Running programs in the context of the virtualenvThe-x/--execparameter allows you to execute any program (not just
a Python one) in the context of the virtualenv.By default the mandatory given argument is considered the executable
name, relative to the virtualenv’sbindirectory, so this is
specially useful to execute installed scripts/program by the declared
dependencies. E.g.:fades -d flake8 -x flake8 my_script_to_be_verified_by_flake8.pyTake in consideration that you can pass an absolute path and it will be
respected (but not a relative path, as it will depend of the virtualenv
location).For example, if you want to run a shell script that in turn runs a Python
program that needs to be executed in the context of the virtualenv, you
can do the following:fades -r requirements.txt --exec /var/lib/foobar/special.shFinally, if the intended code to run is prepared to be executed as a module
(what you would normally run aspython3 -m some_module), you can
use the same parameter withfadesto run that module inside the virtualenv:fades -r requirements.txt -m some_moduleHow to deal with packages that are upgraded in PyPIWhen you tellfadesto create a virtualenv using one dependency and
don’t specify a version, it will install the latest one from PyPI.For example, you dofades-dfoobarand it installs foobar in
version 7. At some point, there is a new version of foobar in PyPI,
version 8, but if dofades-dfoobarit will just reuse previously
created virtualenv, with version 7, not downloading the new version and
creating a new virtualenv with it!You can tell fades to do otherwise, just do:fades -d foobar --check-updates…andfadeswill search updates for the package on PyPI, and as it will
found version 8, will create a new virtualenv using the latest version.From this moment on, if you requestfades-dfoobarit will bring the
virtualenv with the new version. If you want to get a virtualenv with
not-the-latest version for any dependency, just specify the proper versions.You can even use the--check-updatesparameter when specifying the package
version. Say you callfades-dfoobar==7,fadeswill install version 7 no
matter which one is the latest. But if you do:fades -d foobar==7 --check-updates…it will still use version 7, but will inform you that a new version
is available!What about pinning dependencies?One nice benefit offadesis that every time dependencies change in your
project, you actually get to use a new virtualenv automatically.If you don’t pin the dependencies in your requirements file, this has
another nice side effect: everytime you use them in a new environment (or
if you have–check-updatesset) you will get latest versions, effectively
avoiding the trap of sticking in old versions forever.However, this has a bad side. If it happens that a dependency of your
project released a revision between the moment you run the tests and the
moment your project is deployed to the server, it may happen that you
actually put in production an untested combination. Furthermore, it may
happen that even if you do pin your dependencies, the dependencies of
those dependencies may not be pinned, and you get into the same situation.For example, you may have therequests == 2.19.1dependency, butrequestsdeclares its own dependencies, for examplechardet >= 3.0.2, and when running tests locally you may getchardetin version3.0.3, but nothing guarantees you that when deploying your
project to a server (effectively building everything from scratch) you will
not get a newer version ofchardet, which may be totally fine but in fact
it’s something that you did NOT test locally.Here is wherefadescomes to the rescue with the--freezeoption. If
this parameter is given,fadeswill operate exactly as it normally would,
but also will dump the result ofpip freezeinto the specified file.So to continue with the example above, you could run your tests like:fades -d "requests == 2.19.1" --freeze=reqs-frozen.txt -x python3 -m unittest…which will leave youreqs-frozen.txtwith a content similar to:certifi==2018.4.16
chardet==3.0.4
pip==18.0
requests==2.19.1
...And then you could usethat filefor deployment, which hasall packagespinned, so you will get exactly what you was expecting.Under the hood optionsFor particular use cases you can send specifics arguments tovirtualenv,pipandpython. using the--virtuaenv-options,--pip-optionsand--python-optionsrespectively. You have to use that argument for each argument
sent.Examples:fades-drequests--virtualenv-options="--always-copy"--virtualenv-options="--extra-search-dir=/tmp"fades-drequests--pip-options="--index-url='http://example.com'"fades--python-options=-Bfoo.pySetting options using config filesYou can also configure fades using.iniconfig files. fades will search config files in/etc/fades/fades.ini, the path indicated byxdgfor your system
(for example~/config/fades/fades.ini) and.fades.ini.So you can have different settings at system, user and project level.With fades installed you can get your config dir running:python -c "from fades.helpers import get_confdir; print(get_confdir())"The config files are in.iniformat. (configparser) and fades will search for a[fades]section.You have to use the same configurations that in the CLI. The only difference is with the config
options with a dash, it has to be replaced with a underscore.:[fades]
ipython=true
verbose=true
python=python3
check_updates=true
dependency=requests;django>=1.8  # separated by semicolonThere is a little difference in how fades handle these settings: “dependency”, “pip-options” and
“virtualenv-options”. In these cases you have to use a semicolon separated list.The most important thing is that these options will be merged. So if you configure in/etc/fades/fades.ini“dependency=requests” you will have requests in all the virtualenvs
created by fades.How to clean up old virtualenvs?When usingfadesvirtual environments are something you should not have to think about.fadeswill do the right thing and create a new virtualenv that matches the required
dependencies. There are cases however when you’ll want to do some clean up to remove
unnecessary virtual environments from disk.By runningfadeswith the--rmargument,fadeswill remove the
virtualenv matching the provided UUID if such a virtualenv exists (one easy
way to find out the virtualenv’s UUID is callingfadeswith the--get-venv-diroption.Another way to clean up the cache is to remove all venvs that haven’t been used for some time.
In order to do this you need to callfadeswith--clean-unused-venvs.
When fades it’s called with this option, it runs in mantain mode, this means that fades will exit
after finished this task.
All virtualenvs that haven’t been used for more days than the value indicated in param will be
removed.It is recommended to have some automatically way of run this option;
ie, add a cron task that perform this command:fades --clean-unused-venvs=42Some command line examplesExecutefoo.pyunderfades, passing the--barparameter to the child program, in a virtualenv with the dependencies indicated in the source code:fades foo.py --barExecutefoo.pyunderfades, showing all thefadesmessages (verbose mode):fades -v foo.pyExecutefoo.pyunderfades(passing the--barparameter to it), in a virtualenv with the dependencies indicated in the source code and alsodependency1anddependency2(any version > 3.2):fades -d dependency1 -d "dependency2>3.2" foo.py --barExecute the Python interactive interpreter in a virtualenv withdependency1installed:fades -d dependency1Execute the Python interactive interpreter in a virtualenv after installing there all dependencies taken from therequirements.txtfile:fades -r requirements.txtExecute the Python interactive interpreter in a virtualenv after installing there all dependencies taken from filesrequirements.txtandrequirements_devel.txt:fades -r requirements.txt -r requirements_devel.txtUse thedjango-admin.pyscript to start a new project namedfoo, without having to have django previously installed:fades -d django -x django-admin.py startproject fooRemove a virtualenv matching the given uuid from disk and cache index:fades --rm 89a2bf83-c280-4918-a78d-c35506efd69dDownload the script from the given pastebin and executes it (previously building a virtualenv for the dependencies indicated in that pastebin, of course):fades http://linkode.org/#4QI4TrPlGf1gK2V7jPBC47Run all the tests in a project (runningpytestdirectly as a module, for better behaviour) and at the same time freeze dependencies for later deployment:fades -r requirements.txt --freeze -m pytest -vSome examples using fades in project scriptsIncludingfadesin project helper scripts makes it easy to stop
worrying about the virtualenv activation/deactivation when working
in that project, and also solves the problem of needing to
update/change/fix an already created virtualenv if the
dependencies change.This is an example of how a script to run your project may look like:#!/bin/sh
if (command -v fades > /dev/null)
then
    # fades FTW!
    fades -r requirements.txt bin/start
else
    echo 2
    # hope you are in the correct virtualenv
    python3 bin/start
fiTo run the tests, it’s super handy to have a script that also takes care
of the development dependencies:#!/bin/sh
fades -r requirements.txt -r reqs-dev.txt -x python -m pytest -s "$@"What if Python is updated in my system?The virtualenvs created by fades depend on the Python version used to
create them, considering its major and minor version.This means that if run fades with a Python version and then run it again
with a different Python version, it may need to create a new virtualenv.Let’s see some examples. Let’s say you run fades withpython, which
is a symlink in your/usr/bin/topython3.4(running it directly
by hand or because fades is installed to use that Python version).If you have Python 3.4.2 installed in your system, and it’s upgraded to
Python 3.4.3, fades will keep reusing the already created virtualenvs, as
only the micro version changed, not minor or major.But if Python 3.5 is installed in your system, and the defaultpythonis pointed to this new one, fades will start creating all the
virtualenvs again, with this new version.This is a good thing, because you want that the dependencies installed
with one specific Python in the virtualenv are kept being used by the
same Python version.However, if you want to avoid this behaviour, be sure to always call fades
with the specific Python version (/usr/bin/python3.4orpython3.4,
for example), so it won’t matter if a new version is available in the
system.How to install itSeveral instructions to installfadesin different platforms.Simplest wayIn some systems you can installfadesdirectly, no needing to
install previously any dependency.If you are in debian unstable or testing, just do:sudo apt-get install fadesFor Arch Linux, you can install it from theAURusing anyAUR helper, e.g. withpikaur:pikaur -S fadesIn systems with Snaps:snap install fades –classic(why–classic? Because it’s the only way thatfadescould, from
inside the snap, access the rest of the system in case you want to
use a different Python version, or a dependency that needs
compilation, etc).For Mac OS X (andHomebrew):brew install fadesElse, keep reading to know how to install the dependencies first, andfadesin your system next.DependenciesBesides needing Python 3.3 or greater, fades depends also on thepkg_resourcespackage, that comes in withsetuptools.
It’s installed almost everywhere, but in any case,
you can install it in Ubuntu/Debian with:apt-get install python3-setuptoolsAnd on Arch Linux with:pacman -S python-setuptoolsIt also depends onpython-xdgpackage. This package should be
installed on any GNU/Linux OS wiht a freedesktop.org GUI. However it
is anoptionaldependency.You can install it in Ubuntu/Debian with:apt-get install python3-xdgAnd on Arch Linux with:pacman -S python-xdgFades also needs thevirtualenvpackage to support different Python versions for child execution. (see the--pythonoption.)For others debian and ubuntuIf you are NOT in debian unstable or testing (if you are, see
above for better instructions), you can use this.deb.Download it and install doing:sudo dpkg -i fades_*.debUsing pip if you wantpip3 install fadesMultiplatform tarballFinally you can always get the multiplatform tarball and install
it in the old fashion way:wget http://ftp.debian.org/debian/pool/main/f/fades/fades_9.0.1.orig.tar.gz
tar -xf fades_*.tar.gz
cd fades-*
sudo ./setup.py installCan I try it without installing it?Yes! Branch the project and use the executable:git clone https://github.com/PyAr/fades.git
cd fades
bin/fades your_script.pyWhat about Windows?Windows is a platform supported by fades.However, we don’t have a proper Windows installer (a.exeor.msi), but you can install it usingpip, or from the tarball,
or try it directly from the project. All these options are properly
described above.Wedowant to have a Windows installer. If you can help us in this
regard, please contact us. Also we would want a Travis running in
Windows so that GitHub runs all the tests in this platform too before
landing any code. Thanks!Get some help, give some feedbackYou can ask any question or send any recommendation or request to
themailing list.Come chat with us on IRC. The #fades channel is located at theFreenodenetwork.Also, you can open an issuehere(please do if you
find any problem!).Thanks in advance for your time.How to develop fades itselfQuick guide to get you up and running in fades development.Getting the codeClone the project:git clone git@github.com:PyAr/fades.gitInstall dependenciesfadesmanages it’s own dependencies, so there is nothing extra you need to install.To try it, just do:bin/fades -VHow to run the testsWhen starting development, at all times, and specially before wrapping up
a new branch, you need to be sure that all tests pass ok.This is very simple, actually, just run:./testThat will not only check test cases, but also that the code complies with
aesthetic recommendations, and that the README document has a proper format.If you want to runoneparticular test, just specify it. Example:./test tests.test_main:DepsMergingTestCase.test_two_differentDevelopment processJust pick an issue fromthe list.Develop, assure./testis happy, commit, push, create a pull request, etc.Please, if you aim for creating a Pull Request with new code (functionality
or fixes), include tests for your changes.Thanks! Enjoy.