Skip to content

Commit

Permalink
Version 0.0.3 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aljbri committed Oct 20, 2024
1 parent 59939ae commit dd61609
Show file tree
Hide file tree
Showing 10 changed files with 1,419 additions and 765 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ venv.bak/
# Rope project settings
.ropeproject

# PyCharm project settings
.idea
tmp

# mkdocs documentation
/site

Expand All @@ -127,4 +131,4 @@ dmypy.json

# Pyre type checker
.pyre/
setup.py
# setup.py
695 changes: 21 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

186 changes: 150 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,175 @@
# TQuota

[![GitHub Release](https://img.shields.io/github/v/release/aljbri/tquota)](https://github.com/aljbri/tquota/releases/latest)
[![GitHub License](https://img.shields.io/github/license/aljbri/tquota)](https://github.com/aljbri/tquota/blob/master/LICENSE)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tquota)](https://pypi.org/project/tquota)
[![PyPI - Format](https://img.shields.io/pypi/format/tquota)](https://pypi.org/project/tquota)
[![PyPI - Version](https://img.shields.io/pypi/v/tquota)](https://pypi.org/project/tquota)
<!--
[![wheel](https://img.shields.io/pypi/wheel/tquota)](https://pypi.org/project/tquota)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/tquota)]()
-->

# TQuota
Processing timer module: help if the code is running on the cloud server which has a quota limitation, such as [kaggle](https://www.kaggle.com/) and [colab](https://colab.research.google.com/) which have a limit for 9 hours of processing on each session
`tquota.Quota` is a lightweight processing timer module designed to monitor time effectively when running code on cloud platforms with quota limitations, such as [Kaggle](https://www.kaggle.com/) and [Google Colab](https://colab.research.google.com/). These platforms impose a limit of `x` hours of processing per session, the `Quota` class allows users to set a processing quota time and a buffer time before the quota limit ends, ensuring efficient resource management.

## Features

- **Quota Management**: Easily track and manage session time to avoid overuse of limited resources on platforms with quota restrictions.
- **Dynamic Gap Timing**: Automatically adjusts the buffer time (`gap_time`) based on the remaining session time when set to `'auto'`.
- **Auto Gap Calculation**: When `gap_time` is set to `'auto'`, the system dynamically calculates the optimal gap before the session ends, ensuring efficient timing without the need for manual setup.
- **Simple Interface**: The class provides Easy-to-use and intuitive methods to check whether time is still available or if the session has reached its limit.
- **Optional Logging**: Enable logging to track quota usage and gap timing for debugging or monitoring purposes.
- **Compatibility**: It can work with Python versions 2.7 and 3.0+.

---
## Quota Class

# quota class
The package has only one class (quota) that has two parameters
* **quota_time**: type (str) default value (6h) : represent the quota time for the session
* **gap_time**: type (str) default value (30m): represent the time gap between the quota limit and the actual closing time for the session
The package `tquota` includes a single class, `Quota`, which has two main parameters and an optional one:

The time has a strict format to be passed with; it has to part *dw* while
*d*: represent the time as digits
*w*: the time and one character(w) to represent the time period
- **s** : Seconds
- **m** : Minutes
- **h** : Hours
- **d** : Days
* **quota_time**: (str) Default value: `6h`. Represents the maximum processing time for the session.
* **gap_time**: (str) Default value: `'auto'`. Represents the buffer time before the session closes, adjusted dynamically based on elapsed time.
* **enable_logging**: (bool, optional) Default value: `False`. Whether to enable logging or not.

## functions
### Time Format

quota class has two functions:
* time_up : return True if the process reaches it is limit
* hastime : return True if the process still has time to process

# install
you can install the package from [pypi](https://pypi.org/project/tquota).
The time should be specified in a strict format, consisting of two parts: *`dw`*, where:
- **d**: Represents the time as digits
- **w**: Represents the time unit with one character:

[ s: Seconds, m: Minutes, h: Hours, d: Days]

## Functions

The `Quota` class provides the following key methods:

**`time_up`**:
- **Description**: This method checks whether the processing time has reached or exceeded its quota limit.
- **Returns**:
- `True`: If the process has reached or exceeded the defined quota time.
- `False`: If there is still time remaining within the quota limit.
- **Usage**:
```python
if qt.time_up():
print('Time limit reached.')
```

pip install tquota
**`hastime`**:
- **Description**: This method checks whether there is still time left before the process reaches the quota limit.
- **Returns**:
- `True`: If there is still time remaining before reaching the quota.
- `False`: If the process has exceeded the quota time or is within the gap buffer.
- **Usage**:
```python
if qt.hastime():
print('There’s still time to process.')
```

**`remaining_time`**:
- **Description**: This method returns the remaining time before the quota limit is reached in a human-readable format.
- **Returns**: A string representing the remaining time formatted as `"xh:xm:xs"` (e.g., `"0h:10m:15s"` for 10 minutes and 15 seconds remaining).
- **Usage**:
```python
remaining = qt.remaining_time()
print(f'Remaining time: {remaining}')
```
---
## Installation

# usage
Import the quota class as following
You can install the package from [PyPI](https://pypi.org/project/tquota) using the following command:

```bash
pip install tquota
```

Alternatively, you can clone the repository and install the package directly:

```bash
git clone https://github.com/aljbri/tquota.git
cd tquota
pip install .
```
---
## Usage

Import the `Quota` class as follows:

```python
from tquota import Quota
```

from tquota import quota
### Example Usage

Example on using the package:
- Using the **time_up** function:

- Using **time_up** function:
```python
from tquota import quota
from tquota import Quota
import time
# quota _time was set for 1 minute and the gap _time as 30 second
qt = quota('1m','30s')

# Quota time is set for 1 minute and gap time is auto-adjusted
qt = Quota('1m')
# Set quota_time for 1 minute and gap_time for 30 seconds
# qt = Quota('1m', '30s')

for i in range(1000):
time.sleep(1)
if qt.time_up():
print('The process has reached the limited time')
print('The process has reached the limited time.')
break
```
- Using **hastime** function:
- Using the **hastime** function:

```python
from tquota import quota
from tquota import Quota
import time
# quota _time was set for 1 minute and the gap _time as 30 second
qt = quota('1m','30s')

# Quota time is set for 1 minute and gap time is auto-adjusted
# qt = Quota('1m')

# Set quota_time for 1 minute and gap_time for 30 seconds
qt = Quota('1m', '30s')

for i in range(1000):
time.sleep(1)
if not qt.hastime():
print('The process has reached the limited time')
print('The process has reached the limited time.')
break
```
```

---
## Error Handling

The `Quota` class may raise the following exceptions:

- `ValueError`: Raised for invalid time formats or non-positive time values.
- `TypeError`: Raised if non-string values are provided for time parameters.
- `AttributeError`: Raised if internal properties are accessed incorrectly.
---
## License

This project is licensed under the MIT License. See the [LICENSE](https://github.com/aljbri/tquota/blob/master/LICENSE) file for details.

---
## Updates

### v0.0.1
- Initial implementation of the `quota` class.

### v0.0.2
- Major error fix `quota` class.

### v0.0.3
- **Auto Gap Time**: Added support for automatic calculation of `gap_time` when it is set to `'auto'`, dynamically adjusting the buffer time based on the session duration.
- **Error Handling Enhancements**: Improved validation for time formats, with clearer exceptions raised (`ValueError`, `TypeError`, `AttributeError`) for invalid inputs or improper usage.
- **Optimized Logging**: Added an optional logging feature that provides detailed output for quota time, gap time, and overall usage when enabled.
- **Performance Improvements**: Optimized the time-tracking logic for smoother integration into various cloud platforms.
- **Python Compatibility**: Compatible with Python versions 2.7 and 3.0+.

---
## Contributing

Contributions are welcome! If you have suggestions or improvements, please feel free to submit a pull request or open an issue.

---
## Contact

For inquiries or feedback, please contact the author at [mr.aljbri@gmail.com](mailto:mr.aljbri@gmail.com).
1 change: 1 addition & 0 deletions docs/CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tquota.appenvs.com
843 changes: 843 additions & 0 deletions docs/index.html

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "tquota"
version = "0.0.3"
description = "A lightweight processing timer module for quota-based cloud environments."
authors = [
{ name = "Abdussalam Aljbri", email = "mr.aljbri@gmail.com" }
]
maintainers = [
{ name = "Abdussalam Aljbri", email = "mr.aljbri@gmail.com" }
]
license = {text = "MIT License"}
readme = {file = "README.md", content-type = "text/markdown"}
keywords = ["quota", "cloud", "timer", "kaggle", "colab", "session", "management", 'monitor']
requires-python = ">=2.7, <4" # Minimum required Python version

classifiers = [
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.0',
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent'
]

[project.urls]
Homepage = "https://github.com/aljbri/tquota/"
Documentation = "https://aljbri.github.io/tquota/"
Repository = "https://github.com/aljbri/tquota/"
Issues = "https://github.com/aljbri/tquota/issues"

32 changes: 32 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from setuptools import setup, find_packages

# Read the contents of your README file
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()

setup(
name="tquota", # Name of the package
version="0.0.3", # Version number
author="Abdussalam Aljbri", # Author name
author_email="mr.aljbri@gmail.com", # Author email
description="A processing timer module for cloud servers with session quota limitations.",
long_description=long_description, # Use the README.md as the long description
long_description_content_type="text/markdown", # Make sure to specify that it's markdown
url="https://github.com/aljbri/tquota", # Project GitHub URL
packages=find_packages(), # Automatically discover all the packages in your project
classifiers=[
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.0",
"Programming Language :: Python :: 3", # Allows for all 3.x versions
"License :: OSI Approved :: MIT License", # License type
"Operating System :: OS Independent", # OS compatibility
],
python_requires='>=2.7, <4', # Minimum version of Python required
install_requires=[], # Add any dependencies your package needs here
keywords="quota timer cloud session limit processing kaggle colab", # Useful keywords
project_urls={
"Bug Tracker": "https://github.com/aljbri/tquota/issues", # URL to submit issues
"Documentation": "https://github.com/aljbri/tquota/blob/main/README.md", # Documentation URL
"Source Code": "https://github.com/aljbri/tquota", # Source code URL
},
)
70 changes: 70 additions & 0 deletions test/test_quota.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import unittest
import time
from tquota import Quota

class TestQuota(unittest.TestCase):

def test_initialization_valid(self):
"""Test that valid initialization works properly."""
quota = Quota('1h', '5m')
self.assertEqual(quota.quota_time, 3600)
self.assertEqual(quota.gap_time, 300)

def test_initialization_invalid_time_format(self):
"""Test that invalid time formats raise a ValueError."""
with self.assertRaises(ValueError):
Quota('invalid', '5m')

def test_to_seconds(self):
"""Test conversion from time format to seconds."""
quota = Quota('1h')
self.assertEqual(quota._to_seconds('30s'), 30)
self.assertEqual(quota._to_seconds('5m'), 300)
self.assertEqual(quota._to_seconds('2h'), 7200)
self.assertEqual(quota._to_seconds('1d'), 86400)

def test_hastime_before_gap(self):
"""Test hastime returns True before gap time is reached."""
quota = Quota('1m', '10s')
time.sleep(2) # Sleep for a few seconds to simulate execution
self.assertTrue(quota.hastime())

def test_time_up_after_quota(self):
"""Test time_up returns True after quota time is reached."""
quota = Quota('3s', '1s')
time.sleep(4) # Sleep to exceed quota time
self.assertTrue(quota.time_up())

def test_dynamic_gap_time_auto(self):
"""Test automatic gap time adjustment based on execution times."""
quota = Quota('10s', 'auto') # Set gap time to auto
for _ in range(5): # Simulate loop execution
time.sleep(0.5) # Each iteration takes ~0.5s
quota.hastime() # This will update the gap time
self.assertGreater(quota.gap_time, 0.4) # Check if gap time was adjusted

def test_format_time(self):
"""Test that the time formatting function works as expected."""
quota = Quota('1h')
formatted_time = quota._format_time(3661)
self.assertEqual(formatted_time, '1h:1m:1s')

def test_remaining_time(self):
"""Test remaining time calculation."""
quota = Quota('10s')
time.sleep(3)
remaining = quota._remaining_time()
self.assertLessEqual(remaining, 7)

def test_gap_time_greater_than_quota(self):
"""Test that setting gap time greater than quota raises an error."""
with self.assertRaises(ValueError):
Quota('5m', '10m')

def test_logging_enabled(self):
"""Test that logging can be enabled without errors."""
quota = Quota('10s', enable_logging=True)
self.assertTrue(quota.enable_logging)

if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions tquota/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
@author: Abdussalam Aljbri
"""

from .quota import quota
from .quota import Quota

__version__ = '0.0.1'
__version__ = '0.0.3'
Loading

0 comments on commit dd61609

Please sign in to comment.