Graphical Python debugger which lets you easily view the values of all evaluated expressions

Overview

logo birdseye

Build Status Supports Python versions 2.7, 3.5, and 3.6 Join the chat at https://gitter.im/python_birdseye/Lobby

birdseye is a Python debugger which records the values of expressions in a function call and lets you easily view them after the function exits. For example:

Hovering over expressions

You can use birdseye no matter how you run or edit your code. Just pip install birdseye, add the @eye decorator as seen above, run your function however you like, and view the results in your browser. It's also integrated with some common tools for a smoother experience.

Rather than stepping through lines, move back and forth through loop iterations and see how the values of selected expressions change:

Stepping through loop iterations

See which expressions raise exceptions, even if they’re suppressed:

Exception highlighting

Expand concrete data structures and objects to see their contents. Lengths and depths are limited to avoid an overload of data.

Exploring data structures and objects

Calls are organised into functions (which are organised into files) and ordered by time, letting you see what happens at a glance:

List of function calls

Read more documentation here

Comments
  • IndexError: list index out of range

    IndexError: list index out of range

    After running python -m birdseye.clear_db and executing the program again, I'm now getting this exception when I click on a function from the front page.

    Traceback (most recent call last):
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1836, in __call__
        return self.wsgi_app(environ, start_response)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1820, in wsgi_app
        response = self.make_response(self.handle_exception(e))
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1403, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
        raise value
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1817, in wsgi_app
        response = self.full_dispatch_request()
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1477, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1381, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
        raise value
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1475, in full_dispatch_request
        rv = self.dispatch_request()
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/flask/app.py", line 1461, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/littleutils/__init__.py", line 227, in wrapper
        return func(*args, **kwargs)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/birdseye/db.py", line 229, in wrapper
        return func(session, *args, **kwargs)
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/birdseye/server.py", line 132, in func_view
        func = session.query(Function).filter_by(file=path, name=func_name)[0]
      File "/home/user/.envs/dotfiles-_bp8OBTv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2692, in __getitem__
        return list(self[item:item + 1])[0]
    IndexError: list index out of range
    
    

    birdseye 0.8.1 python 3.6.5 ubuntu 18.04

    opened by ghost 11
  • Logo

    Logo

    Current attempt:

    snake-birdseye

    I'm not a graphic designer, so I'm hoping that someone more skilled can make this look better. For now, I'm thinking about the general concept.

    @Almenon, what are your first impressions of this?

    opened by alexmojaki 11
  • VSCode extension

    VSCode extension

    Let me start off by saying great work! Your display is what I wish I had over in AREPL, but I just return the final variables and call it a day :P

    If I have time I might be able to work on a VSCode extension for birdseye, are you interested?

    It looks pretty simple to implement, it would just require checking if the user has birdseye, spawning a process

    python -m birdseye

    Then opening localhost:7777 in a preview pane.

    I already have a preview pane boilerplate to extend from so that part's pretty much done.

    Or theoretically that's how it would work, anyways. I wouldn't be suprised if there was problems along the way.

    opened by Almenon 5
  • Jupyter/IPython notebook plugin/integration

    Jupyter/IPython notebook plugin/integration

    The idea is to mark a notebook cell for tracing by birdseye (perhaps with some magic %birdseye or %eye) and then when you run the cell it creates a new cell below with the code traced as in normal birdseye, i.e. expressions and statements boxed and hoverable.

    This would probably mean some refactoring in this package followed by creating a new package to contain the plugin. I'm not sure of the details at the moment as I've never created a notebook plugin and have very little experience with notebooks in general.

    enhancement 
    opened by alexmojaki 5
  • No module named 'birdseye', windows 10, jupyter lab

    No module named 'birdseye', windows 10, jupyter lab

    Trying to use birdseye with %load_ext birdseye in jupyter lab, win 10. Getting error ModuleNotFoundError: No module named 'birdseye' On another machine with win 7 - everything's perfectly fine.

    Tried different approaches - with conda, virtualenv, different python versions, etc. No result.

    opened by Dene33 4
  • add argparse to handle command line parameters

    add argparse to handle command line parameters

    Hi, I've add argparse in birdseye/server.py to handle command line parameters, which for now are host and port for web service. This is an insignificant modify but I do think it's helpful for the people who like to writing their codes over the clouds (where they can hardly open a browser to debug because they are totally command-line environments).

    opened by houluy 4
  • IPython extension gives ImportError: cannot import name 'ThreadingMixIn' from 'werkzeug.serving'

    IPython extension gives ImportError: cannot import name 'ThreadingMixIn' from 'werkzeug.serving'

    In [1]: %load_ext birdseye
    ---------------------------------------------------------------------------
    ImportError                               Traceback (most recent call last)
    Input In [1], in <cell line: 1>()
    ----> 1 get_ipython().run_line_magic('load_ext', 'birdseye')
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2294, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
       2292     kwargs['local_ns'] = self.get_local_scope(stack_depth)
       2293 with self.builtin_trap:
    -> 2294     result = fn(*args, **kwargs)
       2295 return result
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/IPython/core/magics/extension.py:33, in ExtensionMagics.load_ext(self, module_str)
         31 if not module_str:
         32     raise UsageError('Missing module name.')
    ---> 33 res = self.shell.extension_manager.load_extension(module_str)
         35 if res == 'already loaded':
         36     print("The %s extension is already loaded. To reload it, use:" % module_str)
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/IPython/core/extensions.py:76, in ExtensionManager.load_extension(self, module_str)
         69 """Load an IPython extension by its module name.
         70 
         71 Returns the string "already loaded" if the extension is already loaded,
         72 "no load function" if the module doesn't have a load_ipython_extension
         73 function, or None if it succeeded.
         74 """
         75 try:
    ---> 76     return self._load_extension(module_str)
         77 except ModuleNotFoundError:
         78     if module_str in BUILTINS_EXTS:
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/IPython/core/extensions.py:99, in ExtensionManager._load_extension(self, module_str)
         94             print(("Loading extensions from {dir} is deprecated. "
         95                    "We recommend managing extensions like any "
         96                    "other Python packages, in site-packages.").format(
         97                   dir=compress_user(self.ipython_extension_dir)))
         98 mod = sys.modules[module_str]
    ---> 99 if self._call_load_ipython_extension(mod):
        100     self.loaded.add(module_str)
        101 else:
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/IPython/core/extensions.py:151, in ExtensionManager._call_load_ipython_extension(self, mod)
        149 def _call_load_ipython_extension(self, mod):
        150     if hasattr(mod, 'load_ipython_extension'):
    --> 151         mod.load_ipython_extension(self.shell)
        152         return True
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/birdseye/__init__.py:38, in load_ipython_extension(ipython_shell)
         37 def load_ipython_extension(ipython_shell):
    ---> 38     from birdseye.ipython import BirdsEyeMagics
         39     ipython_shell.register_magics(BirdsEyeMagics)
    
    File ~/.pyenv/versions/3.10.4/lib/python3.10/site-packages/birdseye/ipython.py:13, in <module>
         11 from traitlets import Unicode, Int, Bool
         12 from werkzeug.local import LocalProxy
    ---> 13 from werkzeug.serving import ThreadingMixIn
         15 from birdseye.bird import PY2, Database
         16 from birdseye import server, eye
    
    ImportError: cannot import name 'ThreadingMixIn' from 'werkzeug.serving' (/home/andrei/.pyenv/versions/3.10.4/lib/python3.10/site-packages/werkzeug/serving.py)
    

    I tried uninstalling and then installing Werkzeug and Flask, but the same error is still happening.

    opened by carlosplanchon 3
  • Compatability with python 3.8

    Compatability with python 3.8

    Hi, Love this tool. I keep telling everyone about it. Python 3.8 compatibility would be awesome!

    Edit: I forked it, changed nothing besides adding the 'Programming Language :: Python :: 3.8' classifier inside setup.py, pip installed it locally and it works with 3.8 as is (which makes sense).

    I felt silly creating a PR for adding a single line.

    opened by giladbarnea 3
  • http://localhost:7777/ipython_call rejected conection

    http://localhost:7777/ipython_call rejected conection

    im extra virgin in programming haha and using on thonny, the thing is, the program open a browser windows and then, dont show how is supposed to, i even make: 0. my private ip dmz, turn down smartscreen (windows) 1 .antivirus defender on all his options 2. make exclusions for firewall, deactivated the firewall, changed the port to various numbers 3. open manually the ports on router, i mean, how unsecure my notebook is supposed to be?! hahaha

    image

    packages in thonny: 0. image 1. image

    the bottom of this, is that im trying to understand this code:

    def tri_recursion(k):
      if(k>0):
        result = k+tri_recursion(k-2)
        print(result)
      else:
        result = 0
      return result
    
    print("\n\nRecursion Example Results")
    tri_recursion(6)
    

    any help will be greatly appreciated, even links with google searches, I'm so lost haha

    opened by skoll43 3
  • want birdseye to be included in a pycon poster?

    want birdseye to be included in a pycon poster?

    I'll be going to Pycon in early May to do a poster presentation for AREPL ~ would you like to have birdseye be included in that poster? It falls under the same category of visual debuggers, and I wouldn't mind giving some space on the poster to promote it. Thousands of people attend Pycon each year and it would be a great marketing opportunity for birdseye.

    The poster is 36" by 48" - I could give you 9" by 11". You can send me a mockup or pic or whatever for what you want it to look like. The catch is that I'm planning on printing the poster by May 1, so that would not give you a lot of time :/ Sorry about the late notice.

    I tried e-mailing you but I'm not sure if it went through spam filter.

    opened by Almenon 3
  • Using birdseye in interactive session

    Using birdseye in interactive session

    I want to be able to decorate functions in an interactive session.

    When I try to evaluate such function, it will throw the exception:

    FileNotFoundError: [Errno 2] No such file or directory: '<ipython-input-7-01fc7a9cd10c>'
    

    Initially I thought: go for an easy/hacky fix whenever the filename starts with "<", then replace it with something like "interactive-session".

    But I see you depend on it for the source code from filename. You could try inspect.getsource(obj) instead.

    opened by kootenpv 3
  • Expressions inside f-strings don't get observed

    Expressions inside f-strings don't get observed

    I have written a lot of little Python3 scripts by now and now I discovered the "Birdseye" debugger in Thonny and tried it out. It's honestly a great debugger with one big flaw:
    Inside an f-string, for example

    try:
        raise SyntaxError('Oops!')
    except Exception as e:
        print(f'{type(e).__name__}: {e}')
    

    It correctly prints out SyntaxError: Oops! but in Birdseye the f-string is just one block: birdseye Would it be possible to split up the f-string into its methods and string parts in Birdseye?

    opened by Stehlampe2020 1
  • Feature request: recursively trace calls within traced function

    Feature request: recursively trace calls within traced function

    Hi, thanks for birdseye!

    I often use it to trace a whole flow, e.g a web request, from endpoint to response. It's especially useful when the flow is complicated and can't be debugged locally.

    It can get cumbersome to @eye the first function -> run it -> add an @eye -> run it again -> add the next @eye -> etc.

    It would be great if one could e.g

    def bar(): ...
    
    def baz(): ...
    
    @deep_eye
    def foo(call_bar: bool):
        if call_bar:
            return bar()
        return baz()
    

    Which would be equivalent to simply decorating foo, bar and baz with @eye.

    To avoid exploding, maybe a @deep_eye(trace_limit=10) option could be supported.

    I know birdseye can trace whole modules, but more often than not, functions call functions from other modules, so I'm imagining a trace of a call tree that spans different modules.

    What are your thoughts?

    Thanks, Gilad

    opened by giladbarnea 1
  • Tracing within an exec'd string does not work

    Tracing within an exec'd string does not work

    I am attempting to use birdseye from within another tool, and a part of what it does is modify the source dynamically. This causes attempts to get a filename to fail. Is there a way to get around this without, say creating a temporary file?

    ...
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/pyls_livepy/tracer.py", line 108, in trace_and_report
        report = run_trace_2(modded_source)
                 │           └ 'import pyls_livepy\n\n@pyls_livepy.eye\ndef func(x):\n    """\n    >>> func(5)\n    0\n    """\n    return x * x\n\nfunc(5)\n'
                 └ <function run_trace_2 at 0x7fe36615d830>
    > File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/pyls_livepy/tracer.py", line 78, in run_trace_2
        exec(source)
             └ 'import pyls_livepy\n\n@pyls_livepy.eye\ndef func(x):\n    """\n    >>> func(5)\n    0\n    """\n    return x * x\n\nfunc(5)\n'
      File "<string>", line 3, in <module>
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/birdseye/__init__.py", line 24, in __call__
        return self.__val()(*args, **kwargs)
               │             │       └ {}
               │             └ (<function func at 0x7fe369310e60>,)
               └ <birdseye._SimpleProxy object at 0x7fe368e31750>
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/birdseye/tracer.py", line 273, in __call__
        return self.trace_function(func)
               │    │              └ <function func at 0x7fe369310e60>
               │    └ <function BirdsEye.trace_function at 0x7fe3671f07a0>
               └ <birdseye.bird.BirdsEye object at 0x7fe3671ef110>
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/birdseye/bird.py", line 410, in trace_function
        new_func = super(BirdsEye, self).trace_function(func)
                         │         │                    └ <function func at 0x7fe369310e60>
                         │         └ <birdseye.bird.BirdsEye object at 0x7fe3671ef110>
                         └ <class 'birdseye.bird.BirdsEye'>
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/birdseye/tracer.py", line 204, in trace_function
        source = read_source_file(filename)
                 │                └ '<string>'
                 └ <function read_source_file at 0x7fe36841d8c0>
      File "/home/skeledrew/Projects/pyls-livepy/.nox/make_pyls_livepy_test_env/lib/python3.7/site-packages/birdseye/utils.py", line 202, in read_source_file
        with open_with_encoding_check(filename) as f:
             │                        └ '<string>'
             └ <function open at 0x7fe369e3c4d0>
      File "/home/skeledrew/.conda/envs/utils_env/lib/python3.7/tokenize.py", line 447, in open
        buffer = _builtin_open(filename, 'rb')
                 │             └ '<string>'
                 └ <built-in function open>
    
    FileNotFoundError: [Errno 2] No such file or directory: '<string>'
    
    opened by skeledrew 6
  • Async function tracing

    Async function tracing

    As I see in the code of this debugger, the async functions were deliberately forbidden for tracing. What's the reason for it? And can we expect to see this implemented in the future? I mean the tracing of async functions. Thank you.

    opened by Xeizzeth 1
  • feature_request(IDE): Sublime Text integration

    feature_request(IDE): Sublime Text integration

    1. Summary

    It would be nice, if will be realized integration birdseye for Sublime Text 3. Plugins for Sublime Text are written in Python.

    2. Argumentation

    1. Sublime Text — second most common Python IDE (after PyCharm) by Python Software Foundation Statistics.
    2. See features of Sublime Text for Python. There is everything except the debugger.

    3. Already existing Sublime Text debuggers

    1. Plugin Debugger — bugs, not developed from 2014.
    2. SublimeDebuggerbugs, poor documentation.

    Thanks.

    enhancement 
    opened by Kristinita 6
Owner
Alex Hall
Python metaprogrammer, looking for work
Alex Hall
Full-screen console debugger for Python

PuDB: a console-based visual debugger for Python Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keybo

Andreas Klöckner 2.6k Jan 1, 2023
Debugger capable of attaching to and injecting code into python processes.

DISCLAIMER: This is not an official google project, this is just something I wrote while at Google. Pyringe What this is Pyringe is a python debugger

Google 1.6k Dec 15, 2022
pdb++, a drop-in replacement for pdb (the Python debugger)

pdb++, a drop-in replacement for pdb What is it? This module is an extension of the pdb module of the standard library. It is meant to be fully compat

null 1k Jan 2, 2023
Voltron is an extensible debugger UI toolkit written in Python.

Voltron is an extensible debugger UI toolkit written in Python. It aims to improve the user experience of various debuggers (LLDB, GDB, VDB an

snare 5.9k Dec 30, 2022
NoPdb: Non-interactive Python Debugger

NoPdb: Non-interactive Python Debugger Installation: pip install nopdb Docs: https://nopdb.readthedocs.io/ NoPdb is a programmatic (non-interactive) d

Ondřej Cífka 67 Oct 15, 2022
Tracing instruction in lldb debugger.Just a python-script for lldb.

lldb-trace Tracing instruction in lldb debugger. just a python-script for lldb. How to use it? Break at an address where you want to begin tracing. Im

null 156 Jan 1, 2023
Visual Interaction with Code - A portable visual debugger for python

VIC Visual Interaction with Code A simple tool for debugging and interacting with running python code. This tool is designed to make it easy to inspec

Nathan Blank 1 Nov 16, 2021
An improbable web debugger through WebSockets

wdb - Web Debugger Description wdb is a full featured web debugger based on a client-server architecture. The wdb server which is responsible of manag

Kozea 1.6k Dec 9, 2022
PINCE is a front-end/reverse engineering tool for the GNU Project Debugger (GDB), focused on games.

PINCE is a front-end/reverse engineering tool for the GNU Project Debugger (GDB), focused on games. However, it can be used for any reverse-engi

Korcan Karaokçu 1.5k Jan 1, 2023
Little helper to run Steam apps under Proton with a GDB debugger

protongdb A small little helper for running games with Proton and debugging with GDB Requirements At least Python 3.5 protontricks pip package and its

Joshie 21 Nov 27, 2022
Full featured multi arch/os debugger built on top of PyQt5 and frida

Full featured multi arch/os debugger built on top of PyQt5 and frida

iGio90 1.1k Dec 26, 2022
Arghonaut is an interactive interpreter, visualizer, and debugger for Argh! and Aargh!

Arghonaut Arghonaut is an interactive interpreter, visualizer, and debugger for Argh! and Aargh!, which are Befunge-like esoteric programming language

Aaron Friesen 2 Dec 10, 2021
A simple rubber duck debugger

Rubber Duck Debugger I found myself many times asking a question on StackOverflow or to one of my colleagues just for finding the solution simply by d

null 1 Nov 10, 2021
Hdbg - Historical Debugger

hdbg - Historical Debugger This is in no way a finished product. Do not use this

Fivreld 2 Jan 2, 2022
Trashdbg - TrashDBG the world's worse debugger

The world's worse debugger Over the course of multiple OALABS Twitch streams we

OALabs 21 Jun 17, 2022
The official code of LM-Debugger, an interactive tool for inspection and intervention in transformer-based language models.

LM-Debugger is an open-source interactive tool for inspection and intervention in transformer-based language models. This repository includes the code

Mor Geva 110 Dec 28, 2022
Django package to log request values such as device, IP address, user CPU time, system CPU time, No of queries, SQL time, no of cache calls, missing, setting data cache calls for a particular URL with a basic UI.

django-web-profiler's documentation: Introduction: django-web-profiler is a django profiling tool which logs, stores debug toolbar statistics and also

MicroPyramid 77 Oct 29, 2022
Trace all method entries and exits, the exit also prints the return value, if it is of basic type

Trace all method entries and exits, the exit also prints the return value, if it is of basic type. The apk must have set the android:debuggable="true" flag.

Kurt Nistelberger 7 Aug 10, 2022
printstack is a Python package that adds stack trace links to the builtin print function, so that editors such as PyCharm can link you to the source of the print call.

printstack is a Python package that adds stack trace links to the builtin print function, so that editors such as PyCharm can link to the source of the print call.

null 101 Aug 26, 2022