From 6e6729f7b00faa57b8087b1cedf90eb76df9ebeb Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 12 Feb 2026 18:08:41 +0100 Subject: [PATCH 01/12] project refactoring --- src/app/convertor/service/__init__.py | 0 .../convertor/service/convertor_controller.py | 0 .../convertor/service/convertor_service.py | 30 ---- src/app/convertor/service/data/__init__.py | 0 .../data/inputs/5846093734223028963.ogg | Bin 32303 -> 0 bytes .../data/inputs/5846093734223028963.ogx | Bin 32303 -> 0 bytes src/app/convertor/service/transcription.py | 135 ------------------ src/app/main.py | 36 +---- src/app/static/css/main.css | 16 --- src/app/templates/main.html | 61 -------- 10 files changed, 5 insertions(+), 273 deletions(-) delete mode 100644 src/app/convertor/service/__init__.py delete mode 100644 src/app/convertor/service/convertor_controller.py delete mode 100644 src/app/convertor/service/convertor_service.py delete mode 100644 src/app/convertor/service/data/__init__.py delete mode 100644 src/app/convertor/service/data/inputs/5846093734223028963.ogg delete mode 100644 src/app/convertor/service/data/inputs/5846093734223028963.ogx delete mode 100644 src/app/convertor/service/transcription.py delete mode 100644 src/app/static/css/main.css delete mode 100755 src/app/templates/main.html diff --git a/src/app/convertor/service/__init__.py b/src/app/convertor/service/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/convertor/service/convertor_controller.py b/src/app/convertor/service/convertor_controller.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/convertor/service/convertor_service.py b/src/app/convertor/service/convertor_service.py deleted file mode 100644 index 465fb59..0000000 --- a/src/app/convertor/service/convertor_service.py +++ /dev/null @@ -1,30 +0,0 @@ -from app.convertor.service.transcription import Transcription - - -class ConvertorService: - def __init__(self, model_id, input_file_name, show_text, text_preview_size): - self.model_id = model_id - self.input_file_name = input_file_name - self.show_text = show_text - self.text_preview_size = text_preview_size - - def create_text(self): - transcription = Transcription( - model_id=self.model_id, - input_file_name=self.input_file_name, - show_text=self.show_text, - text_preview_size=self.text_preview_size, - ) - - return transcription.get_transcription() - - -if __name__ == "__main__": - convertor_service = ConvertorService( - model_id="tiny", - input_file_name="./src/app/convertor/service/data/inputs/5846093734223028963.ogg", - show_text=True, - text_preview_size=100, - ) - - text = convertor_service.create_text() diff --git a/src/app/convertor/service/data/__init__.py b/src/app/convertor/service/data/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/convertor/service/data/inputs/5846093734223028963.ogg b/src/app/convertor/service/data/inputs/5846093734223028963.ogg deleted file mode 100644 index 6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32303 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 diff --git a/src/app/convertor/service/data/inputs/5846093734223028963.ogx b/src/app/convertor/service/data/inputs/5846093734223028963.ogx deleted file mode 100644 index 6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32303 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 diff --git a/src/app/convertor/service/transcription.py b/src/app/convertor/service/transcription.py deleted file mode 100644 index f7ee85c..0000000 --- a/src/app/convertor/service/transcription.py +++ /dev/null @@ -1,135 +0,0 @@ -import whisper -import os - - -class Transcription: - def __init__( - self, - model_id="tiny", - input_file_name=".ogg", - show_text=False, - output_file_name="", - text_preview_size=None, - language="english", - ): - self.model_id = model_id - self.input_file_name = input_file_name # self.load_file(input_file_name) - self.show_text = show_text - self.output_file_name = output_file_name - self.text_preview_size = text_preview_size - self.language = language - - ########## Sanity checks for whisper model use ######### - self.whisper_allowed_extensions = [ - "flac", - "m4a", - "mp3", - "mp4", - "mpeg", - "mpga", - "oga", - "ogg", - "wav", - "webm", - ] - self.whisper_model_ids = ["tiny", "base", "small", "medium", "large", "turbo"] - - # The default setting (which selects the turbo model) works well for transcribing English. - # However, the turbo model is not trained for translation tasks. - # If you need to translate non-English speech into English, use one of the - # multilingual models (tiny, base, small, medium, large) instead of turbo. - - self.whisper_model_ids_english_only = [ - "tiny.en", - "base.en", - "small.en", - "medium.en", - ] - self._check_file_extension() - self._check_whisper_model_id() - - @staticmethod - def load_file(input_file_name): - if not os.path.exists(input_file_name): - raise FileNotFoundError(f"File: {input_file_name} does not exist") - return input_file_name - - def _check_file_extension(self): - ext = self.input_file_name.rsplit(".", 1)[-1].lower() - - if ext not in self.whisper_allowed_extensions: - allowed = ", ".join(self.whisper_allowed_extensions) - raise ValueError( - f"Invalid file format: .{ext}\n" f"Allowed formats are: {allowed}" - ) - return True - - def _check_whisper_model_id(self): - if self.model_id not in self.whisper_model_ids: - allowed = ", ".join(self.whisper_model_ids) - raise ValueError( - f"Invalid model ID selection: {self.model_id}\n" - f"Allowed formats are: {allowed}" - ) - return True - - def _get_model(self): - model = whisper.load_model(self.model_id) - return model - - def save_transcription(self, text, output_file_name=""): - file_name = self.output_file_name if not output_file_name else output_file_name - with open(f"{file_name}.txt", "w", encoding="utf-8") as f: - f.write(text) - - def get_transcription(self): - model = self._get_model() - print(f"Using as requested model {self.model_id}.") - print( - f"Transcribing file {self.input_file_name}... this may take a few minutes depening of the file size." - ) - # load audio and pad/trim it to fit 30 seconds - # audio = whisper.load_audio("audio.mp3") - # audio = whisper.pad_or_trim(audio) - - # detect the spoken language - # _, probs = model.detect_language(mel) - # print(f"Detected language: {max(probs, key=probs.get)}") - - result = model.transcribe(self.input_file_name, fp16=False) - - if self.show_text: - if self.text_preview_size: - print(result["text"][: self.text_preview_size]) - else: - print(result["text"]) - - if (len(self.output_file_name) > 0) or (len(self.output_file_name) > 0): - file_name = ( - self.output_file_name if not output_file_name else output_file_name - ) - self.save_transcription(result["text"], file_name) - print(f"Saved transcription as: {file_name}.") - - return result["text"] - - -if __name__ == "__main__": - - data_dir = "data" - input_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogg" - output_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogx" - - model_id = "tiny" - show_text = True - text_preview_size = 10 - - transcription_service = Transcription( - model_id=model_id, - input_file_name=input_file_name, - show_text=show_text, - output_file_name=output_file_name, - text_preview_size=text_preview_size, - ) - - transcription_service.get_transcription() diff --git a/src/app/main.py b/src/app/main.py index 0008775..4a4e19b 100755 --- a/src/app/main.py +++ b/src/app/main.py @@ -1,39 +1,13 @@ -from flask import Flask, render_template, request -from app.convertor.service.convertor_service import ConvertorService - +from convertor.routes import upload_bp +from flask import Flask, render_template app = Flask(__name__) @app.route("/") def main(): - # text = ConvertorService.create_text() - return render_template("main.html", person="enrico") - - -@app.route("/upload", methods=["POST"]) -def upload_file(): - if "file" not in request.files: - return "No file part" - - file = request.files["file"] - - if file.filename == "": - return "No selected file" - - # Instantiate service - convertor_service = ConvertorService( - model_id="tiny", - input_file_name=file.filename, # PATH to the saved file - show_text=True, - text_preview_size=100, - ) - - text = convertor_service.create_text() + return "Talk2Text" - return f"

{text}

" - # Leggi il contenuto del file in memoria - # data = file.read() # bytes - # # oppure se è un testo: file_content = file.read().decode('utf-8') - # return f"Dimensione del file: {len(data)} byte" +# Registrazione dei Blueprint +app.register_blueprint(upload_bp) diff --git a/src/app/static/css/main.css b/src/app/static/css/main.css deleted file mode 100644 index 12ffc62..0000000 --- a/src/app/static/css/main.css +++ /dev/null @@ -1,16 +0,0 @@ -body { - display: flex; - flex-flow: column wrap; - align-items: center; /* centri verticalmente */ - height: 100vh; /* altezza del viewport */ - margin: 0; /* rimuove margini default */ -} - -.card-container { - margin-top: 10vh; - justify-content: center; - width: 80%; - display: flex; - flex-direction: column; - justify-content: center; -} diff --git a/src/app/templates/main.html b/src/app/templates/main.html deleted file mode 100755 index 9dbf923..0000000 --- a/src/app/templates/main.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - Bootstrap demo - - - - - - -
-
-
-
Carica qui il tuo file
-
-
- - -
-
-
-
-
- - - - From 865e514315a057cd9992ecac591b60d7462c0dd3 Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 12 Feb 2026 18:09:06 +0100 Subject: [PATCH 02/12] project refactoring --- data/__init__.py | 0 data/inputs/5846093734223028963.ogg | Bin 0 -> 32303 bytes data/inputs/5846093734223028963.ogx | Bin 0 -> 32303 bytes src/app/convertor/convertor.py | 30 +++++++ src/app/convertor/routes.py | 7 ++ src/app/convertor/service.py | 15 ++++ src/app/convertor/transcription.py | 135 ++++++++++++++++++++++++++++ 7 files changed, 187 insertions(+) create mode 100644 data/__init__.py create mode 100644 data/inputs/5846093734223028963.ogg create mode 100644 data/inputs/5846093734223028963.ogx create mode 100644 src/app/convertor/convertor.py create mode 100644 src/app/convertor/routes.py create mode 100644 src/app/convertor/service.py create mode 100644 src/app/convertor/transcription.py diff --git a/data/__init__.py b/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/data/inputs/5846093734223028963.ogg b/data/inputs/5846093734223028963.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a GIT binary patch literal 32303 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 literal 0 HcmV?d00001 diff --git a/data/inputs/5846093734223028963.ogx b/data/inputs/5846093734223028963.ogx new file mode 100644 index 0000000000000000000000000000000000000000..6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a GIT binary patch literal 32303 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 literal 0 HcmV?d00001 diff --git a/src/app/convertor/convertor.py b/src/app/convertor/convertor.py new file mode 100644 index 0000000..39489b9 --- /dev/null +++ b/src/app/convertor/convertor.py @@ -0,0 +1,30 @@ +from app.convertor.transcription import Transcription + + +class Convertor: + def __init__(self, model_id, input_file_name, show_text, text_preview_size): + self.model_id = model_id + self.input_file_name = input_file_name + self.show_text = show_text + self.text_preview_size = text_preview_size + + def create_text(self): + transcription = Transcription( + model_id=self.model_id, + input_file_name=self.input_file_name, + show_text=self.show_text, + text_preview_size=self.text_preview_size, + ) + + return transcription.get_transcription() + + +if __name__ == "__main__": + convertor_service = ConvertorService( + model_id="tiny", + input_file_name="./src/app/convertor/service/data/inputs/5846093734223028963.ogg", + show_text=True, + text_preview_size=100, + ) + + text = convertor_service.create_text() diff --git a/src/app/convertor/routes.py b/src/app/convertor/routes.py new file mode 100644 index 0000000..0a7c307 --- /dev/null +++ b/src/app/convertor/routes.py @@ -0,0 +1,7 @@ +from flask import Blueprint + +upload_bp = Blueprint('upload-file', __name__, url_prefix='/upload') + +@upload_bp.route('/') +def file_upload(): + return "file conversion" \ No newline at end of file diff --git a/src/app/convertor/service.py b/src/app/convertor/service.py new file mode 100644 index 0000000..b620a46 --- /dev/null +++ b/src/app/convertor/service.py @@ -0,0 +1,15 @@ +class FileService: + + def __init__(self, allowed_extensions, max_size_mb): + self.allowed_extensions = allowed_extensions + self.max_size_mb = max_size_mb + + def validate(self, file): + if not file: + return False + + + return True + + def convert(self, file): + return f"{file.filename} convertito" \ No newline at end of file diff --git a/src/app/convertor/transcription.py b/src/app/convertor/transcription.py new file mode 100644 index 0000000..f7ee85c --- /dev/null +++ b/src/app/convertor/transcription.py @@ -0,0 +1,135 @@ +import whisper +import os + + +class Transcription: + def __init__( + self, + model_id="tiny", + input_file_name=".ogg", + show_text=False, + output_file_name="", + text_preview_size=None, + language="english", + ): + self.model_id = model_id + self.input_file_name = input_file_name # self.load_file(input_file_name) + self.show_text = show_text + self.output_file_name = output_file_name + self.text_preview_size = text_preview_size + self.language = language + + ########## Sanity checks for whisper model use ######### + self.whisper_allowed_extensions = [ + "flac", + "m4a", + "mp3", + "mp4", + "mpeg", + "mpga", + "oga", + "ogg", + "wav", + "webm", + ] + self.whisper_model_ids = ["tiny", "base", "small", "medium", "large", "turbo"] + + # The default setting (which selects the turbo model) works well for transcribing English. + # However, the turbo model is not trained for translation tasks. + # If you need to translate non-English speech into English, use one of the + # multilingual models (tiny, base, small, medium, large) instead of turbo. + + self.whisper_model_ids_english_only = [ + "tiny.en", + "base.en", + "small.en", + "medium.en", + ] + self._check_file_extension() + self._check_whisper_model_id() + + @staticmethod + def load_file(input_file_name): + if not os.path.exists(input_file_name): + raise FileNotFoundError(f"File: {input_file_name} does not exist") + return input_file_name + + def _check_file_extension(self): + ext = self.input_file_name.rsplit(".", 1)[-1].lower() + + if ext not in self.whisper_allowed_extensions: + allowed = ", ".join(self.whisper_allowed_extensions) + raise ValueError( + f"Invalid file format: .{ext}\n" f"Allowed formats are: {allowed}" + ) + return True + + def _check_whisper_model_id(self): + if self.model_id not in self.whisper_model_ids: + allowed = ", ".join(self.whisper_model_ids) + raise ValueError( + f"Invalid model ID selection: {self.model_id}\n" + f"Allowed formats are: {allowed}" + ) + return True + + def _get_model(self): + model = whisper.load_model(self.model_id) + return model + + def save_transcription(self, text, output_file_name=""): + file_name = self.output_file_name if not output_file_name else output_file_name + with open(f"{file_name}.txt", "w", encoding="utf-8") as f: + f.write(text) + + def get_transcription(self): + model = self._get_model() + print(f"Using as requested model {self.model_id}.") + print( + f"Transcribing file {self.input_file_name}... this may take a few minutes depening of the file size." + ) + # load audio and pad/trim it to fit 30 seconds + # audio = whisper.load_audio("audio.mp3") + # audio = whisper.pad_or_trim(audio) + + # detect the spoken language + # _, probs = model.detect_language(mel) + # print(f"Detected language: {max(probs, key=probs.get)}") + + result = model.transcribe(self.input_file_name, fp16=False) + + if self.show_text: + if self.text_preview_size: + print(result["text"][: self.text_preview_size]) + else: + print(result["text"]) + + if (len(self.output_file_name) > 0) or (len(self.output_file_name) > 0): + file_name = ( + self.output_file_name if not output_file_name else output_file_name + ) + self.save_transcription(result["text"], file_name) + print(f"Saved transcription as: {file_name}.") + + return result["text"] + + +if __name__ == "__main__": + + data_dir = "data" + input_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogg" + output_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogx" + + model_id = "tiny" + show_text = True + text_preview_size = 10 + + transcription_service = Transcription( + model_id=model_id, + input_file_name=input_file_name, + show_text=show_text, + output_file_name=output_file_name, + text_preview_size=text_preview_size, + ) + + transcription_service.get_transcription() From ce25f1e4d0fcf9c46659e5584a896f892c35bd8b Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 12 Feb 2026 23:03:40 +0100 Subject: [PATCH 03/12] created main page e convertor app --- src/app/templates/main.html | 101 ++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/app/templates/main.html diff --git a/src/app/templates/main.html b/src/app/templates/main.html new file mode 100644 index 0000000..6830687 --- /dev/null +++ b/src/app/templates/main.html @@ -0,0 +1,101 @@ + + + + + Talk2Text - API Documentation + + + + +
+

Talk2Text

+

Backend API - Speech to Text Service

+
+ +
+
+
+ POST + /upload-file +
+

+ Carica un file audio e restituisce la trascrizione testuale. +

+
+
+ +
© 2026 Talk2Text - Backend Service
+ + From b0d9f6d3953a8a0d1e889924b2a985a8689ee2ea Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 12 Feb 2026 23:03:58 +0100 Subject: [PATCH 04/12] convertor app --- pyproject.toml | 1 + src/app/convertor/convertor.py | 4 +- src/app/convertor/routes.py | 16 +- src/app/main.py | 5 +- uv.lock | 384 +++++++++++++++++++-------------- 5 files changed, 238 insertions(+), 172 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9bcafa2..360601a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ dependencies = [ "ffmpeg>=1.4", "flake8>=7.3.0", "flask>=3.1.2", + "flask-restful>=0.3.10", "openai-whisper>=20250625", "pandas>=2.3.3", "pytest==8.4.2", diff --git a/src/app/convertor/convertor.py b/src/app/convertor/convertor.py index 39489b9..318346f 100644 --- a/src/app/convertor/convertor.py +++ b/src/app/convertor/convertor.py @@ -20,11 +20,11 @@ def create_text(self): if __name__ == "__main__": - convertor_service = ConvertorService( + convertor = Convertor( model_id="tiny", input_file_name="./src/app/convertor/service/data/inputs/5846093734223028963.ogg", show_text=True, text_preview_size=100, ) - text = convertor_service.create_text() + text = convertor.create_text() diff --git a/src/app/convertor/routes.py b/src/app/convertor/routes.py index 0a7c307..e1e0b3f 100644 --- a/src/app/convertor/routes.py +++ b/src/app/convertor/routes.py @@ -1,7 +1,15 @@ from flask import Blueprint +from flask_restful import Api, Resource, request -upload_bp = Blueprint('upload-file', __name__, url_prefix='/upload') +upload_bp = Blueprint("convertor", __name__, url_prefix="/convertor") +api = Api(upload_bp) -@upload_bp.route('/') -def file_upload(): - return "file conversion" \ No newline at end of file + +class FileUploadResource(Resource): + def post(self): + file = request.files.get("file") + + return {"message": "file conversion done", "data": "file"}, 200 + + +api.add_resource(FileUploadResource, "/upload/") diff --git a/src/app/main.py b/src/app/main.py index 4a4e19b..2533414 100755 --- a/src/app/main.py +++ b/src/app/main.py @@ -1,12 +1,13 @@ -from convertor.routes import upload_bp from flask import Flask, render_template +from app.convertor.routes import upload_bp + app = Flask(__name__) @app.route("/") def main(): - return "Talk2Text" + return render_template("main.html") # Registrazione dei Blueprint diff --git a/uv.lock b/uv.lock index ca677ab..75cbd6f 100644 --- a/uv.lock +++ b/uv.lock @@ -1,14 +1,25 @@ version = 1 revision = 3 -requires-python = "==3.12" +requires-python = "==3.12.0" resolution-markers = [ - "sys_platform != 'darwin'", + "sys_platform == 'win32'", + "sys_platform == 'emscripten'", + "sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", "sys_platform == 'darwin'", ] +[[package]] +name = "aniso8601" +version = "10.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/8d/52179c4e3f1978d3d9a285f98c706642522750ef343e9738286130423730/aniso8601-10.0.1.tar.gz", hash = "sha256:25488f8663dd1528ae1f54f94ac1ea51ae25b4d531539b8bc707fed184d16845", size = 47190, upload-time = "2025-04-18T17:29:42.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/75/e0e10dc7ed1408c28e03a6cb2d7a407f99320eb953f229d008a7a6d05546/aniso8601-10.0.1-py2.py3-none-any.whl", hash = "sha256:eb19717fd4e0db6de1aab06f12450ab92144246b257423fe020af5748c0cb89e", size = 52848, upload-time = "2025-04-18T17:29:41.492Z" }, +] + [[package]] name = "black" -version = "25.11.0" +version = "26.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -18,13 +29,14 @@ dependencies = [ { name = "platformdirs" }, { name = "pytokens" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/ad/33adf4708633d047950ff2dfdea2e215d84ac50ef95aff14a614e4b6e9b2/black-25.11.0.tar.gz", hash = "sha256:9a323ac32f5dc75ce7470501b887250be5005a01602e931a15e45593f70f6e08", size = 655669, upload-time = "2025-11-10T01:53:50.558Z" } +sdist = { url = "https://files.pythonhosted.org/packages/13/88/560b11e521c522440af991d46848a2bde64b5f7202ec14e1f46f9509d328/black-26.1.0.tar.gz", hash = "sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58", size = 658785, upload-time = "2026-01-18T04:50:11.993Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/12/5c35e600b515f35ffd737da7febdb2ab66bb8c24d88560d5e3ef3d28c3fd/black-25.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:80e7486ad3535636657aa180ad32a7d67d7c273a80e12f1b4bfa0823d54e8fac", size = 1772831, upload-time = "2025-11-10T02:03:47Z" }, - { url = "https://files.pythonhosted.org/packages/1a/75/b3896bec5a2bb9ed2f989a970ea40e7062f8936f95425879bbe162746fe5/black-25.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6cced12b747c4c76bc09b4db057c319d8545307266f41aaee665540bc0e04e96", size = 1608520, upload-time = "2025-11-10T01:58:46.895Z" }, - { url = "https://files.pythonhosted.org/packages/f3/b5/2bfc18330eddbcfb5aab8d2d720663cd410f51b2ed01375f5be3751595b0/black-25.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb2d54a39e0ef021d6c5eef442e10fd71fcb491be6413d083a320ee768329dd", size = 1682719, upload-time = "2025-11-10T01:56:55.24Z" }, - { url = "https://files.pythonhosted.org/packages/96/fb/f7dc2793a22cdf74a72114b5ed77fe3349a2e09ef34565857a2f917abdf2/black-25.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae263af2f496940438e5be1a0c1020e13b09154f3af4df0835ea7f9fe7bfa409", size = 1362684, upload-time = "2025-11-10T01:57:07.639Z" }, - { url = "https://files.pythonhosted.org/packages/00/5d/aed32636ed30a6e7f9efd6ad14e2a0b0d687ae7c8c7ec4e4a557174b895c/black-25.11.0-py3-none-any.whl", hash = "sha256:e3f562da087791e96cefcd9dda058380a442ab322a02e222add53736451f604b", size = 204918, upload-time = "2025-11-10T01:53:48.917Z" }, + { url = "https://files.pythonhosted.org/packages/f5/13/710298938a61f0f54cdb4d1c0baeb672c01ff0358712eddaf29f76d32a0b/black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f", size = 1878189, upload-time = "2026-01-18T04:59:30.682Z" }, + { url = "https://files.pythonhosted.org/packages/79/a6/5179beaa57e5dbd2ec9f1c64016214057b4265647c62125aa6aeffb05392/black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6", size = 1700178, upload-time = "2026-01-18T04:59:32.387Z" }, + { url = "https://files.pythonhosted.org/packages/8c/04/c96f79d7b93e8f09d9298b333ca0d31cd9b2ee6c46c274fd0f531de9dc61/black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a", size = 1777029, upload-time = "2026-01-18T04:59:33.767Z" }, + { url = "https://files.pythonhosted.org/packages/49/f9/71c161c4c7aa18bdda3776b66ac2dc07aed62053c7c0ff8bbda8c2624fe2/black-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791", size = 1406466, upload-time = "2026-01-18T04:59:35.177Z" }, + { url = "https://files.pythonhosted.org/packages/4a/8b/a7b0f974e473b159d0ac1b6bcefffeb6bec465898a516ee5cc989503cbc7/black-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954", size = 1216393, upload-time = "2026-01-18T04:59:37.18Z" }, + { url = "https://files.pythonhosted.org/packages/e4/3d/51bdb3ecbfadfaf825ec0c75e1de6077422b4afa2091c6c9ba34fbfc0c2d/black-26.1.0-py3-none-any.whl", hash = "sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede", size = 204010, upload-time = "2026-01-18T04:50:09.978Z" }, ] [[package]] @@ -38,20 +50,36 @@ wheels = [ [[package]] name = "certifi" -version = "2022.12.7" +version = "2026.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/f7/2b1b0ec44fdc30a3d31dfebe52226be9ddc40cd6c0f34ffc8923ba423b69/certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", size = 156897, upload-time = "2022-12-07T20:13:22.081Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/4c/3db2b8021bd6f2f0ceb0e088d6b2d49147671f25832fb17970e9b583d742/certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18", size = 155255, upload-time = "2022-12-07T20:13:19.428Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, ] [[package]] name = "charset-normalizer" -version = "2.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/34/44964211e5410b051e4b8d2869c470ae8a68ae274953b1c7de6d98bbcf94/charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", size = 82360, upload-time = "2022-08-19T22:13:48.372Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/51/a507c856293ab05cdc1db77ff4bc1268ddd39f29e7dc4919aa497f0adbec/charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f", size = 39748, upload-time = "2022-08-19T22:13:46.702Z" }, +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] @@ -83,11 +111,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/f0/cc/3b7408b8ecf7c1d20 [[package]] name = "filelock" -version = "3.19.1" +version = "3.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/6b/cc63cdbff46eba1ce2fbd058e9699f99c43f7e604da15413ca0331040bff/filelock-3.21.0.tar.gz", hash = "sha256:48c739c73c6fcacd381ed532226991150947c4a76dcd674f84d6807fd55dbaf2", size = 31341, upload-time = "2026-02-12T15:40:48.544Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, + { url = "https://files.pythonhosted.org/packages/da/ab/05190b5a64101fcb743bc63a034c0fac86a515c27c303c69221093565f28/filelock-3.21.0-py3-none-any.whl", hash = "sha256:0f90eee4c62101243df3007db3cf8fc3ebf1bb13541d3e72c687d6e0f3f7d531", size = 21381, upload-time = "2026-02-12T15:40:46.964Z" }, ] [[package]] @@ -121,22 +149,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c", size = 103308, upload-time = "2025-08-19T21:03:19.499Z" }, ] +[[package]] +name = "flask-restful" +version = "0.3.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aniso8601" }, + { name = "flask" }, + { name = "pytz" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/ce/a0a133db616ea47f78a41e15c4c68b9f08cab3df31eb960f61899200a119/Flask-RESTful-0.3.10.tar.gz", hash = "sha256:fe4af2ef0027df8f9b4f797aba20c5566801b6ade995ac63b588abf1a59cec37", size = 110453, upload-time = "2023-05-21T03:58:55.781Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/7b/f0b45f0df7d2978e5ae51804bb5939b7897b2ace24306009da0cc34d8d1f/Flask_RESTful-0.3.10-py2.py3-none-any.whl", hash = "sha256:1cf93c535172f112e080b0d4503a8d15f93a48c88bdd36dd87269bdaf405051b", size = 26217, upload-time = "2023-05-21T03:58:54.004Z" }, +] + [[package]] name = "fsspec" -version = "2025.9.0" +version = "2026.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/e0/bab50af11c2d75c9c4a2a26a5254573c0bd97cea152254401510950486fa/fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19", size = 304847, upload-time = "2025-09-02T19:10:49.215Z" } +sdist = { url = "https://files.pythonhosted.org/packages/51/7c/f60c259dcbf4f0c47cc4ddb8f7720d2dcdc8888c8e5ad84c73ea4531cc5b/fsspec-2026.2.0.tar.gz", hash = "sha256:6544e34b16869f5aacd5b90bdf1a71acb37792ea3ddf6125ee69a22a53fb8bff", size = 313441, upload-time = "2026-02-05T21:50:53.743Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7", size = 199289, upload-time = "2025-09-02T19:10:47.708Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ab/fb21f4c939bb440104cc2b396d3be1d9b7a9fd3c6c2a53d98c45b3d7c954/fsspec-2026.2.0-py3-none-any.whl", hash = "sha256:98de475b5cb3bd66bedd5c4679e87b4fdfe1a3bf4d707b151b3c07e58c9a2437", size = 202505, upload-time = "2026-02-05T21:50:51.819Z" }, ] [[package]] name = "idna" -version = "3.4" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/e1/43beb3d38dba6cb420cefa297822eac205a277ab43e5ba5d5c46faf96438/idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", size = 183077, upload-time = "2022-09-14T00:24:27.719Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2", size = 61538, upload-time = "2022-09-14T00:24:23.22Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] @@ -171,33 +214,33 @@ wheels = [ [[package]] name = "llvmlite" -version = "0.45.1" +version = "0.46.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/99/8d/5baf1cef7f9c084fb35a8afbde88074f0d6a727bc63ef764fe0e7543ba40/llvmlite-0.45.1.tar.gz", hash = "sha256:09430bb9d0bb58fc45a45a57c7eae912850bedc095cd0810a57de109c69e1c32", size = 185600, upload-time = "2025-10-01T17:59:52.046Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/08ae687ba099c7e3d21fe2ea536500563ef1943c5105bf6ab4ee3829f68e/llvmlite-0.46.0.tar.gz", hash = "sha256:227c9fd6d09dce2783c18b754b7cd9d9b3b3515210c46acc2d3c5badd9870ceb", size = 193456, upload-time = "2025-12-08T18:15:36.295Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/7c/82cbd5c656e8991bcc110c69d05913be2229302a92acb96109e166ae31fb/llvmlite-0.45.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:28e763aba92fe9c72296911e040231d486447c01d4f90027c8e893d89d49b20e", size = 43043524, upload-time = "2025-10-01T18:03:30.666Z" }, - { url = "https://files.pythonhosted.org/packages/9d/bc/5314005bb2c7ee9f33102c6456c18cc81745d7055155d1218f1624463774/llvmlite-0.45.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1a53f4b74ee9fd30cb3d27d904dadece67a7575198bd80e687ee76474620735f", size = 37253123, upload-time = "2025-10-01T18:04:18.177Z" }, - { url = "https://files.pythonhosted.org/packages/96/76/0f7154952f037cb320b83e1c952ec4a19d5d689cf7d27cb8a26887d7bbc1/llvmlite-0.45.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b3796b1b1e1c14dcae34285d2f4ea488402fbd2c400ccf7137603ca3800864f", size = 56288211, upload-time = "2025-10-01T18:01:24.079Z" }, - { url = "https://files.pythonhosted.org/packages/00/b1/0b581942be2683ceb6862d558979e87387e14ad65a1e4db0e7dd671fa315/llvmlite-0.45.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:779e2f2ceefef0f4368548685f0b4adde34e5f4b457e90391f570a10b348d433", size = 55140958, upload-time = "2025-10-01T18:02:30.482Z" }, - { url = "https://files.pythonhosted.org/packages/33/94/9ba4ebcf4d541a325fd8098ddc073b663af75cc8b065b6059848f7d4dce7/llvmlite-0.45.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e6c9949baf25d9aa9cd7cf0f6d011b9ca660dd17f5ba2b23bdbdb77cc86b116", size = 38132231, upload-time = "2025-10-01T18:05:03.664Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f8/4db016a5e547d4e054ff2f3b99203d63a497465f81ab78ec8eb2ff7b2304/llvmlite-0.46.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b9588ad4c63b4f0175a3984b85494f0c927c6b001e3a246a3a7fb3920d9a137", size = 37232767, upload-time = "2025-12-08T18:15:00.737Z" }, + { url = "https://files.pythonhosted.org/packages/aa/85/4890a7c14b4fa54400945cb52ac3cd88545bbdb973c440f98ca41591cdc5/llvmlite-0.46.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3535bd2bb6a2d7ae4012681ac228e5132cdb75fefb1bcb24e33f2f3e0c865ed4", size = 56275176, upload-time = "2025-12-08T18:15:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/6a/07/3d31d39c1a1a08cd5337e78299fca77e6aebc07c059fbd0033e3edfab45c/llvmlite-0.46.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cbfd366e60ff87ea6cc62f50bc4cd800ebb13ed4c149466f50cf2163a473d1e", size = 55128630, upload-time = "2025-12-08T18:15:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/2a/6b/d139535d7590a1bba1ceb68751bef22fadaa5b815bbdf0e858e3875726b2/llvmlite-0.46.0-cp312-cp312-win_amd64.whl", hash = "sha256:398b39db462c39563a97b912d4f2866cd37cba60537975a09679b28fbbc0fb38", size = 38138940, upload-time = "2025-12-08T18:15:10.162Z" }, ] [[package]] name = "markupsafe" -version = "3.0.2" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, ] [[package]] @@ -229,56 +272,55 @@ wheels = [ [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "networkx" -version = "3.5" +version = "3.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] [[package]] name = "numba" -version = "0.62.1" +version = "0.63.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "llvmlite" }, { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/20/33dbdbfe60e5fd8e3dbfde299d106279a33d9f8308346022316781368591/numba-0.62.1.tar.gz", hash = "sha256:7b774242aa890e34c21200a1fc62e5b5757d5286267e71103257f4e2af0d5161", size = 2749817, upload-time = "2025-09-29T10:46:31.551Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/60/0145d479b2209bd8fdae5f44201eceb8ce5a23e0ed54c71f57db24618665/numba-0.63.1.tar.gz", hash = "sha256:b320aa675d0e3b17b40364935ea52a7b1c670c9037c39cf92c49502a75902f4b", size = 2761666, upload-time = "2025-12-10T02:57:39.002Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/fa/30fa6873e9f821c0ae755915a3ca444e6ff8d6a7b6860b669a3d33377ac7/numba-0.62.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:1b743b32f8fa5fff22e19c2e906db2f0a340782caf024477b97801b918cf0494", size = 2685346, upload-time = "2025-09-29T10:43:43.677Z" }, - { url = "https://files.pythonhosted.org/packages/a9/d5/504ce8dc46e0dba2790c77e6b878ee65b60fe3e7d6d0006483ef6fde5a97/numba-0.62.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90fa21b0142bcf08ad8e32a97d25d0b84b1e921bc9423f8dda07d3652860eef6", size = 2688139, upload-time = "2025-09-29T10:44:04.894Z" }, - { url = "https://files.pythonhosted.org/packages/50/5f/6a802741176c93f2ebe97ad90751894c7b0c922b52ba99a4395e79492205/numba-0.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6ef84d0ac19f1bf80431347b6f4ce3c39b7ec13f48f233a48c01e2ec06ecbc59", size = 3796453, upload-time = "2025-09-29T10:42:52.771Z" }, - { url = "https://files.pythonhosted.org/packages/7e/df/efd21527d25150c4544eccc9d0b7260a5dec4b7e98b5a581990e05a133c0/numba-0.62.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9315cc5e441300e0ca07c828a627d92a6802bcbf27c5487f31ae73783c58da53", size = 3496451, upload-time = "2025-09-29T10:43:19.279Z" }, - { url = "https://files.pythonhosted.org/packages/80/44/79bfdab12a02796bf4f1841630355c82b5a69933b1d50eb15c7fa37dabe8/numba-0.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:44e3aa6228039992f058f5ebfcfd372c83798e9464297bdad8cc79febcf7891e", size = 2745552, upload-time = "2025-09-29T10:44:26.399Z" }, + { url = "https://files.pythonhosted.org/packages/14/9c/c0974cd3d00ff70d30e8ff90522ba5fbb2bcee168a867d2321d8d0457676/numba-0.63.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2819cd52afa5d8d04e057bdfd54367575105f8829350d8fb5e4066fb7591cc71", size = 2680981, upload-time = "2025-12-10T02:57:17.579Z" }, + { url = "https://files.pythonhosted.org/packages/cb/70/ea2bc45205f206b7a24ee68a159f5097c9ca7e6466806e7c213587e0c2b1/numba-0.63.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5cfd45dbd3d409e713b1ccfdc2ee72ca82006860254429f4ef01867fdba5845f", size = 3801656, upload-time = "2025-12-10T02:57:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/0d/82/4f4ba4fd0f99825cbf3cdefd682ca3678be1702b63362011de6e5f71f831/numba-0.63.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69a599df6976c03b7ecf15d05302696f79f7e6d10d620367407517943355bcb0", size = 3501857, upload-time = "2025-12-10T02:57:20.721Z" }, + { url = "https://files.pythonhosted.org/packages/af/fd/6540456efa90b5f6604a86ff50dabefb187e43557e9081adcad3be44f048/numba-0.63.1-cp312-cp312-win_amd64.whl", hash = "sha256:bbad8c63e4fc7eb3cdb2c2da52178e180419f7969f9a685f283b313a70b92af3", size = 2750282, upload-time = "2025-12-10T02:57:22.474Z" }, ] [[package]] name = "numpy" -version = "2.3.3" +version = "2.3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/5d/bb7fc075b762c96329147799e1bcc9176ab07ca6375ea976c475482ad5b3/numpy-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cfdd09f9c84a1a934cde1eec2267f0a43a7cd44b2cca4ff95b7c0d14d144b0bf", size = 20957014, upload-time = "2025-09-09T15:56:29.966Z" }, - { url = "https://files.pythonhosted.org/packages/6b/0e/c6211bb92af26517acd52125a237a92afe9c3124c6a68d3b9f81b62a0568/numpy-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb32e3cf0f762aee47ad1ddc6672988f7f27045b0783c887190545baba73aa25", size = 14185220, upload-time = "2025-09-09T15:56:32.175Z" }, - { url = "https://files.pythonhosted.org/packages/22/f2/07bb754eb2ede9073f4054f7c0286b0d9d2e23982e090a80d478b26d35ca/numpy-2.3.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:396b254daeb0a57b1fe0ecb5e3cff6fa79a380fa97c8f7781a6d08cd429418fe", size = 5113918, upload-time = "2025-09-09T15:56:34.175Z" }, - { url = "https://files.pythonhosted.org/packages/81/0a/afa51697e9fb74642f231ea36aca80fa17c8fb89f7a82abd5174023c3960/numpy-2.3.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:067e3d7159a5d8f8a0b46ee11148fc35ca9b21f61e3c49fbd0a027450e65a33b", size = 6647922, upload-time = "2025-09-09T15:56:36.149Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f5/122d9cdb3f51c520d150fef6e87df9279e33d19a9611a87c0d2cf78a89f4/numpy-2.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c02d0629d25d426585fb2e45a66154081b9fa677bc92a881ff1d216bc9919a8", size = 14281991, upload-time = "2025-09-09T15:56:40.548Z" }, - { url = "https://files.pythonhosted.org/packages/51/64/7de3c91e821a2debf77c92962ea3fe6ac2bc45d0778c1cbe15d4fce2fd94/numpy-2.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9192da52b9745f7f0766531dcfa978b7763916f158bb63bdb8a1eca0068ab20", size = 16641643, upload-time = "2025-09-09T15:56:43.343Z" }, - { url = "https://files.pythonhosted.org/packages/30/e4/961a5fa681502cd0d68907818b69f67542695b74e3ceaa513918103b7e80/numpy-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cd7de500a5b66319db419dc3c345244404a164beae0d0937283b907d8152e6ea", size = 16056787, upload-time = "2025-09-09T15:56:46.141Z" }, - { url = "https://files.pythonhosted.org/packages/99/26/92c912b966e47fbbdf2ad556cb17e3a3088e2e1292b9833be1dfa5361a1a/numpy-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93d4962d8f82af58f0b2eb85daaf1b3ca23fe0a85d0be8f1f2b7bb46034e56d7", size = 18579598, upload-time = "2025-09-09T15:56:49.844Z" }, - { url = "https://files.pythonhosted.org/packages/17/b6/fc8f82cb3520768718834f310c37d96380d9dc61bfdaf05fe5c0b7653e01/numpy-2.3.3-cp312-cp312-win32.whl", hash = "sha256:5534ed6b92f9b7dca6c0a19d6df12d41c68b991cef051d108f6dbff3babc4ebf", size = 6320800, upload-time = "2025-09-09T15:56:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/32/ee/de999f2625b80d043d6d2d628c07d0d5555a677a3cf78fdf868d409b8766/numpy-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:497d7cad08e7092dba36e3d296fe4c97708c93daf26643a1ae4b03f6294d30eb", size = 12786615, upload-time = "2025-09-09T15:56:54.422Z" }, - { url = "https://files.pythonhosted.org/packages/49/6e/b479032f8a43559c383acb20816644f5f91c88f633d9271ee84f3b3a996c/numpy-2.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:ca0309a18d4dfea6fc6262a66d06c26cfe4640c3926ceec90e57791a82b6eee5", size = 10195936, upload-time = "2025-09-09T15:56:56.541Z" }, + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, ] [[package]] @@ -290,8 +332,8 @@ dependencies = [ { name = "numba" }, { name = "numpy" }, { name = "tiktoken" }, - { name = "torch", version = "2.9.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, + { name = "torch", version = "2.10.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, + { name = "torch", version = "2.10.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, { name = "tqdm" }, { name = "triton", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'linux2'" }, ] @@ -299,50 +341,50 @@ sdist = { url = "https://files.pythonhosted.org/packages/35/8e/d36f8880bcf18ec02 [[package]] name = "packaging" -version = "24.1" +version = "26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload-time = "2024-06-09T23:19:24.956Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload-time = "2024-06-09T23:19:21.909Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] [[package]] name = "pandas" -version = "2.3.3" +version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, - { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, - { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, - { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, - { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, - { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/0b/38/db33686f4b5fa64d7af40d96361f6a4615b8c6c8f1b3d334eee46ae6160e/pandas-3.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9803b31f5039b3c3b10cc858c5e40054adb4b29b4d81cb2fd789f4121c8efbcd", size = 10334013, upload-time = "2026-01-21T15:50:34.771Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7b/9254310594e9774906bacdd4e732415e1f86ab7dbb4b377ef9ede58cd8ec/pandas-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14c2a4099cd38a1d18ff108168ea417909b2dea3bd1ebff2ccf28ddb6a74d740", size = 9874154, upload-time = "2026-01-21T15:50:36.67Z" }, + { url = "https://files.pythonhosted.org/packages/63/d4/726c5a67a13bc66643e66d2e9ff115cead482a44fc56991d0c4014f15aaf/pandas-3.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d257699b9a9960e6125686098d5714ac59d05222bef7a5e6af7a7fd87c650801", size = 10384433, upload-time = "2026-01-21T15:50:39.132Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/9211f09bedb04f9832122942de8b051804b31a39cfbad199a819bb88d9f3/pandas-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:69780c98f286076dcafca38d8b8eee1676adf220199c0a39f0ecbf976b68151a", size = 10864519, upload-time = "2026-01-21T15:50:41.043Z" }, + { url = "https://files.pythonhosted.org/packages/00/8d/50858522cdc46ac88b9afdc3015e298959a70a08cd21e008a44e9520180c/pandas-3.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4a66384f017240f3858a4c8a7cf21b0591c3ac885cddb7758a589f0f71e87ebb", size = 11394124, upload-time = "2026-01-21T15:50:43.377Z" }, + { url = "https://files.pythonhosted.org/packages/86/3f/83b2577db02503cd93d8e95b0f794ad9d4be0ba7cb6c8bcdcac964a34a42/pandas-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be8c515c9bc33989d97b89db66ea0cececb0f6e3c2a87fcc8b69443a6923e95f", size = 11920444, upload-time = "2026-01-21T15:50:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/64/2d/4f8a2f192ed12c90a0aab47f5557ece0e56b0370c49de9454a09de7381b2/pandas-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a453aad8c4f4e9f166436994a33884442ea62aa8b27d007311e87521b97246e1", size = 9730970, upload-time = "2026-01-21T15:50:47.962Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/ff571be435cf1e643ca98d0945d76732c0b4e9c37191a89c8550b105eed1/pandas-3.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:da768007b5a33057f6d9053563d6b74dd6d029c337d93c6d0d22a763a5c2ecc0", size = 9041950, upload-time = "2026-01-21T15:50:50.422Z" }, ] [[package]] name = "pathspec" -version = "0.12.1" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] [[package]] name = "platformdirs" -version = "4.5.0" +version = "4.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/474d0a8508029286b905622e6929470fb84337cfa08f9d09fbb624515249/platformdirs-4.6.0.tar.gz", hash = "sha256:4a13c2db1071e5846c3b3e04e5b095c0de36b2a24be9a3bc0145ca66fce4e328", size = 23433, upload-time = "2026-02-12T14:36:21.288Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, + { url = "https://files.pythonhosted.org/packages/da/10/1b0dcf51427326f70e50d98df21b18c228117a743a1fc515a42f8dc7d342/platformdirs-4.6.0-py3-none-any.whl", hash = "sha256:dd7f808d828e1764a22ebff09e60f175ee3c41876606a6132a688d809c7c9c73", size = 19549, upload-time = "2026-02-12T14:36:19.743Z" }, ] [[package]] @@ -411,11 +453,16 @@ wheels = [ [[package]] name = "pytokens" -version = "0.3.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4e/8d/a762be14dae1c3bf280202ba3172020b2b0b4c537f94427435f19c413b72/pytokens-0.3.0.tar.gz", hash = "sha256:2f932b14ed08de5fcf0b391ace2642f858f1394c0857202959000b68ed7a458a", size = 17644, upload-time = "2025-11-05T13:36:35.34Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/25/d9db8be44e205a124f6c98bc0324b2bb149b7431c53877fc6d1038dddaf5/pytokens-0.3.0-py3-none-any.whl", hash = "sha256:95b2b5eaf832e469d141a378872480ede3f251a5a5041b8ec6e581d3ac71bbf3", size = 12195, upload-time = "2025-11-05T13:36:33.183Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, + { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, ] [[package]] @@ -429,29 +476,31 @@ wheels = [ [[package]] name = "regex" -version = "2025.11.3" +version = "2026.1.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/86/07d5056945f9ec4590b518171c4254a5925832eb727b56d3c38a7476f316/regex-2026.1.15.tar.gz", hash = "sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5", size = 414811, upload-time = "2026-01-14T23:18:02.775Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/74/18f04cb53e58e3fb107439699bd8375cf5a835eec81084e0bddbd122e4c2/regex-2025.11.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41", size = 489312, upload-time = "2025-11-03T21:31:34.343Z" }, - { url = "https://files.pythonhosted.org/packages/78/3f/37fcdd0d2b1e78909108a876580485ea37c91e1acf66d3bb8e736348f441/regex-2025.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36", size = 291256, upload-time = "2025-11-03T21:31:35.675Z" }, - { url = "https://files.pythonhosted.org/packages/bf/26/0a575f58eb23b7ebd67a45fccbc02ac030b737b896b7e7a909ffe43ffd6a/regex-2025.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1", size = 288921, upload-time = "2025-11-03T21:31:37.07Z" }, - { url = "https://files.pythonhosted.org/packages/ea/98/6a8dff667d1af907150432cf5abc05a17ccd32c72a3615410d5365ac167a/regex-2025.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7", size = 798568, upload-time = "2025-11-03T21:31:38.784Z" }, - { url = "https://files.pythonhosted.org/packages/64/15/92c1db4fa4e12733dd5a526c2dd2b6edcbfe13257e135fc0f6c57f34c173/regex-2025.11.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69", size = 864165, upload-time = "2025-11-03T21:31:40.559Z" }, - { url = "https://files.pythonhosted.org/packages/f9/e7/3ad7da8cdee1ce66c7cd37ab5ab05c463a86ffeb52b1a25fe7bd9293b36c/regex-2025.11.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48", size = 912182, upload-time = "2025-11-03T21:31:42.002Z" }, - { url = "https://files.pythonhosted.org/packages/84/bd/9ce9f629fcb714ffc2c3faf62b6766ecb7a585e1e885eb699bcf130a5209/regex-2025.11.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c", size = 803501, upload-time = "2025-11-03T21:31:43.815Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0f/8dc2e4349d8e877283e6edd6c12bdcebc20f03744e86f197ab6e4492bf08/regex-2025.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695", size = 787842, upload-time = "2025-11-03T21:31:45.353Z" }, - { url = "https://files.pythonhosted.org/packages/f9/73/cff02702960bc185164d5619c0c62a2f598a6abff6695d391b096237d4ab/regex-2025.11.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98", size = 858519, upload-time = "2025-11-03T21:31:46.814Z" }, - { url = "https://files.pythonhosted.org/packages/61/83/0e8d1ae71e15bc1dc36231c90b46ee35f9d52fab2e226b0e039e7ea9c10a/regex-2025.11.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74", size = 850611, upload-time = "2025-11-03T21:31:48.289Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f5/70a5cdd781dcfaa12556f2955bf170cd603cb1c96a1827479f8faea2df97/regex-2025.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0", size = 789759, upload-time = "2025-11-03T21:31:49.759Z" }, - { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, - { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, - { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, + { url = "https://files.pythonhosted.org/packages/92/81/10d8cf43c807d0326efe874c1b79f22bfb0fb226027b0b19ebc26d301408/regex-2026.1.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1", size = 489398, upload-time = "2026-01-14T23:14:43.741Z" }, + { url = "https://files.pythonhosted.org/packages/90/b0/7c2a74e74ef2a7c32de724658a69a862880e3e4155cba992ba04d1c70400/regex-2026.1.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681", size = 291339, upload-time = "2026-01-14T23:14:45.183Z" }, + { url = "https://files.pythonhosted.org/packages/19/4d/16d0773d0c818417f4cc20aa0da90064b966d22cd62a8c46765b5bd2d643/regex-2026.1.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f", size = 289003, upload-time = "2026-01-14T23:14:47.25Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e4/1fc4599450c9f0863d9406e944592d968b8d6dfd0d552a7d569e43bceada/regex-2026.1.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa", size = 798656, upload-time = "2026-01-14T23:14:48.77Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e6/59650d73a73fa8a60b3a590545bfcf1172b4384a7df2e7fe7b9aab4e2da9/regex-2026.1.15-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804", size = 864252, upload-time = "2026-01-14T23:14:50.528Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ab/1d0f4d50a1638849a97d731364c9a80fa304fec46325e48330c170ee8e80/regex-2026.1.15-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c", size = 912268, upload-time = "2026-01-14T23:14:52.952Z" }, + { url = "https://files.pythonhosted.org/packages/dd/df/0d722c030c82faa1d331d1921ee268a4e8fb55ca8b9042c9341c352f17fa/regex-2026.1.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5", size = 803589, upload-time = "2026-01-14T23:14:55.182Z" }, + { url = "https://files.pythonhosted.org/packages/66/23/33289beba7ccb8b805c6610a8913d0131f834928afc555b241caabd422a9/regex-2026.1.15-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3", size = 775700, upload-time = "2026-01-14T23:14:56.707Z" }, + { url = "https://files.pythonhosted.org/packages/e7/65/bf3a42fa6897a0d3afa81acb25c42f4b71c274f698ceabd75523259f6688/regex-2026.1.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb", size = 787928, upload-time = "2026-01-14T23:14:58.312Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f5/13bf65864fc314f68cdd6d8ca94adcab064d4d39dbd0b10fef29a9da48fc/regex-2026.1.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410", size = 858607, upload-time = "2026-01-14T23:15:00.657Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/040e589834d7a439ee43fb0e1e902bc81bd58a5ba81acffe586bb3321d35/regex-2026.1.15-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4", size = 763729, upload-time = "2026-01-14T23:15:02.248Z" }, + { url = "https://files.pythonhosted.org/packages/9b/84/6921e8129687a427edf25a34a5594b588b6d88f491320b9de5b6339a4fcb/regex-2026.1.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d", size = 850697, upload-time = "2026-01-14T23:15:03.878Z" }, + { url = "https://files.pythonhosted.org/packages/8a/87/3d06143d4b128f4229158f2de5de6c8f2485170c7221e61bf381313314b2/regex-2026.1.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22", size = 789849, upload-time = "2026-01-14T23:15:06.102Z" }, + { url = "https://files.pythonhosted.org/packages/77/69/c50a63842b6bd48850ebc7ab22d46e7a2a32d824ad6c605b218441814639/regex-2026.1.15-cp312-cp312-win32.whl", hash = "sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913", size = 266279, upload-time = "2026-01-14T23:15:07.678Z" }, + { url = "https://files.pythonhosted.org/packages/f2/36/39d0b29d087e2b11fd8191e15e81cce1b635fcc845297c67f11d0d19274d/regex-2026.1.15-cp312-cp312-win_amd64.whl", hash = "sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a", size = 277166, upload-time = "2026-01-14T23:15:09.257Z" }, + { url = "https://files.pythonhosted.org/packages/28/32/5b8e476a12262748851fa8ab1b0be540360692325975b094e594dfebbb52/regex-2026.1.15-cp312-cp312-win_arm64.whl", hash = "sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056", size = 270415, upload-time = "2026-01-14T23:15:10.743Z" }, ] [[package]] name = "requests" -version = "2.28.1" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -459,44 +508,43 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a5/61/a867851fd5ab77277495a8709ddda0861b28163c4613b011bc00228cc724/requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", size = 109805, upload-time = "2022-06-29T15:13:42.715Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/91/6d9b8ccacd0412c08820f72cebaa4f0c0441b5cda699c90f618b6f8a1b42/requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349", size = 62843, upload-time = "2022-06-29T15:13:40.685Z" }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] name = "ruff" -version = "0.14.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/f0/62b5a1a723fe183650109407fa56abb433b00aa1c0b9ba555f9c4efec2c6/ruff-0.14.6.tar.gz", hash = "sha256:6f0c742ca6a7783a736b867a263b9a7a80a45ce9bee391eeda296895f1b4e1cc", size = 5669501, upload-time = "2025-11-21T14:26:17.903Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/d2/7dd544116d107fffb24a0064d41a5d2ed1c9d6372d142f9ba108c8e39207/ruff-0.14.6-py3-none-linux_armv6l.whl", hash = "sha256:d724ac2f1c240dbd01a2ae98db5d1d9a5e1d9e96eba999d1c48e30062df578a3", size = 13326119, upload-time = "2025-11-21T14:25:24.2Z" }, - { url = "https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004", size = 13526007, upload-time = "2025-11-21T14:25:26.906Z" }, - { url = "https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332", size = 12676572, upload-time = "2025-11-21T14:25:29.826Z" }, - { url = "https://files.pythonhosted.org/packages/76/a4/f319e87759949062cfee1b26245048e92e2acce900ad3a909285f9db1859/ruff-0.14.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a8e7b9d73d8728b68f632aa8e824ef041d068d231d8dbc7808532d3629a6bef", size = 13140745, upload-time = "2025-11-21T14:25:32.788Z" }, - { url = "https://files.pythonhosted.org/packages/95/d3/248c1efc71a0a8ed4e8e10b4b2266845d7dfc7a0ab64354afe049eaa1310/ruff-0.14.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d50d45d4553a3ebcbd33e7c5e0fe6ca4aafd9a9122492de357205c2c48f00775", size = 13076486, upload-time = "2025-11-21T14:25:35.601Z" }, - { url = "https://files.pythonhosted.org/packages/a5/19/b68d4563fe50eba4b8c92aa842149bb56dd24d198389c0ed12e7faff4f7d/ruff-0.14.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:118548dd121f8a21bfa8ab2c5b80e5b4aed67ead4b7567790962554f38e598ce", size = 13727563, upload-time = "2025-11-21T14:25:38.514Z" }, - { url = "https://files.pythonhosted.org/packages/47/ac/943169436832d4b0e867235abbdb57ce3a82367b47e0280fa7b4eabb7593/ruff-0.14.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57256efafbfefcb8748df9d1d766062f62b20150691021f8ab79e2d919f7c11f", size = 15199755, upload-time = "2025-11-21T14:25:41.516Z" }, - { url = "https://files.pythonhosted.org/packages/c9/b9/288bb2399860a36d4bb0541cb66cce3c0f4156aaff009dc8499be0c24bf2/ruff-0.14.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff18134841e5c68f8e5df1999a64429a02d5549036b394fafbe410f886e1989d", size = 14850608, upload-time = "2025-11-21T14:25:44.428Z" }, - { url = "https://files.pythonhosted.org/packages/ee/b1/a0d549dd4364e240f37e7d2907e97ee80587480d98c7799d2d8dc7a2f605/ruff-0.14.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c4b7ec1e66a105d5c27bd57fa93203637d66a26d10ca9809dc7fc18ec58440", size = 14118754, upload-time = "2025-11-21T14:25:47.214Z" }, - { url = "https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105", size = 13949214, upload-time = "2025-11-21T14:25:50.002Z" }, - { url = "https://files.pythonhosted.org/packages/12/27/4dad6c6a77fede9560b7df6802b1b697e97e49ceabe1f12baf3ea20862e9/ruff-0.14.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:16a33af621c9c523b1ae006b1b99b159bf5ac7e4b1f20b85b2572455018e0821", size = 14106112, upload-time = "2025-11-21T14:25:52.841Z" }, - { url = "https://files.pythonhosted.org/packages/6a/db/23e322d7177873eaedea59a7932ca5084ec5b7e20cb30f341ab594130a71/ruff-0.14.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1432ab6e1ae2dc565a7eea707d3b03a0c234ef401482a6f1621bc1f427c2ff55", size = 13035010, upload-time = "2025-11-21T14:25:55.536Z" }, - { url = "https://files.pythonhosted.org/packages/a8/9c/20e21d4d69dbb35e6a1df7691e02f363423658a20a2afacf2a2c011800dc/ruff-0.14.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c55cfbbe7abb61eb914bfd20683d14cdfb38a6d56c6c66efa55ec6570ee4e71", size = 13054082, upload-time = "2025-11-21T14:25:58.625Z" }, - { url = "https://files.pythonhosted.org/packages/66/25/906ee6a0464c3125c8d673c589771a974965c2be1a1e28b5c3b96cb6ef88/ruff-0.14.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:efea3c0f21901a685fff4befda6d61a1bf4cb43de16da87e8226a281d614350b", size = 13303354, upload-time = "2025-11-21T14:26:01.816Z" }, - { url = "https://files.pythonhosted.org/packages/4c/58/60577569e198d56922b7ead07b465f559002b7b11d53f40937e95067ca1c/ruff-0.14.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:344d97172576d75dc6afc0e9243376dbe1668559c72de1864439c4fc95f78185", size = 14054487, upload-time = "2025-11-21T14:26:05.058Z" }, - { url = "https://files.pythonhosted.org/packages/67/0b/8e4e0639e4cc12547f41cb771b0b44ec8225b6b6a93393176d75fe6f7d40/ruff-0.14.6-py3-none-win32.whl", hash = "sha256:00169c0c8b85396516fdd9ce3446c7ca20c2a8f90a77aa945ba6b8f2bfe99e85", size = 13013361, upload-time = "2025-11-21T14:26:08.152Z" }, - { url = "https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl", hash = "sha256:390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9", size = 14432087, upload-time = "2025-11-21T14:26:10.891Z" }, - { url = "https://files.pythonhosted.org/packages/a5/1f/93f9b0fad9470e4c829a5bb678da4012f0c710d09331b860ee555216f4ea/ruff-0.14.6-py3-none-win_arm64.whl", hash = "sha256:d43c81fbeae52cfa8728d8766bbf46ee4298c888072105815b392da70ca836b2", size = 13520930, upload-time = "2025-11-21T14:26:13.951Z" }, +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c8/39/5cee96809fbca590abea6b46c6d1c586b49663d1d2830a751cc8fc42c666/ruff-0.15.0.tar.gz", hash = "sha256:6bdea47cdbea30d40f8f8d7d69c0854ba7c15420ec75a26f463290949d7f7e9a", size = 4524893, upload-time = "2026-02-03T17:53:35.357Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/88/3fd1b0aa4b6330d6aaa63a285bc96c9f71970351579152d231ed90914586/ruff-0.15.0-py3-none-linux_armv6l.whl", hash = "sha256:aac4ebaa612a82b23d45964586f24ae9bc23ca101919f5590bdb368d74ad5455", size = 10354332, upload-time = "2026-02-03T17:52:54.892Z" }, + { url = "https://files.pythonhosted.org/packages/72/f6/62e173fbb7eb75cc29fe2576a1e20f0a46f671a2587b5f604bfb0eaf5f6f/ruff-0.15.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dcd4be7cc75cfbbca24a98d04d0b9b36a270d0833241f776b788d59f4142b14d", size = 10767189, upload-time = "2026-02-03T17:53:19.778Z" }, + { url = "https://files.pythonhosted.org/packages/99/e4/968ae17b676d1d2ff101d56dc69cf333e3a4c985e1ec23803df84fc7bf9e/ruff-0.15.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d747e3319b2bce179c7c1eaad3d884dc0a199b5f4d5187620530adf9105268ce", size = 10075384, upload-time = "2026-02-03T17:53:29.241Z" }, + { url = "https://files.pythonhosted.org/packages/a2/bf/9843c6044ab9e20af879c751487e61333ca79a2c8c3058b15722386b8cae/ruff-0.15.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:650bd9c56ae03102c51a5e4b554d74d825ff3abe4db22b90fd32d816c2e90621", size = 10481363, upload-time = "2026-02-03T17:52:43.332Z" }, + { url = "https://files.pythonhosted.org/packages/55/d9/4ada5ccf4cd1f532db1c8d44b6f664f2208d3d93acbeec18f82315e15193/ruff-0.15.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6664b7eac559e3048223a2da77769c2f92b43a6dfd4720cef42654299a599c9", size = 10187736, upload-time = "2026-02-03T17:53:00.522Z" }, + { url = "https://files.pythonhosted.org/packages/86/e2/f25eaecd446af7bb132af0a1d5b135a62971a41f5366ff41d06d25e77a91/ruff-0.15.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f811f97b0f092b35320d1556f3353bf238763420ade5d9e62ebd2b73f2ff179", size = 10968415, upload-time = "2026-02-03T17:53:15.705Z" }, + { url = "https://files.pythonhosted.org/packages/e7/dc/f06a8558d06333bf79b497d29a50c3a673d9251214e0d7ec78f90b30aa79/ruff-0.15.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:761ec0a66680fab6454236635a39abaf14198818c8cdf691e036f4bc0f406b2d", size = 11809643, upload-time = "2026-02-03T17:53:23.031Z" }, + { url = "https://files.pythonhosted.org/packages/dd/45/0ece8db2c474ad7df13af3a6d50f76e22a09d078af63078f005057ca59eb/ruff-0.15.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:940f11c2604d317e797b289f4f9f3fa5555ffe4fb574b55ed006c3d9b6f0eb78", size = 11234787, upload-time = "2026-02-03T17:52:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/8a/d9/0e3a81467a120fd265658d127db648e4d3acfe3e4f6f5d4ea79fac47e587/ruff-0.15.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcbca3d40558789126da91d7ef9a7c87772ee107033db7191edefa34e2c7f1b4", size = 11112797, upload-time = "2026-02-03T17:52:49.274Z" }, + { url = "https://files.pythonhosted.org/packages/b2/cb/8c0b3b0c692683f8ff31351dfb6241047fa873a4481a76df4335a8bff716/ruff-0.15.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9a121a96db1d75fa3eb39c4539e607f628920dd72ff1f7c5ee4f1b768ac62d6e", size = 11033133, upload-time = "2026-02-03T17:53:33.105Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5e/23b87370cf0f9081a8c89a753e69a4e8778805b8802ccfe175cc410e50b9/ruff-0.15.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5298d518e493061f2eabd4abd067c7e4fb89e2f63291c94332e35631c07c3662", size = 10442646, upload-time = "2026-02-03T17:53:06.278Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9a/3c94de5ce642830167e6d00b5c75aacd73e6347b4c7fc6828699b150a5ee/ruff-0.15.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:afb6e603d6375ff0d6b0cee563fa21ab570fd15e65c852cb24922cef25050cf1", size = 10195750, upload-time = "2026-02-03T17:53:26.084Z" }, + { url = "https://files.pythonhosted.org/packages/30/15/e396325080d600b436acc970848d69df9c13977942fb62bb8722d729bee8/ruff-0.15.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77e515f6b15f828b94dc17d2b4ace334c9ddb7d9468c54b2f9ed2b9c1593ef16", size = 10676120, upload-time = "2026-02-03T17:53:09.363Z" }, + { url = "https://files.pythonhosted.org/packages/8d/c9/229a23d52a2983de1ad0fb0ee37d36e0257e6f28bfd6b498ee2c76361874/ruff-0.15.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6f6e80850a01eb13b3e42ee0ebdf6e4497151b48c35051aab51c101266d187a3", size = 11201636, upload-time = "2026-02-03T17:52:57.281Z" }, + { url = "https://files.pythonhosted.org/packages/6f/b0/69adf22f4e24f3677208adb715c578266842e6e6a3cc77483f48dd999ede/ruff-0.15.0-py3-none-win32.whl", hash = "sha256:238a717ef803e501b6d51e0bdd0d2c6e8513fe9eec14002445134d3907cd46c3", size = 10465945, upload-time = "2026-02-03T17:53:12.591Z" }, + { url = "https://files.pythonhosted.org/packages/51/ad/f813b6e2c97e9b4598be25e94a9147b9af7e60523b0cb5d94d307c15229d/ruff-0.15.0-py3-none-win_amd64.whl", hash = "sha256:dd5e4d3301dc01de614da3cdffc33d4b1b96fb89e45721f1598e5532ccf78b18", size = 11564657, upload-time = "2026-02-03T17:52:51.893Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b0/2d823f6e77ebe560f4e397d078487e8d52c1516b331e3521bc75db4272ca/ruff-0.15.0-py3-none-win_arm64.whl", hash = "sha256:c480d632cc0ca3f0727acac8b7d053542d9e114a462a145d0b00e7cd658c515a", size = 10865753, upload-time = "2026-02-03T17:53:03.014Z" }, ] [[package]] name = "setuptools" -version = "70.2.0" +version = "82.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8d/e6/2fc95aec377988ff3ca882aa58d4f6ab35ff59a12b1611a9fe3075eb3019/setuptools-70.2.0.tar.gz", hash = "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1", size = 2332711, upload-time = "2024-07-01T16:32:41.666Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/f3/748f4d6f65d1756b9ae577f329c951cda23fb900e4de9f70900ced962085/setuptools-82.0.0.tar.gz", hash = "sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb", size = 1144893, upload-time = "2026-02-08T15:08:40.206Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/54/2a8ecfcc9a714a6fbf86559a4b0f50b126a4ac4269ea8134f2c75c3e73de/setuptools-70.2.0-py3-none-any.whl", hash = "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05", size = 930834, upload-time = "2024-07-01T16:32:34.354Z" }, + { url = "https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl", hash = "sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0", size = 1003468, upload-time = "2026-02-08T15:08:38.723Z" }, ] [[package]] @@ -517,12 +565,13 @@ dependencies = [ { name = "ffmpeg" }, { name = "flake8" }, { name = "flask" }, + { name = "flask-restful" }, { name = "openai-whisper" }, { name = "pandas" }, { name = "pytest" }, { name = "ruff" }, - { name = "torch", version = "2.9.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, + { name = "torch", version = "2.10.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, + { name = "torch", version = "2.10.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, ] [package.metadata] @@ -531,6 +580,7 @@ requires-dist = [ { name = "ffmpeg", specifier = ">=1.4" }, { name = "flake8", specifier = ">=7.3.0" }, { name = "flask", specifier = ">=3.1.2" }, + { name = "flask-restful", specifier = ">=0.3.10" }, { name = "openai-whisper", specifier = ">=20250625" }, { name = "pandas", specifier = ">=2.3.3" }, { name = "pytest", specifier = "==8.4.2" }, @@ -571,7 +621,7 @@ wheels = [ [[package]] name = "torch" -version = "2.9.1" +version = "2.10.0" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ "sys_platform == 'darwin'", @@ -586,15 +636,19 @@ dependencies = [ { name = "typing-extensions", marker = "sys_platform == 'darwin'" }, ] wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1-cp312-none-macosx_11_0_arm64.whl" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0-1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:7fbbf409143a4fe0812a40c0b46a436030a7e1d14fe8c5234dfbe44df47f617e" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0-2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:358bd7125cbec6e692d60618a5eec7f55a51b29e3652a849fd42af021d818023" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:45a1c5057629444aeb1c452c18298fa7f30f2f7aeadd4dc41f9d340980294407" }, ] [[package]] name = "torch" -version = "2.9.1+cpu" +version = "2.10.0+cpu" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ - "sys_platform != 'darwin'", + "sys_platform == 'win32'", + "sys_platform == 'emscripten'", + "sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "filelock", marker = "sys_platform != 'darwin'" }, @@ -606,30 +660,32 @@ dependencies = [ { name = "typing-extensions", marker = "sys_platform != 'darwin'" }, ] wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp312-cp312-manylinux_2_28_aarch64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp312-cp312-win_amd64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp312-cp312-win_arm64.whl" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-linux_aarch64.whl", hash = "sha256:8de5a36371b775e2d4881ed12cc7f2de400b1ad3d728aa74a281f649f87c9b8c" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-linux_s390x.whl", hash = "sha256:9accc30b56cb6756d4a9d04fcb8ebc0bb68c7d55c1ed31a8657397d316d31596" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:179451716487f8cb09b56459667fa1f5c4c0946c1e75fbeae77cfc40a5768d87" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ee40b8a4b4b2cf0670c6fd4f35a7ef23871af956fecb238fbf5da15a72650b1d" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-win_amd64.whl", hash = "sha256:21cb5436978ef47c823b7a813ff0f8c2892e266cfe0f1d944879b5fba81bf4e1" }, + { url = "https://download.pytorch.org/whl/cpu/torch-2.10.0%2Bcpu-cp312-cp312-win_arm64.whl", hash = "sha256:3eaa727e6a73affa61564d86b9d03191df45c8650d0666bd3d57c8597ef61e78" }, ] [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/83/6ba9844a41128c62e810fddddd72473201f3eacde02046066142a2d96cc5/tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad", size = 169504, upload-time = "2024-08-03T22:35:40.339Z" } +sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/5d/acf5905c36149bbaec41ccf7f2b68814647347b72075ac0b1fe3022fdc73/tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd", size = 78351, upload-time = "2024-08-03T22:35:36.644Z" }, + { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, ] [[package]] name = "triton" -version = "3.5.1" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/50/9a8358d3ef58162c0a415d173cfb45b67de60176e1024f71fbc4d24c0b6d/triton-3.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d2c6b915a03888ab931a9fd3e55ba36785e1fe70cbea0b40c6ef93b20fc85232", size = 170470207, upload-time = "2025-11-11T17:41:00.253Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a8/cdf8b3e4c98132f965f88c2313a4b493266832ad47fb52f23d14d4f86bb5/triton-3.6.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74caf5e34b66d9f3a429af689c1c7128daba1d8208df60e81106b115c00d6fca", size = 188266850, upload-time = "2026-01-20T16:00:43.041Z" }, ] [[package]] @@ -643,30 +699,30 @@ wheels = [ [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, ] [[package]] name = "urllib3" -version = "1.26.13" +version = "2.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c2/51/32da03cf19d17d46cce5c731967bf58de9bd71db3a379932f53b094deda4/urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8", size = 300476, upload-time = "2022-11-23T22:34:32.145Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/0c/cc6644eaa594585e5875f46f3c83ee8762b647b51fc5b0fb253a242df2dc/urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", size = 140572, upload-time = "2022-11-23T22:34:29.785Z" }, + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] [[package]] name = "werkzeug" -version = "3.1.3" +version = "3.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925, upload-time = "2024-11-08T15:52:18.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/70/1469ef1d3542ae7c2c7b72bd5e3a4e6ee69d7978fa8a3af05a38eca5becf/werkzeug-3.1.5.tar.gz", hash = "sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67", size = 864754, upload-time = "2026-01-08T17:49:23.247Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498, upload-time = "2024-11-08T15:52:16.132Z" }, + { url = "https://files.pythonhosted.org/packages/ad/e4/8d97cca767bcc1be76d16fb76951608305561c6e056811587f36cb1316a8/werkzeug-3.1.5-py3-none-any.whl", hash = "sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc", size = 225025, upload-time = "2026-01-08T17:49:21.859Z" }, ] From a423ae620d3308c3d7124d42907d122a51d0c81f Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 12 Feb 2026 23:20:01 +0100 Subject: [PATCH 05/12] fix validation --- src/app/convertor/routes.py | 7 ++++--- src/app/convertor/service.py | 9 +++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/app/convertor/routes.py b/src/app/convertor/routes.py index e1e0b3f..d741e7d 100644 --- a/src/app/convertor/routes.py +++ b/src/app/convertor/routes.py @@ -1,15 +1,16 @@ from flask import Blueprint from flask_restful import Api, Resource, request +from app.convertor.service import FileService + upload_bp = Blueprint("convertor", __name__, url_prefix="/convertor") api = Api(upload_bp) class FileUploadResource(Resource): def post(self): - file = request.files.get("file") - - return {"message": "file conversion done", "data": "file"}, 200 + file = FileService("mp3", 1000) + return file.convert(request.files.get("file")) api.add_resource(FileUploadResource, "/upload/") diff --git a/src/app/convertor/service.py b/src/app/convertor/service.py index b620a46..2c05fce 100644 --- a/src/app/convertor/service.py +++ b/src/app/convertor/service.py @@ -1,15 +1,12 @@ class FileService: - def __init__(self, allowed_extensions, max_size_mb): self.allowed_extensions = allowed_extensions self.max_size_mb = max_size_mb def validate(self, file): if not file: - return False - - - return True + return {"error": "Missing file"}, 400 def convert(self, file): - return f"{file.filename} convertito" \ No newline at end of file + self.validate(file) + return f"{file} converted" From b3ba209fc15248ada0b098440d76f46600e48c91 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:02:36 +0100 Subject: [PATCH 06/12] upgrade transcription --- src/app/convertor/convertor.py | 30 ------- src/app/convertor/routes.py | 5 +- src/app/convertor/service.py | 51 ++++++++++- src/app/convertor/transcription.py | 138 ++++++++--------------------- 4 files changed, 88 insertions(+), 136 deletions(-) delete mode 100644 src/app/convertor/convertor.py diff --git a/src/app/convertor/convertor.py b/src/app/convertor/convertor.py deleted file mode 100644 index 318346f..0000000 --- a/src/app/convertor/convertor.py +++ /dev/null @@ -1,30 +0,0 @@ -from app.convertor.transcription import Transcription - - -class Convertor: - def __init__(self, model_id, input_file_name, show_text, text_preview_size): - self.model_id = model_id - self.input_file_name = input_file_name - self.show_text = show_text - self.text_preview_size = text_preview_size - - def create_text(self): - transcription = Transcription( - model_id=self.model_id, - input_file_name=self.input_file_name, - show_text=self.show_text, - text_preview_size=self.text_preview_size, - ) - - return transcription.get_transcription() - - -if __name__ == "__main__": - convertor = Convertor( - model_id="tiny", - input_file_name="./src/app/convertor/service/data/inputs/5846093734223028963.ogg", - show_text=True, - text_preview_size=100, - ) - - text = convertor.create_text() diff --git a/src/app/convertor/routes.py b/src/app/convertor/routes.py index d741e7d..3dd076c 100644 --- a/src/app/convertor/routes.py +++ b/src/app/convertor/routes.py @@ -9,8 +9,9 @@ class FileUploadResource(Resource): def post(self): - file = FileService("mp3", 1000) - return file.convert(request.files.get("file")) + allowed_extensions = ["mp3", "wav", "ogg"] + file_service = FileService(allowed_extensions, 100) + return file_service.convert(request.files.get("file")) api.add_resource(FileUploadResource, "/upload/") diff --git a/src/app/convertor/service.py b/src/app/convertor/service.py index 2c05fce..2550216 100644 --- a/src/app/convertor/service.py +++ b/src/app/convertor/service.py @@ -1,12 +1,59 @@ +import os + +from app.convertor.transcription import Transcription + + class FileService: def __init__(self, allowed_extensions, max_size_mb): self.allowed_extensions = allowed_extensions self.max_size_mb = max_size_mb + self.max_size_bytes = max_size_mb * 1024 * 1024 + + def _allowed_extension(self, filename): + ext = os.path.splitext(filename)[1].lower().replace(".", "") + return ext in self.allowed_extensions + + def _allowed_size(self, file): + file.seek(0, os.SEEK_END) + size = file.tell() + file.seek(0) + return size <= self.max_size_bytes def validate(self, file): if not file: return {"error": "Missing file"}, 400 + # Controllo filename + if not file.filename: + return {"error": "Invalid filename"}, 400 + + # Controllo estensione + if not self._allowed_extension(file.filename): + return {"error": "File extension not allowed"}, 400 + + # Controllo MIME dichiarato + if not file.mimetype.startswith("audio/"): + return {"error": "File is not an audio type"}, 400 + + # Controllo dimensione + if not self._allowed_size(file): + return {"error": f"File exceeds {self.max_size_mb} MB"}, 400 + + return None + def convert(self, file): - self.validate(file) - return f"{file} converted" + error = self.validate(file) + + if error: + return error + + try: + service = Transcription(file_storage=file) + text = service.get_transcription() + return { + "message": "File converted successfully", + "transcription": text, + }, 200 + + except Exception as e: + return {"error": str(e)}, 400 diff --git a/src/app/convertor/transcription.py b/src/app/convertor/transcription.py index f7ee85c..6481c42 100644 --- a/src/app/convertor/transcription.py +++ b/src/app/convertor/transcription.py @@ -1,135 +1,69 @@ -import whisper import os +import tempfile + +import whisper class Transcription: + whisper_allowed_extensions = [ + "flac", + "m4a", + "mp3", + "mp4", + "mpeg", + "mpga", + "oga", + "ogg", + "wav", + "webm", + ] + + whisper_model_ids = ["tiny", "base", "small", "medium", "large", "turbo"] + def __init__( self, + file_storage, # ora riceve il file dall'API model_id="tiny", - input_file_name=".ogg", show_text=False, - output_file_name="", - text_preview_size=None, language="english", ): + self.file_storage = file_storage self.model_id = model_id - self.input_file_name = input_file_name # self.load_file(input_file_name) self.show_text = show_text - self.output_file_name = output_file_name - self.text_preview_size = text_preview_size self.language = language - ########## Sanity checks for whisper model use ######### - self.whisper_allowed_extensions = [ - "flac", - "m4a", - "mp3", - "mp4", - "mpeg", - "mpga", - "oga", - "ogg", - "wav", - "webm", - ] - self.whisper_model_ids = ["tiny", "base", "small", "medium", "large", "turbo"] - - # The default setting (which selects the turbo model) works well for transcribing English. - # However, the turbo model is not trained for translation tasks. - # If you need to translate non-English speech into English, use one of the - # multilingual models (tiny, base, small, medium, large) instead of turbo. - - self.whisper_model_ids_english_only = [ - "tiny.en", - "base.en", - "small.en", - "medium.en", - ] self._check_file_extension() self._check_whisper_model_id() - @staticmethod - def load_file(input_file_name): - if not os.path.exists(input_file_name): - raise FileNotFoundError(f"File: {input_file_name} does not exist") - return input_file_name - def _check_file_extension(self): - ext = self.input_file_name.rsplit(".", 1)[-1].lower() + filename = self.file_storage.filename + ext = filename.rsplit(".", 1)[-1].lower() if ext not in self.whisper_allowed_extensions: - allowed = ", ".join(self.whisper_allowed_extensions) - raise ValueError( - f"Invalid file format: .{ext}\n" f"Allowed formats are: {allowed}" - ) - return True + raise ValueError(f"Invalid file format: .{ext}") def _check_whisper_model_id(self): if self.model_id not in self.whisper_model_ids: - allowed = ", ".join(self.whisper_model_ids) - raise ValueError( - f"Invalid model ID selection: {self.model_id}\n" - f"Allowed formats are: {allowed}" - ) - return True + raise ValueError(f"Invalid model ID selection: {self.model_id}") def _get_model(self): - model = whisper.load_model(self.model_id) - return model - - def save_transcription(self, text, output_file_name=""): - file_name = self.output_file_name if not output_file_name else output_file_name - with open(f"{file_name}.txt", "w", encoding="utf-8") as f: - f.write(text) + return whisper.load_model(self.model_id) def get_transcription(self): model = self._get_model() - print(f"Using as requested model {self.model_id}.") - print( - f"Transcribing file {self.input_file_name}... this may take a few minutes depening of the file size." - ) - # load audio and pad/trim it to fit 30 seconds - # audio = whisper.load_audio("audio.mp3") - # audio = whisper.pad_or_trim(audio) - - # detect the spoken language - # _, probs = model.detect_language(mel) - # print(f"Detected language: {max(probs, key=probs.get)}") - - result = model.transcribe(self.input_file_name, fp16=False) - - if self.show_text: - if self.text_preview_size: - print(result["text"][: self.text_preview_size]) - else: - print(result["text"]) - - if (len(self.output_file_name) > 0) or (len(self.output_file_name) > 0): - file_name = ( - self.output_file_name if not output_file_name else output_file_name - ) - self.save_transcription(result["text"], file_name) - print(f"Saved transcription as: {file_name}.") - - return result["text"] + # Salvataggio temporaneo + with tempfile.NamedTemporaryFile(delete=False, suffix=".tmp") as tmp: + self.file_storage.save(tmp.name) + temp_path = tmp.name -if __name__ == "__main__": + try: + result = model.transcribe(temp_path, fp16=False) - data_dir = "data" - input_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogg" - output_file_name = "./src/app/convertor/service/data/inputs/5846093734223028963.ogx" - - model_id = "tiny" - show_text = True - text_preview_size = 10 + if self.show_text: + print(result["text"]) - transcription_service = Transcription( - model_id=model_id, - input_file_name=input_file_name, - show_text=show_text, - output_file_name=output_file_name, - text_preview_size=text_preview_size, - ) + return result["text"] - transcription_service.get_transcription() + finally: + os.remove(temp_path) From 7c985fac2b8a8aefdab0a7cde82d188d048d1781 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:03:34 +0100 Subject: [PATCH 07/12] refactoring --- data/__init__.py | 0 data/inputs/5846093734223028963.ogg | Bin 32303 -> 0 bytes data/inputs/5846093734223028963.ogx | Bin 32303 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/__init__.py delete mode 100644 data/inputs/5846093734223028963.ogg delete mode 100644 data/inputs/5846093734223028963.ogx diff --git a/data/__init__.py b/data/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/data/inputs/5846093734223028963.ogg b/data/inputs/5846093734223028963.ogg deleted file mode 100644 index 6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32303 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 diff --git a/data/inputs/5846093734223028963.ogx b/data/inputs/5846093734223028963.ogx deleted file mode 100644 index 6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32303 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 From f3cc5a49bcf46b61bf15811387fbfe7b1f1e2e33 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:04:33 +0100 Subject: [PATCH 08/12] fix --- src/app/convertor/transcription.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/convertor/transcription.py b/src/app/convertor/transcription.py index 6481c42..84f90fd 100644 --- a/src/app/convertor/transcription.py +++ b/src/app/convertor/transcription.py @@ -22,7 +22,7 @@ class Transcription: def __init__( self, - file_storage, # ora riceve il file dall'API + file_storage, model_id="tiny", show_text=False, language="english", From 3f376844e375474a933be26eaf90efe7a63eb2e6 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:13:16 +0100 Subject: [PATCH 09/12] fix test --- src/app/convertor/service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/convertor/service.py b/src/app/convertor/service.py index 2550216..49836a9 100644 --- a/src/app/convertor/service.py +++ b/src/app/convertor/service.py @@ -48,8 +48,8 @@ def convert(self, file): return error try: - service = Transcription(file_storage=file) - text = service.get_transcription() + transcription = Transcription(file_storage=file) + text = transcription.get_transcription() return { "message": "File converted successfully", "transcription": text, From dae68e522630c6243fcb6ae4293cbaf96e7774d1 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:35:18 +0100 Subject: [PATCH 10/12] fixed test --- src/app/convertor/data/test.ogg | Bin 0 -> 32303 bytes src/app/convertor/transcription.py | 19 +++++++++++++++++-- tests/test_core.py | 10 +++++----- 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 src/app/convertor/data/test.ogg diff --git a/src/app/convertor/data/test.ogg b/src/app/convertor/data/test.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6e1cc6fd5e59203b7e28a22fbdde565fc14a0d5a GIT binary patch literal 32303 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 literal 0 HcmV?d00001 diff --git a/src/app/convertor/transcription.py b/src/app/convertor/transcription.py index 84f90fd..dd2a80e 100644 --- a/src/app/convertor/transcription.py +++ b/src/app/convertor/transcription.py @@ -26,12 +26,17 @@ def __init__( model_id="tiny", show_text=False, language="english", + test_mode=False, + text_preview_size=None, + output_file_name="", ): self.file_storage = file_storage self.model_id = model_id self.show_text = show_text self.language = language - + self.test_mode = test_mode + self.text_preview_size = text_preview_size + self.output_file_name = output_file_name self._check_file_extension() self._check_whisper_model_id() @@ -49,6 +54,11 @@ def _check_whisper_model_id(self): def _get_model(self): return whisper.load_model(self.model_id) + def _save_transcription(self, text, output_file_name=""): + file_name = self.output_file_name if not output_file_name else output_file_name + with open(f"{file_name}.txt", "w", encoding="utf-8") as f: + f.write(text) + def get_transcription(self): model = self._get_model() @@ -61,7 +71,12 @@ def get_transcription(self): result = model.transcribe(temp_path, fp16=False) if self.show_text: - print(result["text"]) + if self.text_preview_size: + print(result["text"][: self.text_preview_size]) + else: + print(result["text"]) + if self.test_mode: + self._save_transcription(result["text"]) return result["text"] diff --git a/tests/test_core.py b/tests/test_core.py index d9c5e13..6563e14 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -5,24 +5,24 @@ def test_imports(): def test_imports_modules(): - from src.app.convertor.service.transcription import Transcription + from src.app.convertor.transcription import Transcription assert True def test_transcription_text(): - from src.app.convertor.service.transcription import Transcription + from src.app.convertor.transcription import Transcription data_dir = "data" - input_file_name = f"{data_dir}/inputs/5846093734223028963.ogg" - output_file_name = f"{data_dir}/outputs/5846093734223028963" + input_file_name = f"{data_dir}/test.ogg" + output_file_name = f"{data_dir}/test.txt" model_id = "tiny" show_text = True text_preview_size = 10 transcription_service = Transcription( model_id=model_id, - input_file_name=input_file_name, + file_storage=input_file_name, show_text=show_text, output_file_name=output_file_name, text_preview_size=text_preview_size, From b034b5f7f15abd372de0f6a5a9d8f894cbb378e7 Mon Sep 17 00:00:00 2001 From: Enrico Date: Fri, 13 Feb 2026 00:54:34 +0100 Subject: [PATCH 11/12] update test core --- tests/test_core.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_core.py b/tests/test_core.py index 6563e14..55e295c 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -20,9 +20,16 @@ def test_transcription_text(): show_text = True text_preview_size = 10 + from werkzeug.datastructures import FileStorage + + with open(input_file_name, "rb") as f: + file_storage = FileStorage( + stream=f, filename="test.mp3", content_type="audio/mpeg" + ) + transcription_service = Transcription( model_id=model_id, - file_storage=input_file_name, + file_storage=file_storage, show_text=show_text, output_file_name=output_file_name, text_preview_size=text_preview_size, From d15c27ed195838d196658bcb301dd7816ed5013f Mon Sep 17 00:00:00 2001 From: Enrico Date: Thu, 30 Apr 2026 21:59:34 +0200 Subject: [PATCH 12/12] fix --- src/app/convertor/routes.py | 11 ++++++++++- src/app/convertor/service.py | 8 ++++++-- src/app/convertor/transcription.py | 24 ++++++++++++++++++------ src/app/main.py | 3 +++ tests/test_core.py | 9 +++++---- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/app/convertor/routes.py b/src/app/convertor/routes.py index 3dd076c..c03de47 100644 --- a/src/app/convertor/routes.py +++ b/src/app/convertor/routes.py @@ -10,7 +10,16 @@ class FileUploadResource(Resource): def post(self): allowed_extensions = ["mp3", "wav", "ogg"] - file_service = FileService(allowed_extensions, 100) + + language = request.form.get("language") + model = request.form.get("model") + file_service = FileService( + allowed_extensions=allowed_extensions, + max_size_mb=1000, + language=language, + model=model, + ) + return file_service.convert(request.files.get("file")) diff --git a/src/app/convertor/service.py b/src/app/convertor/service.py index 49836a9..cd9a77d 100644 --- a/src/app/convertor/service.py +++ b/src/app/convertor/service.py @@ -4,10 +4,12 @@ class FileService: - def __init__(self, allowed_extensions, max_size_mb): + def __init__(self, allowed_extensions, max_size_mb, model, language): self.allowed_extensions = allowed_extensions self.max_size_mb = max_size_mb self.max_size_bytes = max_size_mb * 1024 * 1024 + self.model = model + self.language = language def _allowed_extension(self, filename): ext = os.path.splitext(filename)[1].lower().replace(".", "") @@ -48,7 +50,9 @@ def convert(self, file): return error try: - transcription = Transcription(file_storage=file) + transcription = Transcription( + file_storage=file, model_id=self.model, language=self.language + ) text = transcription.get_transcription() return { "message": "File converted successfully", diff --git a/src/app/convertor/transcription.py b/src/app/convertor/transcription.py index dd2a80e..6d6aab4 100644 --- a/src/app/convertor/transcription.py +++ b/src/app/convertor/transcription.py @@ -36,20 +36,32 @@ def __init__( self.language = language self.test_mode = test_mode self.text_preview_size = text_preview_size + self.output_file_name = output_file_name - self._check_file_extension() - self._check_whisper_model_id() + + print(self.model_id, self.language) + + check, ext = self._check_file_extension() + if not check: + raise ValueError(f"Invalid file format: .{ext}") + + if not self._check_whisper_model_id(): + raise ValueError(f"Invalid model ID selection: {self.model_id}") def _check_file_extension(self): filename = self.file_storage.filename ext = filename.rsplit(".", 1)[-1].lower() - if ext not in self.whisper_allowed_extensions: - raise ValueError(f"Invalid file format: .{ext}") + if ext in self.whisper_allowed_extensions: + return True, ext + else: + return False, ext def _check_whisper_model_id(self): - if self.model_id not in self.whisper_model_ids: - raise ValueError(f"Invalid model ID selection: {self.model_id}") + if self.model_id in self.whisper_model_ids: + return True + else: + return False def _get_model(self): return whisper.load_model(self.model_id) diff --git a/src/app/main.py b/src/app/main.py index 2533414..bfd559b 100755 --- a/src/app/main.py +++ b/src/app/main.py @@ -3,6 +3,9 @@ from app.convertor.routes import upload_bp app = Flask(__name__) +app.config["MAX_CONTENT_LENGTH"] = 500 * 1024 * 1024 # 500MB +app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0 +app.config["MAX_CONTENT_PATH"] = None @app.route("/") diff --git a/tests/test_core.py b/tests/test_core.py index 55e295c..c67eb6e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -13,8 +13,8 @@ def test_imports_modules(): def test_transcription_text(): from src.app.convertor.transcription import Transcription - data_dir = "data" - input_file_name = f"{data_dir}/test.ogg" + data_dir = "./src/app/convertor/data" + input_file_name = f"./{data_dir}/test.ogg" output_file_name = f"{data_dir}/test.txt" model_id = "tiny" show_text = True @@ -24,7 +24,7 @@ def test_transcription_text(): with open(input_file_name, "rb") as f: file_storage = FileStorage( - stream=f, filename="test.mp3", content_type="audio/mpeg" + stream=f, filename="test.ogg", content_type="audio/ogg" ) transcription_service = Transcription( @@ -33,10 +33,11 @@ def test_transcription_text(): show_text=show_text, output_file_name=output_file_name, text_preview_size=text_preview_size, + test_mode=True, ) assert transcription_service._get_model() is not None - assert transcription_service._check_file_extension() is True + assert transcription_service._check_file_extension()[0] is True assert transcription_service._check_whisper_model_id() is True