adapto 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
adapto/predictor.py CHANGED
@@ -1,24 +1,24 @@
1
- import numpy as np
2
- from sklearn.linear_model import LinearRegression
3
-
4
-
5
- class Predictor:
6
- def __init__(self):
7
- pass
8
-
9
- def train_predictor(self, history):
10
- if len(history) < 2:
11
- return history[-1] if history else 0
12
-
13
- X = np.arange(len(history)).reshape(-1, 1)
14
- y = np.array(history)
15
- model = LinearRegression().fit(X, y)
16
- return model.predict([[len(history)]])[0]
17
-
18
- def predict(self, cpu_history, memory_history, network_sent_history, network_recv_history):
19
- return {
20
- "predicted_cpu": self.train_predictor(cpu_history),
21
- "predicted_memory": self.train_predictor(memory_history),
22
- "predicted_network_sent": self.train_predictor(network_sent_history),
23
- "predicted_network_recv": self.train_predictor(network_recv_history)
24
- }
1
+ import numpy as np
2
+ from sklearn.linear_model import LinearRegression
3
+
4
+
5
+ class Predictor:
6
+ def __init__(self):
7
+ pass
8
+
9
+ def train_predictor(self, history):
10
+ if len(history) < 2:
11
+ return history[-1] if history else 0
12
+
13
+ X = np.arange(len(history)).reshape(-1, 1)
14
+ y = np.array(history)
15
+ model = LinearRegression().fit(X, y)
16
+ return model.predict([[len(history)]])[0]
17
+
18
+ def predict(self, cpu_history, memory_history, network_sent_history, network_recv_history):
19
+ return {
20
+ "predicted_cpu": self.train_predictor(cpu_history),
21
+ "predicted_memory": self.train_predictor(memory_history),
22
+ "predicted_network_sent": self.train_predictor(network_sent_history),
23
+ "predicted_network_recv": self.train_predictor(network_recv_history)
24
+ }
adapto/scaler.py CHANGED
@@ -1,112 +1,128 @@
1
- import psutil
2
- import time
3
- import logging
4
- from collections import deque
5
- from adapto.predictor import Predictor
6
-
7
- # Set up logging
8
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
-
10
-
11
- class AutoScaler:
12
- def __init__(self, scale_up_threshold=80, scale_down_threshold=30, memory_threshold=75,
13
- bandwidth_threshold=100000000, min_instances=1, max_instances=10, history_size=10):
14
- self.scale_up_threshold = scale_up_threshold
15
- self.scale_down_threshold = scale_down_threshold
16
- self.memory_threshold = memory_threshold
17
- self.bandwidth_threshold = bandwidth_threshold # in bytes per second
18
- self.current_instances = min_instances
19
- self.min_instances = min_instances
20
- self.max_instances = max_instances
21
- self.previous_network = psutil.net_io_counters()
22
-
23
- # Data history for prediction
24
- self.cpu_history = deque(maxlen=history_size)
25
- self.memory_history = deque(maxlen=history_size)
26
- self.network_sent_history = deque(maxlen=history_size)
27
- self.network_recv_history = deque(maxlen=history_size)
28
-
29
- self.predictor = Predictor()
30
-
31
- def get_system_metrics(self):
32
- cpu_usage = psutil.cpu_percent(interval=1)
33
- memory_usage = psutil.virtual_memory().percent
34
- load_avg = psutil.getloadavg()[0] if hasattr(psutil, "getloadavg") else 0 # Unix-only
35
- disk_usage = psutil.disk_usage('/').percent
36
- network_metrics = self.get_network_metrics()
37
-
38
- # Store metrics in history
39
- self.cpu_history.append(cpu_usage)
40
- self.memory_history.append(memory_usage)
41
- self.network_sent_history.append(network_metrics['network_sent'])
42
- self.network_recv_history.append(network_metrics['network_recv'])
43
-
44
- return {
45
- "cpu_usage": cpu_usage,
46
- "memory_usage": memory_usage,
47
- "load_avg": load_avg,
48
- "disk_usage": disk_usage,
49
- **network_metrics
50
- }
51
-
52
- def get_network_metrics(self):
53
- network_io = psutil.net_io_counters()
54
- network_sent = network_io.bytes_sent - self.previous_network.bytes_sent
55
- network_recv = network_io.bytes_recv - self.previous_network.bytes_recv
56
- self.previous_network = network_io
57
-
58
- return {
59
- "network_sent": network_sent,
60
- "network_recv": network_recv
61
- }
62
-
63
- def predict_future_usage(self):
64
- return self.predictor.predict(
65
- list(self.cpu_history),
66
- list(self.memory_history),
67
- list(self.network_sent_history),
68
- list(self.network_recv_history)
69
- )
70
-
71
- def scale_up(self):
72
- if self.current_instances < self.max_instances:
73
- self.current_instances += 1
74
- logging.info(f"Scaling up: New instance count = {self.current_instances}")
75
- else:
76
- logging.info("Max instances reached. Cannot scale up further.")
77
-
78
- def scale_down(self):
79
- if self.current_instances > self.min_instances:
80
- self.current_instances -= 1
81
- logging.info(f"Scaling down: New instance count = {self.current_instances}")
82
- else:
83
- logging.info("Min instances reached. Cannot scale down further.")
84
-
85
- def monitor(self, interval=5):
86
- while True:
87
- metrics = self.get_system_metrics()
88
- predictions = self.predict_future_usage()
89
-
90
- logging.info(
91
- f"CPU: {metrics['cpu_usage']}% | Memory: {metrics['memory_usage']}% | Load Avg: {metrics['load_avg']} | Disk: {metrics['disk_usage']}% | Network Sent: {metrics['network_sent']} bytes/s | Network Recv: {metrics['network_recv']} bytes/s")
92
- logging.info(
93
- f"Predicted CPU: {predictions['predicted_cpu']}% | Predicted Memory: {predictions['predicted_memory']}% | Predicted Network Sent: {predictions['predicted_network_sent']} bytes/s | Predicted Network Recv: {predictions['predicted_network_recv']} bytes/s")
94
-
95
- if (predictions['predicted_cpu'] > self.scale_up_threshold or
96
- predictions['predicted_memory'] > self.memory_threshold or
97
- predictions['predicted_network_sent'] > self.bandwidth_threshold or
98
- predictions['predicted_network_recv'] > self.bandwidth_threshold):
99
- self.scale_up()
100
- elif (predictions['predicted_cpu'] < self.scale_down_threshold and
101
- predictions['predicted_memory'] < self.memory_threshold / 2 and
102
- predictions['predicted_network_sent'] < self.bandwidth_threshold / 2 and
103
- predictions['predicted_network_recv'] < self.bandwidth_threshold / 2):
104
- self.scale_down()
105
-
106
- time.sleep(interval)
107
-
108
-
109
- # Example usage
110
- if __name__ == "__main__":
111
- scaler = AutoScaler()
112
- scaler.monitor()
1
+ import psutil
2
+ import time
3
+ import logging
4
+ from collections import deque
5
+ from adapto.predictor import Predictor
6
+
7
+ # Set up logging
8
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
+
10
+
11
+ class AutoScaler:
12
+ def __init__(self, scale_up_threshold=80, scale_down_threshold=30, memory_threshold=75,
13
+ bandwidth_threshold=100000000, min_instances=1, max_instances=10, history_size=10, custom_scaling=None):
14
+ self.scale_up_threshold = scale_up_threshold
15
+ self.scale_down_threshold = scale_down_threshold
16
+ self.memory_threshold = memory_threshold
17
+ self.bandwidth_threshold = bandwidth_threshold # in bytes per second
18
+ self.current_instances = min_instances
19
+ self.min_instances = min_instances
20
+ self.max_instances = max_instances
21
+ self.previous_network = psutil.net_io_counters()
22
+
23
+ # Optional custom scaling function; should accept (metrics, predictions) and return 'scale_up', 'scale_down', or 'no_change'
24
+ self.custom_scaling = custom_scaling
25
+
26
+ # Data history for prediction
27
+ self.cpu_history = deque(maxlen=history_size)
28
+ self.memory_history = deque(maxlen=history_size)
29
+ self.network_sent_history = deque(maxlen=history_size)
30
+ self.network_recv_history = deque(maxlen=history_size)
31
+
32
+ self.predictor = Predictor()
33
+
34
+ def get_system_metrics(self):
35
+ cpu_usage = psutil.cpu_percent(interval=1)
36
+ memory_usage = psutil.virtual_memory().percent
37
+ load_avg = psutil.getloadavg()[0] if hasattr(psutil, "getloadavg") else 0 # Unix-only
38
+ disk_usage = psutil.disk_usage('/').percent
39
+ network_metrics = self.get_network_metrics()
40
+
41
+ # Store metrics in history
42
+ self.cpu_history.append(cpu_usage)
43
+ self.memory_history.append(memory_usage)
44
+ self.network_sent_history.append(network_metrics['network_sent'])
45
+ self.network_recv_history.append(network_metrics['network_recv'])
46
+
47
+ return {
48
+ "cpu_usage": cpu_usage,
49
+ "memory_usage": memory_usage,
50
+ "load_avg": load_avg,
51
+ "disk_usage": disk_usage,
52
+ **network_metrics
53
+ }
54
+
55
+ def get_network_metrics(self):
56
+ network_io = psutil.net_io_counters()
57
+ network_sent = network_io.bytes_sent - self.previous_network.bytes_sent
58
+ network_recv = network_io.bytes_recv - self.previous_network.bytes_recv
59
+ self.previous_network = network_io
60
+
61
+ return {
62
+ "network_sent": network_sent,
63
+ "network_recv": network_recv
64
+ }
65
+
66
+ def predict_future_usage(self):
67
+ return self.predictor.predict(
68
+ list(self.cpu_history),
69
+ list(self.memory_history),
70
+ list(self.network_sent_history),
71
+ list(self.network_recv_history)
72
+ )
73
+
74
+ def scale_up(self):
75
+ if self.current_instances < self.max_instances:
76
+ self.current_instances += 1
77
+ logging.info(f"Scaling up: New instance count = {self.current_instances}")
78
+ else:
79
+ logging.info("Max instances reached. Cannot scale up further.")
80
+
81
+ def scale_down(self):
82
+ if self.current_instances > self.min_instances:
83
+ self.current_instances -= 1
84
+ logging.info(f"Scaling down: New instance count = {self.current_instances}")
85
+ else:
86
+ logging.info("Min instances reached. Cannot scale down further.")
87
+
88
+ def monitor(self, interval=5):
89
+ while True:
90
+ metrics = self.get_system_metrics()
91
+ predictions = self.predict_future_usage()
92
+
93
+ logging.info(
94
+ f"CPU: {metrics['cpu_usage']}% | Memory: {metrics['memory_usage']}% | Load Avg: {metrics['load_avg']} | Disk: {metrics['disk_usage']}% | "
95
+ f"Network Sent: {metrics['network_sent']} bytes/s | Network Recv: {metrics['network_recv']} bytes/s"
96
+ )
97
+ logging.info(
98
+ f"Predicted CPU: {predictions['predicted_cpu']}% | Predicted Memory: {predictions['predicted_memory']}% | "
99
+ f"Predicted Network Sent: {predictions['predicted_network_sent']} bytes/s | Predicted Network Recv: {predictions['predicted_network_recv']} bytes/s"
100
+ )
101
+
102
+ # If a custom scaling strategy is provided, use it to decide the action
103
+ if self.custom_scaling:
104
+ action = self.custom_scaling(metrics, predictions)
105
+ if action == 'scale_up':
106
+ self.scale_up()
107
+ elif action == 'scale_down':
108
+ self.scale_down()
109
+ else:
110
+ # Default scaling strategy
111
+ if (predictions['predicted_cpu'] > self.scale_up_threshold or
112
+ predictions['predicted_memory'] > self.memory_threshold or
113
+ predictions['predicted_network_sent'] > self.bandwidth_threshold or
114
+ predictions['predicted_network_recv'] > self.bandwidth_threshold):
115
+ self.scale_up()
116
+ elif (predictions['predicted_cpu'] < self.scale_down_threshold and
117
+ predictions['predicted_memory'] < self.memory_threshold / 2 and
118
+ predictions['predicted_network_sent'] < self.bandwidth_threshold / 2 and
119
+ predictions['predicted_network_recv'] < self.bandwidth_threshold / 2):
120
+ self.scale_down()
121
+
122
+ time.sleep(interval)
123
+
124
+
125
+ # Example usage
126
+ if __name__ == "__main__":
127
+ scaler = AutoScaler()
128
+ scaler.monitor()
adapto/utils.py CHANGED
@@ -1,5 +1,5 @@
1
- import time
2
-
3
- def log_event(message):
4
- """Log an event with a timestamp."""
1
+ import time
2
+
3
+ def log_event(message):
4
+ """Log an event with a timestamp."""
5
5
  print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {message}")
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Harshal Mehta
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harshal Mehta
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,19 +1,21 @@
1
- Metadata-Version: 2.1
2
- Name: adapto
3
- Version: 0.1.0
4
- Summary: AI-driven auto-scaling library for dynamic resource allocation.
5
- Home-page: https://github.com/hrshlmeht/adapto
6
- Author: Harshal Mehta
7
- Author-email: harshalmehta1998@gmail.com
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Requires-Python: >=3.7
14
- License-File: LICENSE
15
- Requires-Dist: psutil
16
- Requires-Dist: numpy
17
-
18
- UNKNOWN
19
-
1
+ Metadata-Version: 2.2
2
+ Name: adapto
3
+ Version: 0.1.2
4
+ Summary: AI-driven auto-scaling library for dynamic resource allocation.
5
+ Home-page: https://github.com/hrshlmeht/adapto
6
+ Author: Harshal Mehta
7
+ Author-email: harshalmehta1998@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ License-File: LICENSE
13
+ Requires-Dist: psutil
14
+ Requires-Dist: numpy
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: home-page
19
+ Dynamic: requires-dist
20
+ Dynamic: requires-python
21
+ Dynamic: summary
@@ -0,0 +1,9 @@
1
+ adapto/__init__.py,sha256=8SWysOKRVNsD3cOXLOfIdVZx6MxzIqGKEh9Z26QuCyM,30
2
+ adapto/predictor.py,sha256=ze-cMHdf290o3_9D-PQ7yQ8eMz1Utv3E3qTHRUFQiAI,842
3
+ adapto/scaler.py,sha256=qVwnjd6YondkJ_vorinmReXoO0TNf0-CiKUMvDgHYrw,5544
4
+ adapto/utils.py,sha256=6TgDvowlXL__v-OkLSTZF12ZOEqEKCLuNv1LmL70eAY,140
5
+ adapto-0.1.2.dist-info/LICENSE,sha256=B73NNEiUy-CCs4zrOPlOWR39PfoG4zKtK97OnNctjvg,1070
6
+ adapto-0.1.2.dist-info/METADATA,sha256=c42fZm-Mw_GOCTHNpZLqQpT6jv8DaNaIxSwrvqWnUV8,609
7
+ adapto-0.1.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ adapto-0.1.2.dist-info/top_level.txt,sha256=IYsgAr6fnEC1R1ztYmK2ZpFNNGV0qRaf3Tvf-R8j0cM,7
9
+ adapto-0.1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- adapto/__init__.py,sha256=8SWysOKRVNsD3cOXLOfIdVZx6MxzIqGKEh9Z26QuCyM,30
2
- adapto/predictor.py,sha256=RqPbSWwppyI1PQGzGZMihpX5YQoyWvN_G-ocHOa2H0g,866
3
- adapto/scaler.py,sha256=P1f8TDc4mrFpqXffs2FImg9mRRpP0GoYks_3JNyz4O4,4955
4
- adapto/utils.py,sha256=8elBvOHytKcqT9TnVYcDU8yN1SibprjhNKrnSPgBR9E,144
5
- adapto-0.1.0.dist-info/LICENSE,sha256=SAzpYNgJ4rxFNBFW55imF0XI2fjW7O7yXqajoK1SBmw,1091
6
- adapto-0.1.0.dist-info/METADATA,sha256=i2ikB2E6_fVLZgGUmwgC-LCkxr24pEHr2v2lR55vv-c,531
7
- adapto-0.1.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
8
- adapto-0.1.0.dist-info/top_level.txt,sha256=IYsgAr6fnEC1R1ztYmK2ZpFNNGV0qRaf3Tvf-R8j0cM,7
9
- adapto-0.1.0.dist-info/RECORD,,