adapto 0.1.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- adapto/__init__.py +1 -0
- adapto/predictor.py +24 -0
- adapto/scaler.py +112 -0
- adapto/utils.py +5 -0
- adapto-0.1.0.dist-info/LICENSE +21 -0
- adapto-0.1.0.dist-info/METADATA +19 -0
- adapto-0.1.0.dist-info/RECORD +9 -0
- adapto-0.1.0.dist-info/WHEEL +5 -0
- adapto-0.1.0.dist-info/top_level.txt +1 -0
adapto/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
from .scaler import AutoScaler
|
adapto/predictor.py
ADDED
@@ -0,0 +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
|
+
}
|
adapto/scaler.py
ADDED
@@ -0,0 +1,112 @@
|
|
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()
|
adapto/utils.py
ADDED
@@ -0,0 +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.
|
@@ -0,0 +1,19 @@
|
|
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
|
+
|
@@ -0,0 +1,9 @@
|
|
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,,
|
@@ -0,0 +1 @@
|
|
1
|
+
adapto
|