outerbounds 0.3.51__py3-none-any.whl → 0.3.52rc0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -772,3 +772,372 @@ def configure(
772
772
  except Exception as e:
773
773
  click.secho("Writing the configuration file '{}' failed.".format(writer.path()))
774
774
  click.secho("Error: {}".format(str(e)))
775
+
776
+
777
+ @cli.command(help="Switch current perimeter")
778
+ @click.option(
779
+ "-o",
780
+ "--output",
781
+ default="",
782
+ help="Show output in the specified format.",
783
+ type=click.Choice(["json", ""]),
784
+ )
785
+ @click.option("--id", default="", help="Perimeter name to switch to")
786
+ @click.option(
787
+ "-f",
788
+ "--force",
789
+ is_flag=True,
790
+ help="Force change the existing perimeter",
791
+ default=False,
792
+ )
793
+ def switch_perimeter(output="", id=None, force=False):
794
+ switch_perimeter_response = OuterboundsCommandResponse()
795
+
796
+ switch_perimeter_step = CommandStatus(
797
+ "SwitchPerimeter",
798
+ OuterboundsCommandStatus.OK,
799
+ "Perimeter was successfully switched!",
800
+ )
801
+
802
+ if "WORKSTATION_ID" not in os.environ:
803
+ click.secho(
804
+ "outerbounds switch-perimeter is only supported on workstations.",
805
+ fg="red",
806
+ err=True,
807
+ )
808
+ switch_perimeter_step.update(
809
+ status=OuterboundsCommandStatus.FAIL,
810
+ reason="outerbounds switch-perimeter is only supported on workstations.",
811
+ mitigation="",
812
+ )
813
+ switch_perimeter_response.add_step(switch_perimeter_step)
814
+ if output == "json":
815
+ click.echo(json.dumps(switch_perimeter_response.as_dict(), indent=4))
816
+ return
817
+
818
+ metaflow_home_dir = path.expanduser(
819
+ os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
820
+ )
821
+
822
+ if not os.path.exists("{}/config_{}.json".format(metaflow_home_dir, id)):
823
+ click.secho(
824
+ "Perimeter {} does not exist or you don't have access to it".format(id),
825
+ fg="red",
826
+ err=True,
827
+ )
828
+ switch_perimeter_step.update(
829
+ status=OuterboundsCommandStatus.FAIL,
830
+ reason="Perimeter {} does not exist or you don't have access to it".format(
831
+ id
832
+ ),
833
+ mitigation="Please contact your admin or the Outerbounds team for assistance.",
834
+ )
835
+ switch_perimeter_response.add_step(switch_perimeter_step)
836
+ if output == "json":
837
+ click.echo(json.dumps(switch_perimeter_response.as_dict(), indent=4))
838
+ return
839
+
840
+ # If OBP_CONFIG_DIR is set, use that, otherwise use METAFLOW_HOME
841
+ # If neither are set, use ~/.metaflowconfig
842
+ obp_config_dir = path.expanduser(
843
+ os.environ.get(
844
+ "OBP_CONFIG_DIR", os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
845
+ )
846
+ )
847
+
848
+ path_to_config = os.path.expanduser(os.path.join(obp_config_dir, "ob_config.json"))
849
+
850
+ if not os.path.exists(path_to_config):
851
+ click.secho(
852
+ "Config file not found at {}".format(path_to_config), fg="red", err=True
853
+ )
854
+ switch_perimeter_step.update(
855
+ status=OuterboundsCommandStatus.FAIL,
856
+ reason="Config file not found",
857
+ mitigation="Please make sure the config file exists at {}".format(
858
+ path_to_config
859
+ ),
860
+ )
861
+ switch_perimeter_response.add_step(switch_perimeter_step)
862
+ if output == "json":
863
+ click.echo(json.dumps(switch_perimeter_response.as_dict(), indent=4))
864
+ return
865
+
866
+ import fcntl
867
+
868
+ fd = os.open(path_to_config, os.O_WRONLY)
869
+
870
+ try:
871
+ if not force:
872
+ # Try to acquire an exclusive lock
873
+ fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
874
+ else:
875
+ click.secho(
876
+ "Force flag is set. Perimeter will be switched, but can have unintended consequences on other running processes.",
877
+ fg="yellow",
878
+ )
879
+
880
+ ob_config_dict = {"OB_CURRENT_PERIMETER": id}
881
+
882
+ # Now that we have the lock, we can safely write to the file
883
+ with os.fdopen(fd, "w") as file:
884
+ json.dump(ob_config_dict, file, indent=4)
885
+
886
+ click.secho("Perimeter switched to {}".format(id), fg="green")
887
+ except BlockingIOError:
888
+ # This exception is raised if the file is already locked (non-blocking mode)
889
+ click.secho(
890
+ "Can't switch perimeter while Metaflow is in use. Please make sure there are no running python processes or notebooks using metaflow.",
891
+ fg="red",
892
+ err=True,
893
+ )
894
+ switch_perimeter_step.update(
895
+ status=OuterboundsCommandStatus.FAIL,
896
+ reason="Can't switch perimeter while Metaflow is in use.",
897
+ mitigation="Please make sure there are no running python processes or notebooks using metaflow.",
898
+ )
899
+
900
+ switch_perimeter_response.add_step(switch_perimeter_step)
901
+ if output == "json":
902
+ click.echo(json.dumps(switch_perimeter_response.as_dict(), indent=4))
903
+ return
904
+
905
+
906
+ @cli.command(help="Show current perimeter")
907
+ @click.option(
908
+ "-o",
909
+ "--output",
910
+ default="",
911
+ help="Show output in the specified format.",
912
+ type=click.Choice(["json", ""]),
913
+ )
914
+ def show_current_perimeter(output=""):
915
+ show_current_perimeter_response = OuterboundsCommandResponse()
916
+
917
+ show_current_perimeter_step = CommandStatus(
918
+ "ShowCurrentPerimeter",
919
+ OuterboundsCommandStatus.OK,
920
+ "Current Perimeter Fetch Successful.",
921
+ )
922
+
923
+ if "WORKSTATION_ID" not in os.environ:
924
+ click.secho(
925
+ "outerbounds switch-perimeter is only supported on workstations.",
926
+ fg="red",
927
+ err=True,
928
+ )
929
+ show_current_perimeter_step.update(
930
+ status=OuterboundsCommandStatus.FAIL,
931
+ reason="outerbounds show-current-perimeter is only supported on workstations.",
932
+ mitigation="",
933
+ )
934
+ show_current_perimeter_response.add_step(show_current_perimeter_step)
935
+ if output == "json":
936
+ click.echo(json.dumps(show_current_perimeter_response.as_dict(), indent=4))
937
+ return
938
+
939
+ metaflow_home_dir = path.expanduser(
940
+ os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
941
+ )
942
+
943
+ # If OBP_CONFIG_DIR is set, use that, otherwise use METAFLOW_HOME
944
+ # If neither are set, use ~/.metaflowconfig
945
+ obp_config_dir = path.expanduser(
946
+ os.environ.get(
947
+ "OBP_CONFIG_DIR", os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
948
+ )
949
+ )
950
+
951
+ path_to_config = os.path.expanduser(os.path.join(obp_config_dir, "ob_config.json"))
952
+
953
+ if not os.path.exists(path_to_config):
954
+ click.secho(
955
+ "Config file not found at {}".format(path_to_config), fg="red", err=True
956
+ )
957
+ show_current_perimeter_step.update(
958
+ status=OuterboundsCommandStatus.FAIL,
959
+ reason="Config file not found",
960
+ mitigation="Please make sure the config file exists at {}".format(
961
+ path_to_config
962
+ ),
963
+ )
964
+ show_current_perimeter_response.add_step(show_current_perimeter_step)
965
+ if output == "json":
966
+ click.echo(json.dumps(show_current_perimeter_response.as_dict(), indent=4))
967
+ return
968
+
969
+ with open(path_to_config, "r") as file:
970
+ ob_config_dict = json.load(file)
971
+
972
+ if "OB_CURRENT_PERIMETER" not in ob_config_dict:
973
+ click.secho(
974
+ "OB_CURRENT_PERIMETER not found in Config file: {}".format(path_to_config),
975
+ fg="red",
976
+ err=True,
977
+ )
978
+ show_current_perimeter_step.update(
979
+ status=OuterboundsCommandStatus.FAIL,
980
+ reason="OB_CURRENT_PERIMETER not found in Config file: {}",
981
+ mitigation="",
982
+ )
983
+ show_current_perimeter_response.add_step(show_current_perimeter_step)
984
+ if output == "json":
985
+ click.echo(json.dumps(show_current_perimeter_response.as_dict(), indent=4))
986
+ return
987
+
988
+ if os.path.exists(
989
+ os.path.join(
990
+ metaflow_home_dir,
991
+ "config_{}.json".format(ob_config_dict["OB_CURRENT_PERIMETER"]),
992
+ )
993
+ ):
994
+ click.secho(
995
+ "Current Perimeter: {}".format(ob_config_dict["OB_CURRENT_PERIMETER"]),
996
+ fg="green",
997
+ )
998
+ show_current_perimeter_response.add_or_update_data(
999
+ "current_perimeter", ob_config_dict["OB_CURRENT_PERIMETER"]
1000
+ )
1001
+ else:
1002
+ click.secho(
1003
+ "Perimeter config file not found at {}".format(
1004
+ os.path.join(
1005
+ metaflow_home_dir,
1006
+ "config_{}.json".format(ob_config_dict["OB_CURRENT_PERIMETER"]),
1007
+ )
1008
+ ),
1009
+ fg="red",
1010
+ err=True,
1011
+ )
1012
+ show_current_perimeter_step.update(
1013
+ status=OuterboundsCommandStatus.FAIL,
1014
+ reason="Perimeter config file not found",
1015
+ mitigation="Please make sure the perimeter config file exists at {}/config_{}.json".format(
1016
+ metaflow_home_dir, ob_config_dict["OB_CURRENT_PERIMETER"]
1017
+ ),
1018
+ )
1019
+ show_current_perimeter_response.add_step(show_current_perimeter_step)
1020
+
1021
+ if output == "json":
1022
+ click.echo(json.dumps(show_current_perimeter_response.as_dict(), indent=4))
1023
+
1024
+
1025
+ @cli.command(help="List all available perimeters")
1026
+ @click.option(
1027
+ "-o",
1028
+ "--output",
1029
+ default="",
1030
+ help="Show output in the specified format.",
1031
+ type=click.Choice(["json", ""]),
1032
+ )
1033
+ def list_perimeters(output=""):
1034
+ list_perimeters_response = OuterboundsCommandResponse()
1035
+
1036
+ list_perimeters_step = CommandStatus(
1037
+ "ListPerimeters", OuterboundsCommandStatus.OK, "Perimeter Fetch Successful."
1038
+ )
1039
+
1040
+ if "WORKSTATION_ID" not in os.environ:
1041
+ click.secho(
1042
+ "outerbounds list-perimeters is only supported on workstations.",
1043
+ fg="red",
1044
+ err=True,
1045
+ )
1046
+ list_perimeters_step.update(
1047
+ status=OuterboundsCommandStatus.FAIL,
1048
+ reason="outerbounds list-perimeters is only supported on workstations.",
1049
+ mitigation="",
1050
+ )
1051
+ list_perimeters_response.add_step(list_perimeters_step)
1052
+ if output == "json":
1053
+ click.echo(json.dumps(list_perimeters_response.as_dict(), indent=4))
1054
+ return
1055
+
1056
+ metaflow_home_dir = path.expanduser(
1057
+ os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
1058
+ )
1059
+
1060
+ # If OBP_CONFIG_DIR is set, use that, otherwise use METAFLOW_HOME
1061
+ # If neither are set, use ~/.metaflowconfig
1062
+ obp_config_dir = path.expanduser(
1063
+ os.environ.get(
1064
+ "OBP_CONFIG_DIR", os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")
1065
+ )
1066
+ )
1067
+
1068
+ path_to_config = os.path.expanduser(os.path.join(obp_config_dir, "ob_config.json"))
1069
+
1070
+ if not os.path.exists(path_to_config):
1071
+ click.secho(
1072
+ "Config file not found at {}".format(path_to_config), fg="red", err=True
1073
+ )
1074
+ list_perimeters_step.update(
1075
+ status=OuterboundsCommandStatus.FAIL,
1076
+ reason="Config file not found",
1077
+ mitigation="Please make sure the config file exists at {}".format(
1078
+ path_to_config
1079
+ ),
1080
+ )
1081
+ list_perimeters_response.add_step(list_perimeters_step)
1082
+ if output == "json":
1083
+ click.echo(json.dumps(list_perimeters_response.as_dict(), indent=4))
1084
+ return
1085
+
1086
+ with open(path_to_config, "r") as file:
1087
+ ob_config_dict = json.load(file)
1088
+
1089
+ if "OB_CURRENT_PERIMETER" not in ob_config_dict:
1090
+ click.secho(
1091
+ "OB_CURRENT_PERIMETER not found in Config file: {}".format(path_to_config),
1092
+ fg="red",
1093
+ err=True,
1094
+ )
1095
+ list_perimeters_step.update(
1096
+ status=OuterboundsCommandStatus.FAIL,
1097
+ reason="OB_CURRENT_PERIMETER not found in Config file: {}",
1098
+ mitigation="",
1099
+ )
1100
+ list_perimeters_response.add_step(list_perimeters_step)
1101
+ if output == "json":
1102
+ click.echo(json.dumps(list_perimeters_response.as_dict(), indent=4))
1103
+ return
1104
+
1105
+ if os.path.exists(
1106
+ os.path.join(
1107
+ metaflow_home_dir,
1108
+ "config_{}.json".format(ob_config_dict["OB_CURRENT_PERIMETER"]),
1109
+ )
1110
+ ):
1111
+ active_perimeter = ob_config_dict["OB_CURRENT_PERIMETER"]
1112
+ else:
1113
+ click.secho(
1114
+ "Perimeter config file not found at {}".format(
1115
+ os.path.join(
1116
+ metaflow_home_dir,
1117
+ "config_{}.json".format(ob_config_dict["OB_CURRENT_PERIMETER"]),
1118
+ )
1119
+ ),
1120
+ fg="red",
1121
+ err=True,
1122
+ )
1123
+ list_perimeters_step.update(
1124
+ status=OuterboundsCommandStatus.FAIL,
1125
+ reason="Perimeter config file not found",
1126
+ mitigation="Please make sure the perimeter config file exists at {}/config_{}.json".format(
1127
+ metaflow_home_dir, ob_config_dict["OB_CURRENT_PERIMETER"]
1128
+ ),
1129
+ )
1130
+ list_perimeters_response.add_step(list_perimeters_step)
1131
+ return
1132
+
1133
+ perimeter_list = []
1134
+ for file in os.listdir(metaflow_home_dir):
1135
+ if file.startswith("config_") and file.endswith(".json"):
1136
+ perimeter_id = file.split("_")[1].split(".")[0]
1137
+ perimeter_list.append(
1138
+ {"id": perimeter_id, "active": perimeter_id == active_perimeter}
1139
+ )
1140
+
1141
+ list_perimeters_response.add_or_update_data("perimeters", perimeter_list)
1142
+ if output == "json":
1143
+ click.echo(json.dumps(list_perimeters_response.as_dict(), indent=4))
@@ -37,10 +37,14 @@ class OuterboundsCommandResponse:
37
37
  self._message = ""
38
38
  self._steps = []
39
39
  self.metadata = {}
40
+ self._data = {}
40
41
 
41
42
  def add_or_update_metadata(self, key, value):
42
43
  self.metadata[key] = value
43
44
 
45
+ def add_or_update_data(self, key, value):
46
+ self._data[key] = value
47
+
44
48
  def add_step(self, step: CommandStatus):
45
49
  self._steps.append(step)
46
50
  self._process_step_status(step)
@@ -65,4 +69,5 @@ class OuterboundsCommandResponse:
65
69
  "message": self._message,
66
70
  "steps": [step.as_dict() for step in self._steps],
67
71
  "metadata": self.metadata,
72
+ "data": self._data,
68
73
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: outerbounds
3
- Version: 0.3.51
3
+ Version: 0.3.52rc0
4
4
  Summary: More Data Science, Less Administration
5
5
  License: Proprietary
6
6
  Keywords: data science,machine learning,MLOps
@@ -14,17 +14,13 @@ Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Provides-Extra: azure
17
- Provides-Extra: gcp
18
17
  Requires-Dist: PyYAML (>=6.0,<7.0)
19
18
  Requires-Dist: azure-identity (>=1.15.0,<2.0.0) ; extra == "azure"
20
19
  Requires-Dist: azure-storage-blob (>=12.9.0,<13.0.0) ; extra == "azure"
21
20
  Requires-Dist: boto3
22
21
  Requires-Dist: click (>=8.1.3,<9.0.0)
23
- Requires-Dist: google-api-core (>=2.16.1,<3.0.0) ; extra == "gcp"
24
- Requires-Dist: google-auth (>=2.27.0,<3.0.0) ; extra == "gcp"
25
- Requires-Dist: google-cloud-storage (>=2.14.0,<3.0.0) ; extra == "gcp"
26
- Requires-Dist: ob-metaflow (==2.11.0.4)
27
- Requires-Dist: ob-metaflow-extensions (==1.1.42)
22
+ Requires-Dist: ob-metaflow (==2.11.0.3)
23
+ Requires-Dist: ob-metaflow-extensions (==1.1.42rc0)
28
24
  Requires-Dist: opentelemetry-distro (==0.41b0)
29
25
  Requires-Dist: opentelemetry-exporter-otlp-proto-http (==1.20.0)
30
26
  Requires-Dist: opentelemetry-instrumentation-requests (==0.41b0)
@@ -2,13 +2,13 @@ outerbounds/__init__.py,sha256=GPdaubvAYF8pOFWJ3b-sPMKCpyfpteWVMZWkmaYhxRw,32
2
2
  outerbounds/cli_main.py,sha256=e9UMnPysmc7gbrimq2I4KfltggyU7pw59Cn9aEguVcU,74
3
3
  outerbounds/command_groups/__init__.py,sha256=QPWtj5wDRTINDxVUL7XPqG3HoxHNvYOg08EnuSZB2Hc,21
4
4
  outerbounds/command_groups/cli.py,sha256=61VsBlPG2ykP_786eCyllqeM8DMhPAOfj2FhktrSd7k,207
5
- outerbounds/command_groups/local_setup_cli.py,sha256=5S1bcq8mW5YS-PZBO4ZrBAeLwFqcQYmm_t9ALjT77nU,28312
5
+ outerbounds/command_groups/local_setup_cli.py,sha256=HOTvOlb22cF86QmDpdQc6UVx4gFa2hBzsM8qI7Yj6vY,41486
6
6
  outerbounds/command_groups/workstations_cli.py,sha256=VgydQzCas3mlAFyzZuanjl1E8Zh7pBrbKbbP6t6N2WU,18237
7
7
  outerbounds/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  outerbounds/utils/kubeconfig.py,sha256=l1mUP1j9VIq3fsffi5bJ1Nk-hYlwd1dIqkpj7DvVS1E,7936
9
9
  outerbounds/utils/metaflowconfig.py,sha256=zdSeZEc1h4yJAZUrfWIO9EYSy84wdE_JCSEiCxb-su8,2341
10
- outerbounds/utils/schema.py,sha256=nBuarFbdZu0LGhG0YkJ6pEIvdglfM_TO_W_Db2vksb0,2017
11
- outerbounds-0.3.51.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
12
- outerbounds-0.3.51.dist-info/entry_points.txt,sha256=7ye0281PKlvqxu15rjw60zKg2pMsXI49_A8BmGqIqBw,47
13
- outerbounds-0.3.51.dist-info/METADATA,sha256=WAr8ATcx7tGjEu5BMi8yGFU5Er2BiYSqwgFo4X-7yVc,1361
14
- outerbounds-0.3.51.dist-info/RECORD,,
10
+ outerbounds/utils/schema.py,sha256=4_ONlvZGpBb51KKd-q6mNSKWI9P1huOKafrsf9kVqp8,2152
11
+ outerbounds-0.3.52rc0.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
12
+ outerbounds-0.3.52rc0.dist-info/entry_points.txt,sha256=7ye0281PKlvqxu15rjw60zKg2pMsXI49_A8BmGqIqBw,47
13
+ outerbounds-0.3.52rc0.dist-info/METADATA,sha256=xkqrbbaDvrjERYy5fZ0kqk8Y_TEGneAjF5H0e6-uiNs,1148
14
+ outerbounds-0.3.52rc0.dist-info/RECORD,,