Beyond

the pip

Disclaimer: this is not about pip (in particular)

Hi!

I'm Dana

@danielacraciun


source: monkeyuser.com

It's the year 2019

are we supposed to write our own code now??

NOPE.

BUT DOUBT. EVERYTHING.

The good

  • Multitude of libraries
  • Ease of use
  • Open source software

The bad

  • Poorly written & documented
  • Not optimized
  • Might go missing

The ugly

  • Security issues
  • Malicious activity (typosquatting happening)
  • Dependency hell

Review time!

Is the library...

mature?
used in commercial products?
backed up by other organizations?

Is the library...

used all through your project?
heavily relying on other libraries?

Improve the library

Contribute to open source!

Selected a dependency?

Use a pattern...

wrap it up! (the code, that is)

from external_dependency import something

class SomeExternalDependencyClient:
    def __init__(self, credentials, name):
        self.client = something.Client(credentials, name)

    def get_items(self, ids):
        self.client.get(ids)
        
    def send_items(self, item_list):
        self.client.batch_insert(item_list)

The standard library is awesome!

Good resources

You have magic methods...


import hashlib

class Hasher(object):
    def __init__(self, algorithm):
        self.algorithm = algorithm

    def __call__(self, file):
        hash = self.algorithm()
        with open(file, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), ''):
                hash.update(chunk)
        return hash.hexdigest()

md5 = Hasher(hashlib.md5)
sha1 = Hasher(hashlib.sha1)
md5(somefile)	
						

Awesome decorators


from functools import wraps

def retry(count=5, exc_type=Exception):
    def decorator(func):
        @wraps(func)
        def result(*args, **kwargs):
            last_exc = None
            for _ in range(count):
                try:
                    return func(*args, **kwargs)
                except exc_type as e:
                    last_exc = e
            raise last_exc
         return result
     return decorator

@retry
def might_fail():
    # some code here	
						

class Cache:
    def __init__(self):
        self.memo = {}

    def store(self, fn):
        def wrapper(*args):
            if args not in self.memo:
                self.memo[args] = fn(*args)
            return self.memo[args]
        return wrapper

    def clear(self):
        self.memo.clear()

cache = Cache()

@cache.store
def somefct():
    return expensive_call()

cache.clear()
or, as of Python 3.4, use the built-in @lru_cache

Powerful containers


>>> from collections import Counter
>>> colors = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> counter = Counter(colors)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
>>> counter.most_common()[0][0]
'blue'				
						

>>> Point = collections.namedtuple('Point', 'x y')
>>> p = Point(1, y=2)
Point(x=1, y=2)
>>> p.x
1
>>> getattr(p, 'y')
2
>>> p._fields
('x', 'y')			
						

and so many MORE!

date & time handling utilities
powerful regex
os specific operations
dev tools: pydoc, unittest, pdb

I still think libraries are cool, okay?

This is it. Thank you!