Product at Otovo 🏗


How we created the most elegant MLOps tool

I wanted to write about this topic for a while but struggled to frame it correctly. And finally, I landed on just telling the origin story, with some of its invisible sub-stories. So grab a coffee, and let’s start on how I created the most elegant MLOps tool.

Read more...

On Seniority For Software Engineers at Otovo

What makes a great senior engineer? This post explains how we look at that at Otovo.

Read more...

That post with the first year learnings from a PM

Hi, I’m Ida, the product manager (PM) on the Product Platform team. In this post I’ll share three things I learned during my first year as a PM at Otovo – the energy company of the future!

First things first: Yes the people are great. All super competent, engaged and lovely! Otovo does not hire a**holes. Now to business:

Read more...

Using pytest in a Django application

At Otovo, one of our core software systems is a Django application written in Python. For a large codebase, unit tests is an integral part. This is especially true for a large Python application, as there is no compiler to help you out (even though type annotations and mypy do help).

Read more...

Staying close to users when they’re all over the place

In this post, I summarise some reflections on managing a product which is scaling to new markets, and on trying to stay close to the users as the pool grows and diversifies.

Read more...

Why we ditched our BFF and went for Next.js

At Otovo, we’ve been using the last couple of home office months to do some technical improvements: Tailwind, Django 3.0, Vercel, and Next has been on our radar for a while. In this article, I’ll let you know why the latter made us ditch our BFF.

Best friend you say? If you, like me, grew up in the 90s, the term BFF has probably only one meaning in your head: Best Friends Forever. In the last couple of years however, the microservice community has put an effort into claiming and rebranding this term as Backend For Frontend.

Read more...

Using PostgreSQL 10 with PostGIS on Travis CI

Today I needed to fix our Travis CI setup to use PostgreSQL to ensure we run the same version of PostgreSQL in production as well as in our test suite.

Travis provides all PostgreSQL versions that are available in the PostgreSQL official APT repository, so we had the packages we needed.

But, the documentation is a bit lacking, as the packages and setup differs slightly from the default 9.6 database Travis CI provides you with.

So here is the step-by-step guide to running PostgreSQL 10 with PostGIS 2.4 on Travis.

Read more...

Migrating connected Django models to a different type of primary key

Sometimes, old design decisions comes back to bite you. This is one of those tales.

A project I’m working on had a Django model similar to this:

class Municipality(models.Model):
    code = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=100)

and it was used by other models such as:

class ZipCode(models.Model):
    code = models.CharField(max_length=4, primary_key=True)
    municipality = models.ForeignKey(Municipality)

And all was good, until we needed to expand the municipality model to support different countries, and thus a single unique field with only the code - which may collide across countries, was not enough.

For all the modern parts of the code base we use UUIDs as the primary key, so we wanted to migrate the primary key of Municipality to a UUID, while retaining all the relations.

As of September 2017, Django does not support migrating primary keys in any nice manner, so we’re on our own here.

We tried a lot of magic solutions, but we always got stuck with the migrations system not being able to detect and handle the changes nicely.

After some research and quite a bit of trial and error, we settled on the following approach. It has some drawbacks I’ll get back to, but works reasonable well.

Read more...

netsgiro: a parser and builder for AvtaleGiro and OCR Giro files

Today I released the first stable release of netsgiro to PyPI. netsgiro is a Python 3.4+ library for parsing and building Nets “OCR” files.

AvtaleGiro is a direct debit solution that is in widespread use in Norway, with more than 15 000 companies offering it to their customers. OCR Giro is used by Nets and Norwegian banks to update payees on recent deposits to their bank accounts. In combination, AvtaleGiro and OCR Giro allows for a high level of automation of invoicing and payment processing.

The “OCR” file format and file format name originates in days when giro payments were delivered on paper to your bank and then processed either manually or using optical character recognition, OCR. I’m not sure how old the format is, but some of the examples in the OCR Giro specification use dates in 1993, and the specification changelog starts in 1999 and ends in 2003. A couple of decades later, the file format is still in daily use by Nets’ AvtaleGiro and OCR Giro services. In other words, I have high hopes that this will be a very stable open source project requiring minimal maintenance efforts.

Read more...