MEDfl 0.2.1__py3-none-any.whl → 2.0.0__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.
Files changed (55) hide show
  1. MEDfl/LearningManager/__init__.py +13 -13
  2. MEDfl/LearningManager/client.py +150 -181
  3. MEDfl/LearningManager/dynamicModal.py +287 -287
  4. MEDfl/LearningManager/federated_dataset.py +60 -60
  5. MEDfl/LearningManager/flpipeline.py +192 -192
  6. MEDfl/LearningManager/model.py +223 -223
  7. MEDfl/LearningManager/params.yaml +14 -14
  8. MEDfl/LearningManager/params_optimiser.py +442 -442
  9. MEDfl/LearningManager/plot.py +229 -229
  10. MEDfl/LearningManager/server.py +181 -189
  11. MEDfl/LearningManager/strategy.py +82 -138
  12. MEDfl/LearningManager/utils.py +331 -331
  13. MEDfl/NetManager/__init__.py +10 -10
  14. MEDfl/NetManager/database_connector.py +43 -43
  15. MEDfl/NetManager/dataset.py +92 -92
  16. MEDfl/NetManager/flsetup.py +320 -320
  17. MEDfl/NetManager/net_helper.py +254 -254
  18. MEDfl/NetManager/net_manager_queries.py +142 -142
  19. MEDfl/NetManager/network.py +194 -194
  20. MEDfl/NetManager/node.py +184 -184
  21. MEDfl/__init__.py +2 -2
  22. MEDfl/scripts/__init__.py +1 -1
  23. MEDfl/scripts/base.py +29 -29
  24. MEDfl/scripts/create_db.py +126 -126
  25. Medfl/LearningManager/__init__.py +13 -0
  26. Medfl/LearningManager/client.py +150 -0
  27. Medfl/LearningManager/dynamicModal.py +287 -0
  28. Medfl/LearningManager/federated_dataset.py +60 -0
  29. Medfl/LearningManager/flpipeline.py +192 -0
  30. Medfl/LearningManager/model.py +223 -0
  31. Medfl/LearningManager/params.yaml +14 -0
  32. Medfl/LearningManager/params_optimiser.py +442 -0
  33. Medfl/LearningManager/plot.py +229 -0
  34. Medfl/LearningManager/server.py +181 -0
  35. Medfl/LearningManager/strategy.py +82 -0
  36. Medfl/LearningManager/utils.py +331 -0
  37. Medfl/NetManager/__init__.py +10 -0
  38. Medfl/NetManager/database_connector.py +43 -0
  39. Medfl/NetManager/dataset.py +92 -0
  40. Medfl/NetManager/flsetup.py +320 -0
  41. Medfl/NetManager/net_helper.py +254 -0
  42. Medfl/NetManager/net_manager_queries.py +142 -0
  43. Medfl/NetManager/network.py +194 -0
  44. Medfl/NetManager/node.py +184 -0
  45. Medfl/__init__.py +3 -0
  46. Medfl/scripts/__init__.py +2 -0
  47. Medfl/scripts/base.py +30 -0
  48. Medfl/scripts/create_db.py +126 -0
  49. alembic/env.py +61 -61
  50. {MEDfl-0.2.1.dist-info → medfl-2.0.0.dist-info}/METADATA +120 -108
  51. medfl-2.0.0.dist-info/RECORD +55 -0
  52. {MEDfl-0.2.1.dist-info → medfl-2.0.0.dist-info}/WHEEL +1 -1
  53. {MEDfl-0.2.1.dist-info → medfl-2.0.0.dist-info/licenses}/LICENSE +674 -674
  54. MEDfl-0.2.1.dist-info/RECORD +0 -31
  55. {MEDfl-0.2.1.dist-info → medfl-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,142 @@
1
+ from .net_helper import is_str
2
+
3
+ INSERT_DATASET = """
4
+ INSERT INTO DataSets(DataSetName, NodeId, {columns})
5
+ VALUES (:name, :NodeId, {values})
6
+ """
7
+ DELETE_DATASET = """
8
+ DELETE FROM DataSets WHERE DataSetName = :name
9
+ """
10
+
11
+ SELECT_ALL_DATASET_NAMES = """
12
+ SELECT DISTINCT DataSetName,NodeId FROM DataSets
13
+ """
14
+
15
+ SELECT_DATASET_BY_NAME = """
16
+ SELECT * FROM DataSets WHERE DataSetName = :name
17
+ """
18
+
19
+ # node queries
20
+ # sql_queries.py
21
+
22
+ INSERT_NODE_QUERY = (
23
+ "INSERT INTO Nodes(NodeName,NetId,train) VALUES ('{}',{}, {})"
24
+ )
25
+ DELETE_NODE_QUERY = "DELETE FROM Nodes WHERE NodeName = '{}'"
26
+ SELECT_MASTER_COLUMNS_QUERY = "SELECT * FROM MasterDataset LIMIT 1"
27
+ SELECT_DATASET_BY_COLUMN_QUERY = "SELECT * FROM MasterDataset WHERE {} = '{}'"
28
+ SELECT_DATASET_BY_NODE_ID_QUERY = "SELECT * FROM DataSets WHERE NodeId = {}"
29
+
30
+ SELECT_ALL_DATASETS_QUERY = "SELECT DISTINCT DataSetName,NodeName FROM DataSets,Nodes WHERE Nodes.NodeName = '{}' and Nodes.NodeId = DataSets.NodeId"
31
+ SELECT_ALL_NODES_QUERY = "SELECT * FROM Nodes"
32
+
33
+
34
+ # SQL query to insert a new network
35
+ INSERT_NETWORK_QUERY = "INSERT INTO Networks(NetName) VALUES (:name)"
36
+
37
+ # SQL query to delete a network
38
+ DELETE_NETWORK_QUERY = "DELETE FROM Networks WHERE NetName = '{name}'"
39
+
40
+ # SQL query to delete a network
41
+ GET_NETWORK_QUERY = "SELECT * FROM Networks WHERE NetName = '{name}'"
42
+
43
+
44
+ # SQL query to update a network
45
+ UPDATE_NETWORK_QUERY = (
46
+ "UPDATE Networks SET FLsetupId = {FLsetupId} WHERE NetId = {id}"
47
+ )
48
+
49
+ # SQL query to retrieve all nodes for a network
50
+ LIST_ALL_NODES_QUERY = """
51
+ SELECT Nodes.NodeName, Networks.NetName
52
+ FROM Nodes
53
+ JOIN Networks ON Networks.NetId = Nodes.NetId
54
+ WHERE Networks.NetName = :name
55
+ """
56
+
57
+ # SQL query to create the MasterDataset table (SQLite-compatible)
58
+ CREATE_MASTER_DATASET_TABLE_QUERY = """
59
+ CREATE TABLE IF NOT EXISTS MasterDataset (
60
+ PatientId INTEGER PRIMARY KEY AUTOINCREMENT,
61
+ {}
62
+ );
63
+ """
64
+
65
+
66
+ # SQL query to create the datasets table (SQLite-compatible)
67
+ CREATE_DATASETS_TABLE_QUERY = """
68
+ CREATE TABLE IF NOT EXISTS Datasets (
69
+ DataSetId INTEGER PRIMARY KEY AUTOINCREMENT,
70
+ DataSetName VARCHAR(255),
71
+ NodeId INT,
72
+ {}
73
+ );
74
+ """
75
+
76
+
77
+
78
+ # SQL query to insert dataset values
79
+ INSERT_DATASET_VALUES_QUERY = "INSERT INTO MasterDataset({columns}, NodeId) VALUES ('{name}', {nodeId}, {values})"
80
+
81
+
82
+ # FL setup_queries
83
+ # sql_queries.py
84
+
85
+ CREATE_FLSETUP_QUERY = """
86
+ INSERT INTO FLsetup (name, description, creation_date, NetId, column_name)
87
+ VALUES (:name, :description, :creation_date, :net_id, :column_name)
88
+ """
89
+
90
+ DELETE_FLSETUP_QUERY = """
91
+ DELETE FROM FLsetup
92
+ WHERE name = :name
93
+ """
94
+
95
+ UPDATE_FLSETUP_QUERY = UPDATE_NETWORK_QUERY = (
96
+ "UPDATE FLsetup SET column_name ='{column_name}' WHERE name ='{FLsetupName}'"
97
+ )
98
+
99
+
100
+ READ_SETUP_QUERY = """
101
+ SELECT * FROM FLsetup
102
+ WHERE FLsetupId = :flsetup_id
103
+ """
104
+
105
+ READ_ALL_SETUPS_QUERY = """
106
+ SELECT * FROM FLsetup
107
+ """
108
+
109
+ READ_NETWORK_BY_ID_QUERY = """
110
+ SELECT * FROM Networks
111
+ WHERE NetId = :net_id
112
+ """
113
+
114
+ READ_DISTINCT_NODES_QUERY = """
115
+ SELECT DISTINCT {} FROM MasterDataset
116
+ """
117
+
118
+
119
+ # FederatedDataset Queries
120
+ INSERT_FLDATASET_QUERY = (
121
+ "INSERT INTO FedDatasets(name, FLsetupId) VALUES (:name, :FLsetupId)"
122
+ )
123
+ DELETE_FLDATASET_BY_SETUP_AND_PIPELINE_QUERY = "DELETE FROM FedDatasets WHERE FLsetupId = :FLsetupId AND FLpipeId = :FLpipeId"
124
+
125
+
126
+ UPDATE_FLDATASET_QUERY = (
127
+ "UPDATE FedDatasets SET FLpipeId = :FLpipeId WHERE FedId = :FedId"
128
+ )
129
+ SELECT_FLDATASET_BY_NAME_QUERY = "SELECT * FROM FedDatasets WHERE name = :name"
130
+
131
+ CREATE_FLPIPELINE_QUERY = """
132
+ INSERT INTO FLpipeline (name, description, creation_date, results)
133
+ VALUES ('{name}', '{description}', '{creation_date}', '{result}')
134
+ """
135
+ DELETE_FLPIPELINE_QUERY = "DELETE FROM FLpipeline WHERE name = '{name}'"
136
+
137
+ SELECT_FLPIPELINE_QUERY = "SELECT FROM FLpipeline WHERE name = '{name}'"
138
+
139
+ CREATE_TEST_RESULTS_QUERY = """
140
+ INSERT INTO testResults (pipelineid, nodename, confusionmatrix, accuracy , sensivity, ppv , npv , f1score , fpr , tpr )
141
+ VALUES ('{pipelineId}', '{nodeName}', '{confusion_matrix}', '{accuracy}' , '{sensivity}' , '{ppv}' , '{npv}' , '{f1score}' , '{fpr}' , '{tpr}')
142
+ """
@@ -0,0 +1,194 @@
1
+ # src/MEDfl/NetManager/network.py
2
+
3
+ from MEDfl.LearningManager.utils import *
4
+ from .net_helper import *
5
+ from .net_manager_queries import (CREATE_MASTER_DATASET_TABLE_QUERY,
6
+ CREATE_DATASETS_TABLE_QUERY,
7
+ DELETE_NETWORK_QUERY,
8
+ INSERT_NETWORK_QUERY, LIST_ALL_NODES_QUERY,
9
+ UPDATE_NETWORK_QUERY, GET_NETWORK_QUERY)
10
+ from .node import Node
11
+ import pandas as pd
12
+ from MEDfl.LearningManager.utils import params
13
+
14
+ from sqlalchemy import text
15
+ from sqlalchemy.exc import SQLAlchemyError
16
+
17
+ class Network:
18
+ """
19
+ A class representing a network.
20
+
21
+ Attributes:
22
+ name (str): The name of the network.
23
+ mtable_exists (int): An integer flag indicating whether the MasterDataset table exists (1) or not (0).
24
+ """
25
+
26
+ def __init__(self, name: str = ""):
27
+ """
28
+ Initialize a Network instance.
29
+
30
+ Parameters:
31
+ name (str): The name of the network.
32
+ """
33
+ self.name = name
34
+ self.mtable_exists = int(master_table_exists())
35
+ self.validate()
36
+
37
+ db_manager = DatabaseManager()
38
+ db_manager.connect()
39
+ self.eng = db_manager.get_connection()
40
+
41
+ def validate(self):
42
+ """Validate name"""
43
+
44
+ if not isinstance(self.name, str):
45
+ raise TypeError("name argument must be a string")
46
+
47
+ def create_network(self):
48
+ """Create a new network in the database."""
49
+ try:
50
+ print(self.name)
51
+ self.eng.execute(text(INSERT_NETWORK_QUERY), {"name": self.name})
52
+ self.id = self.get_netid_from_name(self.name)
53
+ except SQLAlchemyError as e:
54
+ print(f"Error creating network: {e}")
55
+
56
+ def use_network(self, network_name: str):
57
+ """Use a network in the database.
58
+
59
+ Parameters:
60
+ network_name (str): The name of the network to use.
61
+
62
+ Returns:
63
+ Network or None: An instance of the Network class if the network exists, else None.
64
+ """
65
+ try:
66
+ network = pd.read_sql(
67
+ text(GET_NETWORK_QUERY),
68
+ self.eng,
69
+ params={"name": network_name}
70
+ )
71
+ if not network.empty:
72
+ self.name = network.iloc[0]['NetName']
73
+ self.id = network.iloc[0]['NetId']
74
+ self.mtable_exists = int(master_table_exists())
75
+ self.validate()
76
+ return self
77
+ else:
78
+ return None
79
+ except SQLAlchemyError as e:
80
+ print(f"Error using network: {e}")
81
+ return None
82
+
83
+ def delete_network(self):
84
+ """Delete the network from the database."""
85
+ try:
86
+ self.eng.execute(text(DELETE_NETWORK_QUERY), {"name": self.name})
87
+ except SQLAlchemyError as e:
88
+ print(f"Error deleting network: {e}")
89
+
90
+ def update_network(self, FLsetupId: int):
91
+ """Update the network's FLsetupId in the database.
92
+
93
+ Parameters:
94
+ FLsetupId (int): The FLsetupId to update.
95
+ """
96
+ try:
97
+ self.eng.execute(
98
+ text(UPDATE_NETWORK_QUERY),
99
+ {"FLsetupId": FLsetupId, "id": self.id}
100
+ )
101
+ except SQLAlchemyError as e:
102
+ print(f"Error updating network: {e}")
103
+
104
+ def add_node(self, node: Node):
105
+ """Add a node to the network.
106
+
107
+ Parameters:
108
+ node (Node): The node to add.
109
+ """
110
+ node.create_node(self.id)
111
+
112
+ def list_allnodes(self):
113
+ """List all nodes in the network.
114
+
115
+ Returns:
116
+ DataFrame: A DataFrame containing information about all nodes in the network.
117
+ """
118
+ try:
119
+ query = text(LIST_ALL_NODES_QUERY)
120
+ result_proxy = self.eng.execute(query, name=self.name)
121
+ result_df = pd.DataFrame(result_proxy.fetchall(), columns=result_proxy.keys())
122
+ return result_df
123
+ except SQLAlchemyError as e:
124
+ print(f"Error listing all nodes: {e}")
125
+ return pd.DataFrame()
126
+
127
+ def create_master_dataset(self, path_to_csv: str = params['path_to_master_csv']):
128
+ """
129
+ Create the MasterDataset table and insert dataset values.
130
+
131
+ :param path_to_csv: Path to the CSV file containing the dataset.
132
+ """
133
+ try:
134
+ print(path_to_csv)
135
+ data_df = pd.read_csv(path_to_csv)
136
+
137
+ if self.mtable_exists != 1:
138
+ columns = data_df.columns.tolist()
139
+ columns_str = ",\n".join(
140
+ [
141
+ f"{col} {column_map[str(data_df[col].dtype)]}"
142
+ for col in columns
143
+ ]
144
+ )
145
+ self.eng.execute(
146
+ text(CREATE_MASTER_DATASET_TABLE_QUERY.format(columns_str))
147
+ )
148
+ self.eng.execute(text(CREATE_DATASETS_TABLE_QUERY.format(columns_str)))
149
+
150
+ # Process data
151
+ data_df = process_eicu(data_df)
152
+
153
+ # Insert data in batches
154
+ batch_size = 1000 # Adjust as needed
155
+ for start_idx in range(0, len(data_df), batch_size):
156
+ batch_data = data_df.iloc[start_idx:start_idx + batch_size]
157
+ insert_query = f"INSERT INTO MasterDataset ({', '.join(columns)}) VALUES ({', '.join([':' + col for col in columns])})"
158
+ data_to_insert = batch_data.to_dict(orient='records')
159
+ self.eng.execute(text(insert_query), data_to_insert)
160
+
161
+ self.mtable_exists = 1
162
+ except SQLAlchemyError as e:
163
+ print(f"Error creating master dataset: {e}")
164
+
165
+ @staticmethod
166
+ def list_allnetworks():
167
+ """List all networks in the database.
168
+
169
+ Returns:
170
+ DataFrame: A DataFrame containing information about all networks in the database.
171
+ """
172
+ try:
173
+ db_manager = DatabaseManager()
174
+ db_manager.connect()
175
+ my_eng = db_manager.get_connection()
176
+
177
+ result_proxy = my_eng.execute("SELECT * FROM Networks")
178
+ result = result_proxy.fetchall()
179
+ return pd.DataFrame(result, columns=result_proxy.keys())
180
+ except SQLAlchemyError as e:
181
+ print(f"Error listing all networks: {e}")
182
+ return pd.DataFrame()
183
+
184
+ def get_netid_from_name(self, name):
185
+ """Get network ID from network name."""
186
+ try:
187
+ result = self.eng.execute(text("SELECT NetId FROM Networks WHERE NetName = :name"), {"name": name}).fetchone()
188
+ if result:
189
+ return result[0]
190
+ else:
191
+ return None
192
+ except SQLAlchemyError as e:
193
+ print(f"Error fetching network ID: {e}")
194
+ return None
@@ -0,0 +1,184 @@
1
+ import pandas as pd
2
+
3
+ from .net_helper import *
4
+ from .net_manager_queries import *
5
+ from MEDfl.LearningManager.utils import params
6
+ from MEDfl.NetManager.database_connector import DatabaseManager
7
+
8
+ from sqlalchemy import text, exc
9
+
10
+
11
+ class Node:
12
+ """
13
+ A class representing a node in the network.
14
+
15
+ Attributes:
16
+ name (str): The name of the node.
17
+ train (int): An integer flag representing whether the node is used for training (1) or testing (0).
18
+ test_fraction (float, optional): The fraction of data used for testing when train=1. Default is 0.2.
19
+ """
20
+
21
+ def __init__(
22
+ self, name: str, train: int, test_fraction: float = 0.2, engine=None
23
+ ):
24
+ """
25
+ Initialize a Node instance.
26
+
27
+ Parameters:
28
+ name (str): The name of the node.
29
+ train (int): An integer flag representing whether the node is used for training (1) or testing (0).
30
+ test_fraction (float, optional): The fraction of data used for testing when train=1. Default is 0.2.
31
+ """
32
+ self.name = name
33
+ self.train = train
34
+ self.test_fraction = 1.0 if self.train == 0 else test_fraction
35
+
36
+
37
+ db_manager = DatabaseManager() ;
38
+ db_manager.connect() ;
39
+ self.engine = db_manager.get_connection()
40
+
41
+ def validate(self):
42
+ """Validate name, train, test_fraction"""
43
+ if not isinstance(self.name, str):
44
+ raise TypeError("name argument must be a string")
45
+
46
+ if not isinstance(self.train, int):
47
+ raise TypeError("train argument must be an int")
48
+
49
+ if not isinstance(self.test_fraction, float):
50
+ raise TypeError("test_fraction argument must be a float")
51
+
52
+ def create_node(self, NetId: int):
53
+ """Create a node in the database.
54
+ Parameters:
55
+ NetId (int): The ID of the network to which the node belongs.
56
+
57
+ Returns:
58
+ None
59
+ """
60
+ self.engine.execute(
61
+ text(INSERT_NODE_QUERY.format(self.name, NetId, self.train))
62
+ )
63
+
64
+ def delete_node(self):
65
+ """Delete the node from the database."""
66
+ self.engine.execute(text(DELETE_NODE_QUERY.format(self.name)))
67
+
68
+ def check_dataset_compatibility(self, data_df):
69
+ """Check if the dataset is compatible with the master dataset.
70
+ Parameters:
71
+ data_df (DataFrame): The dataset to check.
72
+
73
+ Returns:
74
+ None
75
+ """
76
+ if master_table_exists() != 1:
77
+ print("MasterDataset doesn't exist")
78
+ else:
79
+ columns = data_df.columns.tolist()
80
+
81
+ # get master_dataset columns
82
+ result_proxy = self.engine.execute(SELECT_MASTER_COLUMNS_QUERY)
83
+ master_table_columns = result_proxy.keys()
84
+
85
+
86
+ assert [x == y for x, y in zip(master_table_columns, columns)]
87
+
88
+ def update_node(self):
89
+ """Update the node information (not implemented)."""
90
+ pass
91
+
92
+ def get_dataset(self, column_name: str = None):
93
+ """Get the dataset for the node based on the given column name.
94
+ Parameters:
95
+ column_name (str, optional): The column name to filter the dataset. Default is None.
96
+
97
+ Returns:
98
+ DataFrame: The dataset associated with the node.
99
+ """
100
+ NodeId = get_nodeid_from_name(self.name)
101
+ if column_name is not None:
102
+ query = text(SELECT_DATASET_BY_COLUMN_QUERY.format(column_name, self.name))
103
+ else:
104
+ query = text(SELECT_DATASET_BY_NODE_ID_QUERY.format(NodeId))
105
+
106
+ result_proxy = self.engine.execute(query)
107
+ node_dataset = pd.DataFrame(result_proxy.fetchall(), columns=result_proxy.keys())
108
+
109
+ return node_dataset
110
+
111
+ def upload_dataset(self, dataset_name: str, path_to_csv: str = params['path_to_test_csv']):
112
+ """Upload the dataset to the database for the node.
113
+
114
+ Parameters:
115
+ dataset_name (str): The name of the dataset.
116
+ path_to_csv (str, optional): Path to the CSV file containing the dataset. Default is the path in params.
117
+
118
+ Returns:
119
+ None
120
+ """
121
+ try:
122
+ data_df = pd.read_csv(path_to_csv)
123
+ nodeId = get_nodeid_from_name(self.name)
124
+ columns = data_df.columns.tolist()
125
+ self.check_dataset_compatibility(data_df)
126
+
127
+ data_df = process_eicu(data_df)
128
+
129
+ # Insert data in batches
130
+ batch_size = 1000 # Adjust as needed
131
+ for start_idx in range(0, len(data_df), batch_size):
132
+ batch_data = data_df.iloc[start_idx:start_idx + batch_size]
133
+ insert_query = f"INSERT INTO Datasets (DataSetName, NodeId, {', '.join(columns)}) VALUES (:dataset_name, :nodeId, {', '.join([':' + col for col in columns])})"
134
+ data_to_insert = batch_data.to_dict(orient='records')
135
+ params = [{"dataset_name": dataset_name, "nodeId": nodeId, **row} for row in data_to_insert]
136
+ self.engine.execute(text(insert_query), params)
137
+ except exc.SQLAlchemyError as e:
138
+ print(f"Error uploading dataset: {e}")
139
+
140
+ def assign_dataset(self, dataset_name:str):
141
+ """Assigning existing dataSet to node
142
+ Parameters:
143
+ dataset_name (str): The name of the dataset to assign.
144
+
145
+ Returns:
146
+ None
147
+ """
148
+
149
+ nodeId = get_nodeid_from_name(self.name)
150
+ query = f"UPDATE DataSets SET nodeId = {nodeId} WHERE DataSetName = '{dataset_name}'"
151
+ self.engine.execute(text(query))
152
+
153
+ def unassign_dataset(self, dataset_name:str):
154
+ """unssigning existing dataSet to node
155
+ Parameters:
156
+ dataset_name (str): The name of the dataset to assign.
157
+
158
+ Returns:
159
+ None
160
+ """
161
+
162
+ query = f"UPDATE DataSets SET nodeId = {-1} WHERE DataSetName = '{dataset_name}'"
163
+ self.engine.execute(text(query))
164
+
165
+ def list_alldatasets(self):
166
+ """List all datasets associated with the node.
167
+ Returns:
168
+ DataFrame: A DataFrame containing information about all datasets associated with the node.
169
+
170
+ """
171
+ return pd.read_sql(
172
+ text(SELECT_ALL_DATASETS_QUERY.format(self.name)), my_eng
173
+ )
174
+
175
+ @staticmethod
176
+ def list_allnodes():
177
+ """List all nodes in the database.
178
+ Returns:
179
+ DataFrame: A DataFrame containing information about all nodes in the database.
180
+
181
+ """
182
+ query = text(SELECT_ALL_NODES_QUERY)
183
+ res = pd.read_sql(query, my_eng)
184
+ return res
Medfl/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .LearningManager import *
2
+ from .NetManager import *
3
+ from .scripts import *
@@ -0,0 +1,2 @@
1
+ # from .base import *
2
+ # from .create_db import *
Medfl/scripts/base.py ADDED
@@ -0,0 +1,30 @@
1
+ import mysql.connector
2
+ from sqlalchemy import create_engine, text
3
+ from configparser import ConfigParser
4
+ import yaml
5
+ import pkg_resources
6
+ import os
7
+
8
+ # Get the directory of the current script
9
+ current_directory = os.path.dirname(os.path.abspath(__file__))
10
+
11
+ # Load configuration from the config file
12
+ config_file_path = os.path.join(current_directory, 'db_config.ini')
13
+
14
+ config = ConfigParser()
15
+ config.read(config_file_path)
16
+ mysql_config = config['mysql']
17
+
18
+
19
+
20
+ connection_string = (
21
+ f"mysql+mysqlconnector://{mysql_config['user']}:{mysql_config['password']}@"
22
+ f"{mysql_config['host']}:{mysql_config['port']}/{mysql_config['database']}"
23
+ )
24
+
25
+ eng = create_engine(
26
+ connection_string,
27
+ execution_options={"autocommit": True},
28
+ )
29
+
30
+ my_eng = eng.connect()
@@ -0,0 +1,126 @@
1
+ import sys
2
+ import sqlite3
3
+ import pandas as pd
4
+ from configparser import ConfigParser
5
+ import os
6
+ import ast
7
+
8
+ from MEDfl.LearningManager.utils import *
9
+
10
+
11
+ def main(csv_file_path):
12
+ try:
13
+ # Get the directory of the current script
14
+ current_directory = os.path.dirname(os.path.abspath(__file__))
15
+
16
+ # Load configuration from the config file
17
+ # config_file_path = os.path.join(current_directory, 'sqllite_config.ini')*
18
+
19
+ config_file_path = load_db_config()
20
+
21
+ # config = ConfigParser()
22
+ # config.read(config_file_path)
23
+ # sqlite_config = config['sqllite']
24
+
25
+ sqlite_config = config_file_path
26
+
27
+
28
+ print('Im here !')
29
+
30
+ # Connect to SQLite database (it will be created if it doesn't exist)
31
+ database_path = sqlite_config['database']
32
+ conn = sqlite3.connect(database_path)
33
+ cursor = conn.cursor()
34
+
35
+ # Drop each table if it exists
36
+ tables = ['Networks', 'FLsetup', 'Nodes', 'DataSets', 'FLpipeline', 'testResults', 'FedDatasets']
37
+ for table in tables:
38
+ cursor.execute(f"DROP TABLE IF EXISTS {table}")
39
+
40
+ # Create Networks table
41
+ cursor.execute(
42
+ "CREATE TABLE Networks( \
43
+ NetId INTEGER PRIMARY KEY AUTOINCREMENT, \
44
+ NetName TEXT \
45
+ );"
46
+ )
47
+
48
+ # Create FLsetup table
49
+ cursor.execute("CREATE TABLE FLsetup (\
50
+ FLsetupId INTEGER PRIMARY KEY AUTOINCREMENT,\
51
+ name TEXT NOT NULL, \
52
+ description TEXT NOT NULL,\
53
+ creation_date TEXT NOT NULL,\
54
+ NetId INTEGER NOT NULL,\
55
+ column_name TEXT\
56
+ )")
57
+
58
+ # Create Nodes table
59
+ cursor.execute("CREATE TABLE Nodes ( \
60
+ NodeId INTEGER PRIMARY KEY AUTOINCREMENT,\
61
+ NodeName TEXT,\
62
+ train BOOLEAN DEFAULT 1,\
63
+ NetId INTEGER\
64
+ )")
65
+
66
+ data_df = pd.read_csv(csv_file_path)
67
+ columns = data_df.columns.tolist()
68
+ column_map = {"object": "TEXT", "int64": "INTEGER", "float64": "REAL"}
69
+ sub_query = ", ".join(f"{col} {column_map[str(data_df[col].dtype)]}" for col in columns)
70
+
71
+ # Create Datasets table by getting columns from the master csv file
72
+ cursor.execute(
73
+ f"CREATE TABLE DataSets( \
74
+ DataSetId INTEGER PRIMARY KEY AUTOINCREMENT, \
75
+ DataSetName TEXT, \
76
+ NodeId INTEGER,\
77
+ {sub_query}\
78
+ )"
79
+ )
80
+
81
+ # Create FLpipeline table
82
+ cursor.execute("CREATE TABLE FLpipeline(\
83
+ id INTEGER PRIMARY KEY AUTOINCREMENT,\
84
+ name TEXT NOT NULL, \
85
+ description TEXT NOT NULL,\
86
+ creation_date TEXT NOT NULL,\
87
+ results TEXT NOT NULL\
88
+ ) ")
89
+
90
+ # Create test results table
91
+ cursor.execute("CREATE TABLE testResults(\
92
+ pipelineId INTEGER,\
93
+ nodename TEXT NOT NULL, \
94
+ confusionmatrix TEXT,\
95
+ accuracy REAL,\
96
+ sensivity REAL,\
97
+ ppv REAL,\
98
+ npv REAL,\
99
+ f1score REAL,\
100
+ fpr REAL,\
101
+ tpr REAL, \
102
+ PRIMARY KEY (pipelineId, nodename)\
103
+ ) ")
104
+
105
+ # Create FederatedDataset table
106
+ cursor.execute("CREATE TABLE FedDatasets (\
107
+ FedId INTEGER PRIMARY KEY AUTOINCREMENT,\
108
+ FLsetupId INTEGER,\
109
+ FLpipeId INTEGER,\
110
+ name TEXT NOT NULL\
111
+ )")
112
+
113
+ # Commit and close the cursor
114
+ conn.commit()
115
+ cursor.close()
116
+ conn.close()
117
+
118
+ except sqlite3.Error as e:
119
+ print(f"Error: {e}")
120
+
121
+ if __name__ == "__main__":
122
+ if len(sys.argv) != 2:
123
+ print("Usage: python script.py <path_to_csv_file>")
124
+ sys.exit(1)
125
+ csv_file_path = sys.argv[1]
126
+ main(csv_file_path)