ratio1 3.4.38__py3-none-any.whl → 3.4.40__py3-none-any.whl

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.
ratio1/_ver.py CHANGED
@@ -1,4 +1,4 @@
1
- __VER__ = "3.4.38"
1
+ __VER__ = "3.4.40"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -2696,7 +2696,7 @@ class GenericSession(BaseDecentrAIObject):
2696
2696
  node = self.__get_node_address(node)
2697
2697
  return node in self._dct_online_nodes_pipelines
2698
2698
 
2699
- def is_peered(self, node):
2699
+ def is_peered(self, node, return_full_address=False):
2700
2700
  """
2701
2701
  Public method for checking if a node is peered with the current session.
2702
2702
  Parameters
@@ -2709,8 +2709,10 @@ class GenericSession(BaseDecentrAIObject):
2709
2709
  bool
2710
2710
  True if the node is peered, False otherwise.
2711
2711
  """
2712
- node = self.__get_node_address(node)
2713
- return self._dct_can_send_to_node.get(node, False)
2712
+ node_addr = self.__get_node_address(node)
2713
+ if return_full_address:
2714
+ return self._dct_can_send_to_node.get(node_addr, False), node_addr
2715
+ return self._dct_can_send_to_node.get(node_addr, False)
2714
2716
 
2715
2717
  def get_last_seen_time(self, node, *, default_value=0):
2716
2718
  """
@@ -2789,15 +2791,58 @@ class GenericSession(BaseDecentrAIObject):
2789
2791
 
2790
2792
  return pipeline, instance
2791
2793
 
2794
+ def maybe_clean_kwargs(
2795
+ self, _kwargs: dict,
2796
+ caller_method_name: str,
2797
+ solver_method_name: str,
2798
+ parameters_to_remove: list[str]
2799
+ ):
2800
+ """
2801
+ This method is used to clean the kwargs dictionary before passing it to a solver method.
2802
+ It can also print warnings
2803
+ Parameters
2804
+ ----------
2805
+ _kwargs : dict
2806
+ The kwargs dictionary to clean.
2807
+ caller_method_name : str
2808
+ The name of the method that is calling this method.
2809
+ solver_method_name : str
2810
+ The name of the solver method that will receive the cleaned kwargs.
2811
+ parameters_to_remove : list[str]
2812
+ A list of parameters to remove from the kwargs dictionary.
2813
+
2814
+ Returns
2815
+ -------
2816
+ res : dict
2817
+ The cleaned kwargs dictionary.
2818
+ """
2819
+
2820
+ for _key in parameters_to_remove:
2821
+ if not isinstance(_key, str):
2822
+ continue
2823
+ # endif param_name not str
2824
+ if _key in _kwargs:
2825
+ _kwargs.pop(_key)
2826
+ warn_msg = f"WARNING! The '{caller_method_name}' passes its own `{_key}`, so the parameter is not used."
2827
+ warn_msg += f" Use '{solver_method_name}' instead if you want to use the `{_key}` parameter."
2828
+ self.log.P(warn_msg, color='y', show=True)
2829
+ # endif _key in _kwargs
2830
+ # endfor parameters to remove
2831
+
2832
+ return _kwargs
2833
+
2792
2834
  def create_web_app(
2793
2835
  self,
2794
2836
  *,
2795
2837
  node,
2796
2838
  name="Ratio1 Web App",
2797
2839
  signature=PLUGIN_SIGNATURES.GENERIC_WEB_APP,
2840
+ tunnel_engine="ngrok",
2841
+ tunnel_engine_enabled=True,
2842
+ cloudflare_token=None,
2798
2843
  ngrok_edge_label=None,
2844
+ ngrok_use_api=True,
2799
2845
  endpoints=None,
2800
- use_ngrok=True,
2801
2846
  extra_debug=False,
2802
2847
  summary="Ratio1 WebApp created via SDK",
2803
2848
  description=None,
@@ -2805,6 +2850,9 @@ class GenericSession(BaseDecentrAIObject):
2805
2850
  ):
2806
2851
  """
2807
2852
  Create a new generic web app on a node.
2853
+ If this uses tunnelling, the app will be exposed using either
2854
+ a cloudflare token, an ngrok edge label or an automatically generated URL.
2855
+ The URL can be automatically generated only in case of ngrok usage(which will also be discontinued).
2808
2856
 
2809
2857
  Parameters
2810
2858
  ----------
@@ -2817,17 +2865,48 @@ class GenericSession(BaseDecentrAIObject):
2817
2865
 
2818
2866
  signature : str, optional
2819
2867
  The signature of the plugin that will be used. Defaults to PLUGIN_SIGNATURES.CUSTOM_WEBAPI_01.
2820
-
2868
+
2869
+ tunnel_engine : str, optional
2870
+ The tunnel engine to use for exposing the web app. Defaults to "ngrok".
2871
+ It can also be "cloudflare" for Cloudflare Tunnel.
2872
+
2873
+ tunnel_engine_enabled : bool, optional
2874
+ If True, will use the specified tunnel engine to expose the web app. Defaults to True.
2875
+
2876
+ ngrok_edge_label : str, optional
2877
+ The label of the edge node that will be used to expose the HTTP server. Defaults to None.
2878
+
2879
+ cloudflare_token : str, optional
2880
+ The Cloudflare token to use for exposing the web app. Defaults to None.
2881
+
2821
2882
  endpoints : list[dict], optional
2822
2883
  A list of dictionaries defining the endpoint configuration. Defaults to None.
2823
-
2824
- use_ngrok : bool, optional
2825
- If True, will use ngrok to expose the web app. Defaults to True.
2826
-
2827
-
2828
2884
  """
2829
-
2830
- ngrok_use_api = True
2885
+ ngrok_kwargs = {}
2886
+ cloudflare_kwargs = {}
2887
+
2888
+ if tunnel_engine_enabled:
2889
+ if tunnel_engine == "ngrok":
2890
+ if not isinstance(ngrok_edge_label, str):
2891
+ ngrok_edge_label = None
2892
+ warn_msg = f"WARNING! Without a pre-defined `ngrok_edge_label`, the URL will be generated automatically, "
2893
+ warn_msg += "but it will not be persistent across restarts."
2894
+ self.P(warn_msg, color='y', show=True)
2895
+ # raise ValueError(f"`ngrok_edge_label` must be a string when using ngrok tunnel engine. {type(ngrok_edge_label)} provided")
2896
+ # endif ngrok edge label not valid
2897
+ ngrok_kwargs = {
2898
+ "ngrok_edge_label": ngrok_edge_label,
2899
+ "ngrok_use_api": ngrok_use_api,
2900
+ }
2901
+ elif tunnel_engine == "cloudflare":
2902
+ if not isinstance(cloudflare_token, str):
2903
+ raise ValueError(f"`cloudflare` must be a string when using cloudflare tunnel engine. {type(cloudflare_token)} provided.")
2904
+ cloudflare_kwargs = {
2905
+ "cloudflare_token": cloudflare_token,
2906
+ }
2907
+ else:
2908
+ raise ValueError("Unsupported tunnel engine: {}".format(tunnel_engine))
2909
+ # endif tunnel engine enabled
2831
2910
 
2832
2911
  pipeline_name = name.replace(" ", "_").lower()
2833
2912
 
@@ -2842,12 +2921,13 @@ class GenericSession(BaseDecentrAIObject):
2842
2921
  instance = pipeline.create_plugin_instance(
2843
2922
  signature=signature,
2844
2923
  instance_id=self.log.get_unique_id(),
2845
- use_ngrok=use_ngrok,
2846
- ngrok_edge_label=ngrok_edge_label,
2847
- ngrok_use_api=ngrok_use_api,
2924
+ tunnel_engine_enabled=tunnel_engine_enabled,
2925
+ tunnel_engine=tunnel_engine,
2848
2926
  api_title=name,
2849
2927
  api_summary=summary,
2850
2928
  api_description=description,
2929
+ **ngrok_kwargs,
2930
+ **cloudflare_kwargs,
2851
2931
  **kwargs
2852
2932
  )
2853
2933
 
@@ -2865,16 +2945,20 @@ class GenericSession(BaseDecentrAIObject):
2865
2945
  *,
2866
2946
  node,
2867
2947
  name="Ratio1 Custom Web API",
2948
+ tunnel_engine="ngrok",
2949
+ tunnel_engine_enabled=True,
2868
2950
  ngrok_edge_label=None,
2951
+ cloudflare_token=None,
2869
2952
  endpoints=None,
2870
- use_ngrok=True,
2871
2953
  extra_debug=False,
2872
2954
  summary="Ratio1 Web API created via SDK",
2873
2955
  description=None,
2874
2956
  **kwargs):
2875
2957
  """
2876
- Creates a custom Web API with endpoints on a node using custom code and either a pre-defined edge label or generates the URL automatically.
2877
-
2958
+ Creates a custom Web API with endpoints on a node using custom code.
2959
+ If this uses tunnelling, the app will be exposed using either
2960
+ a cloudflare token, an ngrok edge label or an automatically generated URL.
2961
+ The URL can be automatically generated only in case of ngrok usage(which will also be discontinued).
2878
2962
 
2879
2963
  Parameters
2880
2964
  ----------
@@ -2885,18 +2969,21 @@ class GenericSession(BaseDecentrAIObject):
2885
2969
  name : str
2886
2970
  Name of the web app.
2887
2971
 
2972
+ tunnel_engine : str, optional
2973
+ The tunnel engine to use for exposing the web app. Defaults to "ngrok".
2974
+ It can also be "cloudflare" for Cloudflare Tunnel.
2975
+
2976
+ tunnel_engine_enabled : bool, optional
2977
+ If True, will use the specified tunnel engine to expose the web app. Defaults to True.
2978
+
2888
2979
  ngrok_edge_label : str, optional
2889
2980
  The label of the edge node that will be used to expose the HTTP server. Defaults to None.
2890
2981
 
2891
- signature : str, optional
2892
- The signature of the plugin that will be used. Defaults to PLUGIN_SIGNATURES.CUSTOM_WEBAPI_01.
2982
+ cloudflare_token : str, optional
2983
+ The Cloudflare token to use for exposing the web app. Defaults to None.
2893
2984
 
2894
2985
  endpoints : list[dict], optional
2895
2986
  A list of dictionaries defining the endpoint configuration. Defaults to None.
2896
-
2897
- use_ngrok : bool, optional
2898
- If True, will use ngrok to expose the web app. Defaults to True.
2899
-
2900
2987
 
2901
2988
  Returns
2902
2989
  -------
@@ -2911,7 +2998,8 @@ class GenericSession(BaseDecentrAIObject):
2911
2998
  pipeline, instance = session.create_custom_webapi(
2912
2999
  node="node_name",
2913
3000
  name="My Custom Web API",
2914
- ngrok_edge_label=None, # no edge specified, will generate url automatically and return it at deploy
3001
+ tunnel_engine='cloudflare',
3002
+ cloudflare_token="<cloudflare_token>",
2915
3003
  endpoints=[
2916
3004
  {
2917
3005
  "path": "/my_endpoint",
@@ -2919,7 +3007,6 @@ class GenericSession(BaseDecentrAIObject):
2919
3007
  "handler": my_handler_function,
2920
3008
  },
2921
3009
  ],
2922
- use_ngrok=True,
2923
3010
  extra_debug=True,
2924
3011
  summary="My Custom Web API",
2925
3012
  description="This is a custom web API created via the SDK.",
@@ -2930,13 +3017,21 @@ class GenericSession(BaseDecentrAIObject):
2930
3017
 
2931
3018
 
2932
3019
  """
3020
+ kwargs = self.maybe_clean_kwargs(
3021
+ _kwargs=kwargs,
3022
+ caller_method_name="create_custom_webapi",
3023
+ solver_method_name="create_web_app",
3024
+ parameters_to_remove=["signature"]
3025
+ )
2933
3026
  return self.create_web_app(
2934
3027
  node=node,
2935
3028
  name=name,
2936
3029
  signature=PLUGIN_SIGNATURES.CUSTOM_WEBAPI_01,
3030
+ tunnel_engine=tunnel_engine,
3031
+ tunnel_engine_enabled=tunnel_engine_enabled,
3032
+ cloudflare_token=cloudflare_token,
2937
3033
  ngrok_edge_label=ngrok_edge_label,
2938
3034
  endpoints=endpoints,
2939
- use_ngrok=use_ngrok,
2940
3035
  extra_debug=extra_debug,
2941
3036
  summary=summary,
2942
3037
  description=description,
@@ -2948,8 +3043,10 @@ class GenericSession(BaseDecentrAIObject):
2948
3043
  *,
2949
3044
  node,
2950
3045
  name="Ratio1 Container Web App",
2951
- signature=PLUGIN_SIGNATURES.CONTAINER_APP_RUNNER,
2952
- use_ngrok=True,
3046
+ tunnel_engine_enabled=True,
3047
+ tunnel_engine="ngrok",
3048
+ cloudflare_token=None,
3049
+ ngrok_edge_label=None,
2953
3050
  extra_debug=False,
2954
3051
  summary="Ratio1 Container WebApp created via SDK",
2955
3052
  description=None,
@@ -2967,39 +3064,40 @@ class GenericSession(BaseDecentrAIObject):
2967
3064
  name : str
2968
3065
  Name of the container web app.
2969
3066
 
2970
- signature : str, optional
2971
- The signature of the plugin that will be used. Defaults to PLUGIN_SIGNATURES.CONTAINER_APP_RUNNER.
3067
+ tunnel_engine : str, optional
3068
+ The tunnel engine to use for exposing the web app. Defaults to "ngrok".
3069
+ It can also be "cloudflare" for Cloudflare Tunnel.
2972
3070
 
2973
- use_ngrok : bool, optional
2974
- If True, will use ngrok to expose the web app. Defaults to True.
2975
- """
3071
+ tunnel_engine_enabled : bool, optional
3072
+ If True, will use the specified tunnel engine to expose the web app. Defaults to True.
2976
3073
 
2977
- ngrok_use_api = True
3074
+ ngrok_edge_label : str, optional
3075
+ The label of the edge node that will be used to expose the HTTP server. Defaults to None.
2978
3076
 
2979
- pipeline_name = name.replace(" ", "_").lower()
3077
+ cloudflare_token : str, optional
3078
+ The Cloudflare token to use for exposing the web app. Defaults to None.
2980
3079
 
2981
- pipeline: WebappPipeline = self.create_pipeline(
3080
+ """
3081
+ kwargs = self.maybe_clean_kwargs(
3082
+ _kwargs=kwargs,
3083
+ caller_method_name="create_container_web_app",
3084
+ solver_method_name="create_web_app",
3085
+ parameters_to_remove=["signature"]
3086
+ )
3087
+ return self.create_web_app(
2982
3088
  node=node,
2983
- name=pipeline_name,
2984
- pipeline_type=WebappPipeline,
3089
+ name=name,
3090
+ signature=PLUGIN_SIGNATURES.CONTAINER_APP_RUNNER,
3091
+ tunnel_engine=tunnel_engine,
3092
+ tunnel_engine_enabled=tunnel_engine_enabled,
3093
+ cloudflare_token=cloudflare_token,
3094
+ ngrok_edge_label=ngrok_edge_label,
2985
3095
  extra_debug=extra_debug,
2986
- # default TYPE is "Void"
2987
- )
2988
-
2989
- instance = pipeline.create_plugin_instance(
2990
- signature=signature,
2991
- instance_id=self.log.get_unique_id(),
2992
- use_ngrok=use_ngrok,
2993
- ngrok_use_api=ngrok_use_api,
2994
- api_title=name,
2995
- api_summary=summary,
2996
- api_description=description,
3096
+ summary=summary,
3097
+ description=description,
2997
3098
  **kwargs
2998
3099
  )
2999
3100
 
3000
- return pipeline, instance
3001
-
3002
-
3003
3101
  def deeploy_launch_container_app(
3004
3102
  self,
3005
3103
  docker_image: str,
@@ -3798,7 +3896,10 @@ class GenericSession(BaseDecentrAIObject):
3798
3896
  *,
3799
3897
  node,
3800
3898
  name="Ratio1 HTTP Server",
3899
+ tunnel_engine="ngrok",
3900
+ tunnel_engine_enabled=True,
3801
3901
  ngrok_edge_label=None,
3902
+ cloudflare_token=None,
3802
3903
  endpoints=None,
3803
3904
  extra_debug=False,
3804
3905
  summary="Ratio1 HTTP Server created via SDK",
@@ -3814,15 +3915,26 @@ class GenericSession(BaseDecentrAIObject):
3814
3915
  Parameters
3815
3916
  ----------
3816
3917
 
3918
+
3817
3919
  node : str
3818
- Address or Name of the ratio1 Edge Protocol edge node that will handle this HTTP server.
3920
+ Address or Name of the ratio1 Edge Protocol edge node that will handle this web app.
3819
3921
 
3820
3922
  name : str
3821
- Name of the HTTP server.
3923
+ Name of the web app.
3924
+
3925
+ tunnel_engine : str, optional
3926
+ The tunnel engine to use for exposing the web app. Defaults to "ngrok".
3927
+ It can also be "cloudflare" for Cloudflare Tunnel.
3928
+
3929
+ tunnel_engine_enabled : bool, optional
3930
+ If True, will use the specified tunnel engine to expose the web app. Defaults to True.
3822
3931
 
3823
3932
  ngrok_edge_label : str, optional
3824
3933
  The label of the edge node that will be used to expose the HTTP server. Defaults to None.
3825
3934
 
3935
+ cloudflare_token : str, optional
3936
+ The Cloudflare token to use for exposing the web app. Defaults to None.
3937
+
3826
3938
  endpoints : list[dict], optional
3827
3939
  A list of dictionaries defining the endpoint configuration. Defaults to None.
3828
3940
 
@@ -3844,10 +3956,19 @@ class GenericSession(BaseDecentrAIObject):
3844
3956
  static_directory = static_directory or '.'
3845
3957
  self.__is_static_directory_valid(static_directory, raise_exception=True)
3846
3958
  endpoints = self.__maybe_add_root_endpoint(endpoints)
3959
+ kwargs = self.maybe_clean_kwargs(
3960
+ _kwargs=kwargs,
3961
+ caller_method_name="create_http_server",
3962
+ solver_method_name="create_web_app",
3963
+ parameters_to_remove=["signature"]
3964
+ )
3847
3965
  return self.create_web_app(
3848
3966
  node=node,
3849
3967
  name=name,
3850
3968
  signature=PLUGIN_SIGNATURES.GENERIC_HTTP_SERVER,
3969
+ tunnel_engine=tunnel_engine,
3970
+ tunnel_engine_enabled=tunnel_engine_enabled,
3971
+ cloudflare_token=cloudflare_token,
3851
3972
  ngrok_edge_label=ngrok_edge_label,
3852
3973
  endpoints=endpoints,
3853
3974
  extra_debug=extra_debug,
@@ -3865,7 +3986,9 @@ class GenericSession(BaseDecentrAIObject):
3865
3986
  *,
3866
3987
  nodes,
3867
3988
  name,
3868
- ngrok_edge_label,
3989
+ ngrok_edge_label=None,
3990
+ cloudflare_token=None,
3991
+ tunnel_engine="ngrok",
3869
3992
  signature=PLUGIN_SIGNATURES.GENERIC_WEB_APP,
3870
3993
  endpoints=None,
3871
3994
  extra_debug=False,
@@ -3894,6 +4017,13 @@ class GenericSession(BaseDecentrAIObject):
3894
4017
  The label of the edge node that will be used to expose the web app. This is mandatory due to the fact
3895
4018
  that the web app will be exposed using ngrok from multiple nodes that all will share the same edge label.
3896
4019
 
4020
+ cloudflare_token : str, optional
4021
+ The Cloudflare token to use for exposing the web app. Defaults to None.
4022
+
4023
+ tunnel_engine : str, optional
4024
+ The tunnel engine to use for exposing the web app. Defaults to "ngrok".
4025
+ It can also be "cloudflare" for Cloudflare Tunnel.
4026
+
3897
4027
  endpoints : list[dict], optional
3898
4028
  A list of dictionaries defining the endpoint configuration. Defaults to None.
3899
4029
 
@@ -3902,40 +4032,40 @@ class GenericSession(BaseDecentrAIObject):
3902
4032
  """
3903
4033
 
3904
4034
  ngrok_use_api = kwargs.pop('ngrok_use_api', True)
3905
- use_ngrok = True
3906
- kwargs.pop('use_ngrok', None)
3907
4035
 
3908
- if ngrok_edge_label is None:
3909
- raise ValueError("The `ngrok_edge_label` parameter is mandatory when creating a balanced web app, in order for all instances to respond to the same URL.")
4036
+ if tunnel_engine == "ngrok" and ngrok_edge_label is None:
4037
+ err_msg = f"The `ngrok_edge_label` parameter is mandatory when creating a balanced web app tunneled with ngrok."
4038
+ err_msg += "This is needed in order for all instances to respond to the same URL."
4039
+ raise ValueError(err_msg)
4040
+ # endif ngrok used and ngrok_edge_label is None
4041
+
4042
+ kwargs = self.maybe_clean_kwargs(
4043
+ _kwargs=kwargs,
4044
+ caller_method_name="create_and_deploy_balanced_web_app",
4045
+ solver_method_name="create_web_app",
4046
+ parameters_to_remove=[
4047
+ "tunnel_engine_enabled"
4048
+ ]
4049
+ )
3910
4050
 
3911
4051
  pipelines, instances = [], []
3912
4052
 
3913
4053
  for node in nodes:
3914
4054
  self.P("Creating web app on node {}...".format(node), color='b')
3915
- pipeline: WebappPipeline = self.create_pipeline(
4055
+
4056
+ pipeline, instance = self.create_web_app(
3916
4057
  node=node,
3917
4058
  name=name,
3918
- pipeline_type=WebappPipeline,
3919
- extra_debug=extra_debug,
3920
- # default TYPE is "Void"
3921
- )
3922
-
3923
- instance = pipeline.create_plugin_instance(
3924
4059
  signature=signature,
3925
- instance_id=self.log.get_unique_id(),
3926
- use_ngrok=use_ngrok,
4060
+ tunnel_engine=tunnel_engine,
4061
+ tunnel_engine_enabled=True,
4062
+ cloudflare_token=cloudflare_token,
3927
4063
  ngrok_edge_label=ngrok_edge_label,
3928
4064
  ngrok_use_api=ngrok_use_api,
4065
+ endpoints=endpoints,
4066
+ extra_debug=extra_debug,
3929
4067
  **kwargs
3930
4068
  )
3931
-
3932
- if endpoints is not None:
3933
- for endpoint in endpoints:
3934
- assert isinstance(endpoint, dict), "Each endpoint must be a dictionary defining the endpoint configuration."
3935
- instance.add_new_endpoint(**endpoint)
3936
- # end for
3937
- # end if we have endpoints defined in the call
3938
-
3939
4069
  pipeline.deploy()
3940
4070
  pipelines.append(pipeline)
3941
4071
  instances.append(instance)
@@ -3981,6 +4111,8 @@ class GenericSession(BaseDecentrAIObject):
3981
4111
  nodes,
3982
4112
  name="Ratio1 HTTP Server",
3983
4113
  ngrok_edge_label=None,
4114
+ cloudflare_token=None,
4115
+ tunnel_engine="ngrok",
3984
4116
  endpoints=None,
3985
4117
  extra_debug=False,
3986
4118
  summary="Ratio1 HTTP Server created via SDK",
@@ -3996,7 +4128,7 @@ class GenericSession(BaseDecentrAIObject):
3996
4128
  Parameters
3997
4129
  ----------
3998
4130
 
3999
- nodes : str
4131
+ nodes : list
4000
4132
  List of addresses or Names of the ratio1 Edge Protocol edge nodes that will handle this HTTP server.
4001
4133
 
4002
4134
  name : str
@@ -4030,6 +4162,8 @@ class GenericSession(BaseDecentrAIObject):
4030
4162
  nodes=nodes,
4031
4163
  name=name,
4032
4164
  signature=PLUGIN_SIGNATURES.GENERIC_HTTP_SERVER,
4165
+ tunnel_engine=tunnel_engine,
4166
+ cloudflare_token=cloudflare_token,
4033
4167
  ngrok_edge_label=ngrok_edge_label,
4034
4168
  endpoints=endpoints,
4035
4169
  extra_debug=extra_debug,
@@ -25,7 +25,7 @@ class WebappPipeline(Pipeline):
25
25
  This is a special type of pipeline that is used to deploy webapps.
26
26
  It will override the deploy method to return the ngrok URL as well as the on_data method to extract the ngrok URL.
27
27
  """
28
- self.ngrok_url = None
28
+ self.app_url = None
29
29
  self.__extra_debug = extra_debug
30
30
  _on_data = [self.__check_payloads, on_data]
31
31
  super().__init__(
@@ -70,7 +70,7 @@ class WebappPipeline(Pipeline):
70
70
  if self.__extra_debug:
71
71
  self.P(f"Received payload from {plugin_signature} ({plugin_instance})")
72
72
  if "NGROK_URL" in data:
73
- self.ngrok_url = data["NGROK_URL"]
73
+ self.app_url = data["NGROK_URL"]
74
74
  return
75
75
 
76
76
  def create_plugin_instance(
@@ -78,19 +78,40 @@ class WebappPipeline(Pipeline):
78
78
  *,
79
79
  signature,
80
80
  instance_id,
81
- config={},
81
+ config={},
82
+ tunnel_engine='ngrok',
83
+ tunnel_engine_enabled=True,
82
84
  ngrok_edge_label=None,
85
+ cloudflare_token=None,
83
86
  **kwargs
84
87
  ):
85
-
86
- if ngrok_edge_label is not None:
87
- self.ngrok_url = "URL_DEFINED_IN_EDGE_LABEL"
88
+ tunnel_kwargs = {
89
+ 'tunnel_engine': tunnel_engine,
90
+ 'tunnel_engine_enabled': tunnel_engine_enabled,
91
+ }
92
+ if not tunnel_engine_enabled:
93
+ self.app_url = "TUNNEL_ENGINE_DISABLED"
94
+ else:
95
+ if tunnel_engine.lower() == 'cloudflare':
96
+ if cloudflare_token is None:
97
+ raise ValueError("Cloudflare token must be provided when using Cloudflare as tunnel engine.")
98
+ self.P("Using Cloudflare as tunnel engine", color="green")
99
+ self.app_url = "URL_DEFINED_IN_CLOUDFLARE_TOKEN"
100
+ tunnel_kwargs['cloudflare_token'] = cloudflare_token
101
+ else:
102
+ self.P("Using ngrok as tunnel engine", color="green")
103
+ if ngrok_edge_label is not None:
104
+ self.app_url = "URL_DEFINED_IN_NGROK_EDGE_LABEL"
105
+ tunnel_kwargs['ngrok_edge_label'] = ngrok_edge_label
106
+ # endif ngrok_edge_label is not None
107
+ # endif tunnel_engine ngrok or cloudflare
108
+ # endif tunnel_engine_enabled
88
109
 
89
110
  return super().create_plugin_instance(
90
111
  signature=signature,
91
112
  instance_id=instance_id,
92
- config=config,
93
- ngrok_edge_label=ngrok_edge_label,
113
+ config=config,
114
+ **tunnel_kwargs,
94
115
  **kwargs
95
116
  )
96
117
 
@@ -106,11 +127,11 @@ class WebappPipeline(Pipeline):
106
127
  res = super().deploy(verbose=verbose, timeout=timeout, **kwargs)
107
128
  # now we wait for the ngrok url to be available
108
129
  start = time.time()
109
- while self.ngrok_url is None:
130
+ while self.app_url is None:
110
131
  elapsed = time.time() - start
111
132
  if elapsed > timeout:
112
133
  msg = "Timeout waiting for ngrok url"
113
134
  self.P(msg, color="red")
114
135
  raise Exception(msg)
115
136
  # return the ngrok url
116
- return self.ngrok_url
137
+ return self.app_url
ratio1/cli/nodes.py CHANGED
@@ -209,52 +209,39 @@ def get_apps(args):
209
209
  return
210
210
 
211
211
  def _send_command_to_node(args, command, ignore_not_found=False):
212
+ from ratio1 import Session
213
+
212
214
  node = args.node
213
215
  silent = not args.verbose
214
216
  ignore_peering = args.ignore_peering
215
217
 
216
218
  t1 = time()
217
- df, _, _, _, _, sess = _get_netstats(
218
- silent=silent, online_only=True, return_session=True, all_info=True,
219
- wait_for_node=node
220
- )
221
-
222
- peered = None
223
- selection = (df.Alias == node) | (df.Address == node)
224
- if 'ETH Address' in df.columns:
225
- selection = selection | (df['ETH Address'] == node)
226
- found = selection.any()
227
- node_addr = None
228
- alias = None
229
- df_found = df[selection]
230
- if found:
231
- alias = df_found.Alias.values[0]
232
- peered = df_found.Peered.values[0]
233
- node_addr = df_found.Address.values[0]
234
- log_with_color(f"{df_found}")
235
- else:
236
- log_with_color("Node '{}' <{}> not found in network (total {} nodes, {} peered).".format(
237
- node, node_addr, df.shape[0], df.Peered.sum()), color='r'
238
- )
239
- node_addr = node
219
+ sess = Session(silent=silent)
220
+
221
+ peered, node_addr = sess.is_peered(node, return_full_address=True)
222
+ found = False
240
223
 
241
- if not peered and not ignore_peering:
242
- log_with_color(f"Node '{node}' <{node_addr}> not peered, exiting...", color='r')
243
- return
224
+ if not ignore_peering:
225
+ found = sess.wait_for_node(node_addr, timeout=30)
226
+ sess.P(f"Node {node_addr} is online.")
244
227
 
228
+ # Display peering status.
245
229
  if not peered:
230
+ if not ignore_peering:
231
+ log_with_color(f"Node <{node_addr}> is not peered. Exiting...", color='r')
232
+ return
233
+
246
234
  if found:
247
235
  log_with_color(f"Node '{node}' <{node_addr}> is not peered.", color='r')
248
236
  else:
249
237
  log_with_color(f"Node '{node}' <{node_addr}> may not accept this command.", color='r')
250
238
 
251
- # TODO: currently this is based on node alias, but we should be based on node address
252
- # and maybe even node alias
253
- if (found and peered) or ignore_not_found:
254
- if found and peered:
255
- log_with_color(f"Sending '{command}' to node '{alias}' <{node_addr}>", color='b')
256
- else:
257
- log_with_color(f"Sending blind '{command}' to node '{alias}' <{node_addr}>", color='b')
239
+ if found and peered:
240
+ log_with_color(f"Sending '{command}' to node <{node_addr}>", color='b')
241
+ else:
242
+ log_with_color(f"Sending blind '{command}' to node <{node_addr}>", color='b')
243
+
244
+ if (found and peered) or ignore_not_found or ignore_peering:
258
245
  if command == COMMANDS.RESTART:
259
246
  sess._send_command_restart_node(node_addr)
260
247
  elif command == COMMANDS.STOP:
@@ -262,7 +249,12 @@ def _send_command_to_node(args, command, ignore_not_found=False):
262
249
  else:
263
250
  log_with_color(f"Command '{command}' not supported.", color='r')
264
251
  return
265
- elapsed = time() - t1
252
+
253
+ sess.close()
254
+ log_with_color(f"Command successfully sent.")
255
+ elapsed = time() - t1
256
+ if not silent:
257
+ log_with_color(f"Command '{command}' seinging took {elapsed}s.", color='b')
266
258
  return
267
259
 
268
260
  def restart_node(args):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ratio1
3
- Version: 3.4.38
3
+ Version: 3.4.40
4
4
  Summary: `ratio1` or Ration1 SDK is the Python SDK required for client app development for the Ratio1 ecosystem
5
5
  Project-URL: Homepage, https://github.com/Ratio1/ratio1_sdk
6
6
  Project-URL: Bug Tracker, https://github.com/Ratio1/ratio1_sdk/issues
@@ -1,16 +1,16 @@
1
1
  ratio1/__init__.py,sha256=YimqgDbjLuywsf8zCWE0EaUXH4MBUrqLxt0TDV558hQ,632
2
- ratio1/_ver.py,sha256=V7rvQhayxcjHTMq_ijAWlHOsx7ILkFTSNsrJsHaRBFU,331
2
+ ratio1/_ver.py,sha256=zlrigFbgf6eJq1eow1kVyGQ8QOgt1xZpjWDhUjft6tY,331
3
3
  ratio1/base_decentra_object.py,sha256=iXvAAf6wPnGWzeeiRfwLojVoan-m1e_VsyPzjUQuENo,4492
4
4
  ratio1/plugins_manager_mixin.py,sha256=X1JdGLDz0gN1rPnTN_5mJXR8JmqoBFQISJXmPR9yvCo,11106
5
5
  ratio1/base/__init__.py,sha256=hACh83_cIv7-PwYMM3bQm2IBmNqiHw-3PAfDfAEKz9A,259
6
6
  ratio1/base/distributed_custom_code_presets.py,sha256=cvz5R88P6Z5V61Ce1vHVVh8bOkgXd6gve_vdESDNAsg,2544
7
- ratio1/base/generic_session.py,sha256=fzpAIqRJbwiBrpFqHXCHxvakAves7cbXRrHURLelffI,179566
7
+ ratio1/base/generic_session.py,sha256=LsZaQTg9IyG0jXMmFhXQqxOCGCPvAPXZoVvom8cWfCc,185526
8
8
  ratio1/base/instance.py,sha256=oQvwzzRvir7851wyhDx_BwN6y_VgsNWwYo53vN33QI4,21914
9
9
  ratio1/base/pipeline.py,sha256=szoHrk1qBdY6NKPUk3tUTsJx3XzYp5C2GTOlzRiQi48,62489
10
10
  ratio1/base/plugin_template.py,sha256=Gs438cSkhvxPujE4CRH_32pcuZaVwI9kia8E4VDRpSU,138794
11
11
  ratio1/base/responses.py,sha256=ZKBZmRhYDv8M8mQ5C_ahGsQvtWH4b9ImRcuerQdZmNw,6937
12
12
  ratio1/base/transaction.py,sha256=l2JCzTgH3-irFwCEBGrS3z8VOisA8GdC3zEfqgJOTG4,5138
13
- ratio1/base/webapp_pipeline.py,sha256=ZNGqZ36DY076XVDfGu2Q61kCt3kxIJ4Mi4QbPZuDVn0,2791
13
+ ratio1/base/webapp_pipeline.py,sha256=zjiLzGnsUEfrSyHWMDoiwQWheM-MXQOeR3YKfFPKXiE,3706
14
14
  ratio1/base/payload/__init__.py,sha256=y8fBI8tG2ObNfaXFWjyWZXwu878FRYj_I8GIbHT4GKE,29
15
15
  ratio1/base/payload/payload.py,sha256=MoCeL6iZzl1an-4eqRpLW0iz6Yk3OvlBrymcmhWeecM,2689
16
16
  ratio1/bc/__init__.py,sha256=BI5pcqHdhwnMdbWTYDLW1cVP_844VtLra-lz7xprgsk,171
@@ -26,7 +26,7 @@ ratio1/certs/s624dbd4.ala.us-east-1.emqxsl.com.crt,sha256=y-6io0tseyx9-a4Pmde1z1
26
26
  ratio1/cli/README.md,sha256=YsT23YcZBRyTKReNZPxD762YqstSWKWz4iZe_UJELPc,73
27
27
  ratio1/cli/cli.py,sha256=D8UCtdTQKi1IqB_PAi3k2FfaM-rnfxmlrOzM4OJBOsA,4352
28
28
  ratio1/cli/cli_commands.py,sha256=aoPnASJ3uPHWqABLCL-E6J3U0npK7kxX8U07s_aR9qA,6290
29
- ratio1/cli/nodes.py,sha256=0QjAbAhn_KrrjiGUXQ0GhnxCM-Zvxhx32FNcQd9hhHI,14237
29
+ ratio1/cli/nodes.py,sha256=EZxjw8G8Kj0PPMHtUJoefm4QootrU50GHlpaJOiHxJo,13787
30
30
  ratio1/cli/oracles.py,sha256=HTQAKEwe-j0E00JKKPCH1GXjelyy0IAjzLZIx8qtimU,11141
31
31
  ratio1/cli/package_update.py,sha256=uRMPW5XV3fBdB_eZfoQDA1SKnJzTJvyfpRJA6T3ZZlQ,4000
32
32
  ratio1/code_cheker/__init__.py,sha256=pwkdeZGVL16ZA4Qf2mRahEhoOvKhL7FyuQbMFLr1E5M,33
@@ -103,8 +103,8 @@ ratio1/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_LtMyCY,10
103
103
  ratio1/utils/config.py,sha256=IMXAN9bpHePKEuTFGRRqFJXz_vBa-wi7s9gLhFEheRY,9953
104
104
  ratio1/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
105
105
  ratio1/utils/oracle_sync/oracle_tester.py,sha256=aJOPcZhtbw1XPqsFG4qYpfv2Taj5-qRXbwJzrPyeXDE,27465
106
- ratio1-3.4.38.dist-info/METADATA,sha256=u-A5X0V6P59pp9vxmt5GgoXUB9JPIz0m_P8n2fyFiy0,12248
107
- ratio1-3.4.38.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
108
- ratio1-3.4.38.dist-info/entry_points.txt,sha256=DR_olREzU1egwmgek3s4GfQslBi-KR7lXsd4ap0TFxE,46
109
- ratio1-3.4.38.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
110
- ratio1-3.4.38.dist-info/RECORD,,
106
+ ratio1-3.4.40.dist-info/METADATA,sha256=oOOOjfuuQspNmWwiwIt2Gz4hRgES9vpgmcBS3ldtd_o,12248
107
+ ratio1-3.4.40.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
108
+ ratio1-3.4.40.dist-info/entry_points.txt,sha256=DR_olREzU1egwmgek3s4GfQslBi-KR7lXsd4ap0TFxE,46
109
+ ratio1-3.4.40.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
110
+ ratio1-3.4.40.dist-info/RECORD,,