From 603f74c5131c18c94c8d7ff4af012dcd546636d7 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:34:31 +0200 Subject: [PATCH 01/10] siegfried - add classes to handle Siegfried calls https://github.com/richardlehane/siegfried --- acacore/siegfried/__init__.py | 2 + acacore/siegfried/siegfried.py | 104 +++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 acacore/siegfried/__init__.py create mode 100644 acacore/siegfried/siegfried.py diff --git a/acacore/siegfried/__init__.py b/acacore/siegfried/__init__.py new file mode 100644 index 0000000..6ad337f --- /dev/null +++ b/acacore/siegfried/__init__.py @@ -0,0 +1,2 @@ +from .siegfried import Siegfried +from .siegfried import SiegfriedResult diff --git a/acacore/siegfried/siegfried.py b/acacore/siegfried/siegfried.py new file mode 100644 index 0000000..f471fef --- /dev/null +++ b/acacore/siegfried/siegfried.py @@ -0,0 +1,104 @@ +from datetime import datetime +from os import PathLike +from subprocess import CompletedProcess +from subprocess import run + +from pydantic import BaseModel +from pydantic import Field +from pydantic import field_validator, ConfigDict + +from acacore.exceptions.files import IdentificationError + + +def _check_process(process: CompletedProcess): + """ + Raises: + IdentificationError: if the process ends with a return code other than 0 + """ + if process.returncode != 0: + raise IdentificationError( + process.stderr or + process.stdout or + f"Unknown siegfried error code {process.returncode}") + + +class SiegfriedIdentifier(BaseModel): + name: str + details: str + + +class SiegfriedMatch(BaseModel): + ns: str + id: str | None + format: str + version: str + mime: str + match_class: str = Field(alias="class") + basis: str + warning: str + + # noinspection PyNestedDecorators + @field_validator("id") + @classmethod + def unknown_id(cls, _id: str | None): + _id = (_id or "").strip() + return None if _id.lower() == "unknown" else _id or None + + +class SiegfriedFile(BaseModel): + filename: str + filesize: int + modified: datetime + errors: str + matches: list[SiegfriedMatch] + + +class SiegfriedResult(BaseModel): + siegfried: str + scandate: datetime + signature: str + created: datetime + identifiers: list[SiegfriedIdentifier] + files: list[SiegfriedFile] + model_config = ConfigDict(extra="forbid") + + +class Siegfried: + """ + A wrapper class to use the Siegfried program with Python and return the results with Pydantic models. + + See Also: + https://github.com/richardlehane/siegfried + """ + + def __init__(self, binary: str | PathLike = "sf"): + """ + Args: + binary: the path to the Siegfried binary, or the program name if it is included in the PATH variable + + Raises: + IdentificationError: if Siegfried is not configured properly + """ + self.binary: str = str(binary) + _check_process(run([self.binary, "-v"], capture_output=True, encoding="utf-8")) + + def identify(self, path: str | PathLike) -> SiegfriedResult: + """ + Identify a file. + + Args: + path: The path to the file + + Returns: + A SiegfriedResult object + + Raises: + IdentificationError: if there is an error calling Siegfried or processing its results + """ + process: CompletedProcess = run([self.binary, "-json", "-multi", "1024", str(path)], + capture_output=True, encoding="utf-8") + _check_process(process) + try: + return SiegfriedResult.model_validate_json(process.stdout) + except ValueError as err: + raise IdentificationError(err) From 105291ef6dd4afd494ef8256cc42dfbe042c2539 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:37:59 +0200 Subject: [PATCH 02/10] siegfried - format --- acacore/siegfried/siegfried.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/acacore/siegfried/siegfried.py b/acacore/siegfried/siegfried.py index f471fef..60468b4 100644 --- a/acacore/siegfried/siegfried.py +++ b/acacore/siegfried/siegfried.py @@ -4,8 +4,9 @@ from subprocess import run from pydantic import BaseModel +from pydantic import ConfigDict from pydantic import Field -from pydantic import field_validator, ConfigDict +from pydantic import field_validator from acacore.exceptions.files import IdentificationError @@ -17,9 +18,8 @@ def _check_process(process: CompletedProcess): """ if process.returncode != 0: raise IdentificationError( - process.stderr or - process.stdout or - f"Unknown siegfried error code {process.returncode}") + process.stderr or process.stdout or f"Unknown siegfried error code {process.returncode}" + ) class SiegfriedIdentifier(BaseModel): @@ -95,8 +95,11 @@ def identify(self, path: str | PathLike) -> SiegfriedResult: Raises: IdentificationError: if there is an error calling Siegfried or processing its results """ - process: CompletedProcess = run([self.binary, "-json", "-multi", "1024", str(path)], - capture_output=True, encoding="utf-8") + process: CompletedProcess = run( + [self.binary, "-json", "-multi", "1024", str(path)], + capture_output=True, + encoding="utf-8", + ) _check_process(process) try: return SiegfriedResult.model_validate_json(process.stdout) From a107049feb7eec08591ba70d47c77bcf80b5f222 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:39:57 +0200 Subject: [PATCH 03/10] databases:files_db - format --- acacore/database/files_db.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/acacore/database/files_db.py b/acacore/database/files_db.py index e8defc4..999effd 100644 --- a/acacore/database/files_db.py +++ b/acacore/database/files_db.py @@ -1,7 +1,6 @@ from datetime import datetime from os import PathLike from sqlite3 import Connection -from typing import Any from typing import Optional from typing import Type from typing import Union @@ -15,16 +14,16 @@ class FileDB(FileDBBase): def __init__( - self, - database: Union[str, bytes, PathLike[str], PathLike[bytes]], - *, - timeout: float = 5.0, - detect_types: int = 0, - isolation_level: Optional[str] = "DEFERRED", - check_same_thread: bool = True, - factory: Optional[Type[Connection]] = Connection, - cached_statements: int = 100, - uri: bool = False, + self, + database: Union[str, bytes, PathLike[str], PathLike[bytes]], + *, + timeout: float = 5.0, + detect_types: int = 0, + isolation_level: Optional[str] = "DEFERRED", + check_same_thread: bool = True, + factory: Optional[Type[Connection]] = Connection, + cached_statements: int = 100, + uri: bool = False, ) -> None: """ A class that handles the SQLite database used by AArhus City Archives to process data archives. @@ -135,13 +134,13 @@ def is_empty(self) -> bool: return not self.files.select(limit=1).fetchone() def add_history( - self, - uuid: UUID, - operation: str, - data: Optional[Union[dict, list, str, int, float, bool, datetime]], - reason: Optional[str] = None, - *, - time: Optional[datetime] = None, + self, + uuid: UUID, + operation: str, + data: Optional[Union[dict, list, str, int, float, bool, datetime]], + reason: Optional[str] = None, + *, + time: Optional[datetime] = None, ): self.history.insert( self.history.model( From 5979973f31649d9adc410c072d6f6384d30d0a5e Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:41:29 +0200 Subject: [PATCH 04/10] acacore - format with black --- acacore/database/base.py | 49 +++++++++++++++++++++++++------- acacore/database/column.py | 11 +++++-- acacore/models/file.py | 5 ++-- acacore/models/file_data.py | 5 ++-- acacore/models/identification.py | 3 +- acacore/utils/functions.py | 4 ++- acacore/utils/log.py | 6 +++- 7 files changed, 63 insertions(+), 20 deletions(-) diff --git a/acacore/database/base.py b/acacore/database/base.py index 6bee159..d4c7b4b 100644 --- a/acacore/database/base.py +++ b/acacore/database/base.py @@ -1,13 +1,23 @@ from datetime import datetime from os import PathLike from pathlib import Path -from sqlite3 import Connection, OperationalError +from sqlite3 import Connection from sqlite3 import Cursor as SQLiteCursor -from typing import Any, Generator, Generic, Optional, Type, TypeVar, Union, overload +from sqlite3 import OperationalError +from typing import Any +from typing import Generator +from typing import Generic +from typing import Optional +from typing import Type +from typing import TypeVar +from typing import Union +from typing import overload from pydantic.main import BaseModel -from .column import Column, SelectColumn, model_to_columns +from .column import Column +from .column import SelectColumn +from .column import model_to_columns T = TypeVar("T") R = TypeVar("R") @@ -47,7 +57,10 @@ def fetchalltuples(self) -> Generator[tuple, None, None]: Returns: Generator: A generator for the tuples in the cursor. """ - return (tuple(c.from_entry(v) for c, v in zip(self.columns, vs)) for vs in self.cursor.fetchall()) + return ( + tuple(c.from_entry(v) for c, v in zip(self.columns, vs)) + for vs in self.cursor.fetchall() + ) def fetchonetuple(self) -> Optional[tuple]: """ @@ -68,7 +81,9 @@ def fetchall(self) -> Generator[dict[str, Any], None, None]: def fetchall(self, model: Type[M]) -> Generator[M, None, None]: ... - def fetchall(self, model: Optional[Type[M]] = None) -> Generator[Union[dict[str, Any], M], None, None]: + def fetchall( + self, model: Optional[Type[M]] = None + ) -> Generator[Union[dict[str, Any], M], None, None]: """ Fetch all results from the cursor and return them as dicts, with the columns' names/aliases used as keys. @@ -89,7 +104,8 @@ def fetchall(self, model: Optional[Type[M]] = None) -> Generator[Union[dict[str, ) return ( - {c.alias or c.name: c.from_entry(v) for c, v in zip(select_columns, vs)} for vs in self.cursor.fetchall() + {c.alias or c.name: c.from_entry(v) for c, v in zip(select_columns, vs)} + for vs in self.cursor.fetchall() ) @overload @@ -228,7 +244,11 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append( "(" + ", ".join(c.create_statement() for c in self.columns) - + (f", primary key ({', '.join(c.name for c in keys)})" if (keys := self.keys) else "") + + ( + f", primary key ({', '.join(c.name for c in keys)})" + if (keys := self.keys) + else "" + ) + ")", ) @@ -274,7 +294,9 @@ def select( statement += f" WHERE {where}" if order_by: - order_statements = [f"{c.name if isinstance(c, Column) else c} {s}" for c, s in order_by] + order_statements = [ + f"{c.name if isinstance(c, Column) else c} {s}" for c, s in order_by + ] statement += f" ORDER BY {','.join(order_statements)}" if limit is not None: @@ -434,11 +456,13 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append("AS") select_names = [ - f"{c.name} as {c.alias}" if c.alias else c.name for c in [SelectColumn.from_column(c) for c in self.columns] + f"{c.name} as {c.alias}" if c.alias else c.name + for c in [SelectColumn.from_column(c) for c in self.columns] ] elements.append( - f"SELECT {','.join(select_names)} " f"FROM {self.on.name if isinstance(self.on, Table) else self.on}", + f"SELECT {','.join(select_names)} " + f"FROM {self.on.name if isinstance(self.on, Table) else self.on}", ) if self.where: @@ -448,7 +472,10 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append("GROUP BY") elements.append( ",".join( - [c.alias or c.name for c in [SelectColumn.from_column(c) for c in self.group_by]], + [ + c.alias or c.name + for c in [SelectColumn.from_column(c) for c in self.group_by] + ], ), ) diff --git a/acacore/database/column.py b/acacore/database/column.py index 249c452..762aac0 100644 --- a/acacore/database/column.py +++ b/acacore/database/column.py @@ -1,6 +1,11 @@ from datetime import datetime from pathlib import Path -from typing import Callable, Generic, Optional, Type, TypeVar, Union +from typing import Callable +from typing import Generic +from typing import Optional +from typing import Type +from typing import TypeVar +from typing import Union from uuid import UUID from pydantic import BaseModel @@ -51,7 +56,9 @@ def _schema_to_column(name: str, schema: dict) -> "Column": else: raise TypeError(f"Cannot recognize type from schema {schema!r}") elif schema_any_of: - if (schema_any_of[-1].get("type", None) != "null" and len(schema_any_of) > 1) or len(schema_any_of) > 2: + if (schema_any_of[-1].get("type", None) != "null" and len(schema_any_of) > 1) or len( + schema_any_of + ) > 2: raise TypeError(f"Cannot recognize type from schema {schema!r}") return _schema_to_column(name, {**schema_any_of[0], **schema}) else: diff --git a/acacore/models/file.py b/acacore/models/file.py index a82d9ae..d1af288 100644 --- a/acacore/models/file.py +++ b/acacore/models/file.py @@ -4,13 +4,14 @@ from pathlib import Path from typing import Optional -from pydantic import UUID4, Field +from pydantic import Field +from pydantic import UUID4 from acacore.utils.io import size_fmt - from .base import ACABase from .identification import Identification + # ----------------------------------------------------------------------------- # Model # ----------------------------------------------------------------------------- diff --git a/acacore/models/file_data.py b/acacore/models/file_data.py index bfe76c3..6f918d8 100644 --- a/acacore/models/file_data.py +++ b/acacore/models/file_data.py @@ -1,10 +1,11 @@ from pathlib import Path -from typing import Any, ClassVar, Optional +from typing import Any +from typing import ClassVar +from typing import Optional from pydantic import model_validator from acacore.database.files_db import FileDB - from .base import ACABase from .file import ArchiveFile diff --git a/acacore/models/identification.py b/acacore/models/identification.py index 9effa0b..a5c4e60 100644 --- a/acacore/models/identification.py +++ b/acacore/models/identification.py @@ -1,4 +1,5 @@ -from typing import Any, Optional +from typing import Any +from typing import Optional from pydantic import model_validator diff --git a/acacore/utils/functions.py b/acacore/utils/functions.py index e72e482..6aa828e 100644 --- a/acacore/utils/functions.py +++ b/acacore/utils/functions.py @@ -1,4 +1,6 @@ -from typing import Callable, Optional, TypeVar +from typing import Callable +from typing import Optional +from typing import TypeVar T = TypeVar("T") R = TypeVar("R") diff --git a/acacore/utils/log.py b/acacore/utils/log.py index e7a0f56..1f28c8f 100644 --- a/acacore/utils/log.py +++ b/acacore/utils/log.py @@ -1,4 +1,8 @@ -from logging import INFO, FileHandler, Formatter, Logger, getLogger +from logging import FileHandler +from logging import Formatter +from logging import INFO +from logging import Logger +from logging import getLogger from pathlib import Path From f3bb1bebd793877d4d96b0ad73b9f60089eccdf3 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:53:57 +0200 Subject: [PATCH 05/10] utils:log - format docstring --- acacore/utils/log.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/acacore/utils/log.py b/acacore/utils/log.py index 1f28c8f..c24c33c 100644 --- a/acacore/utils/log.py +++ b/acacore/utils/log.py @@ -7,13 +7,20 @@ def setup_logger(log_name: str, log_path: Path) -> Logger: - """General method for setting op a log object. Ensures that the different logs we use across tools are standardized. + """ + General method for setting op a log object. Ensures that the different logs we use across tools are standardized. + + Args: + log_name: the name given to the logger within the logging modules own namespace. All descendant logs needs + to have a name on the form 'log_name.descendant_log_name', which often is the name of the module or submodule + that the function is called from. + log_path: the path directly to the log as a `txt` file. If the file is not there, it will be created. + If it already exists, it will append the messages to the file. - ## Args - * log_name: the name given to the logger within the logging modules own namespace. All descendant logs needs to have a name on the form 'log_name.descendant_log_name', which often is the name of the module or submodule that the function is called from. - * log_path: the path directly to the log as a `txt` file. If the file is not there, it will be created. If it already exists, it will append the messages to the file. + Returns: + A Logger instance. """ - # If the parents of the file does not exist, then we make them + if not log_path.parent.exists(): Path.mkdir(log_path.parent, parents=True, exist_ok=True) From 2d0ef0903537ac030c06df258211d2a9da475584 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 12:54:56 +0200 Subject: [PATCH 06/10] utils:log,siegfried - format docstring --- acacore/siegfried/siegfried.py | 6 +++--- acacore/utils/log.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/acacore/siegfried/siegfried.py b/acacore/siegfried/siegfried.py index 60468b4..317c3b3 100644 --- a/acacore/siegfried/siegfried.py +++ b/acacore/siegfried/siegfried.py @@ -74,10 +74,10 @@ class Siegfried: def __init__(self, binary: str | PathLike = "sf"): """ Args: - binary: the path to the Siegfried binary, or the program name if it is included in the PATH variable + binary: The path to the Siegfried binary, or the program name if it is included in the PATH variable Raises: - IdentificationError: if Siegfried is not configured properly + IdentificationError: If Siegfried is not configured properly """ self.binary: str = str(binary) _check_process(run([self.binary, "-v"], capture_output=True, encoding="utf-8")) @@ -93,7 +93,7 @@ def identify(self, path: str | PathLike) -> SiegfriedResult: A SiegfriedResult object Raises: - IdentificationError: if there is an error calling Siegfried or processing its results + IdentificationError: If there is an error calling Siegfried or processing its results """ process: CompletedProcess = run( [self.binary, "-json", "-multi", "1024", str(path)], diff --git a/acacore/utils/log.py b/acacore/utils/log.py index c24c33c..4569a8b 100644 --- a/acacore/utils/log.py +++ b/acacore/utils/log.py @@ -11,10 +11,10 @@ def setup_logger(log_name: str, log_path: Path) -> Logger: General method for setting op a log object. Ensures that the different logs we use across tools are standardized. Args: - log_name: the name given to the logger within the logging modules own namespace. All descendant logs needs + log_name: The name given to the logger within the logging modules own namespace. All descendant logs needs to have a name on the form 'log_name.descendant_log_name', which often is the name of the module or submodule that the function is called from. - log_path: the path directly to the log as a `txt` file. If the file is not there, it will be created. + log_path: The path directly to the log as a `txt` file. If the file is not there, it will be created. If it already exists, it will append the messages to the file. Returns: From d68d9831726f626a2c8c72e6137b2e5967acbe15 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 13:21:46 +0200 Subject: [PATCH 07/10] siegfried - use pre-3.9 type annotations Remove pipes from type annotations --- acacore/siegfried/siegfried.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/acacore/siegfried/siegfried.py b/acacore/siegfried/siegfried.py index 317c3b3..88536c7 100644 --- a/acacore/siegfried/siegfried.py +++ b/acacore/siegfried/siegfried.py @@ -2,6 +2,8 @@ from os import PathLike from subprocess import CompletedProcess from subprocess import run +from typing import Optional +from typing import Union from pydantic import BaseModel from pydantic import ConfigDict @@ -29,7 +31,7 @@ class SiegfriedIdentifier(BaseModel): class SiegfriedMatch(BaseModel): ns: str - id: str | None + id: Optional[str] format: str version: str mime: str @@ -40,7 +42,7 @@ class SiegfriedMatch(BaseModel): # noinspection PyNestedDecorators @field_validator("id") @classmethod - def unknown_id(cls, _id: str | None): + def unknown_id(cls, _id: Optional[str]): _id = (_id or "").strip() return None if _id.lower() == "unknown" else _id or None @@ -71,7 +73,7 @@ class Siegfried: https://github.com/richardlehane/siegfried """ - def __init__(self, binary: str | PathLike = "sf"): + def __init__(self, binary: Union[str, PathLike] = "sf"): """ Args: binary: The path to the Siegfried binary, or the program name if it is included in the PATH variable @@ -82,7 +84,7 @@ def __init__(self, binary: str | PathLike = "sf"): self.binary: str = str(binary) _check_process(run([self.binary, "-v"], capture_output=True, encoding="utf-8")) - def identify(self, path: str | PathLike) -> SiegfriedResult: + def identify(self, path: Union[str, PathLike]) -> SiegfriedResult: """ Identify a file. From f48e87b5367072c12ba676add306f7cf6b7fc3bf Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 13:34:27 +0200 Subject: [PATCH 08/10] database:base,column - format with black Change line length to 120 --- acacore/database/base.py | 33 ++++++++------------------------- acacore/database/column.py | 4 +--- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/acacore/database/base.py b/acacore/database/base.py index d4c7b4b..d95857a 100644 --- a/acacore/database/base.py +++ b/acacore/database/base.py @@ -57,10 +57,7 @@ def fetchalltuples(self) -> Generator[tuple, None, None]: Returns: Generator: A generator for the tuples in the cursor. """ - return ( - tuple(c.from_entry(v) for c, v in zip(self.columns, vs)) - for vs in self.cursor.fetchall() - ) + return (tuple(c.from_entry(v) for c, v in zip(self.columns, vs)) for vs in self.cursor.fetchall()) def fetchonetuple(self) -> Optional[tuple]: """ @@ -81,9 +78,7 @@ def fetchall(self) -> Generator[dict[str, Any], None, None]: def fetchall(self, model: Type[M]) -> Generator[M, None, None]: ... - def fetchall( - self, model: Optional[Type[M]] = None - ) -> Generator[Union[dict[str, Any], M], None, None]: + def fetchall(self, model: Optional[Type[M]] = None) -> Generator[Union[dict[str, Any], M], None, None]: """ Fetch all results from the cursor and return them as dicts, with the columns' names/aliases used as keys. @@ -104,8 +99,7 @@ def fetchall( ) return ( - {c.alias or c.name: c.from_entry(v) for c, v in zip(select_columns, vs)} - for vs in self.cursor.fetchall() + {c.alias or c.name: c.from_entry(v) for c, v in zip(select_columns, vs)} for vs in self.cursor.fetchall() ) @overload @@ -244,11 +238,7 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append( "(" + ", ".join(c.create_statement() for c in self.columns) - + ( - f", primary key ({', '.join(c.name for c in keys)})" - if (keys := self.keys) - else "" - ) + + (f", primary key ({', '.join(c.name for c in keys)})" if (keys := self.keys) else "") + ")", ) @@ -294,9 +284,7 @@ def select( statement += f" WHERE {where}" if order_by: - order_statements = [ - f"{c.name if isinstance(c, Column) else c} {s}" for c, s in order_by - ] + order_statements = [f"{c.name if isinstance(c, Column) else c} {s}" for c, s in order_by] statement += f" ORDER BY {','.join(order_statements)}" if limit is not None: @@ -456,13 +444,11 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append("AS") select_names = [ - f"{c.name} as {c.alias}" if c.alias else c.name - for c in [SelectColumn.from_column(c) for c in self.columns] + f"{c.name} as {c.alias}" if c.alias else c.name for c in [SelectColumn.from_column(c) for c in self.columns] ] elements.append( - f"SELECT {','.join(select_names)} " - f"FROM {self.on.name if isinstance(self.on, Table) else self.on}", + f"SELECT {','.join(select_names)} " f"FROM {self.on.name if isinstance(self.on, Table) else self.on}", ) if self.where: @@ -472,10 +458,7 @@ def create_statement(self, exist_ok: bool = True) -> str: elements.append("GROUP BY") elements.append( ",".join( - [ - c.alias or c.name - for c in [SelectColumn.from_column(c) for c in self.group_by] - ], + [c.alias or c.name for c in [SelectColumn.from_column(c) for c in self.group_by]], ), ) diff --git a/acacore/database/column.py b/acacore/database/column.py index 762aac0..acc06dd 100644 --- a/acacore/database/column.py +++ b/acacore/database/column.py @@ -56,9 +56,7 @@ def _schema_to_column(name: str, schema: dict) -> "Column": else: raise TypeError(f"Cannot recognize type from schema {schema!r}") elif schema_any_of: - if (schema_any_of[-1].get("type", None) != "null" and len(schema_any_of) > 1) or len( - schema_any_of - ) > 2: + if (schema_any_of[-1].get("type", None) != "null" and len(schema_any_of) > 1) or len(schema_any_of) > 2: raise TypeError(f"Cannot recognize type from schema {schema!r}") return _schema_to_column(name, {**schema_any_of[0], **schema}) else: From fb585be4c2ad43efde559cf3832c18c4b23e0217 Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 14:22:39 +0200 Subject: [PATCH 09/10] poetry - use pydantic ^2.4.2 --- poetry.lock | 240 +++++++++++++++++++++++-------------------------- pyproject.toml | 2 +- 2 files changed, 114 insertions(+), 128 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4be3b2c..dd49ea2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "annotated-types" version = "0.5.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -16,7 +15,6 @@ files = [ name = "black" version = "23.7.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -63,7 +61,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -78,7 +75,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -90,7 +86,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -102,7 +97,6 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -114,7 +108,6 @@ files = [ name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -126,7 +119,6 @@ files = [ name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -140,19 +132,18 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pydantic" -version = "2.2.1" +version = "2.4.2" description = "Data validation using Python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-2.2.1-py3-none-any.whl", hash = "sha256:0c88bd2b63ed7a5109c75ab180d55f58f80a4b559682406812d0684d3f4b9192"}, - {file = "pydantic-2.2.1.tar.gz", hash = "sha256:31b5cada74b2320999fb2577e6df80332a200ff92e7775a52448b6b036fce24a"}, + {file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"}, + {file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.6.1" +pydantic-core = "2.10.1" typing-extensions = ">=4.6.1" [package.extras] @@ -160,118 +151,117 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.6.1" +version = "2.10.1" description = "" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic_core-2.6.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:f55001a689111a297c0006c46c0589cfd559261baaa9a37bc35eff05b8cae1a6"}, - {file = "pydantic_core-2.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bb6273068e9450c5c91f58dd277fbd406b896ffa30f0ef312edc5519d07f16ae"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:043212f21c75cb6ee3a92fffbc747410e32b08e1a419ce16a9da98a16d660a7c"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:db0c12f1e9d3bf658634621f3423486803d749fef77a64cfb4252f9d619e1817"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81424dc05c4342a19fb64323bb9d4468e7407b745c00377ccc4d3dd96d5e02fe"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c8f3aebaf92f088b1dafd7101d1ccca0459ae0f5b26017411b9969667d289a9"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd9f14454b4bc89c705ce17951f9c783db82efd2b44a424487c593e2269eef61"}, - {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2effc71653247e76c5b95d15c58d4ca3f591f42f714eb3b32df9d6ec613794a5"}, - {file = "pydantic_core-2.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:56672429f8a89d2a0f4402d912f0dad68c2d05f7c278d3152c6fb4a76c2a429a"}, - {file = "pydantic_core-2.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d0bf1c2545ab253732229c7fe8294d98eb08f99aa25a388267e1bc4d2d7e0a34"}, - {file = "pydantic_core-2.6.1-cp310-none-win32.whl", hash = "sha256:c5be947ad41a7602f941dc834d03e64dd1c7fae65fa85cb4f1004a95c5d50df1"}, - {file = "pydantic_core-2.6.1-cp310-none-win_amd64.whl", hash = "sha256:3d14ae98a8d251402ef8ed017039d2fc3e29fb155f909cd3816ba259fd30fb48"}, - {file = "pydantic_core-2.6.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4a3c20808d3ced90e29439f72a563eadf21d29560935cc818b2dab80b92c114a"}, - {file = "pydantic_core-2.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:da240bbd8191edc6009e7793d5d4d67c55f56225c4788f068d6286c20e5a2038"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de1a3e56e34264d5216c67d2a48185216ada8f5f35a7f4c96a3971847c0de897"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b623e09239ed333d14c02c9fcd1a7bb350b95eca8383f6e9b0d8e373d5a14b5"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a12520a6d502a25f6e47319874e47056b290f1b3c2ed9391444ce81c8cc5b83"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1141f18414aee8865c7917ae1432e419c1983272f53625152493692ff3d6783"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7888b3ee7566865cff3e9edab5d6cdf2e7cf793df17fe53d5e7be3e57eae45ec"}, - {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bdf293b6304bc451678b7016c2505b7d97aa85ff13dac4420027b1b69e15d3d"}, - {file = "pydantic_core-2.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ef56a05bb60336d5e795bf166d6712b2362e6478522c77e8336cb0da8909913"}, - {file = "pydantic_core-2.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3210eb73707e3487c16ef25cfd1663660f4e7d647a181d6c2fb18bc6167985fb"}, - {file = "pydantic_core-2.6.1-cp311-none-win32.whl", hash = "sha256:707e3005e8c129bdac117285b71717c13b9ed81a81eae0b1642f4ddc60028e63"}, - {file = "pydantic_core-2.6.1-cp311-none-win_amd64.whl", hash = "sha256:2b8ccec2189d8a8b83929f79e5bc00c0656f6c2ba4345125c0c82d1b77e15a26"}, - {file = "pydantic_core-2.6.1-cp311-none-win_arm64.whl", hash = "sha256:c1e44b77442fb5b1b6fccea30e3359b14d0a2e5896801243defe54482a591500"}, - {file = "pydantic_core-2.6.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:c82fb25f965f6777032fc2f2856c86149f7709c8f7fd0c020a8631b8211f2bab"}, - {file = "pydantic_core-2.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:494b211b12b8fedd184dbba609f6ed582e23561db57c1996fd6773989dbaef9b"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1281c940f47e5c89b594ef7580045647df1f9ad687edd503bcc0485be94576f4"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d41701c88d8b678c16c10562949f2d28aceacd767cbe51dac9c8c41e6e609fb"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a839c95d5cc91eed053d8dafde4e200c4bc82f56fb1cf7bbfaeb03e2d907929"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c22e4fbfb5823d0fcb2c20ed164b39c3588554f9635f70765e8c9cff0fef67ad"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2fed4ad60ccf2698bd04e95dfc3bd84149ced9605a29fd27d624701e1da300c"}, - {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33b9343aa464d60c31937b361abde08d3af9943f3eb09d3216211b6236bd40c4"}, - {file = "pydantic_core-2.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:56e4953cd911293d6d755e2a97c651826aca76201db8f1ee298939e703721390"}, - {file = "pydantic_core-2.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cd163109047ab41ef1ea34258b35beb3ccac90af2012927ee8ab6ff122fef671"}, - {file = "pydantic_core-2.6.1-cp312-none-win32.whl", hash = "sha256:f5b51ec04743c94288c46e3759769611ab7c5ce0f941113363da96d20d345fb6"}, - {file = "pydantic_core-2.6.1-cp312-none-win_amd64.whl", hash = "sha256:ca5606bd82e255b1d704a4334e5ebf05ae966b69686fae02dcd31c057bdcb113"}, - {file = "pydantic_core-2.6.1-cp312-none-win_arm64.whl", hash = "sha256:dfc8f534a21b60b00f87e5a4fc36b8b8945160a6cc9e7b6e67db541c766c9597"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:b1aed20778092f8334c8eaf91550fa2805221d5e9b40ebdd1f46ee7efc159a48"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:64ff7a4b7ee2a56735af28da76c5dacbba6995801080f739d14610f4aa3de35d"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d8faedb138c704957642fdf154c94f1b3d2a15cbd2472e45665f80463e85ee"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55aac69d7339a63e37164f0a629c3034becc6746d68d126118a3ee4493514bed"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfdb1617af455a551be4cc0471f0bf3bfb1e882db71afad0e587c821326bb749"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aadc84f5bd7b1421b5a6b389ceff46062dd4a58c44cfb75990e9ca2d9d8270df"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1a01dce87507b9a8f1b71933ade85c573a22c9bd4649590e28d8a497afb68bd"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cd6f05f3e237ed6b3949464e7679e55843645fe0fe8d3b33277c321386836f6a"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:760f8a0aeb43ceeff1e536859e071a72e91075d4d37d51470812c4f49e682702"}, - {file = "pydantic_core-2.6.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a1ad48e77935d7dbbc2d75aeb638abbfbd0df0cfacf774dbe98d52271468f00c"}, - {file = "pydantic_core-2.6.1-cp37-none-win32.whl", hash = "sha256:153a5dd24c09ab7544beda967366afbaae8350b327a4ebd5807ed45ec791baa0"}, - {file = "pydantic_core-2.6.1-cp37-none-win_amd64.whl", hash = "sha256:cc7fc3e81b4ea6bce7e0e1d9797f496e957c5e66adf483f89afdce2d81d19986"}, - {file = "pydantic_core-2.6.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:5482d692ae37857695feccb179022728b275b7bfcc1c85bcdf7b556e76bffcd8"}, - {file = "pydantic_core-2.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:45d248c3c5c5c23a8d048cfdebc8151ae7b32a6dc6d68fbca995521e54692207"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dd6c9f47e26779bf1f7da4d6ccd60f66973e63b0a143438f1e20bae296c3fde"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55701608e60418a423db2486b5c64d790f86eb78a11b9077efb6302c50e62564"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:420a76a62dd20a6ef08445abf7cf04dcd8a845a5bb15932c2e88a8e518c70d43"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f253d20314e53ba0fb2b95541b6ed23f44fbcd927fe7674de341545c3327c3d"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5127b811c6a26deb85f5b17a06c26c28ce204e51e0a963b75bdf8612b22546d"}, - {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:51ffa985b874ca7d0dc199bb75c67b77907379291c91532a9e2d981f7b681527"}, - {file = "pydantic_core-2.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4902300e763a2fcc49ae14366493ef1fdbd3c7128b9acf37aef505f671aa681f"}, - {file = "pydantic_core-2.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e1c69334bb843c9bff98f52a1fa6c06420081a561fcecb03c6b9376960bd7de2"}, - {file = "pydantic_core-2.6.1-cp38-none-win32.whl", hash = "sha256:e84812b1ca989b2e9f4913d7b75ae0eece2a90154de35b4c5411ad640bfd387c"}, - {file = "pydantic_core-2.6.1-cp38-none-win_amd64.whl", hash = "sha256:775098e3629a959dfec8444667a53e0916839e9fbf6b55e07d6e2aadde006400"}, - {file = "pydantic_core-2.6.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a32ed5a794918a61bf77b967c197eb78f31ad4e3145860193dc381bde040717e"}, - {file = "pydantic_core-2.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:66eda8ac48ac33e9e5c6541c8e30c702924b70a6f2e9732b74230d9b2dd35fb6"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb5131d75d69b0547ef9a8f46f7b94857411c9badcdd5092de61a3b4943f08c7"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e850f3242d7836a5e15453f798d8569b9754350c8e184ba32d102c515dd507"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f4327fa6a1ac3da62b27d43bb0f27657ed4e601b141ecbfcf8523814b6c33b6"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7b89b2875b967ad5c3c980bf72773851554f80c2529796e815a10c99295d872"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78eadd8d7d5cd8c3616e363c394d721437c339feaa4c28404e2eda79add69781"}, - {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17ab25bb24e98b61d120b7248c2b49ea56ce754a050d6b348be42015fcb7aa25"}, - {file = "pydantic_core-2.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6ea8dd2854fe6cee5ea0d60304ee7877dffe487cf118f221e85029269dd1235d"}, - {file = "pydantic_core-2.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9bf3ba6b4878ee692f6e24230801f682807fd97356bc2064f630fc0a2ad2ead6"}, - {file = "pydantic_core-2.6.1-cp39-none-win32.whl", hash = "sha256:b974d65692333931b4c7f730e7a3135ff854a1e5384bc260de3327ea364c835a"}, - {file = "pydantic_core-2.6.1-cp39-none-win_amd64.whl", hash = "sha256:f34f26d8a5f1a45366189ec30a57f43b21e2172d0d3b62822638dd885cc8eaab"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f7ec4c6edafa3f0eb1aa461e31ea263736cc541b2459dddfbda7085b30844801"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3679b9a1f41eb1b699e9556f91281d78c416cdc59ae90d5733fbe2017f1effe9"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ff36f945342086ee917d4219dd0e59660a2dfcdb86a07696c2791f5d59c07d"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734864605d722a6f8db3b9c96371710f7cb591fbfca40cfeaedf5b67df282438"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7188359b95a2b1aef5744a2ee6af2d9cfc733dd823f8840f4c896129477a172b"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:382d40843ae759d43ef65b67dec713390f9417135c1dd730afbf03cf2f450f45"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4525b8498d362e4e324e3e175239b364768f52bd3563ac4ef9750160f5789de8"}, - {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e55514a022c768cccf07a675d20d07b847980dcd9250f6b516a86bab5612fc01"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:34734d486d059f0f6f5bfa9ba4a41449f666e2abbde002e9fa8b050bc50e3347"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a809498dceb0cd1cd1e57a2bfdc70ea82f424776e0196f4d63c4b6fcdaeb5aab"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:588a5ffd8bbf1b2230611ed1b45221adcf05b981037b2f853b5f20465849b5c1"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:26b81017aeae0d96f776fbce34a3a763d26ac575d8ad3f1202bdfdd2b935954b"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7ddaa2c3c66682f0ff4ebc8c85ef2d8305f32deba79416464c47c93d94ca3740"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d6971131de66d1a37293f2e032206b6984b0dec44f568b453dfe89a84a2de0cc"}, - {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:200704f6824f8014bdccb1ce57cbd328666e6de4ecd77f0b8ab472cdea9c49ce"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:6916b27072c957947919fb32551f08486562bb8616f2e3db9e4e9c1d83d36886"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:136de286abf53f326b90389aaaca8a8050c2570adfc74afe06ab1c35d5d242bf"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60a238bb4ab09a81a6b25c9a0bb12756cfab2d9f3a7a471f857a179f83da0df6"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2034d9b83a59b3b74b9dbf97ddb99de86c08863c1c33aabf80bc95791c7d50c3"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7c3a2b4d1636446dc71da1e949d2cf9ac1ee691ca63a640b77fce0360b4b75be"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:09e4ebd11a0b333b1fca75c1004c76dc9719f3aaf83ae38c42358754d8a76148"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a4536d132a8bbd05bf368fb802a264cb9828f6c85e4029a6a3670bc98ba97323"}, - {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6221c97d6d58f2370650cfe3d81408901a1951c99960e1df9f6f9f8482d73d08"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4223e8bdad41d846a84cda400cd538e1cdc63d98eb4d41951396bfdb88fd8ce9"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c07cdb2e02733e5f26b9b004a1a8b99814d175f8953fa9f59e4293de2b8e9787"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8714e958d01342d08e520ffec6c1acf66cdec83ce51302f9a1a6efb2f784d0b6"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f03541c25a77fb5445055e070b69d292c9818a9195ffbfd3962c0ad0da983e8"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:364c13ef48c9e2f8c2ea8ee0da5ea23db5e218f99e796cbf360a2a7cab511439"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:27ba58bbfd1b2b9da45bfe524e680e2bc747a1ca9738ee5aa18d8cbdcc08e5e6"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:92321582e59da185b76b2eca4488ea95e41800672e57107509d32ebf8ad550f8"}, - {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2da1d21a4f2675d5b8a749674993a65c0537e2066e7ab7b1a4a54ef0b3ac8efd"}, - {file = "pydantic_core-2.6.1.tar.gz", hash = "sha256:5b4efa68bcfa6f2b93624c6660b6cf4b7b4336d4225afb314254a0ed9c9f4153"}, + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"}, + {file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"}, + {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"}, + {file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"}, + {file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"}, + {file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"}, + {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"}, + {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"}, + {file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"}, + {file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"}, + {file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"}, + {file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"}, + {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"}, + {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"}, + {file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"}, + {file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"}, + {file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"}, + {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"}, + {file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"}, + {file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"}, + {file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"}, + {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"}, + {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"}, + {file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"}, + {file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"}, + {file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"}, + {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"}, + {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"}, + {file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"}, + {file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"}, + {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"}, + {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"}, + {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"}, + {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"}, + {file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"}, ] [package.dependencies] @@ -281,7 +271,6 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "ruff" version = "0.0.286" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -308,7 +297,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -320,7 +308,6 @@ files = [ name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -341,7 +328,6 @@ telegram = ["requests"] name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -352,4 +338,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "f7f9155971a72adc62f379b6d8804ab6b5d68f7605466290e9da90620a81bdbb" +content-hash = "0ea02aad62004aa8056fd027dab074af00d2b20bbf73c72cc64a19d10aafbb81" diff --git a/pyproject.toml b/pyproject.toml index 8bdd191..12a00e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.9" -pydantic = "^2.2.1" +pydantic = "^2.4.2" tqdm = "^4.66.1" From aca01413f547d99dbeae59f49babcf3e5aa7130e Mon Sep 17 00:00:00 2001 From: Matteo Campinoti Date: Mon, 16 Oct 2023 14:49:32 +0200 Subject: [PATCH 10/10] siegfried - add method to identify multiple files --- acacore/siegfried/siegfried.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/acacore/siegfried/siegfried.py b/acacore/siegfried/siegfried.py index 88536c7..6edd25b 100644 --- a/acacore/siegfried/siegfried.py +++ b/acacore/siegfried/siegfried.py @@ -1,5 +1,6 @@ from datetime import datetime from os import PathLike +from pathlib import Path from subprocess import CompletedProcess from subprocess import run from typing import Optional @@ -107,3 +108,28 @@ def identify(self, path: Union[str, PathLike]) -> SiegfriedResult: return SiegfriedResult.model_validate_json(process.stdout) except ValueError as err: raise IdentificationError(err) + + def identify_many(self, paths: list[Path]) -> tuple[tuple[Path, SiegfriedFile]]: + """ + Identify multiple files. + + Args: + paths: The paths to the files + + Returns: + A tuple of tuples joining the paths with their SiegfriedFile result + + Raises: + IdentificationError: If there is an error calling Siegfried or processing its results + """ + process: CompletedProcess = run( + [self.binary, "-json", "-multi", "1024", *map(str, paths)], + capture_output=True, + encoding="utf-8", + ) + _check_process(process) + try: + result = SiegfriedResult.model_validate_json(process.stdout) + return tuple(zip(paths, result.files)) + except ValueError as err: + raise IdentificationError(err)