# -*- coding: utf-8

import random, string

def random_string(length,
        letters=True,
        digits=True,
        punctuation=False,
        whitespace=False):
    """ Returns a random string """
    chars = ''
    if letters:
        chars += string.ascii_letters
    if digits:
        chars += string.digits
    if punctuation:
        chars += string.punctuation
    if whitespace:
        chars += string.whitespace
    return ''.join(random.sample(chars, length))

# -*- coding: utf-8

from random import choice
import string

def random_string(length,
        letters=True,
        digits=True,
        punctuation=False,
        whitespace=False):
    """ Returns a random string """
    chars = ''
    if letters:
        chars += string.ascii_letters
    if digits:
        chars += string.digits
    if punctuation:
        chars += string.punctuation
    if whitespace:
        chars += string.whitespace
    return ''.join([choice(chars) for i in range(length)])

--- 
+++ 
@@ -1,7 +1,6 @@
 # -*- coding: utf-8
 
-from random import choice
-import string
+import random, string
 
 def random_string(length,
         letters=True,
@@ -18,4 +17,4 @@
         chars += string.punctuation
     if whitespace:
         chars += string.whitespace
-    return ''.join([choice(chars) for i in range(length)])
+    return ''.join(random.sample(chars, length))
Use random.sample() rather than reinventing it.
