LucaVivona commited on
Commit
f06506b
β€’
1 Parent(s): bbd6e0a

🧰 refactor/clean module, demos, docker-compose, and README.md

Browse files
README.md CHANGED
@@ -1,7 +1,7 @@
1
  # Gradio Flow πŸ€—
2
 
3
- **A web application with a backend in Flask and frontend in Rect, and React Flow that use [React flow](https://reactflow.dev/) node base environment to
4
- stream both gradio and streamlit interfaces, within a single application.**
5
 
6
 
7
  ## Tabel Of Contents πŸ“š
@@ -78,7 +78,7 @@ Now that you're within the docker backend container environment you can start ad
78
 
79
  ```console
80
  > cd ./src
81
- > python index.py
82
  //run example gradio application
83
  ```
84
 
@@ -110,7 +110,7 @@ It is quite simple, and similar within the docker build, the first way you can a
110
  **NOTE** If you use the gradio decorator compiler for gradio flow you need to set a listen port to 2000 or else the api will never get the key and will throw you an error, I'll also provided an example below if this isn't clear.
111
 
112
  ```python
113
- #backend/src/demo.py (functional base)
114
  ##########
115
  from resources import register, tabularGradio
116
 
@@ -118,33 +118,41 @@ from resources import register, tabularGradio
118
  def Hello_World(name):
119
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
120
 
121
- @register(["number", "number"], ["number"], examples=[[1,1]])
122
  def add(x, y):
123
  return x + y
124
 
125
  if __name__ == "__main__":
 
126
  tabularGradio([Hello_World(), add()], ["Hello World", "Add"])
 
 
 
 
127
  ```
128
 
129
  ```python
130
- #backend/src/index.py (Class Base)
131
  ###########
132
  from resources import GradioModule, register
133
 
134
  @GradioModule
135
  class Greeting:
136
 
137
- @register(["text"], ["text"])
138
  def Hello_World(self, name):
139
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
140
 
141
- @register(["number", "number"], ["number"], examples=[[1,1]])
142
  def add(self, x, y):
143
  return x + y
144
 
145
 
146
  if __name__ == "__main__":
147
- Greeting().run(listen=2000)
 
 
 
148
  ````
149
  ## Application πŸ›οΈ
150
- ![Application](https://github.com/commune-ai/Gradio-Flow/blob/gradio-flow/gradio-only/app.png)
 
1
  # Gradio Flow πŸ€—
2
 
3
+ **A web application with a backend in Flask and frontend in Rect, and [React flow](https://reactflow.dev/) node base environment to
4
+ stream both [gradio](https://gradio.app) ( and later [streamlit](https://streamlit.io) ) interfaces, within a single application.**
5
 
6
 
7
  ## Tabel Of Contents πŸ“š
 
78
 
79
  ```console
80
  > cd ./src
81
+ > python demoC.py
82
  //run example gradio application
83
  ```
84
 
 
110
  **NOTE** If you use the gradio decorator compiler for gradio flow you need to set a listen port to 2000 or else the api will never get the key and will throw you an error, I'll also provided an example below if this isn't clear.
111
 
112
  ```python
113
+ #backend/src/demoF.py (functional base)
114
  ##########
115
  from resources import register, tabularGradio
116
 
 
118
  def Hello_World(name):
119
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
120
 
121
+ @register(inputs=["number", "number"], outputs=["number"], examples=[[1,1]])
122
  def add(x, y):
123
  return x + y
124
 
125
  if __name__ == "__main__":
126
+ # run single gradio
127
  tabularGradio([Hello_World(), add()], ["Hello World", "Add"])
128
+
129
+ # run it within Gradio-Flow
130
+ # tabularGradio([Hello_World(), add()], ["Hello World", "Add"], listen=2000)
131
+
132
  ```
133
 
134
  ```python
135
+ #backend/src/demoC.py (Class Base)
136
  ###########
137
  from resources import GradioModule, register
138
 
139
  @GradioModule
140
  class Greeting:
141
 
142
+ @register(["text"], ["text"], examples=[["Luca Vivona"]])
143
  def Hello_World(self, name):
144
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
145
 
146
+ @register(inputs=["number", "number"], outputs=["number"], examples=[[1,1]])
147
  def add(self, x, y):
148
  return x + y
149
 
150
 
151
  if __name__ == "__main__":
152
+ # run just gradio
153
+ Greeting().launch()
154
+ # run it within Gradio-flow
155
+ # Greeting().launch(listen=2000)
156
  ````
157
  ## Application πŸ›οΈ
158
+ ![Application](https://github.com/commune-ai/Gradio-Flow/blob/gradio-flow/gradio-only/app.png)
backend/src/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
  import examples
2
  import resource
3
- import src.demo
4
- import src.index
 
1
  import examples
2
  import resource
3
+ import src.demoF
4
+ import src.demoC
backend/src/__pycache__/__init__.cpython-39.pyc DELETED
Binary file (254 Bytes)
 
backend/src/__pycache__/demo.cpython-39.pyc DELETED
Binary file (701 Bytes)
 
backend/src/{index.py β†’ demoC.py} RENAMED
@@ -3,7 +3,7 @@ from resources import GradioModule, register
3
  @GradioModule
4
  class Greeting:
5
 
6
- @register(["text"], ["text"])
7
  def Hello_World(self, name):
8
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
9
 
@@ -11,5 +11,11 @@ class Greeting:
11
  def add(self, x, y):
12
  return x + y
13
 
 
14
  if __name__ == "__main__":
15
- Greeting().run(listen=2000)
 
 
 
 
 
 
3
  @GradioModule
4
  class Greeting:
5
 
6
+ @register(["text"], ["text"], examples=[["Luca Vivona"]])
7
  def Hello_World(self, name):
8
  return f"Hello {name}, and welcome to Gradio Flow πŸ€—"
9
 
 
11
  def add(self, x, y):
12
  return x + y
13
 
14
+
15
  if __name__ == "__main__":
16
+ # run just gradio
17
+ Greeting().launch()
18
+ # run it within Gradio-flow
19
+ # Greeting().launch(listen=2000)
20
+
21
+
backend/src/{demo.py β†’ demoF.py} RENAMED
@@ -10,4 +10,9 @@ def add(x, y):
10
  return x + y
11
 
12
  if __name__ == "__main__":
13
- tabularGradio([Hello_World(), add()], ["Hello World", "Add"])
 
 
 
 
 
 
10
  return x + y
11
 
12
  if __name__ == "__main__":
13
+ # run single gradio
14
+ tabularGradio([Hello_World(), add()], ["Hello World", "Add"])
15
+
16
+ # run it within Gradio-Flow
17
+ # tabularGradio([Hello_World(), add()], ["Hello World", "Add"], listen=2000)
18
+
backend/src/example/__pycache__/examples.cpython-37.pyc DELETED
Binary file (6.13 kB)
 
backend/src/example/__pycache__/examples.cpython-38.pyc DELETED
Binary file (4.52 kB)
 
backend/src/example/__pycache__/examples.cpython-39.pyc DELETED
Binary file (4.58 kB)
 
backend/src/resources/__pycache__/__init__.cpython-38.pyc DELETED
Binary file (144 Bytes)
 
backend/src/resources/__pycache__/compiler.cpython-39.pyc DELETED
Binary file (7.74 kB)
 
backend/src/resources/__pycache__/dock.cpython-39.pyc DELETED
Binary file (1.15 kB)
 
backend/src/resources/__pycache__/module.cpython-38.pyc DELETED
Binary file (7.84 kB)
 
backend/src/resources/__pycache__/module.cpython-39.pyc CHANGED
Binary files a/backend/src/resources/__pycache__/module.cpython-39.pyc and b/backend/src/resources/__pycache__/module.cpython-39.pyc differ
 
backend/src/resources/module.py CHANGED
@@ -32,10 +32,15 @@ DOCKER_LOCAL_HOST = '0.0.0.0'
32
  DOCKER_PORT = Dock()
33
 
34
  def tabularGradio(funcs, names, name="Tabular Temp Name", **kwargs):
35
- #print([fn.__name__ for fn in funcs])
36
- assert len(funcs) == len(names), f"{bcolor.BOLD}{bcolor.FAIL}πŸ› something went wrong!!! The function you appended dose not match the lenght of the names{bcolor.ENDC}"
37
- # assert all([fn == "wrap" for fn in funcs]), f"{bcolor().BOLD}{bcolor().FAIL}not all of these are decorated with the right decorator{bcolor().ENDC}"
 
 
 
38
  port= kwargs["port"] if "port" in kwargs else DOCKER_PORT.determinePort()
 
 
39
  if 'listen' in kwargs:
40
  try:
41
  requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/append/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : 'Not Applicable', "name" : name, "kwargs" : kwargs})
@@ -43,6 +48,7 @@ def tabularGradio(funcs, names, name="Tabular Temp Name", **kwargs):
43
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The listening api is either not up or you choose the wrong port.πŸ› \n {e}")
44
  return
45
 
 
46
  gr.TabbedInterface(funcs, names).launch(server_port=port,
47
  server_name=f"{DOCKER_LOCAL_HOST}",
48
  inline= kwargs['inline'] if "inline" in kwargs else True,
@@ -63,53 +69,74 @@ def tabularGradio(funcs, names, name="Tabular Temp Name", **kwargs):
63
  ssl_certfile=kwargs['ssl_certfile'] if "ssl_certfile" in kwargs else None,
64
  ssl_keyfile_password=kwargs['ssl_keyfile_password'] if "ssl_keyfile_password" in kwargs else None,
65
  quiet=kwargs['quiet'] if "quiet" in kwargs else False)
 
 
66
  if 'listen' in kwargs:
67
  try:
68
  requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/remove/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : 'Not Applicable', "name" : name, "kwargs" : kwargs})
69
- except Exception as e:
70
-
71
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The api either lost connection or was turned off...πŸ› \n {e}")
72
 
73
  return
74
 
75
-
 
76
  def register(inputs, outputs, examples=None, **kwargs):
77
  def register_gradio(func):
78
- def wrap(*args, **wargs):
79
- fn_name = func.__name__
80
 
81
- if 'self' in func.__code__.co_varnames and func.__name__ in dir(args[0]):
82
-
 
 
 
 
83
  """
84
  given the decorator is on a class then
85
  initialize a registered_gradio_functons
86
  if not already initialize.
87
  """
88
- assert len(inputs) == func.__code__.co_argcount - 1, f"❌ {bcolor.BOLD}{bcolor.FAIL}inputs should have the same length as arguments{bcolor.ENDC}"
 
 
89
 
90
  try:
91
  self = args[0]
92
  self.registered_gradio_functons
93
  except AttributeError:
94
- print("✨Initializing Class Functions...✨\n")
95
  self.registered_gradio_functons = dict()
96
 
97
-
98
-
99
  if not fn_name in self.registered_gradio_functons:
100
- self.registered_gradio_functons[fn_name] = dict(inputs=inputs, outputs=outputs, examples=examples)
101
-
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  if len(args[1:]) == (func.__code__.co_argcount - 1):
103
  return func(*args, **wargs)
 
104
  else :
105
  """
106
  the function is not a class function
107
  """
108
- assert len(inputs) == func.__code__.co_argcount, f"❌ {bcolor.BOLD}{bcolor.FAIL}inputs should have the same length as arguments{bcolor.ENDC}"
 
109
 
 
110
  if len(args) == (func.__code__.co_argcount):
111
  return func(*args, **wargs)
112
 
 
113
  return gr.Interface(fn=func,
114
  inputs=inputs,
115
  outputs=outputs,
@@ -126,82 +153,60 @@ def register(inputs, outputs, examples=None, **kwargs):
126
  allow_flagging=kwargs['allow_flagging'] if "allow_flagging" in kwargs else None,
127
  theme='default',
128
  )
129
-
130
- return None
131
- return wrap
132
  return register_gradio
133
 
134
  def GradioModule(cls):
135
  class Decorator:
136
 
137
  def __init__(self) -> None:
138
- self.cls = cls()
139
-
140
- def get_funcs(self):
141
- return [func for func in dir(self.cls) if not func.startswith("__") and type(getattr(self.cls, func, None)) == type(self.get_funcs) ]
142
-
143
- def compile(self, **kwargs):
144
- print("Just putting on the finishing touches... πŸ”§πŸ§°")
145
- for func in self.get_funcs():
146
- this = getattr(self.cls, func, None)
147
- if this.__name__ == "wrap":
148
- this()
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  demos, names = [], []
151
- for func, param in self.get_registered_gradio_functons().items():
152
  names.append(func)
153
- demos.append(gr.Interface(fn=getattr(self.cls, func, None),
154
- inputs=param['inputs'],
155
- outputs=param['outputs'],
156
- examples=param['examples'],
157
- cache_examples=kwargs['cache_examples'] if "cache_examples" in kwargs else None,
158
- examples_per_page=kwargs['cache_examples'] if "cache_examples" in kwargs else 10,
159
- interpretation=kwargs['interpretation'] if "interpretation" in kwargs else None,
160
- num_shap=kwargs['num_shap'] if "num_shap" in kwargs else 2.0,
161
- title=kwargs['title'] if "title" in kwargs else None,
162
- article=kwargs['article'] if "article" in kwargs else None,
163
- thumbnail=kwargs['thumbnail'] if "thumbnail" in kwargs else None,
164
- css=kwargs['css'] if "css" in kwargs else None,
165
- live=kwargs['live'] if "live" in kwargs else False,
166
- allow_flagging=kwargs['allow_flagging'] if "allow_flagging" in kwargs else None,
167
- theme='default',
168
- ))
169
- print(f"{func}....{bcolor.BOLD}{bcolor.OKGREEN} done {bcolor.ENDC}")
170
-
171
- print("\nHappy Visualizing... πŸš€")
172
  return gr.TabbedInterface(demos, names)
173
 
174
- def get_registered_gradio_functons(self):
175
- try:
176
- self.cls.registered_gradio_functons
177
- except AttributeError:
178
- return None
179
- return self.cls.registered_gradio_functons
180
-
181
-
182
- def run(self, **kwargs):
183
  port= kwargs["port"] if "port" in kwargs else DOCKER_PORT.determinePort()
184
  if 'listen' in kwargs:
185
  try:
186
- requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/append/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : getfile(self.cls.__class__), "name" : self.cls.__class__.__name__, "kwargs" : kwargs})
187
  except Exception:
188
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The listening api is either not up or you choose the wrong port.πŸ›")
189
  return
190
 
191
- self.compile(live=kwargs[ 'live' ] if "live" in kwargs else False,
192
- allow_flagging=kwargs[ 'allow_flagging' ] if "allow_flagging" in kwargs else None,
193
- cache_examples=kwargs['cache_examples'] if "cache_examples" in kwargs else None,
194
- examples_per_page=kwargs['cache_examples'] if "cache_examples" in kwargs else 10,
195
- interpretation=kwargs['interpretation'] if "interpretation" in kwargs else None,
196
- num_shap=kwargs['num_shap'] if "num_shap" in kwargs else 2.0,
197
- title=kwargs['title'] if "title" in kwargs else None,
198
- article=kwargs['article'] if "article" in kwargs else None,
199
- thumbnail=kwargs['thumbnail'] if "thumbnail" in kwargs else None,
200
- css=kwargs['css'] if "css" in kwargs else None,
201
- theme=kwargs['theme'] if "theme" in kwargs else None,
202
- ).launch(server_port=port,
203
  server_name=f"{DOCKER_LOCAL_HOST}",
204
- inline= kwargs['inline'] if "inline" in kwargs else True,
205
  share=kwargs['share'] if "share" in kwargs else None,
206
  debug=kwargs['debug'] if "debug" in kwargs else False,
207
  enable_queue=kwargs['enable_queue'] if "enable_queue" in kwargs else None,
@@ -221,15 +226,13 @@ def GradioModule(cls):
221
  quiet=kwargs['quiet'] if "quiet" in kwargs else False)
222
  if 'listen' in kwargs:
223
  try:
224
- requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/remove/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : getfile(self.cls.__class__), "name" : self.cls.__class__.__name__, "kwargs" : kwargs})
225
  except Exception:
226
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The api either lost connection or was turned off...πŸ›")
227
  return
228
 
229
  return Decorator
230
 
231
-
232
-
233
  class bcolor:
234
  HEADER = '\033[95m'
235
  OKBLUE = '\033[94m'
 
32
  DOCKER_PORT = Dock()
33
 
34
  def tabularGradio(funcs, names, name="Tabular Temp Name", **kwargs):
35
+ """
36
+ takes all gradio Interfaces, and names
37
+ from input and launch the gradio.
38
+ """
39
+
40
+ assert len(funcs) == len(names), f"{bcolor.BOLD}{bcolor.FAIL}πŸ› something went wrong!!! The function you appended dose not match the length of the names{bcolor.ENDC}"
41
  port= kwargs["port"] if "port" in kwargs else DOCKER_PORT.determinePort()
42
+
43
+ # send this to the backend api for it to be read by the react frontend
44
  if 'listen' in kwargs:
45
  try:
46
  requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/append/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : 'Not Applicable', "name" : name, "kwargs" : kwargs})
 
48
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The listening api is either not up or you choose the wrong port.πŸ› \n {e}")
49
  return
50
 
51
+ # provided by gradio a tabularInterface function that take function and names
52
  gr.TabbedInterface(funcs, names).launch(server_port=port,
53
  server_name=f"{DOCKER_LOCAL_HOST}",
54
  inline= kwargs['inline'] if "inline" in kwargs else True,
 
69
  ssl_certfile=kwargs['ssl_certfile'] if "ssl_certfile" in kwargs else None,
70
  ssl_keyfile_password=kwargs['ssl_keyfile_password'] if "ssl_keyfile_password" in kwargs else None,
71
  quiet=kwargs['quiet'] if "quiet" in kwargs else False)
72
+
73
+ # Ctrl+C that ends the process and then continue the code which will remove from the api
74
  if 'listen' in kwargs:
75
  try:
76
  requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/remove/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : 'Not Applicable', "name" : name, "kwargs" : kwargs})
77
+ except Exception as e:
 
78
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The api either lost connection or was turned off...πŸ› \n {e}")
79
 
80
  return
81
 
82
+
83
+
84
  def register(inputs, outputs, examples=None, **kwargs):
85
  def register_gradio(func):
86
+
 
87
 
88
+ def decorator(*args, **wargs):
89
+ if type(outputs) is list:
90
+ assert len(outputs) >= 1, f"❌ {bcolor.BOLD}{bcolor.FAIL}you have no outputs 🀨... {str(type(outputs))} {bcolor.ENDC}"
91
+
92
+ fn_name = func.__name__
93
+ if 'self' in func.__code__.co_varnames and func.__code__.co_varnames[0] == 'self' and fn_name in dir(args[0]):
94
  """
95
  given the decorator is on a class then
96
  initialize a registered_gradio_functons
97
  if not already initialize.
98
  """
99
+
100
+ if type(inputs) is list:
101
+ assert len(inputs) == func.__code__.co_argcount - 1, f"❌ {bcolor.BOLD}{bcolor.FAIL}inputs should have the same length as arguments{bcolor.ENDC}"
102
 
103
  try:
104
  self = args[0]
105
  self.registered_gradio_functons
106
  except AttributeError:
 
107
  self.registered_gradio_functons = dict()
108
 
 
 
109
  if not fn_name in self.registered_gradio_functons:
110
+ self.registered_gradio_functons[fn_name] = dict(inputs=inputs,
111
+ outputs=outputs,
112
+ examples=examples,
113
+ cache_examples=kwargs['cache_examples'] if "cache_examples" in kwargs else None,
114
+ examples_per_page=kwargs['examples_per_page'] if "examples_per_page" in kwargs else 10,
115
+ interpretation=kwargs['interpretation'] if "interpretation" in kwargs else None,
116
+ num_shap=kwargs['num_shap'] if "num_shap" in kwargs else 2.0,
117
+ title=kwargs['title'] if "title" in kwargs else None,
118
+ article=kwargs['article'] if "article" in kwargs else None,
119
+ thumbnail=kwargs['thumbnail'] if "thumbnail" in kwargs else None,
120
+ css=kwargs['css'] if "css" in kwargs else None,
121
+ live=kwargs['live'] if "live" in kwargs else False,
122
+ allow_flagging=kwargs['allow_flagging'] if "allow_flagging" in kwargs else None,
123
+ theme=kwargs['theme'] if "theme" in kwargs else 'default', )
124
+
125
  if len(args[1:]) == (func.__code__.co_argcount - 1):
126
  return func(*args, **wargs)
127
+ return None
128
  else :
129
  """
130
  the function is not a class function
131
  """
132
+ if type(inputs) is list:
133
+ assert len(inputs) == func.__code__.co_argcount, f"❌ {bcolor.BOLD}{bcolor.FAIL}inputs should have the same length as arguments{bcolor.ENDC}"
134
 
135
+ # if the arguments within the functions are inputed then just return the output
136
  if len(args) == (func.__code__.co_argcount):
137
  return func(*args, **wargs)
138
 
139
+ # if there is nothing in the arugumrnt then return the gradio interface
140
  return gr.Interface(fn=func,
141
  inputs=inputs,
142
  outputs=outputs,
 
153
  allow_flagging=kwargs['allow_flagging'] if "allow_flagging" in kwargs else None,
154
  theme='default',
155
  )
156
+ return decorator
 
 
157
  return register_gradio
158
 
159
  def GradioModule(cls):
160
  class Decorator:
161
 
162
  def __init__(self) -> None:
163
+ self.__cls__ = cls()
164
+ self.__get_funcs_attr()
165
+ self.interface = self.__compile()
166
+
167
+ def get_funcs_names(self):
168
+ assert self.get_registered_map() != None, "this is not possible..."
169
+ return [ name for name in self.get_registered_map().keys()]
 
 
 
 
170
 
171
+ def get_registered_map(self):
172
+ assert self.__cls__.registered_gradio_functons != None, "what happen!!!!"
173
+ return self.__cls__.registered_gradio_functons
174
+
175
+ def __get_funcs_attr(self):
176
+ for func in dir(self.__cls__):
177
+ fn = getattr(self.__cls__, func, None)
178
+ if not func.startswith("__") and fn.__name__ == "decorator":
179
+ fn()
180
+
181
+ def __compile(self):
182
+ """
183
+ Initialize all the function
184
+ within the class that are registeed
185
+ """
186
  demos, names = [], []
187
+ for func, param in self.get_registered_map().items():
188
  names.append(func)
189
+ try:
190
+ demos.append(gr.Interface(fn=getattr(self.__cls__, func, None), **param))
191
+ except Exception as e :
192
+ raise e
193
+
194
+ print(f"{bcolor.OKBLUE}COMPLETED: {bcolor.ENDC}All functions are mapped, and ready to launch πŸš€",
195
+ "\n===========================================================\n")
 
 
 
 
 
 
 
 
 
 
 
 
196
  return gr.TabbedInterface(demos, names)
197
 
198
+ def launch(self, **kwargs):
 
 
 
 
 
 
 
 
199
  port= kwargs["port"] if "port" in kwargs else DOCKER_PORT.determinePort()
200
  if 'listen' in kwargs:
201
  try:
202
+ requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/append/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : getfile(self.__cls__.__class__), "name" : self.__cls__.__class__.__name__, "kwargs" : kwargs})
203
  except Exception:
204
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The listening api is either not up or you choose the wrong port.πŸ›")
205
  return
206
 
207
+ self.interface.launch(server_port=port,
 
 
 
 
 
 
 
 
 
 
 
208
  server_name=f"{DOCKER_LOCAL_HOST}",
209
+ inline= kwargs['inline'] if "inline" in kwargs else None,
210
  share=kwargs['share'] if "share" in kwargs else None,
211
  debug=kwargs['debug'] if "debug" in kwargs else False,
212
  enable_queue=kwargs['enable_queue'] if "enable_queue" in kwargs else None,
 
226
  quiet=kwargs['quiet'] if "quiet" in kwargs else False)
227
  if 'listen' in kwargs:
228
  try:
229
+ requests.post(f"http://{DOCKER_LOCAL_HOST}:{ kwargs[ 'listen' ] }/api/remove/port", json={"port" : port, "host" : f'http://localhost:{port}', "file" : getfile(self.__cls__.__class__), "name" : self.__cls__.__class__.__name__, "kwargs" : kwargs})
230
  except Exception:
231
  print(f"**{bcolor.BOLD}{bcolor.FAIL}CONNECTION ERROR{bcolor.ENDC}** πŸ›The api either lost connection or was turned off...πŸ›")
232
  return
233
 
234
  return Decorator
235
 
 
 
236
  class bcolor:
237
  HEADER = '\033[95m'
238
  OKBLUE = '\033[94m'
backend/test/test.py CHANGED
@@ -21,19 +21,48 @@ def Hello(name):
21
  def Goodbye(name):
22
  return f"Goodbye, {name}."
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  class GradioFlowTestCase(unittest.TestCase):
25
- cls = test()
26
  def test_class_func_return(self):
27
- self.assertEqual(self.cls.cls.Hello("Luca"), "Hello, Luca.")
28
- self.assertEqual(self.cls.cls.Goodbye("Luca"), "Goodbye, Luca.")
29
 
 
 
30
 
31
  def test_func_return(self):
32
  self.assertEqual(Hello("Luca"), "Hello, Luca.")
33
  self.assertEqual(Goodbye("Luca"), "Goodbye, Luca.")
34
-
35
-
36
 
37
-
 
 
 
 
 
 
 
 
 
 
38
 
39
  unittest.main()
 
21
  def Goodbye(name):
22
  return f"Goodbye, {name}."
23
 
24
+ @register(['number', 'number'], ['number'], examples=[[9, 10]])
25
+ def add(x=0, y=0):
26
+ return x + y
27
+
28
+ @register(['number'], ['number'], examples=[[9, 10]])
29
+ def error_param(x=0, y=0):
30
+ return x + y
31
+
32
+ @register(['number', "number"], [], examples=[[9, 10]])
33
+ def error_no_output(x=0, y=0):
34
+ return x + y
35
+
36
+ @register(['number', "number"], "number", examples=[[9, 10]])
37
+ def foo(x=0, y=0):
38
+ return x + y
39
+
40
+
41
+
42
+
43
  class GradioFlowTestCase(unittest.TestCase):
44
+ hodl = test()
45
  def test_class_func_return(self):
46
+ self.assertEqual(self.hodl.__cls__.Hello("Luca"), "Hello, Luca.")
47
+ self.assertEqual(self.hodl.__cls__.Goodbye("Luca"), "Goodbye, Luca.")
48
 
49
+ def test_func_default_return(self):
50
+ self.assertEqual(add(1,1), 2)
51
 
52
  def test_func_return(self):
53
  self.assertEqual(Hello("Luca"), "Hello, Luca.")
54
  self.assertEqual(Goodbye("Luca"), "Goodbye, Luca.")
 
 
55
 
56
+ def test_foo(self):
57
+ self.assertEqual(foo(1,1),2)
58
+
59
+ def test_functions_error_catch(self):
60
+ with self.assertRaises(AssertionError):
61
+ error_param()
62
+
63
+ def test_function_error_no_output(self):
64
+ with self.assertRaises(AssertionError):
65
+ error_no_output()
66
+
67
 
68
  unittest.main()
docker-compose.yml CHANGED
@@ -11,6 +11,7 @@ services:
11
  ports:
12
  - "2000:2000"
13
  - "7860-7880:7860-7880"
 
14
  command: "python app.py -p 2000"
15
  frontend :
16
  container_name: frontend
 
11
  ports:
12
  - "2000:2000"
13
  - "7860-7880:7860-7880"
14
+ # - "8501:8501" # streamlit application test
15
  command: "python app.py -p 2000"
16
  frontend :
17
  container_name: frontend