Skip to content

Commit

Permalink
property working
Browse files Browse the repository at this point in the history
  • Loading branch information
dipinknair committed Nov 11, 2024
1 parent c61449e commit 4e2d17d
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 93 deletions.
24 changes: 17 additions & 7 deletions src/ansys/mechanical/core/embedding/rpc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
import time

import rpyc
from rpyc.utils.classic import upload


class Client:
"""Client for connecting to Mechanical services."""
Expand Down Expand Up @@ -57,8 +55,20 @@ def __init__(self, host: str, port: int, timeout: float = 60.0):
def __getattr__(self, attr):
if hasattr(self.root, attr):
return getattr(self.root, attr)
# if hasattr(self.root, attr+"__property__"):
# return getattr(self.root)
propget_name = f"propget_{attr}"
if hasattr(self.root, propget_name):
exposed_fget = getattr(self.root, propget_name)
return exposed_fget()
return self.__dict__.items[attr]
"""
def __setattr__(self, attr, value):
if hasattr(self.root, attr):
inner_prop = getattr(self.root.__class__, attr)
if isinstance(inner_prop, property):
inner_prop.fset(self.root, value)
else:
super().__setattr__(attr, value)
"""

def _connect(self):
self._wait_until_ready()
Expand Down Expand Up @@ -158,6 +168,6 @@ def _download_file(self, remote_file_path, local_file_path, chunk_size=1024, ove

print(f"File {remote_file_path} downloaded to {local_file_path}")

@property
def project_directory(self):
return self.root.exposed_run_python_script("ExtAPI.DataModel.Project.ProjectDirectory")
# @property
# def project_directory(self):
# return self.root.exposed_run_python_script("ExtAPI.DataModel.Project.ProjectDirectory")
69 changes: 51 additions & 18 deletions src/ansys/mechanical/core/embedding/rpc/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _install_class(self, impl):
if methodtype == MethodType.METHOD:
self._install_method(method)
elif methodtype == MethodType.PROP:
self._install_property(method)
self._install_property(method, methodname)

def on_connect(self, conn):
"""Handle client connection."""
Expand All @@ -78,13 +78,27 @@ def on_disconnect(self, conn):
"""Handle client disconnection."""
print("Client disconnected")

def _curry_property(self, prop, propname, get: bool):
"""Curry the given property."""

def posted(*arg):
def curried():
if get:
return getattr(prop._owner, propname)
else:
setattr(prop._owner, propname, *arg)

return self._poster.post(curried)

return posted

def _curry_method(self, method, realmethodname):
"""Curry the given method."""

def posted(*args):
def posted(*args, **kwargs):
def curried():
original_method = getattr(method._owner, realmethodname)
result = original_method(*args)
result = original_method(*args, **kwargs)
return result

return self._poster.post(curried)
Expand All @@ -104,28 +118,47 @@ def curried():

return posted

def _install_property(self, property: property):
def _install_property(self, prop: property, propname: str):
"""Install property with inner and exposed pairs."""
# TODO: check how rpyc has property
print("installing property")
# print("installing property")

# install exposed_fget and fset
# exposed fget gets the inner attr ?

# get value using poster here

if prop.fget:
exposed_get_name = f"exposed_propget_{propname}"
def exposed_propget():
"""Convert to exposed getter."""
f = self._curry_property(prop.fget, propname, True)
result = f()
return result
setattr(self, exposed_get_name, exposed_propget)
if prop.fset:
exposed_set_name = f"exposed_propset_{propname}"
def exposed_propset(arg):
"""Convert to exposed getter."""
f = self._curry_property(prop.fset, propname, True)
result = f(arg)
return result
setattr(self, exposed_set_name, exposed_propset)

def _install_method(self, method):
"""Install methods of impl with inner and exposed pairs."""
exposed_name = f"exposed_{method.__name__}"
inner_name = f"inner_{method.__name__}"
methodname = method.__name__
self._install_method_with_name(methodname, methodname)

def inner_method(*args):
"""Convert to inner method."""
result = method(*args)
return result
def _install_method_with_name(self, method, methodname, innername):
"""Install methods of impl with inner and exposed pairs."""
exposed_name = f"exposed_{methodname}"

def exposed_method(*args):
def exposed_method(*args, **kwargs):
"""Convert to exposed method."""
f = self._curry_method(method, method.__name__)
result = f(*args)
f = self._curry_method(method, innername)
result = f(*args, **kwargs)
return result

setattr(self, inner_name, inner_method)
setattr(self, exposed_name, exposed_method)

def _install_function(self, function):
Expand Down Expand Up @@ -271,9 +304,9 @@ def __init__(self, app):
def __repr__(self):
return '"ServiceMethods instance"'

# @property
@property
@remote_method
def get_project_name(self):
def project_name(self):
return self.helper_func()

def helper_func(self):
Expand Down
2 changes: 2 additions & 0 deletions src/ansys/mechanical/core/embedding/rpc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ def try_get_remote_property(attrname: str, obj: typing.Any) -> typing.Tuple[str,
if class_attribute.fget:
if isinstance(class_attribute.fget, remote_method):
getmethod = class_attribute.fget
getmethod._owner = obj
if class_attribute.fset:
if isinstance(class_attribute.fset, remote_method):
setmethod = class_attribute.fset
setmethod._owner = obj

return (attrname, property(getmethod, setmethod))

Expand Down
1 change: 1 addition & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def __setattr__(self, attr, value):
inner_prop = getattr(self._inner.__class__, attr)
if isinstance(inner_prop, property):
inner_prop.fset(self._inner, value)
print(inner_prop.fset.__name__)
else:
super().__setattr__(attr, value)

Expand Down
19 changes: 10 additions & 9 deletions test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,20 @@ def launch_mechanical(port: int, version: int) -> Client:

# c2: DefaultServiceMethods = launch_server() => creates client, returns client.roo

# print(client.get_project_name())
client.project_name = "hello"
print(client.project_name)
# client.change_project_name("lol")
# print(client.get_project_name())
# print(client.run_python_script("ExtAPI.DataModel.Project", False, "WARNING", 2000))

print(
client.run_python_script(
"ExtAPI.DataModel.Project",
enable_logging=False,
log_level="WARNING",
progress_interval=2000,
)
)
# print(
# client.run_python_script(
# "ExtAPI.DataModel.Project",
# enable_logging=False,
# log_level="WARNING",
# progress_interval=2000,
# )
# )
# print(client.project_directory)

# will this work ? since file is not in server
Expand Down
67 changes: 67 additions & 0 deletions testcopy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
G_stuff = 1

class Foo:
@property
def bar(self):
return G_stuff
@bar.setter
def bar(self, value):
global G_stuff
G_stuff = value

def propget_bar(self):
return self.bar
def propset_bar(self, value):
self.bar = value


class Baz:
def __init__(self, typ):
print("callinginit")
super().__setattr__('_inner', typ())
super().__setattr__('x', 100)
# here install the property

def __getattr__(self, attr):
print(f"calling gettr {attr}")
if hasattr(self._inner, attr):
return getattr(self._inner, attr)
return self.__dict__.items[attr]

def __setattr__(self, attr, value):
if hasattr(self._inner, attr):
inner_prop = getattr(self._inner.__class__, attr)
if isinstance(inner_prop, property):
inner_prop.fset(self._inner, value)
else:
super().__setattr__(attr, value)

import sys

if __name__ == "__main__":
foo=Foo()
print(foo.__class__.__dict__)
barprop: property =getattr(Foo, "bar")
print(barprop.fget(foo))
print(barprop.fset(foo, 3))
print(foo.bar)
baz = Baz(Foo)
sys.exit(0)

# baz = Baz(Foo)
# assert baz.bar == 1
# print(baz.bar)
# print(baz.x)
# baz.x=200
# assert baz.x ==200
# baz.bar = 2
# #setattr(baz, "bar", 2)
# assert G_stuff == 2
# assert baz.bar == 2



# x = "some string"
# x.capitalize()

# getattr(getattr(x, "capitalize"), "__call__")()
59 changes: 0 additions & 59 deletions tests/embedding/test_rpc.py

This file was deleted.

0 comments on commit 4e2d17d

Please sign in to comment.