PyObjectInterface 0.0.1__tar.gz → 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyObjectInterface
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Create a web interface to interact with a class
5
5
  Home-page: https://github.com/RobertJN64/PyObjectInterface
6
6
  Author: Robert Nies
@@ -18,6 +18,7 @@ Requires-Python: >=3.8
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: typing_extensions
21
+ Requires-Dist: flask
21
22
 
22
23
  # PyObjectInterface
23
24
 
@@ -58,9 +58,11 @@ def create_WebController(obj, name, flask_app, recursion_depth = 5, create_priva
58
58
  @flask_app.route(baseurl + '/call_method/<stack>', endpoint=baseurl + '_call_method')
59
59
  def call_method(stack):
60
60
  kwargs = {argname: int(arg) for argname, arg in flask.request.args.items()} #TODO - better kwarg handling
61
- poi.call_method(stack, kwargs)
62
- # TODO - handle return value
63
- return "OK"
61
+ retval = poi.call_method(stack, kwargs)
62
+ if retval is None:
63
+ return "OK"
64
+ else:
65
+ return retval
64
66
 
65
67
  @flask_app.route(baseurl + '/get_attributes', endpoint=baseurl + '_get_attributes')
66
68
  def get_attributes():
@@ -72,7 +72,7 @@ class PyObjectInterface:
72
72
  if not method_stack.startswith(self.base_obj_name + '.'):
73
73
  raise Exception(f"Attempted to call {self.base_obj_name=} with {method_stack=}")
74
74
 
75
- method_name = method_stack.removeprefix(self.base_obj_name + '.')
75
+ method_name = method_stack[len(self.base_obj_name + '.'):] #rm prefix
76
76
  if '.' in method_name:
77
77
  obj_name = method_name.split('.')[0]
78
78
  return self.subobj_dict[obj_name].call_method(method_stack, kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyObjectInterface
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Create a web interface to interact with a class
5
5
  Home-page: https://github.com/RobertJN64/PyObjectInterface
6
6
  Author: Robert Nies
@@ -18,6 +18,7 @@ Requires-Python: >=3.8
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: typing_extensions
21
+ Requires-Dist: flask
21
22
 
22
23
  # PyObjectInterface
23
24
 
@@ -6,7 +6,7 @@ license = MIT
6
6
  license_file = LICENSE
7
7
  url = https://github.com/RobertJN64/PyObjectInterface
8
8
  author_email = robertjnies@gmail.com
9
- version = 0.0.1
9
+ version = 0.0.2
10
10
  long_description = file: README.md
11
11
  long_description_content_type = text/markdown
12
12
  classifiers =
@@ -25,6 +25,7 @@ python_requires = >=3.8
25
25
  include_package_data = True
26
26
  install_requires =
27
27
  typing_extensions
28
+ flask
28
29
 
29
30
  [egg_info]
30
31
  tag_build =
@@ -0,0 +1,144 @@
1
+ from PyObjectInterface.WebController import generate_html
2
+ from PyObjectInterface import PyObjectInterface
3
+ import pytest
4
+
5
+ class Nested:
6
+ def __init__(self):
7
+ self.attr_3 = 3
8
+
9
+ @staticmethod
10
+ def internal_method():
11
+ return "hello from nested"
12
+
13
+ class Basic:
14
+ def __init__(self):
15
+ self.attr_1 = 1
16
+ self._attr_2 = 2
17
+ self.nested = Nested()
18
+
19
+ def method_1(self, a, b=5):
20
+ """Method desc"""
21
+ return f"{self.attr_1} {a} {b}"
22
+
23
+ def _method_2(self):
24
+ pass
25
+
26
+ def __repr__(self):
27
+ return "example repr"
28
+
29
+
30
+
31
+ def test_basic():
32
+ basic = Basic()
33
+ poi = PyObjectInterface(basic, 'Basic')
34
+
35
+ #TEST SCAN
36
+ assert 'attr_1' in poi.attribute_list
37
+ assert '_attr_2' not in poi.attribute_list
38
+ assert 'method_1' in poi.method_dict
39
+ assert '_method_2' not in poi.method_dict
40
+
41
+ assert '__repr__' not in poi.method_dict
42
+ assert '__repr__' not in poi.attribute_list
43
+
44
+ assert 'nested' in poi.subobj_dict
45
+
46
+ assert poi.base_obj_name in repr(poi)
47
+
48
+ def test_method_calls():
49
+ basic = Basic()
50
+ poi = PyObjectInterface(basic, 'Basic')
51
+
52
+ basic.attr_1 = 'some value'
53
+ retval = poi.call_method('Basic.method_1', {'a': 'another_value'})
54
+ assert retval == "some value another_value 5"
55
+
56
+ retval = poi.call_method('Basic.nested.internal_method', {})
57
+ assert retval == "hello from nested"
58
+
59
+ def test_get_attr():
60
+ basic = Basic()
61
+ poi = PyObjectInterface(basic, 'Basic')
62
+ attrs = poi.get_attributes()
63
+ assert attrs['Basic.attr_1'] == '1'
64
+ assert attrs['Basic.nested.attr_3'] == '3'
65
+
66
+ def test_private():
67
+ basic = Basic()
68
+ poi = PyObjectInterface(basic, 'Basic', include_private=True)
69
+ assert 'attr_1' in poi.attribute_list
70
+ assert '_attr_2' in poi.attribute_list
71
+ assert 'method_1' in poi.method_dict
72
+ assert '_method_2' in poi.method_dict
73
+
74
+ assert '__repr__' not in poi.method_dict
75
+ assert '__repr__' not in poi.attribute_list
76
+
77
+ poi.call_method('Basic._method_2', {})
78
+
79
+ class Recursive:
80
+ def __init__(self):
81
+ self.myself = self
82
+
83
+ def test_recursive():
84
+ r = Recursive()
85
+ poi = PyObjectInterface(r, 'r')
86
+
87
+ counter = 0
88
+ while len(poi.subobj_dict):
89
+ poi = poi.subobj_dict['myself']
90
+ counter += 1
91
+ assert counter == 5
92
+
93
+ def test_method_call_exception():
94
+ basic = Basic()
95
+ poi = PyObjectInterface(basic, 'Basic')
96
+ with pytest.raises(Exception,
97
+ match="Attempted to call self.base_obj_name='Basic' with method_stack='NotBasic.method_1'"):
98
+ poi.call_method('NotBasic.method_1', {})
99
+
100
+
101
+ class FuncParams:
102
+ def __init__(self):
103
+ pass
104
+
105
+ @staticmethod
106
+ def static(first_param):
107
+ pass
108
+
109
+ @classmethod
110
+ def classmethod(cls, first_param):
111
+ pass
112
+
113
+ def defaults(self, x, y = None, z = 10, k='string'):
114
+ pass
115
+
116
+ def test_func_params():
117
+ poi = PyObjectInterface(FuncParams(), 'FP')
118
+ assert len(poi.method_dict['static'].args) == 1
119
+ assert poi.method_dict['static'].args[0] == 'first_param'
120
+
121
+ assert len(poi.method_dict['classmethod'].args) == 1
122
+ assert poi.method_dict['classmethod'].args[0] == 'first_param'
123
+
124
+ assert poi.method_dict['defaults'].defaults[0] == ''
125
+ assert poi.method_dict['defaults'].defaults[1] == 'None'
126
+ assert poi.method_dict['defaults'].defaults[2] == '10'
127
+ assert poi.method_dict['defaults'].defaults[3] == "'string'"
128
+
129
+ def test_coverage(): #not useful - just padding code coverage
130
+ fp = FuncParams()
131
+ fp.static(None)
132
+ fp.classmethod(None)
133
+ fp.defaults(None)
134
+
135
+ repr(Basic())
136
+
137
+ def test_html():
138
+ basic = Basic()
139
+ poi = PyObjectInterface(basic, 'Basic')
140
+ generate_html(poi)
141
+
142
+ class Blank: pass
143
+ poi = PyObjectInterface(Blank(), 'Blank')
144
+ assert 'table' not in generate_html(poi)
@@ -1,36 +0,0 @@
1
- from PyObjectInterface import PyObjectInterface
2
-
3
- class Basic:
4
- def __init__(self):
5
- self.attr_1 = 2
6
- self.attr_2 = 2
7
-
8
- def method_1(self):
9
- pass
10
-
11
- def method_2(self, a, b=5):
12
- pass
13
-
14
- def test_basic():
15
- basic = Basic()
16
- poi = PyObjectInterface(basic, 'Basic')
17
- assert 'attr_1' in poi.attribute_list
18
- assert 'attr_2' in poi.attribute_list
19
- assert 'method_1' in poi.method_dict
20
- assert 'method_2' in poi.method_dict
21
-
22
- class Recursive:
23
- def __init__(self):
24
- self.myself = self
25
-
26
- def test_recursive():
27
- r = Recursive()
28
- poi = PyObjectInterface(r, 'r')
29
-
30
- counter = 0
31
- while len(poi.subobj_dict):
32
- poi = poi.subobj_dict['myself']
33
- counter += 1
34
- assert counter == 5
35
-
36
- #TODO - 100% test coverage