diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..33e3211 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +**/__pycache__/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1233b3e --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Package Measurement Conversion API + +This API is designed to convert measurement input strings into a list of total values of measured inflows for each package. The input strings follow a specific encoding format, where each package consists of a number indicating the count of values measured in each measurement cycle, followed by the measured values encoded using alphabetical characters. + +## Pre-requisites + +- Python 3.x +- CherryPy +- SQLite + +## Installation + +### 1. Clone the repository: + + https://github.com/HaithamAlMaamari/PackageMeasurementConversionAPI.git + + +### 2. Navigate to the project directory: + + cd Package_Measurement_Conversion_API + +### 3. Install the required dependencies: + + pip install python + pip install pycharm + pip install sqlite3 + +## Running the Application + +### 1. Start the server application: + + python main.py + +### 2. The server will start, and you will see a status message. + +## API Usage +### 1. To view the converted alphabet input string into the corresponding list of numbers in JSON format. + +### Example requests: + + http://localhost:8080/convert_measurements?input=abbcc + + http://localhost:8080/convert_measurements?input=aa + + +## Contributing +Contributing to this project is prohibited due to Course Restrictions. \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/controller/__init__.py b/controller/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/controller/controller.py b/controller/controller.py new file mode 100644 index 0000000..9cc07f8 --- /dev/null +++ b/controller/controller.py @@ -0,0 +1,46 @@ +import cherrypy +from datetime import datetime + +from services.converter import PackageConverter +from utilities.db import PackageMeasurementHistory +from models.sequence import Sequence + + +class ConverterAPI: + def __init__(self): + self.converter = PackageConverter() + self.sequence_history = PackageMeasurementHistory('./utilities/converter.db') + + @cherrypy.expose + @cherrypy.tools.json_out() + def convert_measurements(self, input=None): + """ + API endpoint to convert measurements from an input string. + """ + try: + input_string = input if input is not None else cherrypy.request.params.get("input", "") + measurement = self.converter.convert_measurements(input_string) # Updated method name + time = datetime.now() + response = "Measurements processed" if measurement != "Invalid" else "Invalid input" + sequence = Sequence(input_string, measurement, time, response) + self.sequence_history.save_curr_seq(sequence) # Ensure this method accepts a Sequence object + + return {"status": "success" if measurement != "Invalid" else "fail", + "err_msg": "", + "result": measurement if measurement != "Invalid" else None} + except Exception as e: + cherrypy.response.status = 500 + return {"status": "fail", "err_msg": str(e), "result": None} + + @cherrypy.expose + @cherrypy.tools.json_out() + def get_history(self): + """ + API endpoint to retrieve measurement history. + """ + try: + history = self.sequence_history.get_history() + return {"status": "success", "err_msg": "","data": history} + except Exception as e: + cherrypy.response.status = 500 + return {"status": "error", "err_msg": str(e), "data": None} diff --git a/conversion_history.db b/conversion_history.db new file mode 100644 index 0000000..82fd855 Binary files /dev/null and b/conversion_history.db differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..8fb4e8e --- /dev/null +++ b/main.py @@ -0,0 +1,38 @@ +import sys +import logging +import cherrypy +from controller.controller import ConverterAPI + + +def setup_logging(): + logging.basicConfig( + filename='utilities/error_log.log', + level=logging.CRITICAL, + format='%(asctime)s:%(levelname)s:%(message)s' + ) + logging.getLogger().addHandler(logging.StreamHandler()) + + +def start_server(port=8080): + try: + cherrypy.config.update({ + 'server.socket_host': '0.0.0.0', + 'server.socket_port': port + }) + cherrypy.tree.mount(ConverterAPI(), '/') + cherrypy.engine.start() + cherrypy.engine.block() + except Exception as e: + logging.critical("Failed to start server: ", exc_info=e) + + +if __name__ == '__main__': + setup_logging() + port = 8080 # Default port + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + logging.error("Invalid port number provided. Using default port (8080).") + + start_server(port) diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/sequence.py b/models/sequence.py new file mode 100644 index 0000000..63b8e8b --- /dev/null +++ b/models/sequence.py @@ -0,0 +1,8 @@ + + +class Sequence: + def __init__(self, input_string, measurement, time, response: str = None): + self.input_string = input_string + self.measurement = measurement + self.response = response + self.time = time diff --git a/services/__init__.py b/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/converter.py b/services/converter.py new file mode 100644 index 0000000..b698878 --- /dev/null +++ b/services/converter.py @@ -0,0 +1,77 @@ +import string + + +class PackageConverter: + def convert_measurements(self, input_string: str) -> list: + """Convert input string to a list of summed measurements.""" + values = [self.convert_char_to_value(char) for char in input_string] + lst = self.convert(values) + return self.process_measurements(lst) + + @staticmethod + def convert_char_to_value(char: str) -> int: + """Convert a character to its corresponding numeric value.""" + if char == '_': + return 0 + return string.ascii_lowercase.index(char.lower()) + 1 + def is_empty(self, lst): + if len(lst) < 1: + return True + else: + return False + + def convert(self, lst): + count = 0 + i = 0 + while not self.is_empty(lst): + # print(lst[i]) + if i >= len(lst): + if count >= 26: + return "invalid" + return lst + elif lst[i] >= 26: + count += 26 + lst.pop(i) + + else: + count += lst[i] + lst[i] = count + i += 1 + count = 0 + return lst + + + + + def process_measurements(self, values: list) -> list: + """Process list of numeric values and sum according to the encoded rules.""" + result = [] + i = 0 + # for i in range(len(values)): + if values != "invalid": + + while not self.is_empty(values): + length = values[0] + values.pop(0) + # print(length, ": ", len(values)) + if length == 0: #or i + length >= len(values): + result.append(0) + break + elif length > len(values): + result = [] + break + + else: + # result.append(sum(values[i+1:i+1+length])) + result.append(sum(values[:length])) + values = values[length:] + # i += length + 1 + else: + result = [] + return result + + +converter = PackageConverter() +# print(converter.convert_measurements("aaa")) +print(converter.convert_measurements("abz")) +# print(converter.convert_measurements("abc")) \ No newline at end of file diff --git a/services/test/__init__.py b/services/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/services/test/test_conversion.py b/services/test/test_conversion.py new file mode 100644 index 0000000..2777b57 --- /dev/null +++ b/services/test/test_conversion.py @@ -0,0 +1,34 @@ +import unittest +from services.converter import PackageConverter + + +class TestPackageConverter(unittest.TestCase): + def setUp(self): + self.converter = PackageConverter() + + def test_single_characters(self): + """Test conversion of single-character strings.""" + self.assertEqual(self.converter.convert_measurements("aa"), [1]) + self.assertEqual(self.converter.convert_measurements("__"), [0]) + self.assertEqual(self.converter.convert_measurements("a_"), [0]) + + def test_multiple_characters(self): + """Test conversion of strings with multiple characters.""" + self.assertEqual(self.converter.convert_measurements('abbcc'), [2, 6]) + self.assertEqual(self.converter.convert_measurements('abcdabcdab'), [2, 7, 7]) + self.assertEqual(self.converter.convert_measurements('abcdabcdab_'), [2, 7, 7, 0]) + + def test_invalid_sequences(self): + """Test conversion of strings that are expected to be invalid.""" + self.assertEqual(self.converter.convert_measurements("abz"), []) + self.assertEqual(self.converter.convert_measurements("aaa"), []) + self.assertEqual(self.converter.convert_measurements("abc"), []) + + def test_edge_cases(self): + """Test conversion of strings with edge cases.""" + self.assertEqual(self.converter.convert_measurements('dz_a_aazzaaa'), [28, 53, 1]) + self.assertEqual(self.converter.convert_measurements('_zzzb'), [0]) + + +if __name__ == '__main__': + unittest.main() diff --git a/utilities/__init__.py b/utilities/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utilities/converter.db b/utilities/converter.db new file mode 100644 index 0000000..c84901e Binary files /dev/null and b/utilities/converter.db differ diff --git a/utilities/db.py b/utilities/db.py new file mode 100644 index 0000000..583c617 --- /dev/null +++ b/utilities/db.py @@ -0,0 +1,35 @@ +import sqlite3 +import logging +from models.sequence import Sequence +import json + + +class PackageMeasurementHistory: + def __init__(self, db_path: str): + self.db_path = db_path + self.create_table() + + def create_table(self): + with sqlite3.connect(self.db_path) as conn: + conn.execute(''' + CREATE TABLE IF NOT EXISTS sequences ( + id INTEGER PRIMARY KEY, + input_string TEXT, + measurements TEXT, + response TEXT, + time TIMESTAMP + ) + ''') + + def save_curr_seq(self, sequence: Sequence) -> bool: + """Save a Sequence object to the database.""" + try: + with sqlite3.connect(self.db_path) as conn: + conn.execute( + "INSERT INTO sequences (input_string, measurements, response, time) VALUES (?, ?, ?, ?)", + (sequence.input_string, json.dumps(sequence.measurement), sequence.response, sequence.time) + ) + return True + except sqlite3.Error as e: + logging.error(f"Error saving sequence: {e}") + return False diff --git a/utilities/error_log.log b/utilities/error_log.log new file mode 100644 index 0000000..de0fbe7 --- /dev/null +++ b/utilities/error_log.log @@ -0,0 +1,217 @@ +2024-05-01 17:30:30,846:INFO:[01/May/2024:17:30:30] ENGINE Bus STARTING +2024-05-01 17:30:30,848:INFO:[01/May/2024:17:30:30] ENGINE Started monitor thread 'Autoreloader'. +2024-05-01 17:30:31,082:INFO:[01/May/2024:17:30:31] ENGINE Serving on http://0.0.0.0:8080 +2024-05-01 17:30:31,083:INFO:[01/May/2024:17:30:31] ENGINE Bus STARTED +2024-05-01 17:31:19,093:INFO:127.0.0.1 - - [01/May/2024:17:31:19] "GET /convert_measurements?input=aa HTTP/1.1" 200 3 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 17:31:26,027:INFO:127.0.0.1 - - [01/May/2024:17:31:26] "GET /convert_measurements?input=abbcc HTTP/1.1" 200 6 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 17:31:50,616:INFO:[01/May/2024:17:31:50] ENGINE Keyboard Interrupt: shutting down bus +2024-05-01 17:31:50,616:INFO:[01/May/2024:17:31:50] ENGINE Bus STOPPING +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE Stopped thread 'Autoreloader'. +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE Bus STOPPED +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE Bus EXITING +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE Bus EXITED +2024-05-01 17:31:50,786:INFO:[01/May/2024:17:31:50] ENGINE Waiting for child threads to terminate... +2024-05-01 19:42:48,626:INFO:[01/May/2024:19:42:48] ENGINE Bus STARTING +2024-05-01 19:42:48,627:INFO:[01/May/2024:19:42:48] ENGINE Started monitor thread 'Autoreloader'. +2024-05-01 19:42:48,849:INFO:[01/May/2024:19:42:48] ENGINE Serving on http://0.0.0.0:8080 +2024-05-01 19:42:48,849:INFO:[01/May/2024:19:42:48] ENGINE Bus STARTED +2024-05-01 19:43:46,136:INFO:127.0.0.1 - - [01/May/2024:19:43:46] "GET /aa HTTP/1.1" 404 1522 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:43:50,617:INFO:127.0.0.1 - - [01/May/2024:19:43:50] "GET /convert_measurements/aa HTTP/1.1" 500 121 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:44:07,455:INFO:127.0.0.1 - - [01/May/2024:19:44:07] "GET /convert_measurements?input=abbcc HTTP/1.1" 500 121 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:44:16,666:INFO:127.0.0.1 - - [01/May/2024:19:44:16] "GET /convert_measurements HTTP/1.1" 500 121 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:45:00,398:INFO:[01/May/2024:19:45:00] ENGINE Keyboard Interrupt: shutting down bus +2024-05-01 19:45:00,398:INFO:[01/May/2024:19:45:00] ENGINE Bus STOPPING +2024-05-01 19:45:00,531:INFO:[01/May/2024:19:45:00] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-01 19:45:00,532:INFO:[01/May/2024:19:45:00] ENGINE Stopped thread 'Autoreloader'. +2024-05-01 19:45:00,532:INFO:[01/May/2024:19:45:00] ENGINE Bus STOPPED +2024-05-01 19:45:00,532:INFO:[01/May/2024:19:45:00] ENGINE Bus EXITING +2024-05-01 19:45:00,532:INFO:[01/May/2024:19:45:00] ENGINE Bus EXITED +2024-05-01 19:45:00,532:INFO:[01/May/2024:19:45:00] ENGINE Waiting for child threads to terminate... +2024-05-01 19:58:50,913:INFO:[01/May/2024:19:58:50] ENGINE Bus STARTING +2024-05-01 19:58:50,914:INFO:[01/May/2024:19:58:50] ENGINE Started monitor thread 'Autoreloader'. +2024-05-01 19:58:51,147:INFO:[01/May/2024:19:58:51] ENGINE Serving on http://0.0.0.0:8080 +2024-05-01 19:58:51,147:INFO:[01/May/2024:19:58:51] ENGINE Bus STARTED +2024-05-01 19:58:56,733:INFO:127.0.0.1 - - [01/May/2024:19:58:56] "GET /convert_measurements HTTP/1.1" 200 48 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:59:01,734:INFO:127.0.0.1 - - [01/May/2024:19:59:01] "GET /convert_measurements?input=abbcc HTTP/1.1" 200 52 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:59:07,260:INFO:127.0.0.1 - - [01/May/2024:19:59:07] "GET /convert_measurements?input=aa HTTP/1.1" 200 49 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-01 19:59:13,194:INFO:[01/May/2024:19:59:13] ENGINE Keyboard Interrupt: shutting down bus +2024-05-01 19:59:13,194:INFO:[01/May/2024:19:59:13] ENGINE Bus STOPPING +2024-05-01 19:59:13,344:INFO:[01/May/2024:19:59:13] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-01 19:59:13,344:INFO:[01/May/2024:19:59:13] ENGINE Stopped thread 'Autoreloader'. +2024-05-01 19:59:13,345:INFO:[01/May/2024:19:59:13] ENGINE Bus STOPPED +2024-05-01 19:59:13,345:INFO:[01/May/2024:19:59:13] ENGINE Bus EXITING +2024-05-01 19:59:13,345:INFO:[01/May/2024:19:59:13] ENGINE Bus EXITED +2024-05-01 19:59:13,345:INFO:[01/May/2024:19:59:13] ENGINE Waiting for child threads to terminate... +2024-05-02 08:47:24,168:CRITICAL:Failed to start server: +Traceback (most recent call last): + File "C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py", line 22, in start_server + cherrypy.tree.mount(ConverterAPI(), '/') + ^^^^^^^^^^^^^^ + File "C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\controller\controller.py", line 12, in __init__ + self.sequence_history = PackageMeasurementHistory('./utilis/converter.db') + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\utilities\db.py", line 10, in __init__ + self.create_table() + File "C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\utilities\db.py", line 13, in create_table + with sqlite3.connect(self.db_path) as conn: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +sqlite3.OperationalError: unable to open database file +2024-05-02 08:48:23,123:INFO:[02/May/2024:08:48:23] ENGINE Bus STARTING +2024-05-02 08:48:23,124:INFO:[02/May/2024:08:48:23] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:48:23,353:INFO:[02/May/2024:08:48:23] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:48:23,353:INFO:[02/May/2024:08:48:23] ENGINE Bus STARTED +2024-05-02 08:49:01,884:INFO:127.0.0.1 - - [02/May/2024:08:49:01] "GET /convert_measurements?input_str=aa HTTP/1.1" 404 2619 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:49:09,511:INFO:127.0.0.1 - - [02/May/2024:08:49:09] "GET /convert_measurements?input=aa HTTP/1.1" 200 49 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:49:43,854:INFO:[02/May/2024:08:49:43] ENGINE Keyboard Interrupt: shutting down bus +2024-05-02 08:49:43,854:INFO:[02/May/2024:08:49:43] ENGINE Bus STOPPING +2024-05-02 08:49:44,027:INFO:[02/May/2024:08:49:44] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 08:49:44,027:INFO:[02/May/2024:08:49:44] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 08:49:44,027:INFO:[02/May/2024:08:49:44] ENGINE Bus STOPPED +2024-05-02 08:49:44,027:INFO:[02/May/2024:08:49:44] ENGINE Bus EXITING +2024-05-02 08:49:44,028:INFO:[02/May/2024:08:49:44] ENGINE Bus EXITED +2024-05-02 08:49:44,028:INFO:[02/May/2024:08:49:44] ENGINE Waiting for child threads to terminate... +2024-05-02 08:52:16,313:INFO:[02/May/2024:08:52:16] ENGINE Bus STARTING +2024-05-02 08:52:16,314:INFO:[02/May/2024:08:52:16] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:52:16,534:INFO:[02/May/2024:08:52:16] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:52:16,534:INFO:[02/May/2024:08:52:16] ENGINE Bus STARTED +2024-05-02 08:52:18,158:INFO:127.0.0.1 - - [02/May/2024:08:52:18] "GET /convert_measurements?input=aa HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:21,590:INFO:127.0.0.1 - - [02/May/2024:08:52:21] "GET /convert_measurements?input=aa HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:26,028:INFO:127.0.0.1 - - [02/May/2024:08:52:26] "GET /convert_measurements?input=aaa HTTP/1.1" 200 39 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:32,388:INFO:127.0.0.1 - - [02/May/2024:08:52:32] "GET /convert_measurements?input=a HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:38,356:INFO:127.0.0.1 - - [02/May/2024:08:52:38] "GET /convert_measurements?input=_ HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:42,612:INFO:127.0.0.1 - - [02/May/2024:08:52:42] "GET /convert_measurements?input=__ HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:47,756:INFO:127.0.0.1 - - [02/May/2024:08:52:47] "GET /convert_measurements?input=__adskjdksaf HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:53,944:INFO:127.0.0.1 - - [02/May/2024:08:52:53] "GET /convert_measurements?input=knfljwnf HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:52:58,624:INFO:127.0.0.1 - - [02/May/2024:08:52:58] "GET /convert_measurements?input=abbcc HTTP/1.1" 200 39 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:53:02,377:INFO:127.0.0.1 - - [02/May/2024:08:53:02] "GET /convert_measurements?input=ndfjsanfjs HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:53:21,267:INFO:127.0.0.1 - - [02/May/2024:08:53:21] "GET /convert_measurements?input=aa HTTP/1.1" 200 36 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 08:54:50,291:INFO:[02/May/2024:08:54:50] ENGINE Restarting because C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\controller\controller.py changed. +2024-05-02 08:54:50,291:INFO:[02/May/2024:08:54:50] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 08:54:50,291:INFO:[02/May/2024:08:54:50] ENGINE Bus STOPPING +2024-05-02 08:54:50,442:INFO:[02/May/2024:08:54:50] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 08:54:50,442:INFO:[02/May/2024:08:54:50] ENGINE Bus STOPPED +2024-05-02 08:54:50,442:INFO:[02/May/2024:08:54:50] ENGINE Bus EXITING +2024-05-02 08:54:50,442:INFO:[02/May/2024:08:54:50] ENGINE Bus EXITED +2024-05-02 08:54:50,454:INFO:[02/May/2024:08:54:50] ENGINE Waiting for child threads to terminate... +2024-05-02 08:54:50,454:INFO:[02/May/2024:08:54:50] ENGINE Re-spawning C:\Program Files\Python312\python.exe C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py +2024-05-02 08:54:50,920:INFO:[02/May/2024:08:54:50] ENGINE Bus STARTING +2024-05-02 08:54:50,921:INFO:[02/May/2024:08:54:50] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:54:51,141:INFO:[02/May/2024:08:54:51] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:54:51,142:INFO:[02/May/2024:08:54:51] ENGINE Bus STARTED +2024-05-02 08:55:20,251:INFO:[02/May/2024:08:55:20] ENGINE Restarting because C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\controller\controller.py changed. +2024-05-02 08:55:20,251:INFO:[02/May/2024:08:55:20] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 08:55:20,251:INFO:[02/May/2024:08:55:20] ENGINE Bus STOPPING +2024-05-02 08:55:20,419:INFO:[02/May/2024:08:55:20] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 08:55:20,419:INFO:[02/May/2024:08:55:20] ENGINE Bus STOPPED +2024-05-02 08:55:20,420:INFO:[02/May/2024:08:55:20] ENGINE Bus EXITING +2024-05-02 08:55:20,421:INFO:[02/May/2024:08:55:20] ENGINE Bus EXITED +2024-05-02 08:55:20,508:INFO:[02/May/2024:08:55:20] ENGINE Waiting for child threads to terminate... +2024-05-02 08:55:20,508:INFO:[02/May/2024:08:55:20] ENGINE Re-spawning C:\Program Files\Python312\python.exe C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py +2024-05-02 08:55:20,993:INFO:[02/May/2024:08:55:20] ENGINE Bus STARTING +2024-05-02 08:55:20,994:INFO:[02/May/2024:08:55:20] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:55:21,225:INFO:[02/May/2024:08:55:21] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:55:21,225:INFO:[02/May/2024:08:55:21] ENGINE Bus STARTED +2024-05-02 08:55:34,114:INFO:[02/May/2024:08:55:34] ENGINE Restarting because C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\controller\controller.py changed. +2024-05-02 08:55:34,114:INFO:[02/May/2024:08:55:34] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 08:55:34,115:INFO:[02/May/2024:08:55:34] ENGINE Bus STOPPING +2024-05-02 08:55:34,258:INFO:[02/May/2024:08:55:34] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 08:55:34,258:INFO:[02/May/2024:08:55:34] ENGINE Bus STOPPED +2024-05-02 08:55:34,258:INFO:[02/May/2024:08:55:34] ENGINE Bus EXITING +2024-05-02 08:55:34,258:INFO:[02/May/2024:08:55:34] ENGINE Bus EXITED +2024-05-02 08:55:34,290:INFO:[02/May/2024:08:55:34] ENGINE Waiting for child threads to terminate... +2024-05-02 08:55:34,290:INFO:[02/May/2024:08:55:34] ENGINE Re-spawning C:\Program Files\Python312\python.exe C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py +2024-05-02 08:55:34,736:INFO:[02/May/2024:08:55:34] ENGINE Bus STARTING +2024-05-02 08:55:34,737:INFO:[02/May/2024:08:55:34] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:55:34,976:INFO:[02/May/2024:08:55:34] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:55:34,976:INFO:[02/May/2024:08:55:34] ENGINE Bus STARTED +2024-05-02 08:56:48,552:INFO:[02/May/2024:08:56:48] ENGINE Restarting because C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\controller\controller.py changed. +2024-05-02 08:56:48,552:INFO:[02/May/2024:08:56:48] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 08:56:48,552:INFO:[02/May/2024:08:56:48] ENGINE Bus STOPPING +2024-05-02 08:56:48,715:INFO:[02/May/2024:08:56:48] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 08:56:48,715:INFO:[02/May/2024:08:56:48] ENGINE Bus STOPPED +2024-05-02 08:56:48,715:INFO:[02/May/2024:08:56:48] ENGINE Bus EXITING +2024-05-02 08:56:48,715:INFO:[02/May/2024:08:56:48] ENGINE Bus EXITED +2024-05-02 08:56:48,788:INFO:[02/May/2024:08:56:48] ENGINE Waiting for child threads to terminate... +2024-05-02 08:56:48,789:INFO:[02/May/2024:08:56:48] ENGINE Re-spawning C:\Program Files\Python312\python.exe C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py +2024-05-02 08:56:49,512:INFO:[02/May/2024:08:56:49] ENGINE Bus STARTING +2024-05-02 08:56:49,513:INFO:[02/May/2024:08:56:49] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 08:56:49,724:INFO:[02/May/2024:08:56:49] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 08:56:49,724:INFO:[02/May/2024:08:56:49] ENGINE Bus STARTED +2024-05-02 09:02:33,971:INFO:[02/May/2024:09:02:33] ENGINE Bus STARTING +2024-05-02 09:02:33,971:INFO:[02/May/2024:09:02:33] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 09:02:34,138:INFO:[02/May/2024:09:02:34] ENGINE Restarting because C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\services\converter.py changed. +2024-05-02 09:02:34,139:INFO:[02/May/2024:09:02:34] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 09:02:34,139:INFO:[02/May/2024:09:02:34] ENGINE Bus STOPPING +2024-05-02 09:02:34,301:INFO:[02/May/2024:09:02:34] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 09:02:34,301:INFO:[02/May/2024:09:02:34] ENGINE Bus STOPPED +2024-05-02 09:02:34,301:INFO:[02/May/2024:09:02:34] ENGINE Bus EXITING +2024-05-02 09:02:34,302:INFO:[02/May/2024:09:02:34] ENGINE Bus EXITED +2024-05-02 09:02:34,326:INFO:[02/May/2024:09:02:34] ENGINE Waiting for child threads to terminate... +2024-05-02 09:02:34,326:INFO:[02/May/2024:09:02:34] ENGINE Re-spawning C:\Program Files\Python312\python.exe C:\Users\71521\Desktop\Eval\PackageMeasurementConversionAPI\main.py +2024-05-02 09:02:34,495:INFO:[02/May/2024:09:02:34] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 09:02:34,495:INFO:[02/May/2024:09:02:34] ENGINE Bus STARTED +2024-05-02 09:02:34,769:INFO:[02/May/2024:09:02:34] ENGINE Bus STARTING +2024-05-02 09:02:34,770:INFO:[02/May/2024:09:02:34] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 09:02:35,945:ERROR:[02/May/2024:09:02:35] ENGINE Error in 'start' listener > +Traceback (most recent call last): + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\portend.py", line 122, in free + Checker(timeout=0.1).assert_free(host, port) + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\portend.py", line 71, in assert_free + list(itertools.starmap(self._connect, info)) + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\portend.py", line 87, in _connect + raise PortNotFree(tmpl.format(**locals())) +portend.PortNotFree: Port 8080 is in use on 127.0.0.1. + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\cherrypy\process\wspbus.py", line 230, in publish + output.append(listener(*args, **kwargs)) + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\cherrypy\_cpserver.py", line 180, in start + super(Server, self).start() + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\cherrypy\process\servers.py", line 177, in start + portend.free(*self.bind_addr, timeout=Timeouts.free) + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\portend.py", line 126, in free + raise Timeout("Port {port} not free on {host}.".format(**locals())) +portend.Timeout: Port 8080 not free on 0.0.0.0. + +2024-05-02 09:02:35,945:ERROR:[02/May/2024:09:02:35] ENGINE Shutting down due to error in start listener: +Traceback (most recent call last): + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\cherrypy\process\wspbus.py", line 268, in start + self.publish('start') + File "C:\Users\71521\AppData\Roaming\Python\Python312\site-packages\cherrypy\process\wspbus.py", line 248, in publish + raise exc +cherrypy.process.wspbus.ChannelFailures: Timeout('Port 8080 not free on 0.0.0.0.') + +2024-05-02 09:02:35,945:INFO:[02/May/2024:09:02:35] ENGINE Bus STOPPING +2024-05-02 09:02:35,946:INFO:[02/May/2024:09:02:35] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) already shut down +2024-05-02 09:02:35,946:INFO:[02/May/2024:09:02:35] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 09:02:35,946:INFO:[02/May/2024:09:02:35] ENGINE Bus STOPPED +2024-05-02 09:02:35,946:INFO:[02/May/2024:09:02:35] ENGINE Bus EXITING +2024-05-02 09:02:35,946:INFO:[02/May/2024:09:02:35] ENGINE Bus EXITED +2024-05-02 09:02:39,835:INFO:127.0.0.1 - - [02/May/2024:09:02:39] "GET /convert_measurements?input=aa HTTP/1.1" 200 51 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 09:02:43,140:INFO:127.0.0.1 - - [02/May/2024:09:02:43] "GET /convert_measurements?input=aaa HTTP/1.1" 200 54 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 09:04:10,062:INFO:[02/May/2024:09:04:10] ENGINE Keyboard Interrupt: shutting down bus +2024-05-02 09:04:10,063:INFO:[02/May/2024:09:04:10] ENGINE Bus STOPPING +2024-05-02 09:04:10,256:INFO:[02/May/2024:09:04:10] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 09:04:10,256:INFO:[02/May/2024:09:04:10] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 09:04:10,256:INFO:[02/May/2024:09:04:10] ENGINE Bus STOPPED +2024-05-02 09:04:10,257:INFO:[02/May/2024:09:04:10] ENGINE Bus EXITING +2024-05-02 09:04:10,257:INFO:[02/May/2024:09:04:10] ENGINE Bus EXITED +2024-05-02 09:04:10,257:INFO:[02/May/2024:09:04:10] ENGINE Waiting for child threads to terminate... +2024-05-02 09:51:36,429:INFO:[02/May/2024:09:51:36] ENGINE Bus STARTING +2024-05-02 09:51:36,429:INFO:[02/May/2024:09:51:36] ENGINE Started monitor thread 'Autoreloader'. +2024-05-02 09:51:36,649:INFO:[02/May/2024:09:51:36] ENGINE Serving on http://0.0.0.0:8080 +2024-05-02 09:51:36,650:INFO:[02/May/2024:09:51:36] ENGINE Bus STARTED +2024-05-02 09:51:41,888:INFO:127.0.0.1 - - [02/May/2024:09:51:41] "GET /convert_measurements?input=aaa HTTP/1.1" 200 50 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 09:51:44,032:INFO:127.0.0.1 - - [02/May/2024:09:51:44] "GET /convert_measurements?input=aa HTTP/1.1" 200 51 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" +2024-05-02 09:52:54,998:INFO:[02/May/2024:09:52:54] ENGINE Keyboard Interrupt: shutting down bus +2024-05-02 09:52:54,999:INFO:[02/May/2024:09:52:54] ENGINE Bus STOPPING +2024-05-02 09:52:55,151:INFO:[02/May/2024:09:52:55] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down +2024-05-02 09:52:55,151:INFO:[02/May/2024:09:52:55] ENGINE Stopped thread 'Autoreloader'. +2024-05-02 09:52:55,152:INFO:[02/May/2024:09:52:55] ENGINE Bus STOPPED +2024-05-02 09:52:55,152:INFO:[02/May/2024:09:52:55] ENGINE Bus EXITING +2024-05-02 09:52:55,152:INFO:[02/May/2024:09:52:55] ENGINE Bus EXITED +2024-05-02 09:52:55,152:INFO:[02/May/2024:09:52:55] ENGINE Waiting for child threads to terminate...