adapto 0.1.0__tar.gz → 0.1.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,17 +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
-
16
- UNKNOWN
17
-
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
adapto-0.1.2/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Adapto - AI-Powered AutoScaler
2
+
3
+ Adapto is an intelligent auto-scaling Python library that monitors system metrics like CPU, memory, and network usage. It uses machine learning to predict resource needs and proactively scale up or down.
4
+
5
+ ## Features
6
+ - Real-time monitoring of CPU, memory, and network usage
7
+ - Prediction-based scaling using machine learning
8
+ - Automatic scale-up and scale-down based on thresholds
9
+ - **Customizable Scaling Strategies** – Define custom rules for scaling based on your needs
10
+
11
+ ## Installation
12
+ Install Adapto via pip:
13
+ ```sh
14
+ pip install adapto
15
+ ```
16
+
17
+ ## Usage
18
+ ### Import the library
19
+ ```python
20
+ from adapto.scaler import AutoScaler
21
+ ```
22
+
23
+ ### Create an instance of AutoScaler
24
+ ```python
25
+ scaler = AutoScaler()
26
+ ```
27
+
28
+ ### Start monitoring and auto-scaling
29
+ ```python
30
+ scaler.monitor()
31
+ ```
32
+
33
+ ### Fetch current system metrics
34
+ ```python
35
+ metrics = scaler.get_system_metrics()
36
+ print(metrics)
37
+ ```
38
+
39
+ ### Predict future resource usage
40
+ ```python
41
+ predictions = scaler.predict_future_usage()
42
+ print(predictions)
43
+ ```
44
+
45
+ ### Define Custom Scaling Strategies
46
+ You can pass a custom scaling function to the `AutoScaler`:
47
+ ```python
48
+ def my_scaling_strategy(metrics):
49
+ if metrics['cpu'] > 80 and metrics['memory'] > 75:
50
+ return 'scale_up'
51
+ elif metrics['cpu'] < 30 and metrics['memory'] < 40:
52
+ return 'scale_down'
53
+ return 'no_change'
54
+
55
+ scaler = AutoScaler(custom_scaling=my_scaling_strategy)
56
+ ```
57
+
58
+ ## Configuration
59
+ You can customize thresholds and instance limits:
60
+ ```python
61
+ scaler = AutoScaler(
62
+ scale_up_threshold=75,
63
+ scale_down_threshold=30,
64
+ memory_threshold=70,
65
+ bandwidth_threshold=100000000, # in bytes per second
66
+ min_instances=1,
67
+ max_instances=10
68
+ )
69
+ ```
70
+
71
+ ## License
72
+ This project is licensed under the MIT License.
@@ -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
+ }
@@ -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()
@@ -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,17 +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
-
16
- UNKNOWN
17
-
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
@@ -9,4 +9,6 @@ adapto.egg-info/PKG-INFO
9
9
  adapto.egg-info/SOURCES.txt
10
10
  adapto.egg-info/dependency_links.txt
11
11
  adapto.egg-info/requires.txt
12
- adapto.egg-info/top_level.txt
12
+ adapto.egg-info/top_level.txt
13
+ tests/test_predictor.py
14
+ tests/test_scaler.py
@@ -1,4 +1,4 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,18 +1,18 @@
1
- from setuptools import setup, find_packages
2
-
3
- setup(
4
- name='adapto',
5
- version='0.1.0',
6
- packages=find_packages(),
7
- install_requires=['psutil', 'numpy'],
8
- description='AI-driven auto-scaling library for dynamic resource allocation.',
9
- author='Harshal Mehta',
10
- author_email='harshalmehta1998@gmail.com',
11
- url='https://github.com/hrshlmeht/adapto',
12
- classifiers=[
13
- 'Programming Language :: Python :: 3',
14
- 'License :: OSI Approved :: MIT License',
15
- 'Operating System :: OS Independent',
16
- ],
17
- python_requires='>=3.7',
18
- )
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='adapto',
5
+ version='0.1.2',
6
+ packages=find_packages(),
7
+ install_requires=['psutil', 'numpy'],
8
+ description='AI-driven auto-scaling library for dynamic resource allocation.',
9
+ author='Harshal Mehta',
10
+ author_email='harshalmehta1998@gmail.com',
11
+ url='https://github.com/hrshlmeht/adapto',
12
+ classifiers=[
13
+ 'Programming Language :: Python :: 3',
14
+ 'License :: OSI Approved :: MIT License',
15
+ 'Operating System :: OS Independent',
16
+ ],
17
+ python_requires='>=3.7',
18
+ )
@@ -0,0 +1,18 @@
1
+ import unittest
2
+ from adapto.predictor import Predictor
3
+
4
+ class TestPredictor(unittest.TestCase):
5
+ def setUp(self):
6
+ self.predictor = Predictor()
7
+
8
+ def test_prediction_with_data(self):
9
+ cpu_history = [10, 20, 30, 40, 50]
10
+ predicted_cpu = self.predictor.train_predictor(cpu_history)
11
+ self.assertIsInstance(predicted_cpu, float)
12
+
13
+ def test_prediction_with_empty_data(self):
14
+ predicted_cpu = self.predictor.train_predictor([])
15
+ self.assertEqual(predicted_cpu, 0)
16
+
17
+ if __name__ == '__main__':
18
+ unittest.main()
@@ -0,0 +1,11 @@
1
+ import unittest
2
+ from adapto.scaler import AutoScaler
3
+
4
+ class TestAutoScaler(unittest.TestCase):
5
+ def test_default_thresholds(self):
6
+ scaler = AutoScaler()
7
+ self.assertEqual(scaler.cpu_threshold, 75)
8
+ self.assertEqual(scaler.memory_threshold, 80)
9
+
10
+ if __name__ == '__main__':
11
+ unittest.main()
adapto-0.1.0/README.md DELETED
@@ -1,12 +0,0 @@
1
- # Adapto 🚀
2
-
3
- **Adapto** is an AI-driven auto-scaling Python library that dynamically adjusts resources based on real-time system usage.
4
-
5
- ## Features
6
- - **Real-time monitoring** of CPU and memory usage
7
- - **Intelligent scaling** to optimize performance
8
- - **Easy integration** with Kubernetes and Docker
9
-
10
- ## Installation
11
- ```sh
12
- pip install adapto
File without changes