Package: secretsanta
secretsantaThis repository implements a basic Python version of aSecret Santautility. It is meant to serve as a tutorial for beginners interested in Python package development.
Each section below mentions typical tools and utilities in a natural order of developing Python packages.Table of ContentsDevelopmenta.Virtual environmentsb.Project requirementsTestinga.PyCharm file typesb.Type hintsc.Property testingd.Mocks in unit testsDocumentationUsage / Jupyter notebookContinuous IntegrationMiscellaneousDevelopmentWe assumePyCharmonUbuntu >= 16.04as the development environment.In PyCharm, check out this repository into a new project, e.g. underVCS > Checkout from Version ControlShell commands below should be entered in theTerminalpane of PyCharm.There is no shortcut in PyCharm to send code from the editor to the terminal, so you need to copy-paste commands instead.Virtual environmentsWe'll use a virtual environment to keep things neat and tidy.A couple of useful references about virtual environments if you've never used them before:Virtual environmentsCreating virtual environmentsInstall support for virtual environments with Python 3.x if you don't have it yet:sudoapt-getinstallpython3-venvConfigure the PyCharm project with a Python 3 virtual environment underFile > Settings > Project > Project interpreterClick on the top-rightgearicon and selectAdd..., then create a newVirtualenv Environment, using<PROJECT_PATH>/venvas location and Python 3.x as interpreter. Also un-tick all checkboxes.We do not usepipenvhere. You may however use it to create a new environmentin the same way.With these settings, anything you execute within the PyCharm project, either at the Terminal or in the Python Console,
will run in the virtual environment. Close and re-open PyCharm to make sure the settings are picked up.Note that you can still temporarily leave the virtual environment from an active Terminal usingdeactivateand re-activate it usingsource./venv/bin/activateYou can also switch to a different project interpreter in PyCharm (Ctrl + Shift + A, search forSwitch Project Interpreter).
Open terminals and Python consoles then need to be restarted for the environment to match the project interpreter.Project requirementsThe project includes filesrequirements.inandrequirements-package.in, defining module / package dependencies.
Such files are compiled into an actualrequirements.txtfile,
which is not committed to Git and should be re-created for the local checkout.Important:make sure all commands are executed inside the virtual environment, e.g. at such a prompt:#> (venv) localuser@Ubuntu:~/PyCharm/secretsanta$Check version of Python, upgradepipand check its version:python--version#> Python 3.6.7pipinstall--upgradepip#> ...pip--version#> pip 19.1.1 from /home/localuser/PyCharm/secretsanta/venv/lib/python3.5/site-packages/pip (python 3.6)Installpip-tools:pipinstallpip-toolsList installed modules:pip list
#> Package       Version
#> ------------- -------
#> Click         7.0    
#> pip           18.1   
#> pip-tools     3.1.0  
#> pkg-resources 0.0.0  
#> setuptools    20.7.0 
#> six           1.11.0Re-generaterequirements.txtfromrequirements.in:pip-compileInstall dependencies defined inrequirements.txt:pip-syncAlternatively, you can right-click on thesecretsantaproject folder in theProjectexplorer and clickSynchronize 'secretsanta'to refresh and see the generated filerequirements.txt.Now you're ready to go. Would there be any update to therequirements.infiles,
make sure you re-executepip-compileandpip-sync.If you change the virtual environment you work with, you should instead runpip-compile -U(then
rerunpip-sync) to make sure that compatible versions of your dependencies are used in the new environment.TestingThere are multiple ways to define and execute tests. Two of the most common ones aredoctestandunittest.Thedoctestmodule allows to run code examples / tests that are defined as part ofdocstrings.Use the following command to see this in action. The-vflag allows us to see verbose output.
In case everything is fine, we would not see any output otherwise.python -m doctest secretsanta/main/core.py -vIt is possible to run code style checks withflake8:flake8If all is fine, you will not see any output.Unit tests are kept undertestsand make use of theunittestframework.Run tests usingtox:toxThetox.inifile contains the following configurations:flake8(checks code style and reports potential issues)pytest(which is used as a test runner)pytest-cov(measures and reports test coverage, see also.coveragercfile)tox(where the Python versions to test with are defined)If you runtoxoutside of the virtual environment, it can run tests for multiple Python versions - this is configured
usingenvlist.The tests will only be run for any Python version that is available in the environment where you run them
(seeskip_missing_interpretersconfiguration key).PyCharm file typesIn PyCharm, you can associate files to a certain type under:File > Settings > Editor > File TypesE.g. use this to get.coveragercmarked up asINI(you can do this after installing the .ini support PyCharm plugin).
Alternatively, you can register the*.iniand.coveragercpatterns to theexistingBuildout Configfile type.Type hintsType hints define what type function arguments and return values should be. They are both a source of documentation
and testing framework to identify bugs more easily, see alsoPEP 484.In order to use them, installmypy(outside of a virtual environment):sudo apt install mypyThen run e.g.:mypy ./secretsanta/main/core.pyto test if the type hints of.pyfile(s) are correct (in which case there may be no output).Property testingWe useHypothesisto define aproperty testfor our matching function:
generated example inputs are tested against desired properties. Hypothesis' generator can be configured to produce typical
data structures, filled with various instances of primitive types. This is done by composing specific annotations.The decorator@given(...)must be present before the test function that shall use generated input.Generated arguments are defined in a comma-separated list, and will be passed to the test function in order:fromhypothesisimportgivenfromhypothesis.strategiesimporttext,integers@given(text(),integers())deftest_some_thing(a_string,an_int):returnGeneration can be controlled by various optional parameters, e.g.text(min_size=2)for testing with strings that
have at least 2 characters.Mocks in unit testsMock objects are used to avoid external side effects. We use the standard Python packageunittest.mock. This provides
a@patchdecorator, which allows us to specify classes to be mocked within the scope of a given test case. Seetest_funs.pyandtest_core.pyfor examples.DocumentationDocumentation is done usingSphinx.Prerequisite: Installation. Open a terminal (outside of a virtual environment) and run below command:sudo apt-get install python3-sphinxCheck installation (and version):sphinx-build --versionInitializing documentation - already done - for reference:sphinx-quickstartThis will lead through an interactive generation process.Suggested values / options are listed here.
Hitting enter without typing anything will take the suggested default shown inside square brackets [ ].Root path for the documentation: docsSeparate source and build directories: ySource file suffix: .rstSphinx extensions: autodoc, doctest, intersphinx, coverage, mathjax, viewcodeCreate Makefile: yIn order to useautodoc, one needs to uncomment the corresponding line indocs/source/conf.py:sys.path.insert(0, os.path.abspath(...And set the appropriate path to the directory containing the modules to be documented.For Sphinx/autodoc to work, the docstrings must be written in correctreStructuredText,
seedocumentationfor details.Building docsYou should be inside the documentation root directory.Using the Makefile:cddocs
makehtmlYou can view the documentation by right-click openingindex.html(docs/build/html) in your browser of choice.
Previewing the .rst files does not work properly in PyCharm, apparently becauseit only supports a subset of Sphinx.Alternative build without Makefile:sphinx-build-bhtml<sourcedir><builddir>PDF output:makelatexpdfUsageTheJupyternotebookSecretSanta.ipynbillustrates the usage of thesecretsantapackage.It can be run in your browser (or directly in PyCharm if you have the professional edition):jupyternotebookSecretSanta.ipynbBelow gives you some useful information about the location ofJupyterrelated directories, e.g. configuration:jupyter--pathA few additional links to some typical earlyJupytertopics:Closing running Jupyter notebook serversCheckpoints and autosaveContinuous IntegrationContinuous Integration (CI) aims to keep state updated to always match the code currently checked in a repository.
This typically includes a build, automated test runs, and possibly making sure that the newly built artifacts are
deployed to a target environment. This helps developers and users by providing timely feedback and showing what the
results of certain checks were on a given version of the code.This repository usesTravis CIto run tests automatically when new commits are pushed. Results
can be viewedhere. Along with test results,
coverage information is generated and uploaded tocodecov, which generates areportout of it.ConfigurationTravis CI is configured using the.travis.ymlfile. This allows specifying the environment(s) to run
tests in; tests will be run for each specified environment. The steps required before running tests are specified underinstall. Finally, the task to run is defined inscript, and we make sure coverage reports are uploaded (seeafter_success). A notification about completed builds is sent to our Slack channel using asecure notification hook.Codecov is configured incodecov.yml, defining the coverage value range (in percent) to match to a color scale, as
well as the coverage checks to be performed and their success criteria. See codecov'sgeneral configurationandcommit status evaluationdocumentation for more information.Notifications from codecov can only be delivered via unencrypted webhook URLs. In order to avoid exposing such hooks in
a public repository, we do not use this functionality here.MiscellaneousMANIFEST.inspecifies extra files that shall be included in a source distribution.Badges: This README features various badges (at the beginning), including a build status badge and a code coverage
status badge.