Access Method inside class using anvil.server.call

Using uplink to communicate with code that I have written in Pycharm. The simple class below contains a function inside the class with args that are defined with values from textboxes on an anvil form. When running the code, I get the following message: anvil.server.UplinkDisconnectedError: The uplink server for “plate_geometry” has been disconnected at [userInterface, line 21](javascript:void(0)) . It appears that anvil cannot find the function when nested inside a class. Is there a work around for this; if not, what is a suggested alternative?

Code below is located in pycharm module

class Plate:
    def __init__(self, a, b):
        self.a = a
        self.b = b

   @anvil.server.callable()
       def plate_geometry():
           return self.a * self.b

Code below is from anvil form

anvil.server.call('plate_geometry', a, b)

I don’t think you should have the brackets for the decorator it should be just: @anvil.server.callable

Normally you would be creating an instance of the class, then calling the method, eg :

p = Plate()
p.geometry(a,b)

If you want to call the method directly as in your example, you would do better to extract the function from the class. You could for example do this in your uplink module :

@anvil.server.callable
def my_geometry_call(a,b):
  p = Plate()
  return p.plate_geometry(a,b)

I may, of course, have misunderstood.

2 Likes

Perhaps question 1 should be, which instance of class Plate should be responding?

  1. Plate.plate_geometry() uses self, so it needs to receive self as its 1st parameter. You may be used to C++, which passes (the equivalent) this implicitly. But Python requires it to be explicit. (As a long-time C++ programmer, I stub my toe on that repeatedly. :sweat_smile:)
  2. Unfortunately, there is no (direct) way to pass any self through an anvil.server.call(). The caller operates in a completely different memory-address space from the callee. (In my case, they are usually in two different computers, an ocean apart.) In effect, that means that anvil.server.call() cannot be used to directly call ordinary (non-static) member functions.

It looks like you are expecting anvil.server.call to see this mismatch, and somehow invoke Plate's constructor for you. It doesn’t do that. You’ll need to be explicit:

# This is an ordinary, *non*-member function (no "self").
@anvil.server.callable
def plate_geometry(a,b):
  p = Plate(a,b)
  return p.plate_geometry()

@david.wylie and @p.colbert thanks for your timely feedback. I was afraid of this but thought I would ask anyways…the goal was to avoid creating multiple methods/functions outside of the class. Just simply trying to leverge the pycharm editor via uplink…davids solution seems like the best alternative…thanks again!

1 Like