<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tiny struggles - engineering blog</title>
    <description>Articles about DevOps and software engineering in mostly Python.
</description>
    <link>http://tinystruggles.com/</link>
    <atom:link href="http://tinystruggles.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Mon, 10 Jul 2017 23:48:15 +0100</pubDate>
    <lastBuildDate>Mon, 10 Jul 2017 23:48:15 +0100</lastBuildDate>
    <generator>Jekyll v2.2.0</generator>
    
      <item>
        <title>Notifications on the channels in Golang</title>
        <description>&lt;p&gt;Notification on a channel is a common concurrency pattern in Golang. In this
post I&amp;#39;m describing how it works and a common trap that I found with
it.&lt;/p&gt;

&lt;h2&gt;Introduction to the pattern&lt;/h2&gt;

&lt;p&gt;This pattern can be used in a situation when there is some piece of work
that updates a variable that then can be consumed by multiple other threads
interested in this value. Imagine a family: mum is cooking a dinner, she
finishes, announces to the children that the dinner is ready and the children
after hearing it come and eat the dinner.&lt;/p&gt;

&lt;p&gt;How could such a thing be implemented in Golang?&lt;/p&gt;

&lt;p&gt;I&amp;#39;m assuming you are familiar with the golang &lt;a href=&quot;https://gobyexample.com/channels&quot;&gt;channels&lt;/a&gt;
and the &lt;a href=&quot;https://gobyexample.com/closing-channels&quot;&gt;closing&lt;/a&gt; of channels.&lt;/p&gt;

&lt;p&gt;To implement such notification system, start with a struct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;with a variable that will be read,&lt;/li&gt;
&lt;li&gt;with a channel for the notification that the value is ready.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the value is updated, the producer thread closes the associated
variableChannel. When the channel gets closed all the reading operations
from it finish, so effectively the consumer threads will be notified that
the thing that they were waiting for finished.&lt;/p&gt;

&lt;p&gt;As an illustration, take a look at the &lt;code&gt;Foo&lt;/code&gt; struct that comes up with a number
that can later be read by 10 different goroutines when it&amp;#39;s ready
 (full example also at &lt;a href=&quot;https://play.golang.org/p/tolS8Qgeja&quot;&gt;https://play.golang.org/p/tolS8Qgeja&lt;/a&gt;).&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;type Foo struct {
    number     int
    numberChan chan struct{}
}

func (f *Foo) ComeUpWithANumber() {
    time.Sleep(1 * time.Second)
    f.number = 42
    close(f.numberChan)
}

func (f *Foo) Number() (int, error) {
    &amp;lt;-f.numberChan
    return f.number, nil
}

func main() {
    f := &amp;amp;Foo{numberChan: make(chan struct{})}
    go f.ComeUpWithANumber()
    for i := 0; i &amp;lt; 10; i++ {
        go func() {
            n, err := f.Number()
            if err != nil {
                fmt.Println(&amp;quot;Error:&amp;quot;, err)
            } else {
                fmt.Println(&amp;quot;Number was&amp;quot;, n)
            }
        }()
    }
    time.Sleep(2 * time.Second)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you run it the result is as expected:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
Number was 42
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Ordering trap&lt;/h2&gt;

&lt;p&gt;Cool! The code works as expected. However, imagine that after some time users
of your software start complaining that sometimes &lt;code&gt;Foo&lt;/code&gt; spends too much time
generating the number. They request a cancellation and timeout feature from you.&lt;/p&gt;

&lt;p&gt;Sure no problem, you add the feature. Accessing the number becomes a bit more
complex (full example at: &lt;a href=&quot;https://play.golang.org/p/9JR-OONNsH&quot;&gt;https://play.golang.org/p/9JR-OONNsH&lt;/a&gt;).&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;func (f *Foo) Number() (int, error) {
    select {
    case &amp;lt;-f.doneChan:
        return 0, errors.New(&amp;quot;canceled&amp;quot;)
    case &amp;lt;-f.numberChan:
        return f.number, nil
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You test your code and you get the unexpected result. There is a bug there!&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Error: canceled
Number was 42
Error: canceled
Error: canceled
Number was 42
Number was 42
Number was 42
Error: canceled
Error: canceled
Error: canceled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This result is a surprise for you because you know that there was no timeout
here and that you close the &lt;code&gt;doneChan&lt;/code&gt; after you&amp;#39;ve updated the number in
your testing scenario. Just like below:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;func (f *Foo) ComeUpWithANumber() {
    time.Sleep(1 * time.Second)
    f.number = 42
    close(f.numberChan)
    close(f.doneChan)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What happened? The answer is that the &lt;code&gt;select&lt;/code&gt; clause will choose any of the
&amp;quot;ready&amp;quot; channels, not necessarily the one that got ready first.
There is no assured order.&lt;/p&gt;

&lt;p&gt;So, even if the &lt;code&gt;number&lt;/code&gt; is ready, before &lt;code&gt;doneChan&lt;/code&gt; was closed, you might end
up on the &lt;code&gt;doneChan&lt;/code&gt; part of select.&lt;/p&gt;

&lt;p&gt;To fix this issue, don&amp;#39;t assume the order of accessing the closed channels. Be
ready for any possible ordering.
The improved version of the &lt;code&gt;Number&lt;/code&gt; function looks as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;func (f *Foo) Number() (int, error) {
    select {
    case &amp;lt;-f.doneChan:
        select {
        case &amp;lt;-f.numberChan:
            return f.number, nil
        default:
            return 0, errors.New(&amp;quot;canceled&amp;quot;)
        }
    case &amp;lt;-f.numberChan:
        return f.number, nil
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Real life example&lt;/h2&gt;

&lt;p&gt;This all might seem a bit far fetched to you. But sadly it isn&amp;#39;t. &lt;a href=&quot;https://github.com/grpc/grpc-go/pull/1281&quot;&gt;Here&lt;/a&gt; is an
example from the golang grpc implementation.&lt;/p&gt;

&lt;p&gt;The original code in the implementatin of the Stream struct was using &lt;code&gt;select&lt;/code&gt;
on multiple channels:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;select {
case &amp;lt;-s.ctx.Done():
    return nil, ContextErr(s.ctx.Err())
case &amp;lt;-s.goAway:
    return nil, ErrStreamDrain
case &amp;lt;-s.headerChan:
    return s.header.Copy(), nil
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And sometimes you would receive the header value and sometimes you would not...&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Jul 2017 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2017/07/09/golang-channel-notification-select.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2017/07/09/golang-channel-notification-select.html</guid>
        
        <category>golang,</category>
        
        <category>go,</category>
        
        <category>programming,</category>
        
        <category>concurrency</category>
        
        
      </item>
    
      <item>
        <title>Golang Concurrency Exercises</title>
        <description>&lt;p&gt;First, little disclaimer: concurrency is hard. Even though,
 someone can tell you that with a great
support for concurrency primitives in Go concurrency will become easy.
 Trivial things will be easy, but you can still end up having problems.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://talks.golang.org/2012/waza/gophercomplex1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;If you are still feeling adventurous, I have some resources for you!&lt;/p&gt;

&lt;p&gt;Some time ago, I organized Concurrent programming in Go workshop in &lt;a href=&quot;https://hackerspace.pl/about_en&quot;&gt;Warsaw
hackerspace&lt;/a&gt;. &lt;a href=&quot;http://go-talks.appspot.com/github.com/ilonajulczuk/go-workshops/concurrency.slide#1&quot;&gt;Slides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;People taking part in the workshop were Go beginners and most of them didn&amp;#39;t
have much experience in writing concurrent programs. Workshops were interactive, so I have
some exercises for you. Exercises start with number 3, because I&amp;#39;ve omitted the trivial ones (you can still read 
about them in the slides). They would require you to use your knowledge about concurrency
and software design, expect them to be open ended.&lt;/p&gt;

&lt;h3&gt;Exercise 3 - vending machine&lt;/h3&gt;

&lt;p&gt;Design a vending machine that will take coins as input and chocolate as output.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s imagine that Gophers have coins of value 1, 2 and 5.
Gopher can choose the item and then has to insert money and wait for
the vending machine to dispense the item.&lt;/p&gt;

&lt;h3&gt;Exercise 4 - design simple work pipeline&lt;/h3&gt;

&lt;p&gt;Hackers started working on the new IRC bot. They decided that the bot
should support command:
&lt;code&gt;~shoutitinreverse&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your task is to design a following string processing pipeline:
put on queue -&amp;gt; strip whitespace -&amp;gt; change to UPPER -&amp;gt; reverse -&amp;gt; print&lt;/p&gt;

&lt;p&gt;What additional features could it support?&lt;/p&gt;

&lt;h3&gt;Exercise 5 - control access to 3D printers&lt;/h3&gt;

&lt;p&gt;During a busy hackaton 3D printers are heavily used.
Write a simulation of hackers trying to access 3D printers.&lt;/p&gt;

&lt;p&gt;In the hackerspace, there are 3 3D printers. There are 7 hackers that are interested in using the printers.&lt;/p&gt;

&lt;p&gt;If the hacker can&amp;#39;t access the printer for more than 5 seconds,
 he gets annoyed and quits the hackaton.
 Hackers use printers for random interval from 1 to 10 seconds and
 usually they need to use the printer at least twice,
 because nothing is perfect for the first time.&lt;/p&gt;

&lt;h3&gt;Exercise 6 - hackerspace membership fees&lt;/h3&gt;

&lt;p&gt;Every month, hackerspace has to pay its bills and every hacker has to pay his or her membership fee.&lt;/p&gt;

&lt;p&gt;Requirements:
- Hackers in general don&amp;#39;t pay their fees the same day every month,
 it&amp;#39;s much more random.
- Bills however have to be paid on time.
- The board wants monthly reports of the funds.&lt;/p&gt;

&lt;p&gt;Use share memory by communication approach (avoid mutexes).&lt;/p&gt;

&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;I hope that it would be useful. If you finish those exercises I would love to see your
solutions.
Exercises were inspired by &lt;a href=&quot;http://whipperstacker.com/2015/10/05/3-trivial-concurrency-exercises-for-the-confused-newbie-gopher/&quot;&gt;3 TRIVIAL CONCURRENCY EXERCISES FOR THE CONFUSED NEWBIE GOPHER&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have fun learning Go!&lt;/p&gt;
</description>
        <pubDate>Wed, 21 Oct 2015 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2015/10/21/golang-concurrency.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/10/21/golang-concurrency.html</guid>
        
        <category>golang,</category>
        
        <category>go,</category>
        
        <category>programming,</category>
        
        <category>concurrency</category>
        
        
      </item>
    
      <item>
        <title>Golang Code Reuse - Generalization tricks</title>
        <description>&lt;p&gt;In this article I want to share with you few tricks that I learned
in go that would allow you to write reusable code. I will start with code
that is written for only one use case and refactor it to be reusable.&lt;/p&gt;

&lt;p&gt;You can see all code from this blogpost in &lt;a href=&quot;https://github.com/ilonajulczuk/backtrack&quot;&gt;github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;How to reuse code in Go?&lt;/h1&gt;

&lt;p&gt;If you want something similar that you already have, what should you do?
How do people avoid duplication without inheritance and generics?&lt;/p&gt;

&lt;p&gt;TL;DR - Using golang interfaces and composition.&lt;/p&gt;

&lt;p&gt;Instead of inheritance, you should use composition and accept interfaces
instead of concrete types. Instead of generics, use narrow interfaces 
describing exactly what you need or if there is no other way and you
 want to be very generic - use empty interfaces &lt;code&gt;interface{}&lt;/code&gt; with &lt;a href=&quot;https://golang.org/doc/faq#generics&quot;&gt;unboxing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you feel little uneasy about golang interfaces, I recommend you to read
some tutorials first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://go-book.appspot.com/interfaces.html&quot;&gt;Interfaces: the awesomesauce of Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go&quot;&gt;How to use interfaces in Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;Algorithmic example&lt;/h1&gt;

&lt;p&gt;I was recently reading section about backtracking in &lt;a href=&quot;http://www.algorist.com/&quot;&gt;The Algorithm Design
Manual by Skiena&lt;/a&gt;. &lt;a href=&quot;https://en.wikipedia.org/wiki/Backtracking&quot;&gt;Backtracking&lt;/a&gt; is a very useful algorithm that can be
used to solve puzzles, generate all possible permutations of given set
or all it subsets.&lt;/p&gt;

&lt;table class=&quot;image&quot;&gt;
&lt;caption align=&quot;bottom&quot;&gt;Sudoku puzzle being solved by backtracking&lt;/caption&gt;
&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/Sudoku_solved_by_bactracking.gif/220px-Sudoku_solved_by_bactracking.gif&quot; alt=&quot;Sudoku puzzle being solved by backtracking&quot;/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;In the book author describes there universal backtracking algorithm.
Examples in the book are written in C and I decided that I would rewrite them to Go.&lt;/p&gt;

&lt;p&gt;Core of alorithm is a &lt;code&gt;Backtrack&lt;/code&gt; function, 
it uses problem specific functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IsSolution(a []elements, k int, n int)&lt;/li&gt;
&lt;li&gt;ConstructCandidates(a []elements, k int, n int) []elements&lt;/li&gt;
&lt;li&gt;ProcessSolution(a []elements, k int, n int)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To solve your problem, you just need to substitute those functions.&lt;/p&gt;

&lt;p&gt;I succeeded in translating the algorithm to Go for the subset generation
 problem, you can see the code below.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;package main

import (
    &amp;quot;fmt&amp;quot;
)

var total int

func Backtrack(a []bool, k int, input int) {
    if IsSolution(a, k, input) {
        ProcessSolution(a, k, input)
        return
    }
    k++

    candidates := ConstructCandidates(a, k, input)
    for _, c := range candidates {
        a[k-1] = c
        Backtrack(a, k, input)
    }
}

func IsSolution(a []bool, k int, n int) bool {
    return k == n
}

func ConstructCandidates(a []bool, k int, n int) []bool {
    return []bool{true, false}
}

func ProcessSolution(a []bool, k int, n int) {
    fmt.Printf(&amp;quot;{&amp;quot;)
    for i, v := range a {
        if v {
            fmt.Printf(&amp;quot;%d&amp;quot;, i)
        }
    }
    fmt.Printf(&amp;quot;}\n&amp;quot;)
    total++
}

func main() {
    a := make([]bool, 10)
    Backtrack(a, 0, 10)
    fmt.Println(&amp;quot;total&amp;quot;, total)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you run the script it will print all possible subsets of range from 0 to 9 inclusive.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$  go run simplebacktrack.go 

{0123456789}
{012345678}
{012345679}
...
{8}
{9}
{}
total 1024
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Algorithm works, but clearly the implementation isn&amp;#39;t reusable, because Backtrack algorithm uses 
hardcoded functions specific to the problem.&lt;/p&gt;

&lt;p&gt;The simplest generalization that we can make is to make Backtrack function
customizable - pass an interface that implements all specific methods to the
Backtrack function!&lt;/p&gt;

&lt;h2&gt;Extracting required functionality to interface&lt;/h2&gt;

&lt;p&gt;Let&amp;#39;s define our interface - it should have almost the same methods that has
our concrete implementation:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;type BacktrackerImpl interface {
    IsSolution(a []interface{}, k int, input interface{}) bool

    ConstructCandidates(a []interface{}, k int, n interface{}) []interface{}

    ProcessSolution(a []interface{}, k int, n interface{})
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that slice of bool &lt;code&gt;[]bool&lt;/code&gt; was replaced with slice of empty interfaces &lt;code&gt;[]interface{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Empty interface is a powerful tool - it describes a type that implements at
least &lt;em&gt;0&lt;/em&gt; methods, which means that every type satisfies empty interface. Thanks to
this property we could use our Backtracker with bools, integers and even
 with Cats (defined as named structs).&lt;/p&gt;

&lt;h2&gt;Changing code to implement interface (close look at empty interfaces)&lt;/h2&gt;

&lt;p&gt;Now we have to modify our subset algorithm to implement this interface:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;// SubsetImpl implements BacktrackerImpl interface.
type SubsetImpl struct {
    total    int
}

func (b *SubsetImpl) IsSolution(a []interface{}, k int, n interface{}) bool {
    return k == n
}

func (b *SubsetImpl) ConstructCandidates(a []interface{}, k int, n interface{}) []interface{} {
    // 1. We can&amp;#39;t just return []bool{true, false} here.
    result := make([]interface{}, 2)
    result[0] = true
    result[1] = false
    return result
}

func (b *SubsetImpl) ProcessSolution(a []interface{}, k int, n interface{}) {
    fmt.Printf(&amp;quot;{&amp;quot;)
    for i, v := range a {
        if v.(bool) { // 2. We convert the type from interface{} to bool.
            fmt.Printf(&amp;quot;%d&amp;quot;, i)
        }
    }
    fmt.Printf(&amp;quot;}\n&amp;quot;)
    b.total++
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First we create a struct with one field - &lt;code&gt;total&lt;/code&gt;. &lt;code&gt;total&lt;/code&gt; was previously a global
variable, now it&amp;#39;s stored inside the instance of the struct.&lt;/p&gt;

&lt;p&gt;We then define methods required by the interface. They take as a receiver pointer
to the instance of &lt;code&gt;SubsetImpl&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;It shouldn&amp;#39;t be a big problems, because we had those functions (&lt;code&gt;ConstructCandidates&lt;/code&gt;, &lt;code&gt;ProcessSolution&lt;/code&gt;, etc)
defined in our first algorithm. The only difference is that those functions took
slice of bools as a first argument and we have to change it to slice of empty interfaces.&lt;/p&gt;

&lt;p&gt;To achieve this we only need to make two
two small changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instead of returning []bool{true, false} we need to allocate slice of empty
interfaces and fill it with boolean values. &lt;a href=&quot;http://stackoverflow.com/questions/12990338/cannot-convert-string-to-interface&quot;&gt;Slice of empty interfaces isn&amp;#39;t &amp;#39;any slice&amp;#39;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We convert the type from interface{} to bool. If the value stored in empty interface was of some other type, program
will panic. You can learn more about type conversions from &lt;a href=&quot;http://blog.denevell.org/golang-interface-type-assertions-switch.html&quot;&gt;type assertions and type switches&lt;/a&gt; article.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;Changing original code to use new interface&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;Backtrack&lt;/code&gt; function already takes three parameters, so at this point it&amp;#39;s better
to make it a method of a type and store data in a struct, than add another parameters.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;type Backtracker struct {
    impl BacktrackerImpl
}

// New creates new backtrackers, it takes implementation of backtracking
// problem as an argument.
func New(i BacktrackerImpl) *Backtracker {
    return &amp;amp;Backtracker{impl: i}
}

// Backtrack explores solutions of the problem. It&amp;#39;s a little simplified
// version (working for all concrete examples in this blogpost).
func (b Backtracker) Backtrack(a []interface{}, k int, input interface{}) {
    if b.impl.IsSolution(a, k, input) {
        b.impl.ProcessSolution(a, k, input)
        return
    }
    k++

    candidates := b.impl.ConstructCandidates(a, k, input)
    for _, c := range candidates {
        a[k-1] = c
        b.Backtrack(a, k, input)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looks like we have all the pieces we need! Our new implementation can be used as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;func main() {
    a := make([]interface{}, 10)
    impl := &amp;amp;SubsetImpl{}
    b := backtrack.New(impl)
    b.Backtrack(a, 0, 10)
    fmt.Println(&amp;quot;total&amp;quot;, impl.total)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Using backtracking algorithm to solve another problem&lt;/h1&gt;

&lt;p&gt;Another implementation example in generator of permutations. It uses integers
instead of bytes.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;type PermutationImpl struct {
    total    int
}

func (b *PermutationImpl) IsSolution(a []interface{}, k int, n interface{}) bool {
    return k == n
}

func (b *PermutationImpl) ConstructCandidates(a []interface{}, k int, n interface{}) []interface{} {

    inPerm := make(map[int]bool)

    for i := 0; i &amp;lt; k-1; i++ {
        inPerm[a[i].(int)] = true
    }

    result := []interface{}{}

    for i := 1; i &amp;lt;= n.(int); i++ {
        if !inPerm[i] {
            result = append(result, i)
        }
    }

    return result
}

func (b *PermutationImpl) ProcessSolution(a []interface{}, k int, n interface{}) {
    fmt.Println(a)
    b.total++
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Permutation implementation can be used in similar way to &lt;code&gt;SubsetImpl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;impl := &amp;amp;PermutationImpl{}
b := backtrack.New(impl)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thanks to empty interfaces everything just works!&lt;/p&gt;

&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;I hope that you enjoyed this blogpost. Definitely reusing code in go can be
challenging without inheritance and generics, but it&amp;#39;s definitely possible. &lt;/p&gt;

&lt;p&gt;This example doesn&amp;#39;t exhaust all the possible ways to write reusable code in
go. I would like to hear your battle stories from the work on go codebases, 
share your experience in the comment section or write me an email at &lt;a href=&quot;mailto:justyna.ilczuk@gmail.com&quot;&gt;justyna.ilczuk@gmail.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can see all code from this blogpost in &lt;a href=&quot;https://github.com/ilonajulczuk/backtrack&quot;&gt;github repo&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 29 Aug 2015 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2015/08/29/golang-code-reuse.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/08/29/golang-code-reuse.html</guid>
        
        <category>golang,</category>
        
        <category>go,</category>
        
        <category>programming,</category>
        
        <category>algorithms</category>
        
        
      </item>
    
      <item>
        <title>API for resource with tags with django and DRF</title>
        <description>&lt;p&gt;Recently I was working on new exciting part of
&lt;a href=&quot;http://www.syncano.com/&quot;&gt;syncano-platform&lt;/a&gt; and I wanted to create a piece of
api that would allow for filtering resources with many to many relationships.&lt;/p&gt;

&lt;p&gt;I wanted to have a resource that can be tagged.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/cambodia4kidsorg/260004685/&quot;&gt;&lt;img src=&quot;https://farm1.staticflickr.com/117/260004685_8d78d77db0_o_d.jpg&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding such tags should be RESTful and straightforward. Also I wanted to add the ability
to search using tags. My go to Rest library is &lt;a href=&quot;http://www.django-rest-framework.org/&quot;&gt;Django Rest Framework&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Currently the most popular solution for tagging in django is
&lt;a href=&quot;https://github.com/alex/django-taggit&quot;&gt;django-taggit&lt;/a&gt;, however
it doesn&amp;#39;t integrate with Django Rest Framework well and heavily uses ContentTypes.
In my current project at work we don&amp;#39;t use ContentTypes at all.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s also a pretty old library and has support for old django, south migrations, stuff
that we just don&amp;#39;t need in new projects.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve read in a blog post &lt;a href=&quot;https://godjango.com/33-tagging-with-django-taggit/&quot;&gt;about django-taggit&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tags can be hard if you try to implement them yourself, so don&amp;#39;t try and just use this library from the start.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And well, I disagree with this quote, how hard can it can be?&lt;/p&gt;

&lt;p&gt;I sometimes prefer to write a simple code, well tailored
to my use case, that install another library with all its dependencies. If library is poorly
written you&amp;#39;ll waste a lot of time debugging its strange behaviors and fighting
with it when trying to tailor it your custom requirements. (I&amp;#39;m looking at you &lt;a href=&quot;https://github.com/omab/python-social-auth&quot;&gt;python social auth&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I decided to just do it myself. We will now distill this experience by building a simple app with two resources and
REST API for them. Here is a &lt;a href=&quot;https://github.com/ilonajulczuk/django-tags&quot;&gt;code&lt;/a&gt; for a whole app.&lt;/p&gt;

&lt;h1&gt;App Ingredients&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;python 3.4&lt;/li&gt;
&lt;li&gt;django 1.8&lt;/li&gt;
&lt;li&gt;Django Rest Framework 3.1&lt;/li&gt;
&lt;li&gt;django-filter&lt;/li&gt;
&lt;li&gt;django-cors-headers 1.1.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simplicity I will use sqlite as a DB.&lt;/p&gt;

&lt;h2&gt;Data models&lt;/h2&gt;

&lt;p&gt;Let&amp;#39;s imagine that we&amp;#39;re building a very simplified version of PYPI. We&amp;#39;re indexing
libraries, we store their names, websites, descriptions and tags.&lt;/p&gt;

&lt;p&gt;User can then search libraries using names, descriptions and tags, they can even
add new tags to them.&lt;/p&gt;

&lt;p&gt;How we will build it? We will have two resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;li&gt;libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In django, models are defined in &lt;code&gt;models.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;models.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.db&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Tag for data. Every tag has unique text.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CharField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__str__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;Tag[id: {id}, text: {text}]&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Library represents a piece of software. It has its website url,&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    name, description and as many tags as you like.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# django has a nice field that validates URLs&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URLField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# name should be in a slug form&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SlugField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CharField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blank&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ManyToManyField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;related_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;libraries&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__str__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;Library[id: {id}, name: {name}]&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we will create nice RESTy api for them. It will be possible to add tags
to libraries and vice versa.&lt;/p&gt;

&lt;p&gt;To use django rest framework with those models, we need at three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;serializers&lt;/li&gt;
&lt;li&gt;views&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I usually start with serializers, serializer will translate our models to
serialized date (it can be other way round too). I&amp;#39;m going to use simple
serializers based on models directly. DRF has &lt;code&gt;ModelSerializer&lt;/code&gt;s for that.&lt;/p&gt;

&lt;p&gt;serializers.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rest_framework&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serializers&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serializers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;libraries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serializers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SlugRelatedField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;many&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;read_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;slug_field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LibrarySerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serializers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serializers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SlugRelatedField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;many&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;slug_field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The only tricky part there was to define &lt;code&gt;SlugRelatedField&lt;/code&gt;s correctly. You can
read more about related fields in DRF
 &lt;a href=&quot;http://www.django-rest-framework.org/api-guide/relations/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With serializers in place, we can move to views part. Views let our app to
communicate with the rest of the world.&lt;/p&gt;

&lt;p&gt;In DRF you can either use views or viewsets. Views are simpler to understand,
because they have the same methods as http verbs. Viewsets simplify lots of things and
they are on higher abstraction level, so instead of post, you have create method.&lt;/p&gt;

&lt;p&gt;Also viewsets combine very well with routers and usually using viewset results in
using much less code.&lt;/p&gt;

&lt;p&gt;Here I will use &lt;code&gt;ModelViewSet&lt;/code&gt;s, that gives us full CRUD functionality for free.&lt;/p&gt;

&lt;p&gt;views.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rest_framework&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.serializers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibrarySerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TagSerializer&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serializer_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TagSerializer&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LibraryViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serializer_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibrarySerializer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Simple, isn&amp;#39;t it?&lt;/p&gt;

&lt;p&gt;Now, let&amp;#39;s connect views to urls.&lt;/p&gt;

&lt;p&gt;urls.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rest_framework.routers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultRouter&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.views&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibraryViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TagViewSet&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;#39;libraries&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibraryViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;#39;tags&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TagViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&amp;#39;s actually all we need to create DRF browsable API for those resources.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/2fIMbNZ.png&quot; alt=&quot;Imgur&quot;&gt;&lt;/p&gt;

&lt;h2&gt;Adding filtering&lt;/h2&gt;

&lt;p&gt;We can add new things now, but finding something is currently a pain.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/denverjeffrey/2561885967/in/photolist-4UokrH-qHQEPc-dYCDcW-oufzqn-hG6Xyx-2mnaga-oomyEr-3HbBZD-9bgFge-6Z1VAo-6TCgyp-98ejH9-5yYtyK-c1Duq9-r1edkT-93i2Tk-mnHEDQ-4PZqiV-mf2iWE-ak9s8g-9XK3Hy-agn3Es-8PCJ8C-gto5h-7NxJZy-dBYFge-or48Jg-9qk81s-dHAAcV-9r12Wr-6f3poB-6TL359-esUVsh-sAvZu9-6awutw-qiqT9Y-qLhUXP-m9mdpr-73Gqjb-qiqQKE-92t8FA-fnpaj6-5NByM-9XK9j3-9qPsEz-6khfv-d9Pguk-ggHwRT-fz9kwb-c3vzMS&quot;&gt;&lt;img src=&quot;https://farm4.staticflickr.com/3278/2561885967_f5f0be5834_z_d.jpg&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s implement filtering! We will enable filtering of libraries by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DRF has a pretty good support for filtering. You can read more about it &lt;a href=&quot;http://www.django-rest-framework.org/api-guide/filtering/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even though support is good, we still have to do some things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a custom filter&lt;/li&gt;
&lt;li&gt;enable filtering Backend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let start from creating a custom filter. We will put in in separate file, so
it will be easier to find.&lt;/p&gt;

&lt;p&gt;filters.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django_filters&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LibraryFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;django_filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FilterSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# default for CharFilter is to have exact lookup_type&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;django_filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CharFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lookup_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;icontains&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;django_filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CharFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lookup_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;icontains&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# tricky part - how to filter by related field?&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# but not by its foreign key (default)&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# `to_field_name` is crucial here&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# `conjoined=True` makes that, the more tags, the more narrow the search&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;django_filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelMultipleChoiceFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;to_field_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;text&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;conjoined&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;description&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;tags&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To create a custom filter, we had to inherit after django_filters.FilterSet,
define our model in Meta and define how each of filters should behave.&lt;/p&gt;

&lt;p&gt;django_filters offers few types of &lt;code&gt;lookup_type&lt;/code&gt;s for example: &lt;code&gt;exact&lt;/code&gt; - that
would match an exact string, &amp;#39;contains&amp;#39;, that would returns matches that contain
given string, you can add &lt;code&gt;i&lt;/code&gt; before those lookup_types, to make them ignore
case.&lt;/p&gt;

&lt;p&gt;The only tricky part is filtering by related field using its field, different than
foreign key. I&amp;#39;ve seen some examples with filtering by related fields using foreign key,
but I couldn&amp;#39;t find in any docs, how to do it with different field (in our case - tag text).&lt;/p&gt;

&lt;p&gt;Eventually I had to dig into source of django fields
to find it out. It&amp;#39;s enough to set &lt;code&gt;to_field_name=&amp;#39;field_name&amp;#39;&lt;/code&gt; and it should work.&lt;/p&gt;

&lt;p&gt;To connect filter with view, you have to add following too lines to the view:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;filter_backends&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DjangoFilterBackend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;filter_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibraryFilter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also set filtering backend in django app settings if you like.&lt;/p&gt;

&lt;p&gt;Here is how it should look like in context:&lt;/p&gt;

&lt;p&gt;views.py&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rest_framework&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.filters&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibraryFilter&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.serializers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibrarySerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TagSerializer&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TagViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serializer_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TagSerializer&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LibraryViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewsets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModelViewSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;queryset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serializer_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibrarySerializer&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filter_backends&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DjangoFilterBackend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filter_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LibraryFilter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Using our API&lt;/h2&gt;

&lt;p&gt;You can now list all tags:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl http://127.0.0.1:8000/tags/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is how result will look like (if you&amp;#39;ve created some data before):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;python&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;libraries&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;django&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;django-rest-framework&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;web&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;libraries&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;django&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you curl libraries:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl http://127.0.0.1:8000/libraries/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;your result will look like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cool web framework&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;django&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;https://www.djangoproject.com/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;tags&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;web&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;python&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;api framework&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;django-rest-framework&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.django-rest-framework.org/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;tags&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;python&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now perform queries with filters like below!&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;curl http://127.0.0.1:8000/libraries/?name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;rest&lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;api framework&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;django-rest-framework&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.django-rest-framework.org/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;tags&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;python&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pretty neat!&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope that you&amp;#39;ll find this blog post useful. Building an APIs can actually be
a pretty complex task, because there are so many components that have to be
connected.&lt;/p&gt;

&lt;p&gt;Also, we&amp;#39;ve just scratched a surface. Our API doesn&amp;#39;t have proper
authorization, paging, ordering, permission system or tests, we also have pretty scarce validation, no api versioning
and we only handle JSON.&lt;/p&gt;

&lt;p&gt;You can download or read full code on &lt;a href=&quot;https://github.com/ilonajulczuk/django-tags&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 04 Jun 2015 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2015/06/04/django-api-resource-with-tags.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/06/04/django-api-resource-with-tags.html</guid>
        
        <category>django,</category>
        
        <category>programming,</category>
        
        <category>python,</category>
        
        <category>REST,</category>
        
        <category>django-rest-framework,</category>
        
        <category>drf,</category>
        
        <category>django-filter</category>
        
        
      </item>
    
      <item>
        <title>Debugging - into rabbit hole with docker containers</title>
        <description>&lt;p&gt;This post will tell a story about successful debugging session.
As an author of a portion of code, we are naturally biased to not to think about worst ways of exploiting it. Luckily I have creative colleagues. Recently one of my colleagues did some additional testing and left me with a destructive, yet interesting bug related to Docker, sandboxing and abuse. In this post I will describe how I approached and fixed it.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;http://syncano.com&quot;&gt;syncano&lt;/a&gt; - company I work at - we allow for custom code execution, it’s a part of our Backend as a Service solution. We run our code in Docker containers which should be more less safe if enough security is in place. We do such things like executing this code on separate machines that rest of the tasks. Those machines have less privileges and less knowledge about the system and containers itself are constrained on things like memory usage and time of execution.&lt;/p&gt;

&lt;p&gt;So I was really surprised recently that snippet such as:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;while True:
    print(“woopdido!”)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;could cause us serious trouble. The symptoms were that codebox (abstraction for wrapper around container and code) wouldn’t time out, but will stay in the pending state. We would expect it to be terminated after 30 seconds. Moreover codeboxes scheduled next, after the one that was stuck, would also stay in pending state.&lt;/p&gt;

&lt;p&gt;In our monitoring platform we could see that load on this kind of workers was surprisingly high and that codeboxes that were meant to time out after 15 or 30 seconds could run for hours! Clearly it was a bug in our implementation of timeout subroutine.&lt;/p&gt;

&lt;p&gt;It was a bit surprising, because I remembered implementing this part of code and writing tests for it. If there was a regression in this part of code, we should catch it on our Continuous Integration server during build. Tests were green.&lt;/p&gt;

&lt;p&gt;I’ve remembered that in our integration test cases I used &lt;code&gt;time.sleep&lt;/code&gt; and quickly tested a codebox with sleep on our staging:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;import time

while True:
    time.sleep(0.1)
    print(“woopdido!”)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this time, the behavior was correct. Maybe it was connected to some kind of waiting? We used to send a signal to container to shut it down if hasn’t finished on time.&lt;/p&gt;

&lt;p&gt;I quickly verified this hypothesis by trying out another example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;x = 0
while True:
    x += 1
return x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This time behavior was also correct. So it wasn’t specific for using time! It was pretty late when I found it out, so I just wrote a small note in the bug ticket. Next step was to recreate the same problem on my local machine next day.&lt;/p&gt;

&lt;p&gt;Recreating the bug was quite messy. One side effect was making my machine swap. One of the first things I noticed was that we were using the pretty old version of the docker library for python.&lt;/p&gt;

&lt;p&gt;I freezed version 0.6 and there was version 1.2.2 out there when I started debugging it. Time passes really fast. From one side of view, it’s bad that we haven’t updated this dependency for half a year, from the other side - it’s nice to have a piece of code that doesn’t have to be modified often.&lt;/p&gt;

&lt;p&gt;Anyway, it turned out that new version has timeout functionality built in. Great, I thought, probably my custom implementation of timeout was wrong in some way and the official one would handle my case better.&lt;/p&gt;

&lt;p&gt;Actually - it didn’t change anything. I also noticed during testing with few flavours of problematic scripts, that the whole problem it’s not really about timeout - but about resource usage. Even if container was killed on time, memory wasn’t returned to the OS. So problem lied somewhere else. My next suspect was extremely verbose printing.&lt;/p&gt;

&lt;p&gt;I measured how much logs can be written to a file during 15 seconds assuming simple printing. Not too much - it would take long to display with tool such as less, less than few hundreds Mbs. It definitely didn’t match the behavior of eating all my RAM (16 Gb on my private laptop and 8Gb on my work machine). However if I did more ‘printing’ problem only had gotten worse:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;for _ in range(1000000):
    print(“hello” * 1000000)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Would it my RAM with speed of half Gb per second - and before actual time out machine would start swapping like crazy. It shouldn’t happen, because newly spawned containers were memory constrained and not even one of my containers seemed to be busy - by observing their processes I would rather say that they were bored. Problem was probably on host.&lt;/p&gt;

&lt;p&gt;I could easily observe the RAM / cpu disaster in a window with htop opened. There were two ways to get out from this situation - restart my computer or restart docker. Both very tedious, because with whole environment using docker it meant restarting the whole stack every time.&lt;/p&gt;

&lt;p&gt;When I tried to access logs from the container which was running codebox containers, for few times I got an interesting exception:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;# docker run -ti ubuntu:trusty bash
FATA[0028] Error response from daemon: Cannot start container 02533d9e9afcc81818d3d71aa7498e0f41e7904483fd041fa45a0638423a5d3a: [8] System error: fork/exec /usr/bin/docker: cannot allocate memory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initially I thought that it was because docker had eaten all my RAM, but it turned out that I could do other things that required memory allocations. Puzzled, I googled this exact exception message.&lt;/p&gt;

&lt;p&gt;It led me to the issue on docker’s github page. The main asker describe the similar problem, verbose logging resulted in big memory leaks. Bingo! That looked roughly like my problem.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/docker/docker/issues/9139&quot;&gt;github issue&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;memory leak in buffer grow #9139
 Closed e-max opened this issue on Nov 13, 2014 · 29 comments&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Memory leak issue in buffer grow. It sounded nasty, but I decided to read all the comments. Some devs suggested using different logging handlers available in new versions of docker, but it didn’t work for me - I had to restart my environment few times more.
Moreover on the end of the issue page Docker devs say that those problems won’t be fixed until 1.7 (probably).&lt;/p&gt;

&lt;p&gt;Sometimes you’re left to your own devices. I thought for a while about creating a patch for Docker, but it wouldn’t be there until the next release, I also wouldn’t be able to use my own patched version of docker, because we have some other environment constraints. Well, I’m also a very novice golang programmer and I had no experience with fixing memory allocation problems. So I had to think about workaround on our side.&lt;/p&gt;

&lt;p&gt;If you’ve spend some time in terminal window on Linux or Mac, you’re probably familiar with stream redirection. If you can’t print to foreground, why not redirect it to the files? It’s a good solution because it’s language independent, so I wouldn’t have to worry about capturing streams in every language that we support for codebox. &amp;gt; sign in bash is much more elegant.&lt;/p&gt;

&lt;p&gt;It sounded like the exact thing that I needed. I quickly changed the command string that was passed to newly created containers:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&amp;#39;python my_script.py&amp;#39; -&amp;gt; &amp;#39;python my_script.py &amp;gt; logs&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I started the adversary container and… nothing changed. And my computer started swapping again. Duh, what could go wrong?&lt;/p&gt;

&lt;p&gt;I remembered that sometimes writes in Copy On Write filesystems can give worse performance, than those on more typical ones, such as EXT4, however this behavior was clearly strange.  I tried to mount logs file as volume, so that I would omit COW filesystem.&lt;/p&gt;

&lt;p&gt;It didn’t work, not only my computer also ended up without free RAM, I also couldn’t see any logs in the mounted files. It was strange and on this point I was also pretty tired. I got some coffee, juggled for five minutes and helped fellow devops in his problem.&lt;/p&gt;

&lt;p&gt;I clearly wasn’t redirecting correctly to the files. Luckily, the offensive containers were running for 15 to 30 seconds depending on my timeout configuration and I could make sure that stdout was redirected by looking up container’s logs.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ docker log -f nifty_ritchie
logging
logging
logging
….
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;They weren’t redirected correctly. By sheer accident I remembered that I’ve read somewhere on some blog or even in docs, that wrapping calls of docker commands in &lt;code&gt;bash -c ‘original bash stuff’&lt;/code&gt; could solve some unexpected behavior.&lt;/p&gt;

&lt;p&gt;That was it.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt; &amp;#39;bash -c ‘python my_script.py &amp;gt; logs 2&amp;gt; errors’&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;was a winning combination.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I was lucky that it took me only one day to debug this problem. Bugs always seem obvious in retrospect, but can be a real rabbit hole and consume lots of your precious time that could be spent on developing features.&lt;/p&gt;

&lt;p&gt;Here are my rules of thumb for debugging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recreate your bug in local environment that you control (if that’s possible)&lt;/li&gt;
&lt;li&gt;write your hypothesis down&lt;/li&gt;
&lt;li&gt;write down your assumptions and try to test them as fast as possible, preferably in isolation&lt;/li&gt;
&lt;li&gt;always try to learn more about the problem&lt;/li&gt;
&lt;li&gt;take breaks - thinking in front of computer can be really hard, especially if you’re deeply involved into problem, it&amp;#39;s also very important to avoid getting unproductive and wasting your time, I&amp;#39;ve recently seen a very good talk &lt;a href=&quot;http://summit.pywaw.org/&quot;&gt;&amp;#39;Into the Rabbit Hole&amp;#39;&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/asendecka&quot;&gt;@asendecka&lt;/a&gt; that talks about exactly that.&lt;/li&gt;
&lt;li&gt;talk to people :) - if they’re technical, they will help you spot flaws in your thinking, if they aren’t technical, at least you’ll get some perspective during the break&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debugging is more like art than a science. I would like to hear about your opinions and your best techniques.
Just comment below, talk to me on twitter on &lt;a href=&quot;https://twitter.com/attilczuk&quot;&gt;@attilczuk&lt;/a&gt; or write me an email to &lt;a href=&quot;mailto:justyna.ilczuk@gmail.com&quot;&gt;justyna.ilczuk@gmail.com&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 30 May 2015 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2015/05/30/debugging-adventure-docker0.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/05/30/debugging-adventure-docker0.html</guid>
        
        <category>devops,</category>
        
        <category>programming,</category>
        
        <category>docker,</category>
        
        <category>bug,</category>
        
        <category>bugs,</category>
        
        <category>debugging</category>
        
        
      </item>
    
      <item>
        <title>Docker Meetup in Warsaw</title>
        <description>&lt;p&gt;You&amp;#39;ve probably heard about Docker already, it&amp;#39;s a hot DevOps technology that gained
popularity during last two years. Last month I&amp;#39;ve organized a first Docker Meetup
in 2015 in Warsaw.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.datacenterdude.com/wp-content/uploads/2015/03/docker-square.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;I did it with a help of my great team at &lt;a href=&quot;http://www.syncano.com/&quot;&gt;Syncano&lt;/a&gt;, the company provided
office, food &amp;amp; drinks and all needed infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/0FINL7G.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;The website for the meetup is &lt;a href=&quot;http://www.meetup.com/Docker-Warsaw-Poland/events/219527919/&quot;&gt;here&lt;/a&gt;.
Almost 60 people made RSVPs (we had to limit number of people, because we were little 
worried if our office can handle it).&lt;/p&gt;

&lt;p&gt;We had two talks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker in Everyday Development - 30 min, Justyna Ilczuk from Syncano (me ;) )&lt;/li&gt;
&lt;li&gt;Introduction To Kubernetes - 45 min, Filip Grzadkawski from Google&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and workshops during which we were practicing working with Docker CLI and installed
docker-compose (which wasn&amp;#39;t so easy on fedora! It started working after doing it from
the &lt;a href=&quot;http://simononsoftware.com/virtualenv-tutorial/&quot;&gt;virtualenv&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://photos4.meetupstatic.com/photos/event/1/3/d/d/600_435845085.jpeg&quot; alt=&quot;workshops&quot;&gt;&lt;/p&gt;

&lt;p&gt;Workshops were mostly improvised, but turned out to be well received. I really enjoyed
working with Tomasz Cholewa (coorganizer of the workshops). I have a development
background and Tomek is an Ops person - combining our perspectives was an interesting experience.
We&amp;#39;ve met for the first time on this workshops.&lt;/p&gt;

&lt;p&gt;Apart from workshops, I prepared a talk about using Docker in everyday Development.
I talk there a bit about reasons for doing it and then I move to tools that I recommend
for creating development environments with Docker.&lt;/p&gt;

&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/46911065&quot; width=&quot;476&quot; height=&quot;400&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;If you like my talk, pass it on. If you have some questions, ask them here or drop me an email.&lt;/p&gt;

&lt;p&gt;Organizing this meetup was a great experience and I don&amp;#39;t want to stop on one event,
so if you have some interesting talk that you would like to give in Warsaw next month, contact me.&lt;/p&gt;
</description>
        <pubDate>Sun, 12 Apr 2015 00:00:00 +0100</pubDate>
        <link>http://tinystruggles.com/2015/04/12/running-docker-meetup-in-warsaw0.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/04/12/running-docker-meetup-in-warsaw0.html</guid>
        
        <category>devops,</category>
        
        <category>meetup,</category>
        
        <category>docker</category>
        
        
      </item>
    
      <item>
        <title>Bash monitoring tips - watch &amp; tee</title>
        <description>&lt;p&gt;Recently I was debugging some problem with deployment in &lt;a href=&quot;http://www.syncano.com/&quot;&gt;Syncano&lt;/a&gt; (where I work) and I wanted to catch
an exact moment when the problem occurred. Docker was dying on a host without any good reason.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s assume that I wanted to observe what Docker containers are running at a given moment.&lt;/p&gt;

&lt;p&gt;Here is my snippet, we will later describe it in detail:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ watch -n 3 &amp;#39;date &amp;gt;&amp;gt; dump_ps &amp;amp;&amp;amp; docker ps | tee -a dump_ps&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;watch&lt;/li&gt;
&lt;li&gt;date&lt;/li&gt;
&lt;li&gt;docker ps (but can be replaced by any command that you&amp;#39;re interested in)&lt;/li&gt;
&lt;li&gt;tee&lt;/li&gt;
&lt;li&gt;tmux (later in the blog post)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What it does?&lt;/p&gt;

&lt;p&gt;It executes a command in single quotes &lt;code&gt;&amp;#39;date &amp;gt;&amp;gt; dump_ps &amp;amp;&amp;amp; docker ps | tee -a dump_ps&amp;#39;&lt;/code&gt; every three seconds, displays it on the screen and appends to file.&lt;/p&gt;

&lt;p&gt;The command consists of two parts &lt;code&gt;date &amp;gt;&amp;gt; dump_ps&lt;/code&gt; and &lt;code&gt;docker ps | tee -a dump_ps&lt;/code&gt;, both of them append to &lt;code&gt;dump_ps&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;date &amp;gt;&amp;gt; ps&lt;/code&gt; is pretty self-explanatory, because it just appends a current date to a file. You can pass arguments to the date program to adjust the format - &lt;a href=&quot;http://unixhelp.ed.ac.uk/CGI/man-cgi?date&quot;&gt;date man page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we typed:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ watch -n 3 &amp;#39;date &amp;gt;&amp;gt; time_is_passing&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and interrupted after few seconds, we could see the time written to &lt;code&gt;time_is_passing&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ cat time_is_passing 
nie, 22 mar 2015, 03:57:08 PDT
nie, 22 mar 2015, 03:57:11 PDT
nie, 22 mar 2015, 03:57:14 PDT
nie, 22 mar 2015, 03:57:17 PDT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output may differ if you have different locale / timezone settings.&lt;/p&gt;

&lt;p&gt;The second part of the command: &lt;code&gt;docker ps | tee -a dump_ps&lt;/code&gt; is a little more complicated.&lt;/p&gt;

&lt;p&gt;If you have docker installed, &lt;code&gt;docker ps&lt;/code&gt; will show you info about the containers running on your host. More info about Docker command line commands may be found &lt;a href=&quot;https://docs.docker.com/reference/commandline/cli/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you don&amp;#39;t want to play with docker, you can replace this command with &lt;code&gt;top&lt;/code&gt; - it will show you your processes instead.&lt;/p&gt;

&lt;p&gt;Ok, so the first command would normally display an output on the screen or pass it through the pipe to another program. What we want to do here is
to both show and append the text to the file. There is a program just for that in every Linux distro. It&amp;#39;s called tee.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Tee.svg/400px-Tee.svg.png&quot; alt=&quot;tee from wikipedia&quot;&gt;&lt;/p&gt;

&lt;p&gt;Image from wikipedia article about &lt;a href=&quot;http://en.wikipedia.org/wiki/Tee_%28command%29&quot;&gt;tee&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ echo &amp;quot;I love command line&amp;quot; | tee interests
I love command line

$ cat interests 
I love command line
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However if we wrote another interest to the file in a similar way:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ echo &amp;quot;I love climbing&amp;quot; | tee interests
I love climbing

$ cat interests                         
I love climbing
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We would replace the whole file! It&amp;#39;s because &lt;code&gt;tee&lt;/code&gt; without arguments is like using &lt;code&gt;&amp;gt;&lt;/code&gt;. To append to a file pass the &lt;code&gt;-a&lt;/code&gt; flag to &lt;code&gt;tee&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ echo &amp;quot;I love command line&amp;quot; | tee -a interests
I love command line

$ echo &amp;quot;I love Linux&amp;quot; | tee -a interests
I love Linux

$ cat interests                         
I love climbing
I love command line
I love Linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cool! We can now build an ad hoc dashboard that refreshes every three seconds and dumps all the info to the file.&lt;/p&gt;

&lt;p&gt;But what if we wanted to monitor more than one thing at once on the same screen? Let&amp;#39;s enter the world of &lt;code&gt;tmux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tmux is a terminal multiplexer - if you haven&amp;#39;t heard of it, grab a &lt;a href=&quot;https://danielmiessler.com/study/tmux/&quot;&gt;tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It can be installed with apt-get or yum:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;sudo apt-get install tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;sudo yum install tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, so if you have tmux installed, type:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ tmux
$ Ctrl-B+&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your screen should split vertically. Then run the command in the first pane and switch to the other one with &lt;code&gt;Ctrl-B+Up Arrow&lt;/code&gt; and run the next command.&lt;/p&gt;

&lt;p&gt;Here is a result from my laptop:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/77VGM1r.png&quot; alt=&quot;Imgur&quot;&gt;&lt;/p&gt;

&lt;p&gt;I hope that you&amp;#39;ve learned something new. Shell is full of small gems that really shine when used together.&lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;
</description>
        <pubDate>Sun, 22 Mar 2015 00:00:00 +0000</pubDate>
        <link>http://tinystruggles.com/2015/03/22/bash-monitoring-tips.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2015/03/22/bash-monitoring-tips.html</guid>
        
        <category>devops,</category>
        
        <category>bash,</category>
        
        <category>shell,</category>
        
        <category>watch,</category>
        
        <category>tmux,</category>
        
        <category>tee</category>
        
        
      </item>
    
      <item>
        <title>Maker Productivity 101</title>
        <description>&lt;p&gt;In this blog post I want to share with you some of my best reflections about
how to be productive with many serious, projects at the same time.&lt;/p&gt;

&lt;h2&gt;Maker schedule vs Manager schedule&lt;/h2&gt;

&lt;p&gt;Paul Graham differentiates in &lt;a href=&quot;http://www.paulgraham.com/makersschedule.html&quot;&gt;his
article&lt;/a&gt; between two schedules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;maker&lt;/li&gt;
&lt;li&gt;manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In manager schedule - you change what you&amp;#39;re doing every hour - meetings,
calls, urgent events. It&amp;#39;s about managing resources and reacting to changes.&lt;/p&gt;

&lt;p&gt;On the other hand in maker schedule you work in bigger chunks of time - such us
a block of five hours - to focus on complex things, research, implement and
create. It&amp;#39;s often accompanied with a state of flow.&lt;/p&gt;

&lt;h2&gt;GTD and todo lists&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;re interested in productivity - you&amp;#39;ve probably heard already about
&lt;a href=&quot;http://alphaefficiency.com/gtd/&quot;&gt;GTD&lt;/a&gt; philosophy - write down, manage, set
priorities, execute tasks from the lists you produced (it&amp;#39;s actually much more
complex system).&lt;/p&gt;

&lt;p&gt;However not everything reduces to &lt;a href=&quot;http://calnewport.com/blog/2012/12/21/getting-unremarkable-things-done-the-problem-with-david-allens-universalism/&quot;&gt;clear and easy to accomplish next
actions&lt;/a&gt;.
Sometimes there is also a [deep work] to do.&lt;/p&gt;

&lt;p&gt;And to do something really meaningful we don&amp;#39;t need a better list of next
actions, but we need to train our ability to focus on meaningful things for
long periods of time. GTD works for the schedule of manager, but for makers
(researchers, artists) it really doesn&amp;#39;t make sense.&lt;/p&gt;

&lt;p&gt;There are also TODO lists, which are very helpful when your life is in a
complete chaos and you want to write things down to get it out of your head and
see what&amp;#39;s really there to prioritize. However maintaining TODO lists for long
periods of time can be &lt;a href=&quot;http://blog.codinghorror.com/todont/&quot;&gt;bad for you&lt;/a&gt; -
mostly because tasks tend to accumulate and long lists can fill your free time
with lots of triva, not mentioning making you feel overwhelmed or guilty that
you have so many tasks to do.&lt;/p&gt;

&lt;p&gt;Another problem with small tasks I see is that they demand frequesnt context
switching. If I have 4 big projects and I chunk the time for them to 30 minutes
blocks - it turns out awful - I don&amp;#39;t get things done - even though I spend
this time, also - I don&amp;#39;t enter flow state which I&amp;#39;ll describe later in the
article. &lt;/p&gt;

&lt;p&gt;My another big problem is that I cannot stop thinking about next things after
the chunk and I start micromanaging myself - which turns out to be stressful.&lt;/p&gt;

&lt;h2&gt;Flow&lt;/h2&gt;

&lt;p&gt;Flow is a very productive and focused state of mind, person experiencing flow
can be totally immersed in the task. You can read more about &lt;a href=&quot;http://en.wikipedia.org/wiki/Flow_(psychology)&quot;&gt;it&amp;#39;s definition
here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In short the biggest benefit of flow is that you can get a lot done and get
lots of satisfaction from it, because flow just is an immensely rewarding and
fulfilling experience. &lt;/p&gt;

&lt;p&gt;However to get into the state of flow you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;challenging task with clear goal &lt;/li&gt;
&lt;li&gt;enough uninterrupted time to gain focus&lt;/li&gt;
&lt;li&gt;freedom of distractions&lt;/li&gt;
&lt;li&gt;enough skill, so that the task won&amp;#39;t be impossible for you&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Challenge_vs_skill.svg/300px-Challenge_vs_skill.svg.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Flow is one of the most important reasons why I love programming - I often
catch myself totally immersed into programming task. &lt;/p&gt;

&lt;p&gt;For long time I didn&amp;#39;t know a lot of people working in this way. When I first
met some &amp;#39;makers&amp;#39; they looked totally disorganized, yet they turned out to be
surprisingly productive. It changed the way I approach productivity now.&lt;/p&gt;

&lt;h2&gt;Focus&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m currently pursuing more projects that I think it&amp;#39;s sane to pursue
in the same time. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working almost full time as software engineer in a really exciting startup&lt;/li&gt;
&lt;li&gt;finishing my degree in applied physics - I attend some classes, have some
projects to do and tests&lt;/li&gt;
&lt;li&gt;writing a bachelor&amp;#39;s thesis (complex systems,
statistical nonequilibrium physics, math - hypergraphs)&lt;/li&gt;
&lt;li&gt;writing a technical book for Packt Publishing - writing on this blog&lt;/li&gt;
&lt;li&gt;constantly improving my skills as software engineer - learning tools and frameworks, learning
fundamentals, security, devops, operating systems and more &lt;/li&gt;
&lt;li&gt;building things in &lt;a href=&quot;https://hackerspace.pl/&quot;&gt;local hackerspace&lt;/a&gt; - lately quadcopters&lt;/li&gt;
&lt;li&gt;some minor personal projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would also want to contribute more to open source, read more books and
exercise more - however the last one isn&amp;#39;t so bad actually, because I manage to
work out at least once a week.&lt;/p&gt;

&lt;p&gt;However - it&amp;#39;s easy to spot problems with this list - it&amp;#39;s too long. Apart from
university and work eating up at least 10 hours a day of my time, I have
approximately 6 or maybe even 4 hours (social life, relaxing?) I could do some
work. As I mentioned previously half an hour blocks don&amp;#39;t work for me.&lt;/p&gt;

&lt;h3&gt;How to gain focus then?&lt;/h3&gt;

&lt;h4&gt;Remove distractions&lt;/h4&gt;

&lt;p&gt;My biggest distraction is most of the time is browsing
the internet.&lt;/p&gt;

&lt;p&gt;Turn off the internet connection in your computer. Print what you want to read.
Work in a room without your computer, use paper!&lt;/p&gt;

&lt;p&gt;Or if you have to work with computer, turn off all the unnecessary tabs and
communicators, to leave only what you need to do your work.&lt;/p&gt;

&lt;h4&gt;Socialize less&lt;/h4&gt;

&lt;p&gt;Yes, it might be a bit strange to say this - because
meeting new people and spending time with friends is usually considered a good
thing in life. But when your time is sparse you have to make space for quiet
time just for yourself to push things forward.&lt;/p&gt;

&lt;h4&gt;Choose one thing or max two&lt;/h4&gt;

&lt;p&gt;Having 6 ongoing projects doesn&amp;#39;t mean that
you have to do progress everyday in all of them.&lt;/p&gt;

&lt;p&gt;Instead of doing really small chunks of easy work in all of them, choose one
project and make a big progress in it.&lt;/p&gt;

&lt;h4&gt;Store possible tasks and remove them&lt;/h4&gt;

&lt;p&gt;There are lot&amp;#39;s of cool articles in the internet - both technical (potentially
useful) and sociopolitical - which may grab your attention. Reading an article
can take approximately 10 minuters, it&amp;#39;s not really so much right? However it
usually doesn&amp;#39;t stop on one, but more likely on 10 articles in the row - just
before you wanted to do something, or just when you took a small break. And 100
minutes is can make a real difference I you spend it on meaningful projects.&lt;/p&gt;

&lt;p&gt;How to resist the urge of reading the article now - in this particular moment?
My answer is - save it for later.&lt;/p&gt;

&lt;p&gt;I discovered a &lt;a href=&quot;http://getpocket.com/&quot;&gt;Pocket&lt;/a&gt;. It&amp;#39;s a simple app for saving
what you want to read later and synchronizing it across all of your devices so
you can read it offline on your phone or using different computer.&lt;/p&gt;

&lt;p&gt;It also has one killer feature - it&amp;#39;s possible to remove items from the list -
and your list should be short.&lt;/p&gt;

&lt;h2&gt;Other tips&lt;/h2&gt;

&lt;h3&gt;Books over articles&lt;/h3&gt;

&lt;p&gt;Although articles are nice to get started in some areas, it&amp;#39;s often much better
to read a proper book on a subject. Reading a technical book 100 minutes per
day will greatly improve your skills and knowledge in contrast to articles on
the web.&lt;/p&gt;

&lt;p&gt;What books are you reading right now? Do you feel that you can&amp;#39;t get through
them or there are just to many books you want to read?&lt;/p&gt;

&lt;p&gt;Or maybe you aren&amp;#39;t reading anything from your field right now? Why?&lt;/p&gt;

&lt;h3&gt;Track how much time you spend on your projects&lt;/h3&gt;

&lt;p&gt;It might turn out that you&amp;#39;re not productive in some of your pursuits, because
you don&amp;#39;t spend enough time on it.&lt;/p&gt;

&lt;p&gt;The best way I found so far to motivate
myself to spend time on something and accurately track it in the same time is
&lt;a href=&quot;https://www.beeminder.com/&quot;&gt;beeminder&lt;/a&gt;. In beeminder you set your goals - like
doing more of something, and you declare your commitment weekly. If you don&amp;#39;t
meet your goals, you pay money to beeminder and amount of money at stake
increases.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/LiUua1C.png&quot; alt=&quot;personal_beeminding&quot;&gt;&lt;/p&gt;

&lt;p&gt;It also gives you insights how big is typical daily chunk you invest into doing
something. I love it.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;There is no silver bullet - however focusing and prioritizing helps a lot. I
hope that my tips and tool would be useful for you. Thanks for reading and get
back to work ;).&lt;/p&gt;
</description>
        <pubDate>Sun, 30 Nov 2014 00:00:00 +0000</pubDate>
        <link>http://tinystruggles.com/2014/11/30/maker-productivity-101.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2014/11/30/maker-productivity-101.html</guid>
        
        <category>making,</category>
        
        <category>productivity</category>
        
        
      </item>
    
      <item>
        <title>Virtualenv the Docker way</title>
        <description>&lt;p&gt;This post will describe how to use virtualenv&amp;#39;s tricks to run python
inside Docker container extending concept of python virtual environment,
without changing any current habits.&lt;/p&gt;

&lt;p&gt;If you develop in python you&amp;#39;ve probably heard about &lt;code&gt;pip&lt;/code&gt; and &lt;code&gt;virtualenv&lt;/code&gt;,
if not... go read about &lt;a href=&quot;http://www.dabapps.com/blog/introduction-to-pip-and-virtualenv-python/&quot;&gt;them&lt;/a&gt;
now. They&amp;#39;re pretty standard way of managing dependencies
in python.&lt;/p&gt;

&lt;h1&gt;Virtualenv &amp;amp; pip workflow&lt;/h1&gt;

&lt;p&gt;Typical workflow with virtualenv and pip looks as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ virtualenv .
$ source /bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above steps we create a virtual environment and &lt;code&gt;activate&lt;/code&gt; it.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;(docker-virtualenv)
# att at lapunov in ~/Projects/docker-virtualenv on git:master x [8:05:05]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With virtualenv we can start using pip without worrying that it will pollute
our global space.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ pip install -r requirements.txt
$ pip install my_new_dependency
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we no more want to use a virtualenv, we can get rid of it by:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Simple, right? &lt;/p&gt;

&lt;h1&gt;All dependencies are in docker now...&lt;/h1&gt;

&lt;p&gt;Pip and virtualenv work well and you get used to them,
but here comes &lt;a href=&quot;https://www.docker.com/whatisdocker/&quot;&gt;Docker&lt;/a&gt; and lots of things change. Now, you install
all dependencies inside a container instead of virtualenv &lt;/p&gt;

&lt;p&gt;Installing dependencies in docker has it&amp;#39;s advantages
over using just virtualenv
- because thanks to containers - you don&amp;#39;t have to worry about system&amp;#39;s dependencies,
and your app is now better isolated.&lt;/p&gt;

&lt;p&gt;However running
python becomes a bit cumbersome, because you don&amp;#39;t have dependencies
installed on your machine, and you would have to get into docker container
to run python there.&lt;/p&gt;

&lt;p&gt;For example you work with &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt; and
want to run &lt;code&gt;./manage.py shell_plus&lt;/code&gt;, as you always did,
in a current directory?&lt;/p&gt;

&lt;p&gt;Or run &lt;code&gt;./manage.py collect_static&lt;/code&gt;, or just play around
with packages you&amp;#39;ve just installed using IPython?&lt;/p&gt;

&lt;p&gt;You first have to enter a docker container. And depending on your
&lt;a href=&quot;http://docs.docker.com/reference/builder/&quot;&gt;Dockerfile&lt;/a&gt;
you can have few things wrong - default directory, user,
environment variables...&lt;/p&gt;

&lt;p&gt;It isn&amp;#39;t the nicest developer experience ever. The best thing would be
to not change our habits at all.&lt;/p&gt;

&lt;h1&gt;Virtualenv&amp;#39;s &lt;code&gt;bin/activate&lt;/code&gt;&lt;/h1&gt;

&lt;p&gt;What if we have something like virtualenv which would change our python
so it runs inside the Docker?&lt;/p&gt;

&lt;p&gt;All we have to do this is to change how python is executed.&lt;/p&gt;

&lt;p&gt;Instead of running a &lt;code&gt;python&lt;/code&gt; binary we can run a &lt;code&gt;python&lt;/code&gt; bash script,
which will run &lt;code&gt;python&lt;/code&gt; inside a Docker container containing all our
installed dependencies.&lt;/p&gt;

&lt;p&gt;Do you remember what virtualenv does? It creates a bunch of directories:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;bin  lib  man  share
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And stores a new &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt; and so on in &lt;code&gt;bin&lt;/code&gt; directory as well as magical
&lt;code&gt;activate&lt;/code&gt; file which shouldn&amp;#39;t be run but sourced.&lt;/p&gt;

&lt;p&gt;When we do:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ source bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We change python to the local one. &lt;code&gt;activate&lt;/code&gt; is quite simple and it uses the
fact that python looks for python executable on using the &lt;code&gt;PATH&lt;/code&gt; environment variable,
and uses the first &lt;code&gt;python&lt;/code&gt; executable it finds. So &lt;code&gt;activate&lt;/code&gt; prepends
virtualenv bin path to &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ echo $PATH         
/home/att/Projects/docker-virtualenv/bin:/usr/local/sbin:/usr/local/bin
(docker-virtualenv)
$ echo $VIRTUAL_ENV 
/home/att/Projects/docker-virtualenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Fake your python&lt;/h1&gt;

&lt;p&gt;We can do a similar thing as virtualenv does. Let&amp;#39;s create a bin directory:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ mkdir bin
$ cp ../my_other_project_with_virtualenv/bin/activate bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and change: &lt;code&gt;VIRTUAL_ENV&lt;/code&gt; environment variable to &lt;code&gt;pwd&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;VIRTUAL_ENV=`pwd`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we only have to create a fake python executable.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ echo &amp;quot;echo &amp;#39;hello&amp;#39;&amp;quot; &amp;gt; bin/python  # create a dummy python
$ chmod +x bin/python  # make script executable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we should have now a structure like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ tree bin
bin
├── activate
└── python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To use our new &lt;code&gt;python&lt;/code&gt; ;), we have to source &lt;code&gt;activate&lt;/code&gt; again.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ source bin/activate
$ python             
hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hurray! It means that we have dummy python in place, and it&amp;#39;s a default python now.
We only have to make it a little bit more useful and run a python inside a Docker
container.&lt;/p&gt;

&lt;p&gt;This is an example content of &lt;code&gt;bin/python&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ cat bin/python
#!/bin/bash
docker run -it docker_image_name python &amp;quot;$@&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you rewrite a &lt;code&gt;bin/python&lt;/code&gt; to the version above and reload activate,
you run python in Docker just like always:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But it will be little slower to start...&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ time python -c &amp;quot;print(&amp;#39;hello&amp;#39;)&amp;quot;
hello
python -c &amp;quot;print(&amp;#39;hello&amp;#39;)&amp;quot;  0,02s user 0,01s system 10% cpu 0,318 total
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However - it works!&lt;/p&gt;

&lt;p&gt;If you work with &lt;a href=&quot;http://www.fig.sh/&quot;&gt;fig&lt;/a&gt; - tool for isolated Docker 
development environments, you probably should use
a &lt;code&gt;fig run&lt;/code&gt; instead of &lt;code&gt;docker run&lt;/code&gt; - because it will setup also
a rest of containers for you with proper links, volumes and environment
variables. Running with root privileges without a good reason is a bad practice
so it should be avoided. I use a &lt;a href=&quot;http://phusion.github.io/baseimage-docker/&quot;&gt;docker/baseimage&lt;/a&gt;
as base for some of my
Docker images, so I have a &lt;code&gt;/sbin/setuser command&lt;/code&gt; which I use to run
commands as a different user.&lt;/p&gt;

&lt;p&gt;After the changes mentioned above (assuming using &lt;code&gt;fig&lt;/code&gt; and &lt;code&gt;baseimage&lt;/code&gt;)
&lt;code&gt;bin/python&lt;/code&gt; might look as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;#!/bin/bash
cd /home/att/Projects/docker-virtualenv  # fig has to find `fig.yml`
fig run docker_image /sbin/setuser virtualenv python &amp;quot;$@&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you don&amp;#39;t have to remember that your python app is in Docker. Just use
python as you always do :).&lt;/p&gt;

&lt;p&gt;And to restore normal python, just run&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
        <pubDate>Sun, 16 Nov 2014 00:00:00 +0000</pubDate>
        <link>http://tinystruggles.com/2014/11/16/docker-virtualenv.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2014/11/16/docker-virtualenv.html</guid>
        
        <category>programming</category>
        
        <category>python</category>
        
        <category>docker</category>
        
        <category>virtualenv</category>
        
        
      </item>
    
      <item>
        <title>Side effects of mock</title>
        <description>&lt;h1&gt;What is mock&lt;/h1&gt;

&lt;p&gt;Python &lt;code&gt;mock&lt;/code&gt; module allows you to replace parts of your system under test with mock objects
and make assertions about how they have been used.&lt;/p&gt;

&lt;p&gt;Mock is available in the standard library in python3 as part of &lt;code&gt;unittest&lt;/code&gt; module.
You can read it&amp;#39;s documentation &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html&quot;&gt;here&lt;/a&gt;.
In python 2, &lt;code&gt;mock&lt;/code&gt; is available to install with &lt;a href=&quot;https://pip.pypa.io/en/latest/&quot;&gt;pip&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;Use cases&lt;/h1&gt;

&lt;p&gt;What do we use mocks for? Mock are mostly used in unit tests.
We try to make tests as short and focused on what we test as possible.&lt;/p&gt;

&lt;h2&gt;Mock call to external service&lt;/h2&gt;

&lt;p&gt;As I stated in the first paragraph, mock is mainly used for testing. Recently
I was implementing a social signup and I didn&amp;#39;t want to call
facebook every time, but I wanted to test if the signup works as it&amp;#39;s
supposed to.&lt;/p&gt;

&lt;p&gt;Calling an external service such as facebook is really expensive,
because http requests take time (hundreds of milliseconds at least) 
and requires
thinking about lots of complex things - such as if your access token is
still valid. And we usually don&amp;#39;t want to think about it during testing,
because we want to test this one specific detail of our code.&lt;/p&gt;

&lt;p&gt;Below is a short gist of this usage of mock:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;get_json_mock = mock.Mock(return_value={&amp;#39;name&amp;#39;: &amp;#39;John&amp;#39;,
                                        &amp;#39;email&amp;#39;: &amp;#39;john@doe.com&amp;#39;})

class SocialAuthViewTest(APITestCase):
    backend = &amp;quot;facebook&amp;quot;

    def setUp(self):
        test_token = &amp;#39;token test_facebook&amp;#39;
        self.url = reverse(&amp;#39;authenticate_social&amp;#39;, args=(self.backend,))
        self.client.defaults[&amp;#39;HTTP_X_AUTHORIZATION&amp;#39;] = test_token

    @mock.patch(&amp;#39;social.backends.base.BaseAuth.get_json&amp;#39;, get_json_mock)
    def test_returns_200_when_user_found(self):
        response = self.client.post(self.url)
        self.assertEqual(response.status_code, 200)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we know which function is called and what it should return, we can
patch it using &lt;code&gt;@mock.patch&lt;/code&gt; decorator and
previously created &lt;code&gt;Mock&lt;/code&gt; object with &lt;code&gt;return_value&lt;/code&gt; set to what we want
to get as result of function call.&lt;/p&gt;

&lt;h2&gt;Locally turn off logging&lt;/h2&gt;

&lt;p&gt;Let&amp;#39;s imagine that we&amp;#39;ve already implemented most of
our social login functionality and now we want to test if
our API properly reacts to bad logging in attacks.&lt;/p&gt;

&lt;p&gt;We don&amp;#39;t want user to see ugly &lt;code&gt;500&lt;/code&gt; - internal server error HTTP error code,
but &lt;code&gt;401&lt;/code&gt; unauthorized HTTP error code.&lt;/p&gt;

&lt;p&gt;When we get information from an external service that credentials were invalid
we should log the accident. In tests our logger prints to standard out.
But do we want an ugly
traceback in our tests output? I would rather see something like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;....................................
----------------------------------------------------------------------
Ran 17 tests in 1.610s

OK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Short and clean. But how should I keep loggers quiet?&lt;/p&gt;

&lt;p&gt;I quickly searched the web to find good solutions to this problem.
Stack overflow provides 
&lt;a href=&quot;http://stackoverflow.com/questions/5255657/how-can-i-disable-logging-while-running-unit-tests-in-python-django&quot;&gt;some answers&lt;/a&gt;
but they weren&amp;#39;t satisfactory to me, because most of them included
changing logging too much, by changing it&amp;#39;s level globally in tests.&lt;/p&gt;

&lt;p&gt;I wanted a more fine grained approach and I used &lt;code&gt;mock&lt;/code&gt; library for it.&lt;/p&gt;

&lt;p&gt;First I had to find the the file logging the exception and understand
how it&amp;#39;s done.&lt;/p&gt;

&lt;p&gt;Here is a file &lt;code&gt;users/views.py&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;logger = logging.getLogger(__name__)

def sign_in_or_signup(register, access_token):
    try:
        return request.backend.do_auth(access_token)
    except requests.HTTPError:
        logger.exception(&amp;#39;Invalid login&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#39;s a pretty standard django way to use logging. We create logger instance
for the module and use it to print out messages to standard out or
send details of errors to some external service such as &lt;a href=&quot;https://getsentry.com/welcome/&quot;&gt;sentry&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we only could mock this logger to swallow exceptions...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;users/tests/test_social_signup.py&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;    @mock.patch(&amp;#39;users.views.logger&amp;#39;, mock.Mock())
    def test_user_authenticates_wrong_access_token(self):
        self.client.defaults[&amp;#39;HTTP_X_AUTHORIZATION&amp;#39;] = &amp;#39;token iamjustwrong&amp;#39;
        response = self.client.post(self.url)
        self.assertEquals(response.status_code, 401)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voilà, done! It&amp;#39;s even easier than the previous example.&lt;/p&gt;

&lt;h2&gt;Testing a behavior flow&lt;/h2&gt;

&lt;p&gt;Another interesting usage of mock can be while testing
&lt;code&gt;check and retry if wrong&lt;/code&gt; pattern.&lt;/p&gt;

&lt;p&gt;My coworker was testing this kind of behavior and used
code similar to the one below:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;def generate_value_mock(*args, **kwargs):
    iterator = getattr(generate_value_mock, &amp;#39;iterator&amp;#39;, 0)
    setattr(generate_value_mock, &amp;#39;iterator&amp;#39;, iterator + 1)

    if iterator &amp;lt; 2:
        return &amp;#39;a&amp;#39;
    return &amp;#39;b&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nice piece of advanced python, right? Actually it demands
thinking, it&amp;#39;s complex. Maybe it even should be tested to
be sure that it&amp;#39;s behavior is correct. One of the testing rules is that
we don&amp;#39;t test tests, so they should be as simple as possible.&lt;/p&gt;

&lt;p&gt;Guess what, we can use &lt;code&gt;mock&lt;/code&gt; library to simplify this piece of
code. Below is the gist from &lt;a href=&quot;http://blog.atte.ro/2013/11/10/ipython-now-your-tools.html&quot;&gt;IPython&lt;/a&gt;
representing how it works:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;m = mock.Mock()
In [17]: m.test.side_effect = [&amp;#39;a&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;]

In [18]: m.test()
Out[18]: &amp;#39;a&amp;#39;

In [19]: m.test()
Out[19]: &amp;#39;a&amp;#39;

In [20]: m.test()
Out[20]: &amp;#39;b&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can set &lt;code&gt;side_effect&lt;/code&gt; on Mock object. Depending on what type of object
we pass to it, we can get different behaviors when calling mock object.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value.
Alternatively &lt;code&gt;side_effect&lt;/code&gt; can be an exception class or instance. In this case the exception will be raised when the mock is called.
If &lt;code&gt;side_effect&lt;/code&gt; is an iterable then each call to the mock will return the next value from the iterable.
A &lt;code&gt;side_effect&lt;/code&gt; can be cleared by setting it to None.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can read more about this particular property
&lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;It&amp;#39;s only a tip of the iceberg...&lt;/h1&gt;

&lt;p&gt;If you haven&amp;#39;t heard about &lt;code&gt;mock&lt;/code&gt; before, you might find this examples impressive,
however they don&amp;#39;t show even 10% of real capabilities of python &lt;code&gt;mock&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;I recommending you reading it&amp;#39;s &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html&quot;&gt;detailed documentation&lt;/a&gt;
or if you prefer more hands on approach, you can check out
&lt;a href=&quot;http://www.toptal.com/python/an-introduction-to-mocking-in-python&quot;&gt;mock tutorial form Toptal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, happy mocking!&lt;/p&gt;
</description>
        <pubDate>Sat, 08 Nov 2014 00:00:00 +0000</pubDate>
        <link>http://tinystruggles.com/2014/11/08/mock-side-effect.html</link>
        <guid isPermaLink="true">http://tinystruggles.com/2014/11/08/mock-side-effect.html</guid>
        
        <category>programming</category>
        
        <category>python</category>
        
        <category>testing</category>
        
        <category>mock</category>
        
        
      </item>
    
  </channel>
</rss>
