FlowFX

Install an extra LaTeX font package on PythonAnywhere

This week I installed a LaTeX font package in my PythonAnywhere account. The TL;DR: just install it manually.


I've been using LaTeX on and off for more than 10 years now. But I never dove into the depths of the system, typesetting mathematical expressions was fun enough for me.

So I rely on Google a good bit. But that's fine, as there are always new things to discover. Plus: the PythonAnywere support is superb! I had a very helpful email exchange with Giles. Thanks!

Using the TeXLive distribution on my Mac, and on the Ubuntu server that runs PythonAnywhere, the way to install packages nowadays is to use the tlmgr command, which I can only assume to be an abbreviation for TeX Live manager.

$ tlmgr install roboto

Well, that didn't work, because I am not root nor sudo. Turns out, there is a tlmgr User Mode which, after initializing a local user tree

$ tlmgr init-usertree

allows me to install additional LaTeX packages into my home directory under ~/texmf. So:

$ tlmgr --usermode install roboto

should have done it. Unfortunately I got the following error message.

$ tlmgr --usermode install roboto
/usr/bin/tlmgr: could not find a usable xzdec.
/usr/bin/tlmgr: Please install xzdec and try again.

Thanks to Giles, it was easy to install the missing xz package.

$ wget https://tukaani.org/xz/xz-5.2.3.tar.gz
$ tar xf xz-5.2.3.tar.gz 
$ cd xz-5.2.3/
$ ./configure --prefix=$HOME/.local
$ make
$ make install

That actually worked. But then tlmgr spit out this:

Unknown directive ...containerchecksum
06c8c1fff8b025f6f55f8629af6e41a6dd695e13bbdfe8b78b678e9cb0cfa509826355f4ece20d8a99b49bcee3c5931b8d766f0fc3dae0d6a645303d487600b0..., please fix it! at /usr/share/texlive/tlpkg/TeXLive/TLPOBJ.pm line 210, <$retfh> line 5761.

This is a clear case for Google, and Google didn't disappoint. The installed version of Tex Live is from 2013 and doesn't work with the current package repositories.

$ tlmgr --version
(running on Debian, switching to user mode!)
tlmgr revision 32912 (2014-02-08 00:49:53 +0100)
tlmgr using installation: /usr/share/texlive
TeX Live (http://tug.org/texlive) version 2013

After setting the repository to an old archived one,

$ tlmgr option repository ftp://tug.org/historic/systems/texlive/2013/tlnet-final

the TeX Live installation was happy.

But, it turns out, the 2013 repository doesn't even include the roboto font package. So…

TL;DR

… in the end, I installed the font by hand, following the instructions here: http://www.ctan.org/tex-archive/fonts/roboto/.

$ wget http://mirror.ctan.org/install/fonts/roboto.tds.zip
$ cd ~/texmf
$ unzip ~/roboto.tds.zip
$ texhash
$ updmap --enable Map=roboto.map

And now I have the roboto font available for pdflatex on PythonAnywhere!

How to test django template tags

Testing django template tags by Krzysztof Żuraw.

Populate your Django test database with pytest fixtures

I'm working on a side project that uses data from an external API. For performance reasons I store this data in a local database. But when running pytest, all my tests always start with a clean database. That's not good, as I need the data to run many of the tests, and adding it from the API is very time consuming.

Of course, Django has a solution for this, confusingly called fixtures, and pytest has a way to use Django fixtures in a custom pytest fixture to populate the database with initial test data.

Because it took me a while to find this, I document it here. It works like this:

Dump the data

Using Django's own dumpdata management command, you dump all or selected tables from your local database into a JSON file in a subfolder of the app named fixtures. My Django app is called potatoes, and I want the data for my two models Potato and SturdyPotato.

$ ./manage.py dumpdata potatoes.Potato potatoes.SturdyPotato -o potatoes/fixtures/potatoes_data.json

Load the data

The corresponding loaddata command can be used with pytest's django_db_setup fixture to load the data into the test database.

# tests/conftest.py

import pytest

from django.core.management import call_command

@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        call_command('loaddata', 'potatoes_data.json')

Use pytest fixture

Now, in every test that needs it, I use this session-scoped fixture, and the test data is available.

# tests/test_models.py

def test_my_potatoes(db, django_db_setup):
    # GIVEN a full database of potatoes, as provided by the django_db_setup fixture
    all_my_potatoes = Potato.objects.all()

The Cat Empire live at Lowlands festival 2014

Hach…

Disable Django/Python logging with pytest fixture

Yesterday, I added Sentry error tracking to my Django app, and configured it to register every log entry with level INFO and above. Now, everytime I ran my test suite, there were events logged with Sentry that I didn't really care about. Naturally, I wanted to disable the default logging behavior for tests.

StackOverflow, naturally, provides part of the answer:

logging.disable(logging.CRITICAL)

will disable all logging calls with levels less severe than or equal to CRITICAL.

(http://stackoverflow.com/a/5255760)

But how to run this on every test? Pytest to the rescue! I use an autouse fixture:

  • if an autouse fixture is defined in a conftest.py file then all tests in all test modules below its directory will invoke the fixture.

And this is what I put into my conftest.py files:

@pytest.fixture(autouse=True)
def disable_logging():
    """Disable logging in all tests."""
    logging.disable(logging.INFO)

That's it. Love it!