arrow icon indicating copy to clipboard operation
arrow copied to clipboard

Using pytest to debug a flight.FlightServerBase subclass

Open pvardanis opened this issue 2 years ago • 4 comments

Describe the usage question you have. Please include as many useful details as possible.

I'd like to be able to set breakpoints in my flight.FlightServerBase subclass to be able to debug my code, using VSCode. Currently, I instantiate a local server and a client in pytest like this:

@pytest.fixture(scope="session")
def test_client():
    with InferenceFlightServer(address) as _, FlightClient(address) as client:
        yield client

and using the client to call a do_exchange function within a test like this:

writer, reader = test_client.do_exchange(descriptor)

However, I cannot make my debugger stop in any of the breakpoints within the subclass. What I'm looking for is something similar to how flask test_client works, that makes it possible to debug the service endpoints.

Here's my launch.json config:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": false
        }
    ]
}

Currently using pyarrow==12.0.1 under a macOS M1 processor.

Similar issue I found with no solution can be found here.

Component(s)

Python

pvardanis avatar Jul 24 '23 13:07 pvardanis

Hi. I have the same issue. Isn't it a bug? Can anyone reply about why does it not hit any breakpoint? Thanks

xshirax avatar Oct 24 '23 12:10 xshirax

Hit this recently, here is the workaround to use a debugger with the Flight server until it works OOTB

class MyFlightServer(flight.FlightServerBase):
    def get_flight_info(self, context: flight.ServerCallContext, descriptor: flight.FlightDescriptor) -> flight.FlightInfo:
        try:
            import prided
            pydevd.connected = True
            pydevd.settrace(suspend=False)
        except ImportError:
            # Not running in debugger
            pass
        # Do work.

delta003 avatar Oct 24 '23 12:10 delta003

FWIW - thanks to @delta003 's comment - we had success with using a decorator function:

import functools

def debuggable(func):
    """A decorator to enable GUI (i.e. PyCharm) debugging in the
       decorated Arrow Flight RPC Server function.

       See: https://github.com/apache/arrow/issues/36844
       for more details...
    """

    @functools.wraps(func)
    def wrapper_decorator(*args, **kwargs):
        try:
            import pydevd
            pydevd.connected = True
            pydevd.settrace(suspend=False)
        except ImportError:
            # Not running in debugger
            pass
        value = func(*args, **kwargs)
        return value

    return wrapper_decorator
    
    
class FlightServer(pyarrow.flight.FlightServerBase):

    @debuggable
    def get_flight_info(self, context: pyarrow.flight.ServerCallContext, descriptor: pyarrow.flight.FlightDescriptor) -> pyarrow.flight.FlightInfo:
        do_stuff()

    @debuggable
    def do_get(self, context: pyarrow.flight.ServerCallContext, ticket: pyarrow.flight.Ticket) -> pyarrow.flight.FlightDataStream:
        do_stuff()

This seemed to work great for us - we hope this helps some folks facing the same issue until it works OOTB.

prmoore77 avatar Oct 26 '23 18:10 prmoore77

This issue has been marked as stale because it has had no activity in the past 365 days. Please remove the stale label or comment below, or this issue will be closed in 14 days. If this usage question has evolved into a feature request or docs update, please remove the 'Type: usage' label and add the 'Type: enhancement' label instead.

thisisnic avatar Nov 18 '25 12:11 thisisnic