Slide 1

Slide 1 text

Python Debugging with PuDB, Charles, and cProfile Christopher Beacham / Lady Red, Senior Engineer @ Hipmunk Hipmunk: [email protected] Personal: [email protected]

Slide 2

Slide 2 text

I write code, and this is a little bit embarrassing, but…

Slide 3

Slide 3 text

I write code, and this is a little bit embarrassing, but… My Code Has Bugs

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

The faster we can find bugs, the faster we can fix them

Slide 6

Slide 6 text

The faster we can find bugs, the faster we can fix them It’s hard to see what a program is doing!

Slide 7

Slide 7 text

Debugging tools can make the invisible visible.

Slide 8

Slide 8 text

PuDB - Interactive visual debugger. Charles Proxy - Web debugging proxy cProfile + others - python profilers and visualization tools Tools we’ll cover:

Slide 9

Slide 9 text

Stop using Print Statements One is never enough You’ll never find a problem you aren’t specifically looking for You have to remember to delete them

Slide 10

Slide 10 text

Debugging Process Systematically check your assumptions in a binary search First Test

Slide 11

Slide 11 text

Debugging Process Systematically check your assumptions in a binary search First Test Second Test

Slide 12

Slide 12 text

Debugging Process Systematically check your assumptions in a binary search First Test Second Test Third Test

Slide 13

Slide 13 text

Debugging Process Systematically check your assumptions in a binary search First Test Second Test Third Test FOUND THE BUG

Slide 14

Slide 14 text

How many of you have used a debugger before?

Slide 15

Slide 15 text

PuDB PuDB is my favorite debugger. It’s very similar to pdb and ipdb, but it’s VISUAL. It show you everything in scope, your code, and a terminal.

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Let’s USE it!

Slide 27

Slide 27 text

We’re going to use PuDB to debug a fortune webserver written in python (flask)

Slide 28

Slide 28 text

PuDB: Extra Credit - You can use PuDB for unit tests - both in the test, - the code under test, - and you can step smoothly between them - If you use nose testing, you can drop into Pudb on failures with the nose-pudb package - PuDB will catch exceptions, giving you a chance to inspect the entire scope.

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

How many of you have used one of these tools? (Dev tools) nettop curl

Slide 31

Slide 31 text

What is Charles? ● Charles is a web debugging proxy ● It shows the content and statistics about any HTTP/HTTPS traffic that passes through it. ● You can repeat requests, modify, intercept, all the forms of beautiful meddling.

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

Breaking SSL Charles is the Man in the Middle

Slide 34

Slide 34 text

Fortune - now with distributed architecture?

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

(make slide showing editing a request)

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Let’s USE it!

Slide 54

Slide 54 text

Charles - Extra Credit ● It can publish a gist to github of a request/response ● You can view xml/json/protocol buffers in a structured way ● You can get the curl command for a given request ● Use breakpoints or rewrite tool to modify any request in realtime

Slide 55

Slide 55 text

Charles extra credit - continued ● You can throttle to mimic low-speed connections ● You can blacklist hosts to block connections to them ● It can serve local files from a local folder in response to requests to a server ● You can use Charles “Mirror” tool to record a mirror of a site to disk, and then use Map Local to serve it back up ● … there’s a ton more

Slide 56

Slide 56 text

Charles is nagware After you install it, it’ll keep bugging you until you buy a license. I think it’s just one developer building it, so yeah, if you find it useful, it’s a good cause to buy a license and support his work. (I’m not being compensated for this talk - I just like this software)

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

How many of you have had code that was slow?

Slide 59

Slide 59 text

How many of you have had code that was slow? How many have used profiling to identify why?

Slide 60

Slide 60 text

Is anyone not sure what a profiler is or how it works?

Slide 61

Slide 61 text

Profiling Profiling is a different hippopotamus from debugging.

Slide 62

Slide 62 text

Profiling - Interpreting a profiler output is almost an art.

Slide 63

Slide 63 text

Profiling - Interpreting a profiler output is almost an art. - You can’t recognize wrong unless you would know what right looks like.

Slide 64

Slide 64 text

Profiling - Interpreting a profiler output is almost an art. - You can’t recognize wrong unless you would know what right looks like. - A lot of profiling is reading between the lines

Slide 65

Slide 65 text

Profiling - Always profile before making performance-related improvements.

Slide 66

Slide 66 text

Profiling - Always profile before making performance-related improvements. - Profiling before making performance-related improvements can keep you from wasting your time

Slide 67

Slide 67 text

Profiling - Always profile before making performance-related improvements. - Profiling before making performance-related improvements can keep you from wasting your time - Your assumptions about what is taking the most time are often wrong.

Slide 68

Slide 68 text

Profiling - Always profile before making performance-related improvements. - Profiling before making performance-related improvements can keep you from wasting your time - Your assumptions about what is taking the most time are often wrong. - Speeding up code that is already fast is useless!

Slide 69

Slide 69 text

Profiling - Always profile before making performance-related improvements. - Profiling before making performance-related improvements can keep you from wasting your time - Your assumptions about what is taking the most time are often wrong. - Speeding up code that is already fast is useless! - You must profile with realistic load / realistic data

Slide 70

Slide 70 text

The Sad State of Python Profilers I wanted to tell you that there was an awesome profiler tool you should use...

Slide 71

Slide 71 text

The Sad State of Python Profilers I wanted to tell you that there was an awesome profiler tool you should use...

Slide 72

Slide 72 text

cProfile! Python has 3 built-in profilers, but cProfile is the most commonly used one. It’s in the standard library. python -m cProfile [-o output_file] [-s sort_order] myscript.py Two output formats - binary and human readable.

Slide 73

Slide 73 text

“Human readable” output I find it’s best to sort by cumtime (cumulative time) Difficult to distinguish which times are additive, and which times are nested. Gets confusing for anything more than the simplest program 47371645 function calls in 20.013 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.001 0.001 20.013 20.013 simulation.py:3() 2 9.524 4.762 20.006 10.003 simulation.py:24(run_simulation) 2441124 1.842 0.000 2.324 0.000 queue.py:82(enqueue) 2297290 1.804 0.000 2.320 0.000 queue.py:39(enqueue) 2294714 1.369 0.000 1.369 0.000 queue.py:52(dequeue) 18940222 1.260 0.000 1.260 0.000 {method 'random' of '_random.Random' objects} 2438880 1.160 0.000 1.160 0.000 queue.py:95(dequeue) 4738410 0.750 0.000 0.750 0.000 {max} 2297290 0.517 0.000 0.517 0.000 queue.py:28(__init__) 2441124 0.482 0.000 0.482 0.000 queue.py:69(__init__) 2439596 0.347 0.000 0.347 0.000 queue.py:105(is_empty) 2295021 0.342 0.000 0.342 0.000 queue.py:62(is_empty) 2441122 0.300 0.000 0.300 0.000 queue.py:102(size) 2297288 0.282 0.000 0.282 0.000 queue.py:59(size) 9471 0.028 0.000 0.028 0.000 {built-in method now} 1 0.001 0.001 0.004 0.004 random.py:40() 1 0.002 0.002 0.002 0.002 hashlib.py:56() 1 0.001 0.001 0.002 0.002 queue.py:1()

Slide 74

Slide 74 text

47371645 function calls in 20.013 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.001 0.001 20.013 20.013 simulation.py:3() 2 9.524 4.762 20.006 10.003 simulation.py:24(run_simulation) 2441124 1.842 0.000 2.324 0.000 queue.py:82(enqueue) 2297290 1.804 0.000 2.320 0.000 queue.py:39(enqueue) 2294714 1.369 0.000 1.369 0.000 queue.py:52(dequeue) 18940222 1.260 0.000 1.260 0.000 {method 'random' of '_random.Random' objects} 2438880 1.160 0.000 1.160 0.000 queue.py:95(dequeue) 4738410 0.750 0.000 0.750 0.000 {max}

Slide 75

Slide 75 text

cProfile Visualizers cProfile can make binary output that can be read by several tools.

Slide 76

Slide 76 text

pyprof2calltree + qcachegrind

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

while True: now = datetime.now() ...

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

After - datetime.now is no more! while True: now = datetime.now() ... while True: if count % 1000 == 0: now = datetime.now() …

Slide 81

Slide 81 text

Simulation complete, ran 287,768.6 operations per second Simulation complete, ran 419,200.0 operations per second

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

PuDB Install: pip install pudb Invoke import pudb; pudb.set_trace() PUDB https://documen.tician.de/pudb/ Nose-PUDB (for nose testing) - https://pypi.python.org/pypi/nose-pudb

Slide 85

Slide 85 text

Charles https://www.charlesproxy.com

Slide 86

Slide 86 text

Profiling cProfile https://docs.python.org/3/library/profile.html Using cProfile w/ pyprof2calltree and kcachegrind/qcachegrind: https://julien.danjou.info/blog/2015/guide-to-python-profiling-cprofile-concrete-case -carbonara

Slide 87

Slide 87 text

Happy Hunting!!