merge main
This commit is contained in:
commit
1cb58728b2
76 changed files with 9241 additions and 5829 deletions
154
cli/src/api/open-api/api.ts
generated
154
cli/src/api/open-api/api.ts
generated
|
@ -862,6 +862,53 @@ export interface BulkIdsDto {
|
||||||
*/
|
*/
|
||||||
'ids': Array<string>;
|
'ids': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface CLIPConfig
|
||||||
|
*/
|
||||||
|
export interface CLIPConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {CLIPMode}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'mode'?: CLIPMode;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const CLIPMode = {
|
||||||
|
Vision: 'vision',
|
||||||
|
Text: 'text'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type CLIPMode = typeof CLIPMode[keyof typeof CLIPMode];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -951,6 +998,39 @@ export interface CheckExistingAssetsResponseDto {
|
||||||
*/
|
*/
|
||||||
'existingIds': Array<string>;
|
'existingIds': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ClassificationConfig
|
||||||
|
*/
|
||||||
|
export interface ClassificationConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'minScore': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -1766,6 +1846,21 @@ export interface MergePersonDto {
|
||||||
*/
|
*/
|
||||||
'ids': Array<string>;
|
'ids': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const ModelType = {
|
||||||
|
ImageClassification: 'image-classification',
|
||||||
|
FacialRecognition: 'facial-recognition',
|
||||||
|
Clip: 'clip'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type ModelType = typeof ModelType[keyof typeof ModelType];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -1991,6 +2086,45 @@ export interface QueueStatusDto {
|
||||||
*/
|
*/
|
||||||
'isPaused': boolean;
|
'isPaused': boolean;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface RecognitionConfig
|
||||||
|
*/
|
||||||
|
export interface RecognitionConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'maxDistance': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'minScore': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -2803,10 +2937,16 @@ export interface SystemConfigJobDto {
|
||||||
export interface SystemConfigMachineLearningDto {
|
export interface SystemConfigMachineLearningDto {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {ClassificationConfig}
|
||||||
* @memberof SystemConfigMachineLearningDto
|
* @memberof SystemConfigMachineLearningDto
|
||||||
*/
|
*/
|
||||||
'clipEncodeEnabled': boolean;
|
'classification': ClassificationConfig;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {CLIPConfig}
|
||||||
|
* @memberof SystemConfigMachineLearningDto
|
||||||
|
*/
|
||||||
|
'clip': CLIPConfig;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
|
@ -2815,16 +2955,10 @@ export interface SystemConfigMachineLearningDto {
|
||||||
'enabled': boolean;
|
'enabled': boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {RecognitionConfig}
|
||||||
* @memberof SystemConfigMachineLearningDto
|
* @memberof SystemConfigMachineLearningDto
|
||||||
*/
|
*/
|
||||||
'facialRecognitionEnabled': boolean;
|
'facialRecognition': RecognitionConfig;
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof SystemConfigMachineLearningDto
|
|
||||||
*/
|
|
||||||
'tagImageEnabled': boolean;
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
|
|
@ -8,17 +8,11 @@ from .schemas import ModelType
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
cache_folder: str = "/cache"
|
cache_folder: str = "/cache"
|
||||||
classification_model: str = "microsoft/resnet-50"
|
|
||||||
clip_image_model: str = "ViT-B-32::openai"
|
|
||||||
clip_text_model: str = "ViT-B-32::openai"
|
|
||||||
facial_recognition_model: str = "buffalo_l"
|
|
||||||
min_tag_score: float = 0.9
|
|
||||||
eager_startup: bool = False
|
eager_startup: bool = False
|
||||||
model_ttl: int = 0
|
model_ttl: int = 0
|
||||||
host: str = "0.0.0.0"
|
host: str = "0.0.0.0"
|
||||||
port: int = 3003
|
port: int = 3003
|
||||||
workers: int = 1
|
workers: int = 1
|
||||||
min_face_score: float = 0.7
|
|
||||||
test_full: bool = False
|
test_full: bool = False
|
||||||
request_threads: int = os.cpu_count() or 4
|
request_threads: int = os.cpu_count() or 4
|
||||||
model_inter_op_threads: int = 1
|
model_inter_op_threads: int = 1
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from io import BytesIO
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import cv2
|
import orjson
|
||||||
import numpy as np
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import Body, Depends, FastAPI
|
from fastapi import FastAPI, Form, HTTPException, UploadFile
|
||||||
from PIL import Image
|
from fastapi.responses import ORJSONResponse
|
||||||
|
from starlette.formparsers import MultiPartParser
|
||||||
|
|
||||||
from app.models.base import InferenceModel
|
from app.models.base import InferenceModel
|
||||||
|
|
||||||
from .config import settings
|
from .config import settings
|
||||||
from .models.cache import ModelCache
|
from .models.cache import ModelCache
|
||||||
from .schemas import (
|
from .schemas import (
|
||||||
EmbeddingResponse,
|
|
||||||
FaceResponse,
|
|
||||||
MessageResponse,
|
MessageResponse,
|
||||||
ModelType,
|
ModelType,
|
||||||
TagResponse,
|
|
||||||
TextModelRequest,
|
|
||||||
TextResponse,
|
TextResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
MultiPartParser.max_file_size = 2**24 # spools to disk if payload is 16 MiB or larger
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,37 +30,9 @@ def init_state() -> None:
|
||||||
app.state.thread_pool = ThreadPoolExecutor(settings.request_threads)
|
app.state.thread_pool = ThreadPoolExecutor(settings.request_threads)
|
||||||
|
|
||||||
|
|
||||||
async def load_models() -> None:
|
|
||||||
models: list[tuple[str, ModelType, dict[str, Any]]] = [
|
|
||||||
(settings.classification_model, ModelType.IMAGE_CLASSIFICATION, {}),
|
|
||||||
(settings.clip_image_model, ModelType.CLIP, {"mode": "vision"}),
|
|
||||||
(settings.clip_text_model, ModelType.CLIP, {"mode": "text"}),
|
|
||||||
(settings.facial_recognition_model, ModelType.FACIAL_RECOGNITION, {}),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Get all models
|
|
||||||
for model_name, model_type, model_kwargs in models:
|
|
||||||
await app.state.model_cache.get(model_name, model_type, eager=settings.eager_startup, **model_kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
async def startup_event() -> None:
|
async def startup_event() -> None:
|
||||||
init_state()
|
init_state()
|
||||||
await load_models()
|
|
||||||
|
|
||||||
|
|
||||||
@app.on_event("shutdown")
|
|
||||||
async def shutdown_event() -> None:
|
|
||||||
app.state.thread_pool.shutdown()
|
|
||||||
|
|
||||||
|
|
||||||
def dep_pil_image(byte_image: bytes = Body(...)) -> Image.Image:
|
|
||||||
return Image.open(BytesIO(byte_image))
|
|
||||||
|
|
||||||
|
|
||||||
def dep_cv_image(byte_image: bytes = Body(...)) -> np.ndarray[int, np.dtype[Any]]:
|
|
||||||
byte_image_np = np.frombuffer(byte_image, np.uint8)
|
|
||||||
return cv2.imdecode(byte_image_np, cv2.IMREAD_COLOR)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/", response_model=MessageResponse)
|
@app.get("/", response_model=MessageResponse)
|
||||||
|
@ -76,57 +45,27 @@ def ping() -> str:
|
||||||
return "pong"
|
return "pong"
|
||||||
|
|
||||||
|
|
||||||
@app.post(
|
@app.post("/predict")
|
||||||
"/image-classifier/tag-image",
|
async def predict(
|
||||||
response_model=TagResponse,
|
model_name: str = Form(alias="modelName"),
|
||||||
status_code=200,
|
model_type: ModelType = Form(alias="modelType"),
|
||||||
)
|
options: str = Form(default="{}"),
|
||||||
async def image_classification(
|
text: str | None = Form(default=None),
|
||||||
image: Image.Image = Depends(dep_pil_image),
|
image: UploadFile | None = None,
|
||||||
) -> list[str]:
|
) -> Any:
|
||||||
model = await app.state.model_cache.get(settings.classification_model, ModelType.IMAGE_CLASSIFICATION)
|
if image is not None:
|
||||||
labels = await predict(model, image)
|
inputs: str | bytes = await image.read()
|
||||||
return labels
|
elif text is not None:
|
||||||
|
inputs = text
|
||||||
|
else:
|
||||||
|
raise HTTPException(400, "Either image or text must be provided")
|
||||||
|
|
||||||
|
model: InferenceModel = await app.state.model_cache.get(model_name, model_type, **orjson.loads(options))
|
||||||
|
outputs = await run(model, inputs)
|
||||||
|
return ORJSONResponse(outputs)
|
||||||
|
|
||||||
|
|
||||||
@app.post(
|
async def run(model: InferenceModel, inputs: Any) -> Any:
|
||||||
"/sentence-transformer/encode-image",
|
|
||||||
response_model=EmbeddingResponse,
|
|
||||||
status_code=200,
|
|
||||||
)
|
|
||||||
async def clip_encode_image(
|
|
||||||
image: Image.Image = Depends(dep_pil_image),
|
|
||||||
) -> list[float]:
|
|
||||||
model = await app.state.model_cache.get(settings.clip_image_model, ModelType.CLIP, mode="vision")
|
|
||||||
embedding = await predict(model, image)
|
|
||||||
return embedding
|
|
||||||
|
|
||||||
|
|
||||||
@app.post(
|
|
||||||
"/sentence-transformer/encode-text",
|
|
||||||
response_model=EmbeddingResponse,
|
|
||||||
status_code=200,
|
|
||||||
)
|
|
||||||
async def clip_encode_text(payload: TextModelRequest) -> list[float]:
|
|
||||||
model = await app.state.model_cache.get(settings.clip_text_model, ModelType.CLIP, mode="text")
|
|
||||||
embedding = await predict(model, payload.text)
|
|
||||||
return embedding
|
|
||||||
|
|
||||||
|
|
||||||
@app.post(
|
|
||||||
"/facial-recognition/detect-faces",
|
|
||||||
response_model=FaceResponse,
|
|
||||||
status_code=200,
|
|
||||||
)
|
|
||||||
async def facial_recognition(
|
|
||||||
image: cv2.Mat = Depends(dep_cv_image),
|
|
||||||
) -> list[dict[str, Any]]:
|
|
||||||
model = await app.state.model_cache.get(settings.facial_recognition_model, ModelType.FACIAL_RECOGNITION)
|
|
||||||
faces = await predict(model, image)
|
|
||||||
return faces
|
|
||||||
|
|
||||||
|
|
||||||
async def predict(model: InferenceModel, inputs: Any) -> Any:
|
|
||||||
return await asyncio.get_running_loop().run_in_executor(app.state.thread_pool, model.predict, inputs)
|
return await asyncio.get_running_loop().run_in_executor(app.state.thread_pool, model.predict, inputs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,16 +60,21 @@ class InferenceModel(ABC):
|
||||||
self._load(**model_kwargs)
|
self._load(**model_kwargs)
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
|
|
||||||
def predict(self, inputs: Any) -> Any:
|
def predict(self, inputs: Any, **model_kwargs: Any) -> Any:
|
||||||
if not self._loaded:
|
if not self._loaded:
|
||||||
print(f"Loading {self.model_type.value.replace('_', ' ')} model...")
|
print(f"Loading {self.model_type.value.replace('_', ' ')} model...")
|
||||||
self.load()
|
self.load()
|
||||||
|
if model_kwargs:
|
||||||
|
self.configure(**model_kwargs)
|
||||||
return self._predict(inputs)
|
return self._predict(inputs)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def _predict(self, inputs: Any) -> Any:
|
def _predict(self, inputs: Any) -> Any:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
def configure(self, **model_kwargs: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def _download(self, **model_kwargs: Any) -> None:
|
def _download(self, **model_kwargs: Any) -> None:
|
||||||
...
|
...
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from io import BytesIO
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
|
|
||||||
import onnxruntime as ort
|
import onnxruntime as ort
|
||||||
|
@ -8,7 +9,7 @@ from clip_server.model.clip import BICUBIC, _convert_image_to_rgb
|
||||||
from clip_server.model.clip_onnx import _MODELS, _S3_BUCKET_V2, CLIPOnnxModel, download_model
|
from clip_server.model.clip_onnx import _MODELS, _S3_BUCKET_V2, CLIPOnnxModel, download_model
|
||||||
from clip_server.model.pretrained_models import _VISUAL_MODEL_IMAGE_SIZE
|
from clip_server.model.pretrained_models import _VISUAL_MODEL_IMAGE_SIZE
|
||||||
from clip_server.model.tokenization import Tokenizer
|
from clip_server.model.tokenization import Tokenizer
|
||||||
from PIL.Image import Image
|
from PIL import Image
|
||||||
from torchvision.transforms import CenterCrop, Compose, Normalize, Resize, ToTensor
|
from torchvision.transforms import CenterCrop, Compose, Normalize, Resize, ToTensor
|
||||||
|
|
||||||
from ..schemas import ModelType
|
from ..schemas import ModelType
|
||||||
|
@ -74,9 +75,12 @@ class CLIPEncoder(InferenceModel):
|
||||||
image_size = _VISUAL_MODEL_IMAGE_SIZE[CLIPOnnxModel.get_model_name(self.model_name)]
|
image_size = _VISUAL_MODEL_IMAGE_SIZE[CLIPOnnxModel.get_model_name(self.model_name)]
|
||||||
self.transform = _transform_pil_image(image_size)
|
self.transform = _transform_pil_image(image_size)
|
||||||
|
|
||||||
def _predict(self, image_or_text: Image | str) -> list[float]:
|
def _predict(self, image_or_text: Image.Image | str) -> list[float]:
|
||||||
|
if isinstance(image_or_text, bytes):
|
||||||
|
image_or_text = Image.open(BytesIO(image_or_text))
|
||||||
|
|
||||||
match image_or_text:
|
match image_or_text:
|
||||||
case Image():
|
case Image.Image():
|
||||||
if self.mode == "text":
|
if self.mode == "text":
|
||||||
raise TypeError("Cannot encode image as text-only model")
|
raise TypeError("Cannot encode image as text-only model")
|
||||||
pixel_values = self.transform(image_or_text)
|
pixel_values = self.transform(image_or_text)
|
||||||
|
|
|
@ -9,7 +9,6 @@ from insightface.model_zoo import ArcFaceONNX, RetinaFace
|
||||||
from insightface.utils.face_align import norm_crop
|
from insightface.utils.face_align import norm_crop
|
||||||
from insightface.utils.storage import BASE_REPO_URL, download_file
|
from insightface.utils.storage import BASE_REPO_URL, download_file
|
||||||
|
|
||||||
from ..config import settings
|
|
||||||
from ..schemas import ModelType
|
from ..schemas import ModelType
|
||||||
from .base import InferenceModel
|
from .base import InferenceModel
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ class FaceRecognizer(InferenceModel):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
model_name: str,
|
model_name: str,
|
||||||
min_score: float = settings.min_face_score,
|
min_score: float = 0.7,
|
||||||
cache_dir: Path | str | None = None,
|
cache_dir: Path | str | None = None,
|
||||||
**model_kwargs: Any,
|
**model_kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -69,11 +68,13 @@ class FaceRecognizer(InferenceModel):
|
||||||
)
|
)
|
||||||
self.rec_model.prepare(ctx_id=0)
|
self.rec_model.prepare(ctx_id=0)
|
||||||
|
|
||||||
def _predict(self, image: cv2.Mat) -> list[dict[str, Any]]:
|
def _predict(self, image: np.ndarray[int, np.dtype[Any]] | bytes) -> list[dict[str, Any]]:
|
||||||
|
if isinstance(image, bytes):
|
||||||
|
image = cv2.imdecode(np.frombuffer(image, np.uint8), cv2.IMREAD_COLOR)
|
||||||
bboxes, kpss = self.det_model.detect(image)
|
bboxes, kpss = self.det_model.detect(image)
|
||||||
if bboxes.size == 0:
|
if bboxes.size == 0:
|
||||||
return []
|
return []
|
||||||
assert isinstance(kpss, np.ndarray)
|
assert isinstance(image, np.ndarray) and isinstance(kpss, np.ndarray)
|
||||||
|
|
||||||
scores = bboxes[:, 4].tolist()
|
scores = bboxes[:, 4].tolist()
|
||||||
bboxes = bboxes[:, :4].round().tolist()
|
bboxes = bboxes[:, :4].round().tolist()
|
||||||
|
@ -102,3 +103,6 @@ class FaceRecognizer(InferenceModel):
|
||||||
@property
|
@property
|
||||||
def cached(self) -> bool:
|
def cached(self) -> bool:
|
||||||
return self.cache_dir.is_dir() and any(self.cache_dir.glob("*.onnx"))
|
return self.cache_dir.is_dir() and any(self.cache_dir.glob("*.onnx"))
|
||||||
|
|
||||||
|
def configure(self, **model_kwargs: Any) -> None:
|
||||||
|
self.det_model.det_thresh = model_kwargs.get("min_score", self.det_model.det_thresh)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
from io import BytesIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from huggingface_hub import snapshot_download
|
from huggingface_hub import snapshot_download
|
||||||
from optimum.onnxruntime import ORTModelForImageClassification
|
from optimum.onnxruntime import ORTModelForImageClassification
|
||||||
from optimum.pipelines import pipeline
|
from optimum.pipelines import pipeline
|
||||||
from PIL.Image import Image
|
from PIL import Image
|
||||||
from transformers import AutoImageProcessor
|
from transformers import AutoImageProcessor
|
||||||
|
|
||||||
from ..config import settings
|
|
||||||
from ..schemas import ModelType
|
from ..schemas import ModelType
|
||||||
from .base import InferenceModel
|
from .base import InferenceModel
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class ImageClassifier(InferenceModel):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
model_name: str,
|
model_name: str,
|
||||||
min_score: float = settings.min_tag_score,
|
min_score: float = 0.9,
|
||||||
cache_dir: Path | str | None = None,
|
cache_dir: Path | str | None = None,
|
||||||
**model_kwargs: Any,
|
**model_kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -56,8 +56,13 @@ class ImageClassifier(InferenceModel):
|
||||||
feature_extractor=processor,
|
feature_extractor=processor,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _predict(self, image: Image) -> list[str]:
|
def _predict(self, image: Image.Image | bytes) -> list[str]:
|
||||||
|
if isinstance(image, bytes):
|
||||||
|
image = Image.open(BytesIO(image))
|
||||||
predictions: list[dict[str, Any]] = self.model(image) # type: ignore
|
predictions: list[dict[str, Any]] = self.model(image) # type: ignore
|
||||||
tags = [tag for pred in predictions for tag in pred["label"].split(", ") if pred["score"] >= self.min_score]
|
tags = [tag for pred in predictions for tag in pred["label"].split(", ") if pred["score"] >= self.min_score]
|
||||||
|
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
def configure(self, **model_kwargs: Any) -> None:
|
||||||
|
self.min_score = model_kwargs.get("min_score", self.min_score)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from enum import Enum
|
from enum import StrEnum
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
@ -20,18 +20,6 @@ class MessageResponse(BaseModel):
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
class TagResponse(BaseModel):
|
|
||||||
__root__: list[str]
|
|
||||||
|
|
||||||
|
|
||||||
class Embedding(BaseModel):
|
|
||||||
__root__: list[float]
|
|
||||||
|
|
||||||
|
|
||||||
class EmbeddingResponse(BaseModel):
|
|
||||||
__root__: Embedding
|
|
||||||
|
|
||||||
|
|
||||||
class BoundingBox(BaseModel):
|
class BoundingBox(BaseModel):
|
||||||
x1: int
|
x1: int
|
||||||
y1: int
|
y1: int
|
||||||
|
@ -39,23 +27,7 @@ class BoundingBox(BaseModel):
|
||||||
y2: int
|
y2: int
|
||||||
|
|
||||||
|
|
||||||
class Face(BaseModel):
|
class ModelType(StrEnum):
|
||||||
image_width: int
|
|
||||||
image_height: int
|
|
||||||
bounding_box: BoundingBox
|
|
||||||
score: float
|
|
||||||
embedding: Embedding
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
alias_generator = to_lower_camel
|
|
||||||
allow_population_by_field_name = True
|
|
||||||
|
|
||||||
|
|
||||||
class FaceResponse(BaseModel):
|
|
||||||
__root__: list[Face]
|
|
||||||
|
|
||||||
|
|
||||||
class ModelType(Enum):
|
|
||||||
IMAGE_CLASSIFICATION = "image-classification"
|
IMAGE_CLASSIFICATION = "image-classification"
|
||||||
CLIP = "clip"
|
CLIP = "clip"
|
||||||
FACIAL_RECOGNITION = "facial-recognition"
|
FACIAL_RECOGNITION = "facial-recognition"
|
||||||
|
|
799
machine-learning/poetry.lock
generated
799
machine-learning/poetry.lock
generated
|
@ -720,69 +720,69 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cython"
|
name = "cython"
|
||||||
version = "3.0.0"
|
version = "3.0.2"
|
||||||
description = "The Cython compiler for writing C extensions in the Python language."
|
description = "The Cython compiler for writing C extensions in the Python language."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
files = [
|
files = [
|
||||||
{file = "Cython-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c7d728e1a49ad01d41181e3a9ea80b8d14e825f4679e4dd837cbf7bca7998a5"},
|
{file = "Cython-3.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8ccb91d2254e34724f1541b2a6fcdfacdb88284185b0097ae84e0ddf476c7a38"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:626a4a6ef4b7ced87c348ea805488e4bd39dad9d0b39659aa9e1040b62bbfedf"},
|
{file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c298b1589205ecaaed0457ad05e0c8a43e7db2053607f48ed4a899cb6aa114df"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33c900d1ca9f622b969ac7d8fc44bdae140a4a6c7d8819413b51f3ccd0586a09"},
|
{file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e825e682cef76d0c33384f38b56b7e87c76152482a914dfc78faed6ff66ce05a"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a65bc50dc1bc2faeafd9425defbdef6a468974f5c4192497ff7f14adccfdcd32"},
|
{file = "Cython-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77ec0134fc1b10aebef2013936a91c07bff2498ec283bc2eca099ee0cb94d12e"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b71b399b10b038b056ad12dce1e317a8aa7a96e99de7e4fa2fa5d1c9415cfb9"},
|
{file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c90eeb94395315e65fd758a2f86b92904fce7b50060b4d45a878ef6767f9276e"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f42f304c097cc53e9eb5f1a1d150380353d5018a3191f1b77f0de353c762181e"},
|
{file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:38085523fa7a299638d051ae08144222785639882f6291bd275c0b12db1034ff"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-win32.whl", hash = "sha256:3e234e2549e808d9259fdb23ebcfd145be30c638c65118326ec33a8d29248dc2"},
|
{file = "Cython-3.0.2-cp310-cp310-win32.whl", hash = "sha256:b032cb0c69082f0665b2c5fb416d041157062f1538336d0edf823b9ee500e39c"},
|
||||||
{file = "Cython-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:829c8333195100448a23863cf64a07e1334fae6a275aefe871458937911531b6"},
|
{file = "Cython-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:067b2b9eb487bd61367b296f11b7c1c70a084b3eb7d5a572f607cd1fc5ca5586"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06db81b1a01858fcc406616f8528e686ffb6cf7c3d78fb83767832bfecea8ad8"},
|
{file = "Cython-3.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:213ff9f95de319e54b520bf31edd6aa7a1fa4fbf617c2beb0f92362595e6476a"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c93634845238645ce7abf63a56b1c5b6248189005c7caff898fd4a0dac1c5e1e"},
|
{file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bebbca13078125a35937966137af4bd0300a0c66fd7ae4ce36adc049b13bdf3"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa606675c6bd23478b1d174e2a84e3c5a2c660968f97dc455afe0fae198f9d3d"},
|
{file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e5587128e8c2423aefcffa4ded4ddf60d44898938fbb7c0f236636a750a94f"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3355e6f690184f984eeb108b0f5bbc4bcf8b9444f8168933acf79603abf7baf"},
|
{file = "Cython-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e2853d484643c6b7ac3bdb48392753442da1c71b689468fa3176b619bebe54"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:93a34e1ca8afa4b7075b02ed14a7e4969256297029fb1bfd4cbe48f7290dbcff"},
|
{file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e722732e9aa9bde667ed6d87525234823eb7766ca234cfb19d7e0c095a2ef4"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb1165ca9e78823f9ad1efa5b3d83156f868eabd679a615d140a3021bb92cd65"},
|
{file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:989787fc24a95100a26918b6577d06e15a8868a3ed267009c5cfcf1a906179ac"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-win32.whl", hash = "sha256:2fadde1da055944f5e1e17625055f54ddd11f451889110278ef30e07bd5e1695"},
|
{file = "Cython-3.0.2-cp311-cp311-win32.whl", hash = "sha256:d21801981db44b7e9f9768f121317946461d56b51de1e6eff3c42e8914048696"},
|
||||||
{file = "Cython-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:254ed1f03a6c237fa64f0c6e44862058de65bfa2e6a3b48ca3c205492e0653aa"},
|
{file = "Cython-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:809617cf4825b2138ce0ec827e1f28e39668743c81ac8286373f8d148c05f088"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4e212237b7531759befb92699c452cd65074a78051ae4ee36ff8b237395ecf3d"},
|
{file = "Cython-3.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5682293d344b7dbad97ce6eceb9e887aca6e53499709db9da726ca3424e5559d"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f29307463eba53747b31f71394ed087e3e3e264dcc433e62de1d51f5c0c966c"},
|
{file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e08ff5da5f5b969639784b1bffcd880a0c0f048d182aed7cba9945ee8b367c2"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53328a8af0806bebbdb48a4191883b11ee9d9dfb084d84f58fa5a8ab58baefc9"},
|
{file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8850269ff59f77a1629e26d0576701925360d732011d6d3516ccdc5b2c2bc310"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5962e70b15e863e72bed6910e8c6ffef77d36cc98e2b31c474378f3b9e49b0e3"},
|
{file = "Cython-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:550b3fbe9b3c555b44ded934f4822f9fcc04dfcee512167ebcbbd370ccede20e"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9e69139f4e60ab14c50767a568612ea64d6907e9c8e0289590a170eb495e005f"},
|
{file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4db017b104f47b1185237702f6ed2651839c8124614683efa7c489f3fa4e19d9"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c40bdbcb2286f0aeeb5df9ce53d45da2d2a9b36a16b331cd0809d212d22a8fc7"},
|
{file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75a2395cc7b78cff59be6e9b7f92bbb5d7b8d25203f6d3fb6f72bdb7d3f49777"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-win32.whl", hash = "sha256:8abb8915eb2e57fa53d918afe641c05d1bcc6ed1913682ec1f28de71f4e3f398"},
|
{file = "Cython-3.0.2-cp312-cp312-win32.whl", hash = "sha256:786b6034a91e886116bb562fe42f8bf0f97c3e00c02e56791d02675959ed65b1"},
|
||||||
{file = "Cython-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:30a4bd2481e59bd7ab2539f835b78edc19fc455811e476916f56026b93afd28b"},
|
{file = "Cython-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc9d173ab8b167cae674f6deed8c65ba816574797a2bd6d8aa623277d1fa81ca"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0e1e4b7e4bfbf22fecfa5b852f0e499c442d4853b7ebd33ae37cdec9826ed5d8"},
|
{file = "Cython-3.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8948504338d7a140ce588333177dcabf0743a68dbc83b0174f214f5b959634d5"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b00df42cdd1a285a64491ba23de08ab14169d3257c840428d40eb7e8e9979af"},
|
{file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a51efba0e136b2af358e5a347bae09678b17460c35cf1eab24f0476820348991"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:650d03ddddc08b051b4659778733f0f173ca7d327415755c05d265a6c1ba02fb"},
|
{file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05cb2a73810f045d328b7579cf98f550a9e601df5e282d1fea0512d8ad589011"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4965f2ebade17166f21a508d66dd60d2a0b3a3b90abe3f72003baa17ae020dd6"},
|
{file = "Cython-3.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22ba78e48bdb65977928ecb275ac8c82df7b0eefa075078a1363a5af4606b42e"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4123c8d03167803df31da6b39de167cb9c04ac0aa4e35d4e5aa9d08ad511b84d"},
|
{file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:302281b927409b3e0ef8cd9251eab782cf1acd2578eab305519fbae5d184b7e9"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:296c53b6c0030cf82987eef163444e8d7631cc139d995f9d58679d9fd1ddbf31"},
|
{file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a1c3675394b81024aaf56e4f53c2b4f81d9a116c7049e9d4706f810899c9134e"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-win32.whl", hash = "sha256:0d2c1e172f1c81bafcca703093608e10dc16e3e2d24c5644c17606c7fdb1792c"},
|
{file = "Cython-3.0.2-cp36-cp36m-win32.whl", hash = "sha256:34f7b014ebce5d325c8084e396c81cdafbd8d82be56780dffe6b67b28c891f1b"},
|
||||||
{file = "Cython-3.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:bc816d8eb3686d6f8d165f4156bac18c1147e1035dc28a76742d0b7fb5b7c032"},
|
{file = "Cython-3.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:477cd3549597f09a1608da7b05e16ba641e9aedd171b868533a5a07790ed886f"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8d86651347bbdbac1aca1824696c5e4c0a3b162946c422edcca2be12a03744d1"},
|
{file = "Cython-3.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a49dde9f9e29ea82f29aaf3bb1a270b6eb90b75d627c7ff2f5dd3764540ae646"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84176bd04ce9f3cc8799b47ec6d1959fa1ea5e71424507df7bbf0b0915bbedef"},
|
{file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc1c8013fad0933f5201186eccc5f2be223cafd6a8dcd586d3f7bb6ba84dc845"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35abcf07b8277ec95bbe49a07b5c8760a2d941942ccfe759a94c8d2fe5602e9f"},
|
{file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b75e9c9d7ad7c9dd85d45241d1d4e3c5f66079c1f84eec91689c26d98bc3349"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a44d6b9a29b2bff38bb648577b2fcf6a68cf8b1783eee89c2eb749f69494b98d"},
|
{file = "Cython-3.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f43c4d3ecd9e3b8b7afe834e519f55cf4249b1088f96d11b96f02c55cbaeff7"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4dc6bbe7cf079db37f1ebb9b0f10d0d7f29e293bb8688e92d50b5ea7a91d82f3"},
|
{file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dab6a923e21e212aa3dc6dde9b22a190f5d7c449315a94e57ddc019ea74a979b"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e28763e75e380b8be62b02266a7995a781997c97c119efbdccb8fb954bcd7574"},
|
{file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae453cfa933b919c0a19d2cc5dc9fb28486268e95dc2ab7a11ab7f99cf8c3883"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-win32.whl", hash = "sha256:edae615cb4af51d5173e76ba9aea212424d025c57012e9cdf2f131f774c5ba71"},
|
{file = "Cython-3.0.2-cp37-cp37m-win32.whl", hash = "sha256:b1f023d36a3829069ed11017c670128be3f135a9c17bd64c35d3b3442243b05c"},
|
||||||
{file = "Cython-3.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:20c604e974832aaf8b7a1f5455ee7274b34df62a35ee095cd7d2ed7e818e6c53"},
|
{file = "Cython-3.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:011c4e0b75baee1843334562487eb4fbc0c59ddb2cc32a978b972a81eedcbdcc"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c85fd2b1cbd9400d60ebe074795bb9a9188752f1612be3b35b0831a24879b91f"},
|
{file = "Cython-3.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:832bbee87bca760efeae248ddf19ccd77f9a2355cb6f8a64f20cc377e56957b3"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:090256c687106932339f87f888b95f0d69c617bc9b18801555545b695d29d8ab"},
|
{file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe806d154b6b7f0ab746dac36c022889e2e7cf47546ff9afdc29a62cfa692d0"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cec2a67a0a7d9d4399758c0657ca03e5912e37218859cfbf046242cc532bfb3b"},
|
{file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e486331a29e7700b1ad5f4f753bef483c81412a5e64a873df46d6cb66f9a65de"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1cdd01ce45333bc264a218c6e183700d6b998f029233f586a53c9b13455c2d2"},
|
{file = "Cython-3.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d41a1dfbaab74449873e7f8e6cd4239850fe7a50f7f784dd99a560927f3bac"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecee663d2d50ca939fc5db81f2f8a219c2417b4651ad84254c50a03a9cb1aadd"},
|
{file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4dca13c86d6cd523c7d8bbf8db1b2bbf8faedd0addedb229158d8015ad1819e1"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:30f10e79393b411af7677c270ea69807acb9fc30205c8ff25561f4deef780ec1"},
|
{file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:10cbfb37f31938371a6213cc8b5459c639954aed053efeded3c012d4c5915db9"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-win32.whl", hash = "sha256:609777d3a7a0a23b225e84d967af4ad2485c8bdfcacef8037cf197e87d431ca0"},
|
{file = "Cython-3.0.2-cp38-cp38-win32.whl", hash = "sha256:e663c237579c033deaa2cb362b74651da7712f56e441c11382510a8c4c4f2dd7"},
|
||||||
{file = "Cython-3.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:7f4a6dfd42ae0a45797f50fc4f6add702abf46ab3e7cd61811a6c6a97a40e1a2"},
|
{file = "Cython-3.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:2f84bd6cefa5130750c492038170c44f1cbd6f42e9ed85e168fd9cb453f85160"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2d8158277c8942c0b20ff4c074fe6a51c5b89e6ac60cef606818de8c92773596"},
|
{file = "Cython-3.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f37e4287f520f3748a06ad5eaae09ba4ac68f52e155d70de5f75780d83575c43"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e34f99b2a8c1e11478541b2822e6408c132b98b6b8f5ed89411e5e906631ea"},
|
{file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd30826ca8b27b2955a63c8ffe8aacc9f0779582b4bd154cf7b441ac10dae2cb"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:877d1c8745df59dd2061a0636c602729e9533ba13f13aa73a498f68662e1cbde"},
|
{file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08d67c7225a09eeb77e090c8d4f60677165b052ccf76e3a57d8237064e5c2de2"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204690be60f0ff32eb70b04f28ef0d1e50ffd7b3f77ba06a7dc2389ee3b848e0"},
|
{file = "Cython-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e625eec8c5c9a8cb062a318b257cc469d301bed952c7daf86e38bbd3afe7c91"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06fcb4628ccce2ba5abc8630adbeaf4016f63a359b4c6c3827b2d80e0673981c"},
|
{file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1b12a8f23270675b537d1c3b988f845bea4bbcc66ae0468857f5ede0526d4522"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:090e24cfa31c926d0b13d8bb2ef48175acdd061ae1413343c94a2b12a4a4fa6f"},
|
{file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:62dd78afdf748a58dae9c9b9c42a1519ae30787b28ce5f84a0e1bb54144142ca"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-win32.whl", hash = "sha256:4cd00f2158dc00f7f93a92444d0f663eda124c9c29bbbd658964f4e89c357fe8"},
|
{file = "Cython-3.0.2-cp39-cp39-win32.whl", hash = "sha256:d0d0cc4ecc05f41c5e02af14ac0083552d22efed976f79eb7bade55fed63b25d"},
|
||||||
{file = "Cython-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:5b4cc896d49ce2bae8d6a030f9a4c64965b59c38acfbf4617685e17f7fcf1731"},
|
{file = "Cython-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:147cc1d3dda8b06de9d86df5e59cdf15f0a522620168b7349a5ec88b48104d7d"},
|
||||||
{file = "Cython-3.0.0-py2.py3-none-any.whl", hash = "sha256:ff1aef1a03cfe293237c7a86ae9625b0411b2df30c53d1a7f29a8d381f38a1df"},
|
{file = "Cython-3.0.2-py2.py3-none-any.whl", hash = "sha256:8f1c9e4b8e413da211dd7942440cf410ff0eafb081309e04e81f4fafbb146bf2"},
|
||||||
{file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"},
|
{file = "Cython-3.0.2.tar.gz", hash = "sha256:9594818dca8bb22ae6580c5222da2bc5cc32334350bd2d294a00d8669bcc61b5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -889,13 +889,13 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flask"
|
name = "flask"
|
||||||
version = "2.3.2"
|
version = "2.3.3"
|
||||||
description = "A simple framework for building complex web applications."
|
description = "A simple framework for building complex web applications."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "Flask-2.3.2-py3-none-any.whl", hash = "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0"},
|
{file = "flask-2.3.3-py3-none-any.whl", hash = "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b"},
|
||||||
{file = "Flask-2.3.2.tar.gz", hash = "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef"},
|
{file = "flask-2.3.3.tar.gz", hash = "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -903,7 +903,7 @@ blinker = ">=1.6.2"
|
||||||
click = ">=8.1.3"
|
click = ">=8.1.3"
|
||||||
itsdangerous = ">=2.1.2"
|
itsdangerous = ">=2.1.2"
|
||||||
Jinja2 = ">=3.1.2"
|
Jinja2 = ">=3.1.2"
|
||||||
Werkzeug = ">=2.3.3"
|
Werkzeug = ">=2.3.7"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
async = ["asgiref (>=3.2)"]
|
async = ["asgiref (>=3.2)"]
|
||||||
|
@ -1185,101 +1185,119 @@ test = ["cffi (>=1.12.2)", "coverage (>=5.0)", "dnspython (>=1.16.0,<2.0)", "idn
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "geventhttpclient"
|
name = "geventhttpclient"
|
||||||
version = "2.0.9"
|
version = "2.0.10"
|
||||||
description = "http client library for gevent"
|
description = "http client library for gevent"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f4dcd420c74f68ffc493abdc0964583f762e0f03c9ccd62b8dcfa589f8cabe49"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2ba6814f4a31286573f7fd24154bdb9cbe4ae01e754f48d71b1944798bf663"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5fe8766994434ed6dc807d2e5726e9cec536b5593885b50598fe763908242054"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c01dfb0de68f219b7a534121caa71481e32574bba7fe547fa37ee47a73a7b224"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c23aacbe40f767d4bfb4215b51302d68f9611f2e730521e65c7239854177c30f"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1b2c7e6bb15910a2e86f8da375adfd63ac07587a1c764cedc082b00390bcd76e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f9ead0e6eb8302b394744c8ad7df71b1482e40402ecc208b446dba870bbafa1"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:022801e2323e3e673e3c7034f6bc5440b4651649df03396eb1b3a86a6aba899d"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15393cf588d24bf90b430299733ed161829065d14df99db250b40a83ec7978aa"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcfc1489e71b010d8ce8857578cdb1b8ba348626807aa9d077fc73c9864e51e1"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41b35daa9fe8217f295bc162492260daf4d4e1d9e3e8ed1fa2085a003cb5bb86"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef527f67653488000218283368e526fa699604e03e98ce4e0e588e89116977d"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0373b1d920cb2c1d65913258e2abe1534f5c6d1e687ed9322ad47858d75fd7d0"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a673a4b6b1839c8491372e43208912040c25a34254c60bf1d084489ddc300ee"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:344f22ce6cc959e67c32c9992422ee623b2e92da80b7774f939a03a8f66a823b"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2ceae04de8bdb4ef1d0ca7724cd9cad77c6611aac3830a24a7f13747e8b748c7"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2f467fc073631dd7c13f289ab59e82ae9b181a1faabcc8b23be48a48e8e45ba9"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dc3effc56065a5c26292ca26127e6fdd0f68429b413e847a8b7bad38972aab53"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:9f1395906e79b7d3db97199625ae9050c1249e2cb8073bb32495c375af351849"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:304c1d24d33b19cae53614ffc91c68d1e682d8b60a4d9eefcf87fcd099b1c2f2"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3c8f035c55f8db9b3a976d813dd20965ecf957e268e420e66b88cba81a66f3ac"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d39b468aba4dbec358eb0205d41791afc53651eee789566239e544ed6c8b7dbb"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-win32.whl", hash = "sha256:372776cdcad9a34a8635da4002f1614a36269ee02e968750c4fbde6ea83360d7"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-win32.whl", hash = "sha256:91cd3f680ee413cc83819f0e1f63e49297c550099e85bbee92e73960d3eba041"},
|
||||||
{file = "geventhttpclient-2.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:9a11b88ce228f91bd47acacb573acbcdf8276b933e2fd7e4f7aa6259c279271e"},
|
{file = "geventhttpclient-2.0.10-cp310-cp310-win_amd64.whl", hash = "sha256:9a9c02c44b1e4e6edf929aa7c98b665f4db9cdcd406e4a9b4897f48127a6dd6b"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273cde2893c13cbdfcad46e6a0fb906aa3f6b050e712cba0e46cfa59aca4c330"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cb079f45fdc8e2bf7157ef55727d8c2bb7c95fb4f754dac61d7a9b91da0c5c1a"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba0f8863526a2cf44567fda5981da90278583d3006aef02482a92b7d7e38e610"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd657ba277f4888b5a4b5da72a587641d6725d1e6ab0dd6875f29ad0a3458ad5"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8da5696d055883cef55fe52246ea2a686bae865d4d38900f67c7c3df7d01eaa"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd589226e908a6c2556572ff3b13fe00308849b44dec47bb794de27afa0339de"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e25e14c91898217f3a69346c2704e4629634b3429cdff226e716e6d830c402e1"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e38a4123ed63935ccaf18054135e50fe4f798744f10d37faa9d2eaddfcff12f"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46b08a7de94a3db62ebeb41e68097db1e3836eef2e2febccb2d710add8943838"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9711c629559b1f0be4977a2be79899fb90085a5a1f85ca435ec91d6a5648ff3f"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e33f23168824338a84e05e47808a48895e78e77c5d2ec353a6e77a0b727057"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7435458eada516d1caf8499a2618db1160e62bbe0c8e4d6f3ab03fc507587dff"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f505a7060aeafd7ed94acc8c234690717ed03aa6421580847ade8d4a6d8741c1"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:446b17f342315d8c63c020732b9ab939a874014c84cf250d66ffd96c877f6d96"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bc0cd15d51b5817efeef98d6ffe51bebd371c0c81731b239d0c6e81923c3b986"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:68279ab30e20f48fbac4371cd5850c77ecc37f24ef656f8c37afd5454576bc57"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9a7e72d38e3a4d4f84c11dbfd74b70e70c3c9099ea7336a6c6227e0628c83a67"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0823827d029aed708d6ed577994cdd3b4c1466690be0b7f27f3b459783ab7c6a"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:62edef5141ea260caa91618b133d8888d9af6767e11a2e972dbb5be0e297ff8e"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:505722ef30d680c983812795e047dbb2d09dc0f476015e5d3411251bb960e3b1"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:40cc9acfb7096b8fa3a4c4634dcc0a1cfc6a0a5501c597d1c4a5574fde1bb1be"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8ebf2ce3ca1308ffc9daae1f45860b2f5a3c1a75f6c46b2d12b9a478f7c4f05e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-win32.whl", hash = "sha256:44e7de9925356486988f72b239d1608597b6d1462664a7fa7ad5b8704a3f6f4e"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-win32.whl", hash = "sha256:4ad20f6f03e34e44366e6794a28bd0b35b09e1dca3350bbf0a72c50d64c9c266"},
|
||||||
{file = "geventhttpclient-2.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:03b3c64fcd16795a5acbdf8588e05a58fde498cd550285cf3ea6e1c6cc28378c"},
|
{file = "geventhttpclient-2.0.10-cp311-cp311-win_amd64.whl", hash = "sha256:c1883adee9c69374e30f43f7bea85dd4a7b4cc440e3c6ecf975bef04e1f8a972"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:be198e668c8573e4cc7fa8e6b71e32a94765c424bc6a8cdd5fc23ab23769864c"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7525bd48fadc93a79d13383cf38a10eed6c9f2f3c65e1f3a8cd4978dfcf023a0"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f550e6ceb67a6cac9e42915612a10c0f799666fa309be796db65585690d8262"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c6820591122c4444652238806c0c97f6c0de76d790bab255fd242962c8026654"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5210e91b1a1d9f2bcd414238cae2593b66172098db7bde396ae2fdb8e658eb85"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34a06879a2dbc2a78edf8cfcabbcc67a177d0642b0e4490b771b72ebceea4537"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97f4c7f57bf24b669bc2e71de725067a4b73f280fc20875fd8c7cee712b754f3"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:441a16eb8743b44c7b6f0acbbdc38d6f407f0763eb859ae0ae6e61427ac86c3e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01869edfc3f9b892dfdd0b3ef102c97dd250725e8364de2e450d9ee2e3bf74db"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf3a7a5c6b244c6d55de9d28245f70ee33cca8353355a9b10ea0c2e08ff24a0"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a85f9d272af4bc599a54496cb420ee0654c35023d6cd7f2a49c36d5a5d30e375"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e65a91c7a4e559d0f60dab4439d15355ade9c30f5c73276bb748b000a062e8f"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:9f78d0bda2583a7f9d87cc987ab9976bf4e85d467af7d8fa39f51bed1918e812"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d051f15c3c92140ce142336ae05a76868ce05a86b4e15c5becb5431beaf53a07"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2e8013742b22586c25c797d7d7bfb8882b2eed43051f28f7617ea302cf4e5098"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:224d1f34e32d683889f8a92f92ce3a1e4bb2f3f4a3d85b931a8df493dd59e9e7"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:1eb410b5522ef617923470f036774388c191eda3ae47abf5a175f628cff75928"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:309a35f033766476765a48a9c2712ffb988c3e3d50cd4b98eaa77e34b470af7e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-win32.whl", hash = "sha256:12de78429c420ac3dbfd4e89fbd1d9d2cf9a60c06a82fc39a398f92d5f717c95"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:d9d09579969cfb244e88bb599ac93549d8c0b56018de1f1ffade4a986951ad1d"},
|
||||||
{file = "geventhttpclient-2.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:5eb747774ed72467b3b77913bfe041f0be4a22958dd7538a654bf24107d1b917"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:15ecc1599646755d7e2e5648606c21ace00c3337c2d72d33b4e2de5d66b4ed65"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:36e9c7e4f86db9335123a12b343c2b91d8d7fe4724428ac418bcfcd471248bc9"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-win32.whl", hash = "sha256:c99dd907622f28523c3f90b8718643c103ce6519be7128e75730c398fd23d157"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a7d8a7d7ee6b08e44e58e92e47ca4b50edf8ed64b8906bd0a6cbb481aeae69b"},
|
{file = "geventhttpclient-2.0.10-cp312-cp312-win_amd64.whl", hash = "sha256:9532ee9066072737fe0eac1714c99792d7007769d529a056bc0c238946f67fdf"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:186d3e4f549a004f0ae8857db81f05798d48dd9e6cbfa97dfa46f6177883458d"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7197223e650b9e07e1b3ddc1b41b8cdc1c2c4b408f392bdf827efa8c0cb6c67b"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c0ed350c0f4598f6d07d6fdc2d3546a1611ebf15fcdc83bc77dea6d22f2ef38"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304b9d67c91db96633d89b938b68020d7f787ff962580b1cff819d4218d7eb45"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0c557aeb45a005c72200842fddfb507bbd7f2ec9296059c7ea3977ea226d4e7"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd4aa396f69f4063b7fcddb2c400c9eea933bcce63f3c65fc28a1869c88179c"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6c9ea74c83e94ea7c9869e383f93fa20a5fbde9cfb020400cdb75c39e029507a"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8da6f49e65cdcc19fbc37978d9e3e14ba30c949d9a5492e0f96e1e5270f2305"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9b072c041993b3242aeccce0d436bcb951f83e83517d5f5c0b9b97efe6ee273e"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba65c48a63042deadc8e4f1f5348409d851d6fa06f8a1b5a58fd6fd24e50daaf"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d17ea1282fef41aa1b43e193869f0b9119fab919fe90092dfa5754fd6a012982"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f3dcbf4a53852498128937e870c4b0ced1ed49b9153c68d12a52a0711652b9cf"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4941aa5e45479a6595469754d6395e5d1a76cf555d0d111aa4c128d8f4ebd41b"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:976e86d63fd1cd3bda4f78ec469b6d1c8dec4259abeb62191464e8dd4d40bb8e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-win32.whl", hash = "sha256:2d36b3a241a4c64a094622c4da67b98141295ab9ba24a79671235bb8735047f5"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:05be35bc7d2bd3ad6f0aa5042ae5a0b171ff19ec75ffeae1b4a2698572dd67a4"},
|
||||||
{file = "geventhttpclient-2.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:f7a99e0976ac64d21f54be87083b6ec440753db50db36d83b2b2b0b6edaacad7"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b3556a97e1c71d6b323076e6153f3afcf4f2e37ad79c3fe6d5bf006d3c1b5436"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f46848b5c6610c671a7258757bf4d34032c56a80ead880e69890d9ef5c1e63a1"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-win32.whl", hash = "sha256:2b2d801205000f673f879b4edc1064b7dfc1bdd0dc5257bf565e6e7386b818bf"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b671b736468e35e588f24d2219d9f84f3c69c466fdc76ce47774106eb3af2c10"},
|
{file = "geventhttpclient-2.0.10-cp36-cp36m-win_amd64.whl", hash = "sha256:7fd672aa9186607ac802b09efd3c835eb808f930a5c3489553dbfcbe78539129"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b290897e50e0f378d4cabdafffe2f51950d1c820722ee39b37657eda7339a3a8"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:551b147e4c2ea60bfefc4f12dd061bfe84792497a32a369f8dab7f503da5aa05"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41cad9ddc365edf77cb62a4e3a8168dee9ee37109b410a42c5ec0691403dbe37"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:113c001d339b9e5c209f6f9da9271b0011341c25a4171d142c1d802bc0889ec4"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0b69bc9632827b108aba11d85e7c604290e413486e7dc9ddf471303ceab4381"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fcdfdbbbf3c96265aca110433a5ce68e807336fa58bd7ef0651e66032037575"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:988121fdd5b8939c4071ce45b26f9e3aa1cb050e3087ee02b28e7c21bcada35c"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:223daf689883680eef2aa1b773a2bd7e6500749615332b0a0949ee11afeeeff9"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db4db1ceaa88d648c43a318af16690fb59f13ad1fc48603e054c563490950034"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45343be209224de6e525611938a41a4269c36df3b3c1f6e12f99af188d192a4"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:192be8b440e6512c384cc5be98b3b3e8b39dcae0f7c10aee3c3491f30a20e676"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c268f7573f2b3cceabdc086abca96a59fb2766acbf60fb349ccbc208b6051e7c"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ffed7591e612cb80935ed11c1fb0a752aed3f014a48b9404cd0c77182e82335c"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c8117ef8e405fa05f5ea50fd9eb1d538bb7eeb86dba2849fb25d8296fabb70fc"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:c2b06ccac902fb243384da12692be240e7a9ddcd2efedcde2444872546ada83c"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fb70548781b3ba3531ec3572ae6f4cd87f387822c412fff1ee6fe52c2e4b66cf"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8257d9538a1d342a2052c0df099a318d7611562a4725985ac652a356c5cd45c9"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b87dcef1ca6eb9127fd60844f1dd77063081335079b498bc1e1cd8e4764b6863"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-win32.whl", hash = "sha256:ce61c0be828e10dbfac91ed7160f651ecc2fbad44ed1815eaac6e9d41e09a87a"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-win32.whl", hash = "sha256:8ff70f24183705f2cb63dc132b4dd4e0eec58b8f182fde76f5a205e4608266cd"},
|
||||||
{file = "geventhttpclient-2.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:aa2b47489bd229fce3ab626c370eb8d18fd6116611552de9d8979c37238fc62b"},
|
{file = "geventhttpclient-2.0.10-cp37-cp37m-win_amd64.whl", hash = "sha256:f30d83152339779650a97471f27ef2fb2e6804ce660c96790c0d01c66648483f"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a16bde611a76ada61c9af9acc20b88d5ee6c025deede2680fde084838a3bfbae"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:786e120946a4dc1c7ede5a04943119540a1ccc22227029cdb7988a3d216885b1"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:780d04ea934e254af9de90402f29804e6a3455c3bfa44acc1e8ccb65ce5115a9"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c27943dff539c4bc19f31ea8bffbb79a215e3b3f72b87686791956af39586ac4"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3033399fcbe1fbafbe6ff56afb587725aa993ab549845ebbd8a2206be6082cb"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a377934706416ef04b92291540b609c7dde004a7ccb3b4e047873af2432d78e4"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d32d3f6f413a6a16ac3bfe4cb53f0935c52f33820d2da21d9929ec6a910519b"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b91c1a73e99ef4542e7098a997d1a4bce08cafb935e24a7b6d02c6da2359c91d"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6684b82fd3719d4823ef2eda1edd5bfbf3154e5c2241db0ed858ffb99f8a4ad9"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80683052062f4cb6f18e7d2b1dba91f9536f7955a12660d599ed64bb4aa56d1e"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38f5c6cfa9387ad741f0b5033b6de12eeb670870149a50b7a64444c84f8e7167"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44c06c9882cc50201e5c7fe667eae73a491b6590018aa43c54c79e88c30abdb0"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d654ae061852c842a75b1a38f42b5523389475fe9015de732a55242f6d221e"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271834908b41954fedc777478ffdc10050387bb5863805e19301b80e0fd85618"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:491ee724ba4057b076610be20da6345a66c630d82ed52f12014ce8bad5a699ab"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f48dfd37d341c8433e7a2f76108b3d21614ccf2fbe00051d9dd29b3258efa6"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eab149b7119ac7a6243cad85173f9f9e9ae004e299358181641dddc39233a2d1"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d6110eb2f685c6dcaff56e9b3b161da2eb432eea15b68cee0f51ec5d28c886ea"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f6ad2c5590a68b7e959ab5f4adab78008ba3a661482c1fb56a38eba09744b899"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a9e9c1c080a527dd9047e0421231cdd2394eeb92f94836f4ad7d7fece937ba26"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47bb3025950cc9bf0fd627b101380cf5b0efbbaa591198b851352b24966931cb"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fa34492682347420384e49bd7c15886330af685924fc64badefce642867e4856"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-win32.whl", hash = "sha256:549756ac0e3cc916d6830f0d6147803a5c93beae96f8504f685e4e841d6ace29"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-win32.whl", hash = "sha256:ea66408103b4c8954cbd3cc464be0e968a139d073987555a280760fb56fed41f"},
|
||||||
{file = "geventhttpclient-2.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:e3133d3e492c5dfb78f9c0f87e1ede78545e7f4bb4851a063df2321669540004"},
|
{file = "geventhttpclient-2.0.10-cp38-cp38-win_amd64.whl", hash = "sha256:ef45b4facbaf7793373a32cab3f3e9460b76eb5f854b066f53b4753eca0efa7d"},
|
||||||
{file = "geventhttpclient-2.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3fca4415c9d9282a8b5f4de03661be3b1083b97b3e43a1f4b56cec4b933b9705"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75e09f122824d1d4aa3e9e48089a5e6f5c0925c817dfb99a65aeafa173243a27"},
|
||||||
{file = "geventhttpclient-2.0.9-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b85ca16b34170787a48ac2c69622bba2f2a3541ee55b442576a12f63181f13e"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c9b4269873ce14bdd0977ae7b3b29e55ba2dc187b1088665cfe78fc094fc6795"},
|
||||||
{file = "geventhttpclient-2.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:711f3522ce20d2de5abe22cafdeee0896f9f682de7690622510c5f8a859c50d2"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39db24bf426471cf81530675459ea209355032bf73f55a6e111f28853fe7564f"},
|
||||||
{file = "geventhttpclient-2.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96479cafe8cca4e24a1ba53efe3c3c6cf9f10e8cb0398f4cbcf23b4233e103f2"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9148ce0072e6f2c644522b38d22d2749367dd599a4b32991ca9fc5feb112c5"},
|
||||||
{file = "geventhttpclient-2.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d742f4288844ec5dbed2af4396fca8d37b5f4d2730ca31fe3575d67a2910e28f"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:452624f7e1b16e27c5df5b4f639a5a45f9372d9d9a8e7d2754f2f034b04d43d3"},
|
||||||
{file = "geventhttpclient-2.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:53e929c7920fb7841d4b2cde50ed3fdde803948977a333de33a924a9ccfccd38"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57ecf4d4a09b502d2d4b25bc074b10290d595d80b6ce86294ecdd992cff80fb9"},
|
||||||
{file = "geventhttpclient-2.0.9-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4693365990aa6d5cb104cea80dd831b8032f6a4f77790fa8b837fc25e86f8e5"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e338a3b23d05c7550a6163b8d367de953be25f1d94949d043b325390df72d527"},
|
||||||
{file = "geventhttpclient-2.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99bb292a4f4fa4a23d22e6bf1799530d0cb675dae87d81d77079abe98f71150d"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6d2b0b87bb933911dadb702df74a7da91a4cdd86b6d75800db8494d7e5709e70"},
|
||||||
{file = "geventhttpclient-2.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4533b7023a90cb9766213f70d15bc76bb66b7b441c3976f27e254403a6c738fa"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5396759194bef95b92128dfd8b80d332f809de23193a2529071a519afd6e9250"},
|
||||||
{file = "geventhttpclient-2.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9b6341c937d01ba48028a3d605fded6fd2eed692bb1ddc941d2aa3dd317eed9"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c13ba845f042d0807f6024b80c458b22b615028cc4f4ad23bd67c6db9de9969e"},
|
||||||
{file = "geventhttpclient-2.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a05a3345796accd0a9acb3fc133a0e4cd949d3e63becec34fcb2e8d001dd92fe"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24b33b88fc7b815139b80736bb46a7f6113abc7edd3d846cd99fc8d8c31d8439"},
|
||||||
{file = "geventhttpclient-2.0.9-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32cc9bd3518aa0772065175aa6eddadff8b05688683940bfd583cb468b518987"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-win32.whl", hash = "sha256:e545fa59f298f6fc5219403f06819271f77a67216d1352f5cf703f292be05c3e"},
|
||||||
{file = "geventhttpclient-2.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e7185e91b52f6d2cdab849ba24c8ac24b3bd1ad8eb9917e4ed86f4e93f718b1"},
|
{file = "geventhttpclient-2.0.10-cp39-cp39-win_amd64.whl", hash = "sha256:216e451ea72fe2372bc72e34f214ef8bc9d62b049d9048f88f81338e1c6008a5"},
|
||||||
{file = "geventhttpclient-2.0.9-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62a47451abf94422b3f0efda4f147111f2f4a75f7e55db974cf4b35acaee0131"},
|
{file = "geventhttpclient-2.0.10-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:71a224032b2da3fe30d75fb57fb9d3e8ff323895e14facd9374e585d5bf52d01"},
|
||||||
{file = "geventhttpclient-2.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:dc75486b0847c185856f981b728a2bbfe09e8a754676e57a8549660157918d2f"},
|
{file = "geventhttpclient-2.0.10-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bed5b6051582bdf39c7ff15051ec0758d1a0ebcb6ff09b6ae600717caf3f379e"},
|
||||||
{file = "geventhttpclient-2.0.9.tar.gz", hash = "sha256:8abc39d346e923bd6a7b405d38dd01e19146594b6304032f382eda8b0f631513"},
|
{file = "geventhttpclient-2.0.10-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e2e2eed1d821854f9f32f475d258af605a87ce12dc4d93abe61c022bf2bb06e"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2cd1ecc9a389ca54a5e538769c3f35a82478006dc50eb505989d2ff6c3cf518"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:fb7018bfd4f6808d4e3b9cdda2dcb52cc01236a4bb65e18021fb8816996e9cd3"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6df4957678eb05a6ccfbbb96a9490345758620b53fe5653052979df94819765b"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508bcc82f7259e316f2060025e7ff899acc8032c645e765bb780083e39060c07"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:961dac20f0f4b8cfa4e2eaafe2d20d74448a5a04239135fa1867a9a1bc3fd986"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:826fa6487ba1c1b7186dcdc300c216fd9b8cf34e307335b4cad1769736988ce9"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b30c9495b43b2f67b6a0102ee3fd497762b6bf972e435e5974fd8d2cb5263235"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e2a9a5e52abc8d3275902c1199ff810264b033e346bcf19da920f9b6de1ea916"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:993b653c7c3d4e0683067b2e324fd749649e87b453205def6a4809dd30498b44"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aa110a66936c37a8bbc2a51515fc0f7e99404e245ef15af8346fa2f6b4f6698"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ce4699fcadc17786cba0b461ff59d0231277155439b274fa12861f93fa764c8"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:23fedc0bf219cc42f9b3d565953a08a429c09642859b86174535977bb281f1c1"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a9e99fa203a43a8393cf01e5a6433e74524c97bf67e39c4f062c8fff27f49360"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0dfcfdc3a05e2145fe15f8b9cc7dd8b9fcd545dd42d051be0a2a828b8b3cc4a3"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b56abccfea3fe154f29dbc518737c70d63c1f44da4c956e31e9a5ff65074de19"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9f8d335e7e3579608904e001ba9b055d3f30b184db550c32901b3b86af71b92"},
|
||||||
|
{file = "geventhttpclient-2.0.10-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:96f1a63f18eb4a66ea9d6ab211d756afe8b6d5c6e80beff298cd7b65a3d710c7"},
|
||||||
|
{file = "geventhttpclient-2.0.10.tar.gz", hash = "sha256:b7c97b26511957a36a894ec54651c08890a69e118b69755f8e74bfc37c63391b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1614,13 +1632,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "imageio"
|
name = "imageio"
|
||||||
version = "2.31.1"
|
version = "2.31.2"
|
||||||
description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats."
|
description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "imageio-2.31.1-py3-none-any.whl", hash = "sha256:4106fb395ef7f8dc0262d6aa1bb03daba818445c381ca8b7d5dfc7a2089b04df"},
|
{file = "imageio-2.31.2-py3-none-any.whl", hash = "sha256:a78fbcb33432042a4d6993c87f3ea1f136d908318ce7dda857846ccff73294de"},
|
||||||
{file = "imageio-2.31.1.tar.gz", hash = "sha256:f8436a02af02fd63f272dab50f7d623547a38f0e04a4a73e2b02ae1b8b180f27"},
|
{file = "imageio-2.31.2.tar.gz", hash = "sha256:ae19221f4a8f118f1c9451e8f5357faeeacdf956198cf374bc8ab00f1ff7d525"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1720,79 +1738,115 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kiwisolver"
|
name = "kiwisolver"
|
||||||
version = "1.4.4"
|
version = "1.4.5"
|
||||||
description = "A fast implementation of the Cassowary constraint solver"
|
description = "A fast implementation of the Cassowary constraint solver"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"},
|
||||||
{file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"},
|
{file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"},
|
||||||
{file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"},
|
{file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"},
|
||||||
{file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"},
|
||||||
{file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"},
|
{file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"},
|
||||||
{file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"},
|
||||||
{file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"},
|
||||||
{file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"},
|
||||||
{file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"},
|
||||||
{file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"},
|
||||||
{file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"},
|
{file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"},
|
||||||
{file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"},
|
||||||
{file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"},
|
||||||
{file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"},
|
||||||
{file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"},
|
||||||
{file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"},
|
||||||
{file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"},
|
||||||
{file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"},
|
||||||
{file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"},
|
||||||
{file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"},
|
||||||
{file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"},
|
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"},
|
||||||
|
{file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"},
|
||||||
|
{file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"},
|
||||||
|
{file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2302,42 +2356,42 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "onnx"
|
name = "onnx"
|
||||||
version = "1.14.0"
|
version = "1.14.1"
|
||||||
description = "Open Neural Network Exchange"
|
description = "Open Neural Network Exchange"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "onnx-1.14.0-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:fb35c2c347486416f87f41557242c05d7ee804d3676c6c8c98eef6f5b1889e7b"},
|
{file = "onnx-1.14.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:05d8609b4148f8ee4bd5d8186875ccb288300106242fc5201b8b575681bbd5c4"},
|
||||||
{file = "onnx-1.14.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd683d4aa6d55365582055a6c1e10a55d6c08a59e9216cbb67e37ad3a5b2b980"},
|
{file = "onnx-1.14.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f131c2fd36f7848437be9de3b1fa5449a94245e16c6f275f66ac7cf8f183ec26"},
|
||||||
{file = "onnx-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00b0d2620c10dcb9ec33441e807dc5851d2843d445e0faab5e22c8ad6874a67a"},
|
{file = "onnx-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8d7abe048d0e9e31541dc62e9e40b8411b11377d2a22ed842e678802b4e1aa"},
|
||||||
{file = "onnx-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01893a4a2d70b68e8ee20269ccde4069a6fd243dc9e296643e2afeb0050527bc"},
|
{file = "onnx-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:921ad325b17484698d9d65978e123b1f351328ea50de6f84f25d09d5c7dde361"},
|
||||||
{file = "onnx-1.14.0-cp310-cp310-win32.whl", hash = "sha256:0753b0f118be71ff109dd994a3d6769e5871e9feaddfada77931c63f9de534b3"},
|
{file = "onnx-1.14.1-cp310-cp310-win32.whl", hash = "sha256:6c8156be97762814c7c835d597320ef1f6630f034344fbc672cd6edddbbf78ee"},
|
||||||
{file = "onnx-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:d8c3a2354d9d997c7a4a5e467b5373c98dc549d4a33c77d5723e1eda7e87559c"},
|
{file = "onnx-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:776ab461515c20cc4e24dbd75af32b6b1e64de931dc5873b049f13bfec1c96e9"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:5e780fd1ed25493596a141e93303d0b2897acb9ebfdee7047a916d8f8e525ab3"},
|
{file = "onnx-1.14.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:93e614edaf87ea1adba24663780ac62e30f421c117d695379daa9ff816de821b"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9d28d64cbac3ebdc0c9761a300340c60ec60316099906e354e5059e90335fb3b"},
|
{file = "onnx-1.14.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:65672ae827ea5f0e59dc0d1cef1c0ed5083d5e8348946f98f1715ebb123573e9"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba92fed1aa27cba385bc3890fbbe6484603e837e67c957b22899f93c70990cc4"},
|
{file = "onnx-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6efa7375d91b1da10badd1d2701a94b0e9b111a5e1a227be1bf877450cea84ac"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fab7e6e1c2d9d6479edad8e9088cdfd87ea293cb08f31565adabfb33c6e5789"},
|
{file = "onnx-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9cd91b85cfbb0d6478f4a1a0aee4d95cf8839adc48c69130a0cf8452f21db4"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-win32.whl", hash = "sha256:6e966f5ef38a0521595cad6a1d14d9ae205c593d2824d8c1fa044fa5ba15370d"},
|
{file = "onnx-1.14.1-cp311-cp311-win32.whl", hash = "sha256:1072baf93e04bbbed45f8f997cbbe96e179080b4cd95bc676882fe64aa709dd6"},
|
||||||
{file = "onnx-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:1fe8ba794d261d722018bd1385f02f966aace0fcb5448881ab5dd55ab0ebb81b"},
|
{file = "onnx-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:16a6667aff34431ab828b393ed8153c0a0cf15152d76f8d93aa48fb206217827"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-macosx_10_12_universal2.whl", hash = "sha256:c16dacf577700ff9cb076c61c880d1a4bc612eed96280396a54ee1e1bd7e2d68"},
|
{file = "onnx-1.14.1-cp37-cp37m-macosx_10_12_universal2.whl", hash = "sha256:3fde9e1854e525aae93b403c1174bf68dc86ac92b6f8fb4af0fe3ec0d1440631"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:bbdca51da9fa9ec43eebd8c640bf71c05daa2afbeaa2c6478466470e28e41111"},
|
{file = "onnx-1.14.1-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:58e6eb27c99dbefc84b4234388f5f668b49a1aaeced1580cb96f5fe05800a77c"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3315c304d23a06ebd07fffe2456ab7f1e0a8dba317393d5c17a671ae2da6645e"},
|
{file = "onnx-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84653e8e19f5d051f9e7ed9cf7285527fd34e093e3b50554121849664e97c254"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1545159f2e7fbc5b4a3ae032cd4d9ddeafc62c4f27fe22cbc3ecff49338992"},
|
{file = "onnx-1.14.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b4a0e029b3604dc5294a7333f622d8c04d6a6a1bc4f51054195074f61b8f41a"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:18cd98f7e234e268cb60c47a1f8ea5f6ffba50fe11de924b17498b1571d0cd2c"},
|
{file = "onnx-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:f5046bfbe7f9bab59fc53984aaa5b47a35c8f8e98787053e1650049a1aaf12de"},
|
||||||
{file = "onnx-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a8f7454acded506b6359ee0837c8527c64964973d7d25ed6b16b7d4314599502"},
|
{file = "onnx-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b37e7bd8baf75efa78ecce713273e2aa29c8c06f69cee6107b413cd03bf59b20"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a9702e7dd120bca421a820020151cbb1003077e17ded29cc8d44ff32a9a57ad8"},
|
{file = "onnx-1.14.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:758dc585885e997f1086019f098e7ce0a4b3ab7d5a89bb2093572bb68ea906c1"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:369c3ecace7e8c7df6efbcbc712b262626796ae4a83decd29111afafa025a30c"},
|
{file = "onnx-1.14.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:486ced7588437ff08a03914ac110d64caa686ff7fa766123d15c8d8eeec29210"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fbcdc1a0c1057785bc5f7254aca0cf0b49d19c74696f1ade107638054157315"},
|
{file = "onnx-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:498ecc3e545b80685501c26b62eeeda0b8ae2f2ba8ff3f650ce1f526924aa699"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed099fbdada4accead109a4479d5f73fb974566cce8d3c6fca94774f9645934c"},
|
{file = "onnx-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e991e867b799df0d7ed4cdad94c6a3ed9bebaceef3e574ac9eed314e1bfca0ef"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-win32.whl", hash = "sha256:296e689aa54a9ae4e560b2bb149a64e96775699a0624af5f631665b9cda90482"},
|
{file = "onnx-1.14.1-cp38-cp38-win32.whl", hash = "sha256:a8c3b1398b156f8bae9882ed8c602e1aa5171180fffcbeb1f9a337fe307c1df4"},
|
||||||
{file = "onnx-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:e1607f97007515df303c1f40b77363545af99a1f32d2f73240c8aa526cdbd109"},
|
{file = "onnx-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:cf20e7a346d22468a128a40c5cc1f4d20c3939e21e74fc8e3be8ba66c6f82444"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:7800b6ec74b1fe3fbb3bf4a2380e2f4007c1a7f2d6927599ad40eead6eae5e19"},
|
{file = "onnx-1.14.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:17f78637d2f6c3c9afad0611fe4c583b6ba4839ac724af0846e5db24dc8dadc0"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:45d3effe59e20d0a9fdc51f5bb8f38299086c79576b894ed945e6a058c4b210a"},
|
{file = "onnx-1.14.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:60ad73263a06056f9aa288b082887c6330be08475471c3a009f62439b2a67dca"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a593b46015326feb949781d030cb1d0d5d388cca52bff2e2995badf55d56b38d"},
|
{file = "onnx-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030aa47e28337fd81f4d884032660e40912a4763ce4e5a4b4144380271390e82"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54614942574415ef3f0bce0800c6f41ecea8201f8042754e204ee8c0a8e473e1"},
|
{file = "onnx-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b113fa0183034743e6477fec928e478a6d94eee8d9a4376c144d20d736cdc45"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-win32.whl", hash = "sha256:dcfaeb2d15e93c456003fac13ffa35144ba9d2666a83e2cef650dd5c90a2b768"},
|
{file = "onnx-1.14.1-cp39-cp39-win32.whl", hash = "sha256:b9c28a99d4a620cb1d31120d35e0fab54073b9725ed50c3cd3ec7beb876e8dba"},
|
||||||
{file = "onnx-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:0639427ac61e5a0181f4f7c89f9fc82b3c9715c95071f9c3de79bbe303a4ae65"},
|
{file = "onnx-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:bdb15fc4b7f2a8a19abb52ac9672db876f9505e7219e206bcb7530e7c1274e55"},
|
||||||
{file = "onnx-1.14.0.tar.gz", hash = "sha256:43b85087c6b919de66872a043c7f4899fe6f840e11ffca7e662b2ce9e4cc2927"},
|
{file = "onnx-1.14.1.tar.gz", hash = "sha256:70903afe163643bd71195c78cedcc3f4fa05a2af651fd950ef3acbb15175b2d1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2442,13 +2496,13 @@ numpy = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "optimum"
|
name = "optimum"
|
||||||
version = "1.11.2"
|
version = "1.12.0"
|
||||||
description = "Optimum Library is an extension of the Hugging Face Transformers library, providing a framework to integrate third-party libraries from Hardware Partners and interface with their specific functionality."
|
description = "Optimum Library is an extension of the Hugging Face Transformers library, providing a framework to integrate third-party libraries from Hardware Partners and interface with their specific functionality."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7.0"
|
python-versions = ">=3.7.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "optimum-1.11.2-py3-none-any.whl", hash = "sha256:1382d923f95e053db677b1bc84803828921b41dd15d094cc61deab33ab5d4fb2"},
|
{file = "optimum-1.12.0-py3-none-any.whl", hash = "sha256:4eb2e800b5ef52aa4c744b7494aa2000be8b583dfc99dddd5c0e9384ea0d77a0"},
|
||||||
{file = "optimum-1.11.2.tar.gz", hash = "sha256:664fa01aa4734d13ba291d41e7b901d333cea45b6c55d66098f43160bf7533ab"},
|
{file = "optimum-1.12.0.tar.gz", hash = "sha256:a74e051c4d776a900b6452a12a36e0afadbebee112a8205a30adac9216a4991b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2468,7 +2522,7 @@ diffusers = ["diffusers"]
|
||||||
doc-build = ["accelerate"]
|
doc-build = ["accelerate"]
|
||||||
exporters = ["onnx", "onnxruntime", "timm"]
|
exporters = ["onnx", "onnxruntime", "timm"]
|
||||||
exporters-gpu = ["onnx", "onnxruntime-gpu", "timm"]
|
exporters-gpu = ["onnx", "onnxruntime-gpu", "timm"]
|
||||||
exporters-tf = ["h5py", "numpy (<1.24.0)", "onnx", "onnxruntime", "tensorflow (>=2.4)", "tf2onnx", "timm"]
|
exporters-tf = ["h5py", "numpy (<1.24.0)", "onnx", "onnxruntime", "tensorflow (>=2.4,<=2.12.1)", "tf2onnx", "timm"]
|
||||||
furiosa = ["optimum-furiosa"]
|
furiosa = ["optimum-furiosa"]
|
||||||
graphcore = ["optimum-graphcore"]
|
graphcore = ["optimum-graphcore"]
|
||||||
habana = ["optimum-habana"]
|
habana = ["optimum-habana"]
|
||||||
|
@ -2483,6 +2537,75 @@ openvino = ["optimum-intel[openvino] (>=1.10.1)"]
|
||||||
quality = ["black (>=23.1,<24.0)", "ruff (>=0.0.241,<=0.0.259)"]
|
quality = ["black (>=23.1,<24.0)", "ruff (>=0.0.241,<=0.0.259)"]
|
||||||
tests = ["Pillow", "diffusers (>=0.17.0)", "einops", "invisible-watermark", "parameterized", "pytest", "pytest-xdist", "requests", "sacremoses", "torchaudio", "torchvision"]
|
tests = ["Pillow", "diffusers (>=0.17.0)", "einops", "invisible-watermark", "parameterized", "pytest", "pytest-xdist", "requests", "sacremoses", "torchaudio", "torchvision"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "orjson"
|
||||||
|
version = "3.9.5"
|
||||||
|
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ad6845912a71adcc65df7c8a7f2155eba2096cf03ad2c061c93857de70d699ad"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e298e0aacfcc14ef4476c3f409e85475031de24e5b23605a465e9bf4b2156273"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:83c9939073281ef7dd7c5ca7f54cceccb840b440cec4b8a326bda507ff88a0a6"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e174cc579904a48ee1ea3acb7045e8a6c5d52c17688dfcb00e0e842ec378cabf"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8d51702f42c785b115401e1d64a27a2ea767ae7cf1fb8edaa09c7cf1571c660"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f13d61c0c7414ddee1ef4d0f303e2222f8cced5a2e26d9774751aecd72324c9e"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d748cc48caf5a91c883d306ab648df1b29e16b488c9316852844dd0fd000d1c2"},
|
||||||
|
{file = "orjson-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bd19bc08fa023e4c2cbf8294ad3f2b8922f4de9ba088dbc71e6b268fdf54591c"},
|
||||||
|
{file = "orjson-3.9.5-cp310-none-win32.whl", hash = "sha256:5793a21a21bf34e1767e3d61a778a25feea8476dcc0bdf0ae1bc506dc34561ea"},
|
||||||
|
{file = "orjson-3.9.5-cp310-none-win_amd64.whl", hash = "sha256:2bcec0b1024d0031ab3eab7a8cb260c8a4e4a5e35993878a2da639d69cdf6a65"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8547b95ca0e2abd17e1471973e6d676f1d8acedd5f8fb4f739e0612651602d66"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87ce174d6a38d12b3327f76145acbd26f7bc808b2b458f61e94d83cd0ebb4d76"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a960bb1bc9a964d16fcc2d4af5a04ce5e4dfddca84e3060c35720d0a062064fe"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a7aa5573a949760d6161d826d34dc36db6011926f836851fe9ccb55b5a7d8e8"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b2852afca17d7eea85f8e200d324e38c851c96598ac7b227e4f6c4e59fbd3df"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa185959c082475288da90f996a82e05e0c437216b96f2a8111caeb1d54ef926"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:89c9332695b838438ea4b9a482bce8ffbfddde4df92750522d928fb00b7b8dce"},
|
||||||
|
{file = "orjson-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2493f1351a8f0611bc26e2d3d407efb873032b4f6b8926fed8cfed39210ca4ba"},
|
||||||
|
{file = "orjson-3.9.5-cp311-none-win32.whl", hash = "sha256:ffc544e0e24e9ae69301b9a79df87a971fa5d1c20a6b18dca885699709d01be0"},
|
||||||
|
{file = "orjson-3.9.5-cp311-none-win_amd64.whl", hash = "sha256:89670fe2732e3c0c54406f77cad1765c4c582f67b915c74fda742286809a0cdc"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:15df211469625fa27eced4aa08dc03e35f99c57d45a33855cc35f218ea4071b8"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9f17c59fe6c02bc5f89ad29edb0253d3059fe8ba64806d789af89a45c35269a"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca6b96659c7690773d8cebb6115c631f4a259a611788463e9c41e74fa53bf33f"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26fafe966e9195b149950334bdbe9026eca17fe8ffe2d8fa87fdc30ca925d30"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9006b1eb645ecf460da067e2dd17768ccbb8f39b01815a571bfcfab7e8da5e52"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebfdbf695734b1785e792a1315e41835ddf2a3e907ca0e1c87a53f23006ce01d"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4a3943234342ab37d9ed78fb0a8f81cd4b9532f67bf2ac0d3aa45fa3f0a339f3"},
|
||||||
|
{file = "orjson-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e6762755470b5c82f07b96b934af32e4d77395a11768b964aaa5eb092817bc31"},
|
||||||
|
{file = "orjson-3.9.5-cp312-none-win_amd64.whl", hash = "sha256:c74df28749c076fd6e2157190df23d43d42b2c83e09d79b51694ee7315374ad5"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:88e18a74d916b74f00d0978d84e365c6bf0e7ab846792efa15756b5fb2f7d49d"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28514b5b6dfaf69097be70d0cf4f1407ec29d0f93e0b4131bf9cc8fd3f3e374"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b81aca8c7be61e2566246b6a0ca49f8aece70dd3f38c7f5c837f398c4cb142"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:385c1c713b1e47fd92e96cf55fd88650ac6dfa0b997e8aa7ecffd8b5865078b1"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9850c03a8e42fba1a508466e6a0f99472fd2b4a5f30235ea49b2a1b32c04c11"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4449f84bbb13bcef493d8aa669feadfced0f7c5eea2d0d88b5cc21f812183af8"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:86127bf194f3b873135e44ce5dc9212cb152b7e06798d5667a898a00f0519be4"},
|
||||||
|
{file = "orjson-3.9.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0abcd039f05ae9ab5b0ff11624d0b9e54376253b7d3217a358d09c3edf1d36f7"},
|
||||||
|
{file = "orjson-3.9.5-cp37-none-win32.whl", hash = "sha256:10cc8ad5ff7188efcb4bec196009d61ce525a4e09488e6d5db41218c7fe4f001"},
|
||||||
|
{file = "orjson-3.9.5-cp37-none-win_amd64.whl", hash = "sha256:ff27e98532cb87379d1a585837d59b187907228268e7b0a87abe122b2be6968e"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5bfa79916ef5fef75ad1f377e54a167f0de334c1fa4ebb8d0224075f3ec3d8c0"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87dfa6ac0dae764371ab19b35eaaa46dfcb6ef2545dfca03064f21f5d08239f"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50ced24a7b23058b469ecdb96e36607fc611cbaee38b58e62a55c80d1b3ad4e1"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1b74ea2a3064e1375da87788897935832e806cc784de3e789fd3c4ab8eb3fa5"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7cb961efe013606913d05609f014ad43edfaced82a576e8b520a5574ce3b2b9"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1225d2d5ee76a786bda02f8c5e15017462f8432bb960de13d7c2619dba6f0275"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f39f4b99199df05c7ecdd006086259ed25886cdbd7b14c8cdb10c7675cfcca7d"},
|
||||||
|
{file = "orjson-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a461dc9fb60cac44f2d3218c36a0c1c01132314839a0e229d7fb1bba69b810d8"},
|
||||||
|
{file = "orjson-3.9.5-cp38-none-win32.whl", hash = "sha256:dedf1a6173748202df223aea29de814b5836732a176b33501375c66f6ab7d822"},
|
||||||
|
{file = "orjson-3.9.5-cp38-none-win_amd64.whl", hash = "sha256:fa504082f53efcbacb9087cc8676c163237beb6e999d43e72acb4bb6f0db11e6"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6900f0248edc1bec2a2a3095a78a7e3ef4e63f60f8ddc583687eed162eedfd69"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17404333c40047888ac40bd8c4d49752a787e0a946e728a4e5723f111b6e55a5"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0eefb7cfdd9c2bc65f19f974a5d1dfecbac711dae91ed635820c6b12da7a3c11"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68c78b2a3718892dc018adbc62e8bab6ef3c0d811816d21e6973dee0ca30c152"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:591ad7d9e4a9f9b104486ad5d88658c79ba29b66c5557ef9edf8ca877a3f8d11"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cc2cbf302fbb2d0b2c3c142a663d028873232a434d89ce1b2604ebe5cc93ce8"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b26b5aa5e9ee1bad2795b925b3adb1b1b34122cb977f30d89e0a1b3f24d18450"},
|
||||||
|
{file = "orjson-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef84724f7d29dcfe3aafb1fc5fc7788dca63e8ae626bb9298022866146091a3e"},
|
||||||
|
{file = "orjson-3.9.5-cp39-none-win32.whl", hash = "sha256:664cff27f85939059472afd39acff152fbac9a091b7137092cb651cf5f7747b5"},
|
||||||
|
{file = "orjson-3.9.5-cp39-none-win_amd64.whl", hash = "sha256:91dda66755795ac6100e303e206b636568d42ac83c156547634256a2e68de694"},
|
||||||
|
{file = "orjson-3.9.5.tar.gz", hash = "sha256:6daf5ee0b3cf530b9978cdbf71024f1c16ed4a67d05f6ec435c6e7fe7a52724c"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "23.1"
|
version = "23.1"
|
||||||
|
@ -2667,13 +2790,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pluggy"
|
name = "pluggy"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
description = "plugin and hook calling mechanisms for python"
|
description = "plugin and hook calling mechanisms for python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"},
|
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
|
||||||
{file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"},
|
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -2755,36 +2878,40 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyarrow"
|
name = "pyarrow"
|
||||||
version = "12.0.1"
|
version = "13.0.0"
|
||||||
description = "Python library for Apache Arrow"
|
description = "Python library for Apache Arrow"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"},
|
{file = "pyarrow-13.0.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:1afcc2c33f31f6fb25c92d50a86b7a9f076d38acbcb6f9e74349636109550148"},
|
||||||
{file = "pyarrow-12.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345e1828efdbd9aa4d4de7d5676778aba384a2c3add896d995b23d368e60e5af"},
|
{file = "pyarrow-13.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70fa38cdc66b2fc1349a082987f2b499d51d072faaa6b600f71931150de2e0e3"},
|
||||||
{file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d6009fdf8986332b2169314da482baed47ac053311c8934ac6651e614deacd6"},
|
{file = "pyarrow-13.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd57b13a6466822498238877892a9b287b0a58c2e81e4bdb0b596dbb151cbb73"},
|
||||||
{file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3c4cbbf81e6dd23fe921bc91dc4619ea3b79bc58ef10bce0f49bdafb103daf"},
|
{file = "pyarrow-13.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ce69f7bf01de2e2764e14df45b8404fc6f1a5ed9871e8e08a12169f87b7a26"},
|
||||||
{file = "pyarrow-12.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdacf515ec276709ac8042c7d9bd5be83b4f5f39c6c037a17a60d7ebfd92c890"},
|
{file = "pyarrow-13.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:588f0d2da6cf1b1680974d63be09a6530fd1bd825dc87f76e162404779a157dc"},
|
||||||
{file = "pyarrow-12.0.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:749be7fd2ff260683f9cc739cb862fb11be376de965a2a8ccbf2693b098db6c7"},
|
{file = "pyarrow-13.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6241afd72b628787b4abea39e238e3ff9f34165273fad306c7acf780dd850956"},
|
||||||
{file = "pyarrow-12.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6895b5fb74289d055c43db3af0de6e16b07586c45763cb5e558d38b86a91e3a7"},
|
{file = "pyarrow-13.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:fda7857e35993673fcda603c07d43889fca60a5b254052a462653f8656c64f44"},
|
||||||
{file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1887bdae17ec3b4c046fcf19951e71b6a619f39fa674f9881216173566c8f718"},
|
{file = "pyarrow-13.0.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:aac0ae0146a9bfa5e12d87dda89d9ef7c57a96210b899459fc2f785303dcbb67"},
|
||||||
{file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c9cb8eeabbadf5fcfc3d1ddea616c7ce893db2ce4dcef0ac13b099ad7ca082"},
|
{file = "pyarrow-13.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d7759994217c86c161c6a8060509cfdf782b952163569606bb373828afdd82e8"},
|
||||||
{file = "pyarrow-12.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ce4aebdf412bd0eeb800d8e47db854f9f9f7e2f5a0220440acf219ddfddd4f63"},
|
{file = "pyarrow-13.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:868a073fd0ff6468ae7d869b5fc1f54de5c4255b37f44fb890385eb68b68f95d"},
|
||||||
{file = "pyarrow-12.0.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e0d8730c7f6e893f6db5d5b86eda42c0a130842d101992b581e2138e4d5663d3"},
|
{file = "pyarrow-13.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51be67e29f3cfcde263a113c28e96aa04362ed8229cb7c6e5f5c719003659d33"},
|
||||||
{file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43364daec02f69fec89d2315f7fbfbeec956e0d991cbbef471681bd77875c40f"},
|
{file = "pyarrow-13.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:d1b4e7176443d12610874bb84d0060bf080f000ea9ed7c84b2801df851320295"},
|
||||||
{file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051f9f5ccf585f12d7de836e50965b3c235542cc896959320d9776ab93f3b33d"},
|
{file = "pyarrow-13.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:69b6f9a089d116a82c3ed819eea8fe67dae6105f0d81eaf0fdd5e60d0c6e0944"},
|
||||||
{file = "pyarrow-12.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:be2757e9275875d2a9c6e6052ac7957fbbfc7bc7370e4a036a9b893e96fedaba"},
|
{file = "pyarrow-13.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ab1268db81aeb241200e321e220e7cd769762f386f92f61b898352dd27e402ce"},
|
||||||
{file = "pyarrow-12.0.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cf812306d66f40f69e684300f7af5111c11f6e0d89d6b733e05a3de44961529d"},
|
{file = "pyarrow-13.0.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:ee7490f0f3f16a6c38f8c680949551053c8194e68de5046e6c288e396dccee80"},
|
||||||
{file = "pyarrow-12.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:459a1c0ed2d68671188b2118c63bac91eaef6fc150c77ddd8a583e3c795737bf"},
|
{file = "pyarrow-13.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3ad79455c197a36eefbd90ad4aa832bece7f830a64396c15c61a0985e337287"},
|
||||||
{file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e705e33eaf666bbe508a16fd5ba27ca061e177916b7a317ba5a51bee43384c"},
|
{file = "pyarrow-13.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68fcd2dc1b7d9310b29a15949cdd0cb9bc34b6de767aff979ebf546020bf0ba0"},
|
||||||
{file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9120c3eb2b1f6f516a3b7a9714ed860882d9ef98c4b17edcdc91d95b7528db60"},
|
{file = "pyarrow-13.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc6fd330fd574c51d10638e63c0d00ab456498fc804c9d01f2a61b9264f2c5b2"},
|
||||||
{file = "pyarrow-12.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c780f4dc40460015d80fcd6a6140de80b615349ed68ef9adb653fe351778c9b3"},
|
{file = "pyarrow-13.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:e66442e084979a97bb66939e18f7b8709e4ac5f887e636aba29486ffbf373763"},
|
||||||
{file = "pyarrow-12.0.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a3c63124fc26bf5f95f508f5d04e1ece8cc23a8b0af2a1e6ab2b1ec3fdc91b24"},
|
{file = "pyarrow-13.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:0f6eff839a9e40e9c5610d3ff8c5bdd2f10303408312caf4c8003285d0b49565"},
|
||||||
{file = "pyarrow-12.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b13329f79fa4472324f8d32dc1b1216616d09bd1e77cfb13104dec5463632c36"},
|
{file = "pyarrow-13.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b30a27f1cddf5c6efcb67e598d7823a1e253d743d92ac32ec1eb4b6a1417867"},
|
||||||
{file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb656150d3d12ec1396f6dde542db1675a95c0cc8366d507347b0beed96e87ca"},
|
{file = "pyarrow-13.0.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:09552dad5cf3de2dc0aba1c7c4b470754c69bd821f5faafc3d774bedc3b04bb7"},
|
||||||
{file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6251e38470da97a5b2e00de5c6a049149f7b2bd62f12fa5dbb9ac674119ba71a"},
|
{file = "pyarrow-13.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3896ae6c205d73ad192d2fc1489cd0edfab9f12867c85b4c277af4d37383c18c"},
|
||||||
{file = "pyarrow-12.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:3de26da901216149ce086920547dfff5cd22818c9eab67ebc41e863a5883bac7"},
|
{file = "pyarrow-13.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6647444b21cb5e68b593b970b2a9a07748dd74ea457c7dadaa15fd469c48ada1"},
|
||||||
{file = "pyarrow-12.0.1.tar.gz", hash = "sha256:cce317fc96e5b71107bf1f9f184d5e54e2bd14bbf3f9a3d62819961f0af86fec"},
|
{file = "pyarrow-13.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47663efc9c395e31d09c6aacfa860f4473815ad6804311c5433f7085415d62a7"},
|
||||||
|
{file = "pyarrow-13.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:b9ba6b6d34bd2563345488cf444510588ea42ad5613df3b3509f48eb80250afd"},
|
||||||
|
{file = "pyarrow-13.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:d00d374a5625beeb448a7fa23060df79adb596074beb3ddc1838adb647b6ef09"},
|
||||||
|
{file = "pyarrow-13.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:c51afd87c35c8331b56f796eff954b9c7f8d4b7fef5903daf4e05fcf017d23a8"},
|
||||||
|
{file = "pyarrow-13.0.0.tar.gz", hash = "sha256:83333726e83ed44b0ac94d8d7a21bbdee4a05029c3b1e8db58a863eec8fd8a33"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2993,6 +3120,20 @@ files = [
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["click (>=5.0)"]
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-multipart"
|
||||||
|
version = "0.0.6"
|
||||||
|
description = "A streaming multipart parser for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"},
|
||||||
|
{file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2023.3"
|
version = "2023.3"
|
||||||
|
@ -3736,13 +3877,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tifffile"
|
name = "tifffile"
|
||||||
version = "2023.8.12"
|
version = "2023.8.25"
|
||||||
description = "Read and write TIFF files"
|
description = "Read and write TIFF files"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "tifffile-2023.8.12-py3-none-any.whl", hash = "sha256:d1ef06461a947a6800ba6121b330b54a57fb9cbf7e5bc0adab8307081297d66b"},
|
{file = "tifffile-2023.8.25-py3-none-any.whl", hash = "sha256:40318485b59e9acb62e7139f22bd46e6760f92daea562b79900bfce3ee2613b7"},
|
||||||
{file = "tifffile-2023.8.12.tar.gz", hash = "sha256:824956b6d974b9d346aae59932bea862a2ad18fcc2b1a820b6941b7f6ddb2bca"},
|
{file = "tifffile-2023.8.25.tar.gz", hash = "sha256:0a3ebcdfe71eb61a487dd22eaf21ed8962c511e6eb692153c7ac15f81798dfa4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -3985,18 +4126,18 @@ telegram = ["requests"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transformers"
|
name = "transformers"
|
||||||
version = "4.31.0"
|
version = "4.32.0"
|
||||||
description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
|
description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.0"
|
python-versions = ">=3.8.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "transformers-4.31.0-py3-none-any.whl", hash = "sha256:8487aab0195ce1c2a5ae189305118b9720daddbc7b688edb09ccd79e3b149f6b"},
|
{file = "transformers-4.32.0-py3-none-any.whl", hash = "sha256:32d8adf0ed76285508e7fd66657b4448ec1f882599ae6bf6f9c36bd7bf798402"},
|
||||||
{file = "transformers-4.31.0.tar.gz", hash = "sha256:4302fba920a1c24d3a429a29efff6a63eac03f3f3cf55b55927fc795d01cb273"},
|
{file = "transformers-4.32.0.tar.gz", hash = "sha256:ca510f9688d2fe7347abbbfbd13f2f6dcd3c8349870c8d0ed98beed5f579b354"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
filelock = "*"
|
filelock = "*"
|
||||||
huggingface-hub = ">=0.14.1,<1.0"
|
huggingface-hub = ">=0.15.1,<1.0"
|
||||||
numpy = ">=1.17"
|
numpy = ">=1.17"
|
||||||
packaging = ">=20.0"
|
packaging = ">=20.0"
|
||||||
protobuf = {version = "*", optional = true, markers = "extra == \"sentencepiece\""}
|
protobuf = {version = "*", optional = true, markers = "extra == \"sentencepiece\""}
|
||||||
|
@ -4011,18 +4152,18 @@ tqdm = ">=4.27"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
accelerate = ["accelerate (>=0.20.3)"]
|
accelerate = ["accelerate (>=0.20.3)"]
|
||||||
agents = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.9,!=1.12.0)"]
|
agents = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.9,!=1.12.0)"]
|
||||||
all = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
|
all = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
|
||||||
audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
|
audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
|
||||||
codecarbon = ["codecarbon (==1.2.0)"]
|
codecarbon = ["codecarbon (==1.2.0)"]
|
||||||
deepspeed = ["accelerate (>=0.20.3)", "deepspeed (>=0.9.3)"]
|
deepspeed = ["accelerate (>=0.20.3)", "deepspeed (>=0.9.3)"]
|
||||||
deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"]
|
deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"]
|
||||||
dev = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
|
dev = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
|
||||||
dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"]
|
dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"]
|
||||||
dev-torch = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
|
dev-torch = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
|
||||||
docs = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
|
docs = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
|
||||||
docs-specific = ["hf-doc-builder"]
|
docs-specific = ["hf-doc-builder"]
|
||||||
fairscale = ["fairscale (>0.3)"]
|
fairscale = ["fairscale (>0.3)"]
|
||||||
flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"]
|
flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"]
|
||||||
flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
|
flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
|
||||||
ftfy = ["ftfy"]
|
ftfy = ["ftfy"]
|
||||||
integrations = ["optuna", "ray[tune]", "sigopt"]
|
integrations = ["optuna", "ray[tune]", "sigopt"]
|
||||||
|
@ -4050,7 +4191,7 @@ tokenizers = ["tokenizers (>=0.11.1,!=0.11.3,<0.14)"]
|
||||||
torch = ["accelerate (>=0.20.3)", "torch (>=1.9,!=1.12.0)"]
|
torch = ["accelerate (>=0.20.3)", "torch (>=1.9,!=1.12.0)"]
|
||||||
torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
|
torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
|
||||||
torch-vision = ["Pillow (<10.0.0)", "torchvision"]
|
torch-vision = ["Pillow (<10.0.0)", "torchvision"]
|
||||||
torchhub = ["filelock", "huggingface-hub (>=0.14.1,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"]
|
torchhub = ["filelock", "huggingface-hub (>=0.15.1,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"]
|
||||||
video = ["av (==9.2.0)", "decord (==0.6.0)"]
|
video = ["av (==9.2.0)", "decord (==0.6.0)"]
|
||||||
vision = ["Pillow (<10.0.0)"]
|
vision = ["Pillow (<10.0.0)"]
|
||||||
|
|
||||||
|
@ -4164,33 +4305,33 @@ test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "my
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchfiles"
|
name = "watchfiles"
|
||||||
version = "0.19.0"
|
version = "0.20.0"
|
||||||
description = "Simple, modern and high performance file watching and code reload in python."
|
description = "Simple, modern and high performance file watching and code reload in python."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"},
|
{file = "watchfiles-0.20.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3796312bd3587e14926013612b23066912cf45a14af71cf2b20db1c12dadf4e9"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"},
|
{file = "watchfiles-0.20.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d0002d81c89a662b595645fb684a371b98ff90a9c7d8f8630c82f0fde8310458"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:570848706440373b4cd8017f3e850ae17f76dbdf1e9045fc79023b11e1afe490"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0351d20d03c6f7ad6b2e8a226a5efafb924c7755ee1e34f04c77c3682417fa"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:007dcc4a401093010b389c044e81172c8a2520dba257c88f8828b3d460c6bb38"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d82dbc1832da83e441d112069833eedd4cf583d983fb8dd666fbefbea9d99c0"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99f4c65fd2fce61a571b2a6fcf747d6868db0bef8a934e8ca235cc8533944d95"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"},
|
{file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5392dd327a05f538c56edb1c6ebba6af91afc81b40822452342f6da54907bbdf"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"},
|
{file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:08dc702529bb06a2b23859110c214db245455532da5eaea602921687cfcd23db"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"},
|
{file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d4e66a857621584869cfbad87039e65dadd7119f0d9bb9dbc957e089e32c164"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"},
|
{file = "watchfiles-0.20.0-cp37-abi3-win32.whl", hash = "sha256:a03d1e6feb7966b417f43c3e3783188167fd69c2063e86bad31e62c4ea794cc5"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"},
|
{file = "watchfiles-0.20.0-cp37-abi3-win_amd64.whl", hash = "sha256:eccc8942bcdc7d638a01435d915b913255bbd66f018f1af051cd8afddb339ea3"},
|
||||||
{file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"},
|
{file = "watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c"},
|
||||||
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"},
|
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d97db179f7566dcf145c5179ddb2ae2a4450e3a634eb864b09ea04e68c252e8e"},
|
||||||
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"},
|
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:835df2da7a5df5464c4a23b2d963e1a9d35afa422c83bf4ff4380b3114603644"},
|
||||||
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"},
|
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:608cd94a8767f49521901aff9ae0c92cc8f5a24d528db7d6b0295290f9d41193"},
|
||||||
{file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"},
|
{file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89d1de8218874925bce7bb2ae9657efc504411528930d7a83f98b1749864f2ef"},
|
||||||
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"},
|
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:13f995d5152a8ba4ed7c2bbbaeee4e11a5944defc7cacd0ccb4dcbdcfd78029a"},
|
||||||
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"},
|
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9b5c8d3be7b502f8c43a33c63166ada8828dbb0c6d49c8f9ce990a96de2f5a49"},
|
||||||
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"},
|
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e43af4464daa08723c04b43cf978ab86cc55c684c16172622bdac64b34e36af0"},
|
||||||
{file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"},
|
{file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d9e1f75c4f86c93d73b5bd1ebe667558357548f11b4f8af4e0e272f79413ce"},
|
||||||
{file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"},
|
{file = "watchfiles-0.20.0.tar.gz", hash = "sha256:728575b6b94c90dd531514677201e8851708e6e4b5fe7028ac506a200b622019"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -4552,4 +4693,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.11"
|
||||||
content-hash = "1a8981686295b3de58b41192c608a69a2c05983c47f93451c8a6ed50304b7cb3"
|
content-hash = "6d200d3ea1ccf9fb89f44043e3e0845e70f19aac374b96227559375f44508dc5"
|
||||||
|
|
|
@ -30,6 +30,9 @@ rich = "^13.4.2"
|
||||||
ftfy = "^6.1.1"
|
ftfy = "^6.1.1"
|
||||||
setuptools = "^68.0.0"
|
setuptools = "^68.0.0"
|
||||||
open-clip-torch = "^2.20.0"
|
open-clip-torch = "^2.20.0"
|
||||||
|
python-multipart = "^0.0.6"
|
||||||
|
orjson = "^3.9.5"
|
||||||
|
safetensors = "0.3.2"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
mypy = "^1.3.0"
|
mypy = "^1.3.0"
|
||||||
|
|
|
@ -255,7 +255,7 @@ class ExifBottomSheet extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
"ƒ/${exifInfo.fNumber} ${exifInfo.exposureTime} ${exifInfo.focalLength} mm ISO${exifInfo.iso} ",
|
"ƒ/${exifInfo.fNumber} ${exifInfo.exposureTime} ${exifInfo.focalLength} mm ISO ${exifInfo.iso ?? ''} ",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
15
mobile/openapi/.openapi-generator/FILES
generated
15
mobile/openapi/.openapi-generator/FILES
generated
|
@ -35,11 +35,14 @@ doc/AuthDeviceResponseDto.md
|
||||||
doc/AuthenticationApi.md
|
doc/AuthenticationApi.md
|
||||||
doc/BulkIdResponseDto.md
|
doc/BulkIdResponseDto.md
|
||||||
doc/BulkIdsDto.md
|
doc/BulkIdsDto.md
|
||||||
|
doc/CLIPConfig.md
|
||||||
|
doc/CLIPMode.md
|
||||||
doc/ChangePasswordDto.md
|
doc/ChangePasswordDto.md
|
||||||
doc/CheckDuplicateAssetDto.md
|
doc/CheckDuplicateAssetDto.md
|
||||||
doc/CheckDuplicateAssetResponseDto.md
|
doc/CheckDuplicateAssetResponseDto.md
|
||||||
doc/CheckExistingAssetsDto.md
|
doc/CheckExistingAssetsDto.md
|
||||||
doc/CheckExistingAssetsResponseDto.md
|
doc/CheckExistingAssetsResponseDto.md
|
||||||
|
doc/ClassificationConfig.md
|
||||||
doc/CreateAlbumDto.md
|
doc/CreateAlbumDto.md
|
||||||
doc/CreateProfileImageResponseDto.md
|
doc/CreateProfileImageResponseDto.md
|
||||||
doc/CreateTagDto.md
|
doc/CreateTagDto.md
|
||||||
|
@ -68,6 +71,7 @@ doc/LogoutResponseDto.md
|
||||||
doc/MapMarkerResponseDto.md
|
doc/MapMarkerResponseDto.md
|
||||||
doc/MemoryLaneResponseDto.md
|
doc/MemoryLaneResponseDto.md
|
||||||
doc/MergePersonDto.md
|
doc/MergePersonDto.md
|
||||||
|
doc/ModelType.md
|
||||||
doc/OAuthApi.md
|
doc/OAuthApi.md
|
||||||
doc/OAuthCallbackDto.md
|
doc/OAuthCallbackDto.md
|
||||||
doc/OAuthConfigDto.md
|
doc/OAuthConfigDto.md
|
||||||
|
@ -80,6 +84,7 @@ doc/PersonApi.md
|
||||||
doc/PersonResponseDto.md
|
doc/PersonResponseDto.md
|
||||||
doc/PersonUpdateDto.md
|
doc/PersonUpdateDto.md
|
||||||
doc/QueueStatusDto.md
|
doc/QueueStatusDto.md
|
||||||
|
doc/RecognitionConfig.md
|
||||||
doc/SearchAlbumResponseDto.md
|
doc/SearchAlbumResponseDto.md
|
||||||
doc/SearchApi.md
|
doc/SearchApi.md
|
||||||
doc/SearchAssetDto.md
|
doc/SearchAssetDto.md
|
||||||
|
@ -189,6 +194,9 @@ lib/model/check_duplicate_asset_dto.dart
|
||||||
lib/model/check_duplicate_asset_response_dto.dart
|
lib/model/check_duplicate_asset_response_dto.dart
|
||||||
lib/model/check_existing_assets_dto.dart
|
lib/model/check_existing_assets_dto.dart
|
||||||
lib/model/check_existing_assets_response_dto.dart
|
lib/model/check_existing_assets_response_dto.dart
|
||||||
|
lib/model/classification_config.dart
|
||||||
|
lib/model/clip_config.dart
|
||||||
|
lib/model/clip_mode.dart
|
||||||
lib/model/create_album_dto.dart
|
lib/model/create_album_dto.dart
|
||||||
lib/model/create_profile_image_response_dto.dart
|
lib/model/create_profile_image_response_dto.dart
|
||||||
lib/model/create_tag_dto.dart
|
lib/model/create_tag_dto.dart
|
||||||
|
@ -216,6 +224,7 @@ lib/model/logout_response_dto.dart
|
||||||
lib/model/map_marker_response_dto.dart
|
lib/model/map_marker_response_dto.dart
|
||||||
lib/model/memory_lane_response_dto.dart
|
lib/model/memory_lane_response_dto.dart
|
||||||
lib/model/merge_person_dto.dart
|
lib/model/merge_person_dto.dart
|
||||||
|
lib/model/model_type.dart
|
||||||
lib/model/o_auth_callback_dto.dart
|
lib/model/o_auth_callback_dto.dart
|
||||||
lib/model/o_auth_config_dto.dart
|
lib/model/o_auth_config_dto.dart
|
||||||
lib/model/o_auth_config_response_dto.dart
|
lib/model/o_auth_config_response_dto.dart
|
||||||
|
@ -225,6 +234,7 @@ lib/model/people_update_item.dart
|
||||||
lib/model/person_response_dto.dart
|
lib/model/person_response_dto.dart
|
||||||
lib/model/person_update_dto.dart
|
lib/model/person_update_dto.dart
|
||||||
lib/model/queue_status_dto.dart
|
lib/model/queue_status_dto.dart
|
||||||
|
lib/model/recognition_config.dart
|
||||||
lib/model/search_album_response_dto.dart
|
lib/model/search_album_response_dto.dart
|
||||||
lib/model/search_asset_dto.dart
|
lib/model/search_asset_dto.dart
|
||||||
lib/model/search_asset_response_dto.dart
|
lib/model/search_asset_response_dto.dart
|
||||||
|
@ -309,6 +319,9 @@ test/check_duplicate_asset_dto_test.dart
|
||||||
test/check_duplicate_asset_response_dto_test.dart
|
test/check_duplicate_asset_response_dto_test.dart
|
||||||
test/check_existing_assets_dto_test.dart
|
test/check_existing_assets_dto_test.dart
|
||||||
test/check_existing_assets_response_dto_test.dart
|
test/check_existing_assets_response_dto_test.dart
|
||||||
|
test/classification_config_test.dart
|
||||||
|
test/clip_config_test.dart
|
||||||
|
test/clip_mode_test.dart
|
||||||
test/create_album_dto_test.dart
|
test/create_album_dto_test.dart
|
||||||
test/create_profile_image_response_dto_test.dart
|
test/create_profile_image_response_dto_test.dart
|
||||||
test/create_tag_dto_test.dart
|
test/create_tag_dto_test.dart
|
||||||
|
@ -337,6 +350,7 @@ test/logout_response_dto_test.dart
|
||||||
test/map_marker_response_dto_test.dart
|
test/map_marker_response_dto_test.dart
|
||||||
test/memory_lane_response_dto_test.dart
|
test/memory_lane_response_dto_test.dart
|
||||||
test/merge_person_dto_test.dart
|
test/merge_person_dto_test.dart
|
||||||
|
test/model_type_test.dart
|
||||||
test/o_auth_api_test.dart
|
test/o_auth_api_test.dart
|
||||||
test/o_auth_callback_dto_test.dart
|
test/o_auth_callback_dto_test.dart
|
||||||
test/o_auth_config_dto_test.dart
|
test/o_auth_config_dto_test.dart
|
||||||
|
@ -349,6 +363,7 @@ test/person_api_test.dart
|
||||||
test/person_response_dto_test.dart
|
test/person_response_dto_test.dart
|
||||||
test/person_update_dto_test.dart
|
test/person_update_dto_test.dart
|
||||||
test/queue_status_dto_test.dart
|
test/queue_status_dto_test.dart
|
||||||
|
test/recognition_config_test.dart
|
||||||
test/search_album_response_dto_test.dart
|
test/search_album_response_dto_test.dart
|
||||||
test/search_api_test.dart
|
test/search_api_test.dart
|
||||||
test/search_asset_dto_test.dart
|
test/search_asset_dto_test.dart
|
||||||
|
|
5
mobile/openapi/README.md
generated
5
mobile/openapi/README.md
generated
|
@ -208,11 +208,14 @@ Class | Method | HTTP request | Description
|
||||||
- [AuthDeviceResponseDto](doc//AuthDeviceResponseDto.md)
|
- [AuthDeviceResponseDto](doc//AuthDeviceResponseDto.md)
|
||||||
- [BulkIdResponseDto](doc//BulkIdResponseDto.md)
|
- [BulkIdResponseDto](doc//BulkIdResponseDto.md)
|
||||||
- [BulkIdsDto](doc//BulkIdsDto.md)
|
- [BulkIdsDto](doc//BulkIdsDto.md)
|
||||||
|
- [CLIPConfig](doc//CLIPConfig.md)
|
||||||
|
- [CLIPMode](doc//CLIPMode.md)
|
||||||
- [ChangePasswordDto](doc//ChangePasswordDto.md)
|
- [ChangePasswordDto](doc//ChangePasswordDto.md)
|
||||||
- [CheckDuplicateAssetDto](doc//CheckDuplicateAssetDto.md)
|
- [CheckDuplicateAssetDto](doc//CheckDuplicateAssetDto.md)
|
||||||
- [CheckDuplicateAssetResponseDto](doc//CheckDuplicateAssetResponseDto.md)
|
- [CheckDuplicateAssetResponseDto](doc//CheckDuplicateAssetResponseDto.md)
|
||||||
- [CheckExistingAssetsDto](doc//CheckExistingAssetsDto.md)
|
- [CheckExistingAssetsDto](doc//CheckExistingAssetsDto.md)
|
||||||
- [CheckExistingAssetsResponseDto](doc//CheckExistingAssetsResponseDto.md)
|
- [CheckExistingAssetsResponseDto](doc//CheckExistingAssetsResponseDto.md)
|
||||||
|
- [ClassificationConfig](doc//ClassificationConfig.md)
|
||||||
- [CreateAlbumDto](doc//CreateAlbumDto.md)
|
- [CreateAlbumDto](doc//CreateAlbumDto.md)
|
||||||
- [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md)
|
- [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md)
|
||||||
- [CreateTagDto](doc//CreateTagDto.md)
|
- [CreateTagDto](doc//CreateTagDto.md)
|
||||||
|
@ -240,6 +243,7 @@ Class | Method | HTTP request | Description
|
||||||
- [MapMarkerResponseDto](doc//MapMarkerResponseDto.md)
|
- [MapMarkerResponseDto](doc//MapMarkerResponseDto.md)
|
||||||
- [MemoryLaneResponseDto](doc//MemoryLaneResponseDto.md)
|
- [MemoryLaneResponseDto](doc//MemoryLaneResponseDto.md)
|
||||||
- [MergePersonDto](doc//MergePersonDto.md)
|
- [MergePersonDto](doc//MergePersonDto.md)
|
||||||
|
- [ModelType](doc//ModelType.md)
|
||||||
- [OAuthCallbackDto](doc//OAuthCallbackDto.md)
|
- [OAuthCallbackDto](doc//OAuthCallbackDto.md)
|
||||||
- [OAuthConfigDto](doc//OAuthConfigDto.md)
|
- [OAuthConfigDto](doc//OAuthConfigDto.md)
|
||||||
- [OAuthConfigResponseDto](doc//OAuthConfigResponseDto.md)
|
- [OAuthConfigResponseDto](doc//OAuthConfigResponseDto.md)
|
||||||
|
@ -249,6 +253,7 @@ Class | Method | HTTP request | Description
|
||||||
- [PersonResponseDto](doc//PersonResponseDto.md)
|
- [PersonResponseDto](doc//PersonResponseDto.md)
|
||||||
- [PersonUpdateDto](doc//PersonUpdateDto.md)
|
- [PersonUpdateDto](doc//PersonUpdateDto.md)
|
||||||
- [QueueStatusDto](doc//QueueStatusDto.md)
|
- [QueueStatusDto](doc//QueueStatusDto.md)
|
||||||
|
- [RecognitionConfig](doc//RecognitionConfig.md)
|
||||||
- [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md)
|
- [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md)
|
||||||
- [SearchAssetDto](doc//SearchAssetDto.md)
|
- [SearchAssetDto](doc//SearchAssetDto.md)
|
||||||
- [SearchAssetResponseDto](doc//SearchAssetResponseDto.md)
|
- [SearchAssetResponseDto](doc//SearchAssetResponseDto.md)
|
||||||
|
|
18
mobile/openapi/doc/CLIPConfig.md
generated
Normal file
18
mobile/openapi/doc/CLIPConfig.md
generated
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# openapi.model.CLIPConfig
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**enabled** | **bool** | |
|
||||||
|
**mode** | [**CLIPMode**](CLIPMode.md) | | [optional]
|
||||||
|
**modelName** | **String** | |
|
||||||
|
**modelType** | [**ModelType**](ModelType.md) | | [optional]
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
14
mobile/openapi/doc/CLIPMode.md
generated
Normal file
14
mobile/openapi/doc/CLIPMode.md
generated
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# openapi.model.CLIPMode
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
18
mobile/openapi/doc/ClassificationConfig.md
generated
Normal file
18
mobile/openapi/doc/ClassificationConfig.md
generated
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# openapi.model.ClassificationConfig
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**enabled** | **bool** | |
|
||||||
|
**minScore** | **int** | |
|
||||||
|
**modelName** | **String** | |
|
||||||
|
**modelType** | [**ModelType**](ModelType.md) | | [optional]
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
14
mobile/openapi/doc/ModelType.md
generated
Normal file
14
mobile/openapi/doc/ModelType.md
generated
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# openapi.model.ModelType
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
19
mobile/openapi/doc/RecognitionConfig.md
generated
Normal file
19
mobile/openapi/doc/RecognitionConfig.md
generated
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# openapi.model.RecognitionConfig
|
||||||
|
|
||||||
|
## Load the model package
|
||||||
|
```dart
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
Name | Type | Description | Notes
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**enabled** | **bool** | |
|
||||||
|
**maxDistance** | **int** | |
|
||||||
|
**minScore** | **int** | |
|
||||||
|
**modelName** | **String** | |
|
||||||
|
**modelType** | [**ModelType**](ModelType.md) | | [optional]
|
||||||
|
|
||||||
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import 'package:openapi/api.dart';
|
||||||
## Properties
|
## Properties
|
||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**clipEncodeEnabled** | **bool** | |
|
**classification** | [**ClassificationConfig**](ClassificationConfig.md) | |
|
||||||
|
**clip** | [**CLIPConfig**](CLIPConfig.md) | |
|
||||||
**enabled** | **bool** | |
|
**enabled** | **bool** | |
|
||||||
**facialRecognitionEnabled** | **bool** | |
|
**facialRecognition** | [**RecognitionConfig**](RecognitionConfig.md) | |
|
||||||
**tagImageEnabled** | **bool** | |
|
|
||||||
**url** | **String** | |
|
**url** | **String** | |
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
5
mobile/openapi/lib/api.dart
generated
5
mobile/openapi/lib/api.dart
generated
|
@ -71,11 +71,14 @@ part 'model/audit_deletes_response_dto.dart';
|
||||||
part 'model/auth_device_response_dto.dart';
|
part 'model/auth_device_response_dto.dart';
|
||||||
part 'model/bulk_id_response_dto.dart';
|
part 'model/bulk_id_response_dto.dart';
|
||||||
part 'model/bulk_ids_dto.dart';
|
part 'model/bulk_ids_dto.dart';
|
||||||
|
part 'model/clip_config.dart';
|
||||||
|
part 'model/clip_mode.dart';
|
||||||
part 'model/change_password_dto.dart';
|
part 'model/change_password_dto.dart';
|
||||||
part 'model/check_duplicate_asset_dto.dart';
|
part 'model/check_duplicate_asset_dto.dart';
|
||||||
part 'model/check_duplicate_asset_response_dto.dart';
|
part 'model/check_duplicate_asset_response_dto.dart';
|
||||||
part 'model/check_existing_assets_dto.dart';
|
part 'model/check_existing_assets_dto.dart';
|
||||||
part 'model/check_existing_assets_response_dto.dart';
|
part 'model/check_existing_assets_response_dto.dart';
|
||||||
|
part 'model/classification_config.dart';
|
||||||
part 'model/create_album_dto.dart';
|
part 'model/create_album_dto.dart';
|
||||||
part 'model/create_profile_image_response_dto.dart';
|
part 'model/create_profile_image_response_dto.dart';
|
||||||
part 'model/create_tag_dto.dart';
|
part 'model/create_tag_dto.dart';
|
||||||
|
@ -103,6 +106,7 @@ part 'model/logout_response_dto.dart';
|
||||||
part 'model/map_marker_response_dto.dart';
|
part 'model/map_marker_response_dto.dart';
|
||||||
part 'model/memory_lane_response_dto.dart';
|
part 'model/memory_lane_response_dto.dart';
|
||||||
part 'model/merge_person_dto.dart';
|
part 'model/merge_person_dto.dart';
|
||||||
|
part 'model/model_type.dart';
|
||||||
part 'model/o_auth_callback_dto.dart';
|
part 'model/o_auth_callback_dto.dart';
|
||||||
part 'model/o_auth_config_dto.dart';
|
part 'model/o_auth_config_dto.dart';
|
||||||
part 'model/o_auth_config_response_dto.dart';
|
part 'model/o_auth_config_response_dto.dart';
|
||||||
|
@ -112,6 +116,7 @@ part 'model/people_update_item.dart';
|
||||||
part 'model/person_response_dto.dart';
|
part 'model/person_response_dto.dart';
|
||||||
part 'model/person_update_dto.dart';
|
part 'model/person_update_dto.dart';
|
||||||
part 'model/queue_status_dto.dart';
|
part 'model/queue_status_dto.dart';
|
||||||
|
part 'model/recognition_config.dart';
|
||||||
part 'model/search_album_response_dto.dart';
|
part 'model/search_album_response_dto.dart';
|
||||||
part 'model/search_asset_dto.dart';
|
part 'model/search_asset_dto.dart';
|
||||||
part 'model/search_asset_response_dto.dart';
|
part 'model/search_asset_response_dto.dart';
|
||||||
|
|
10
mobile/openapi/lib/api_client.dart
generated
10
mobile/openapi/lib/api_client.dart
generated
|
@ -235,6 +235,10 @@ class ApiClient {
|
||||||
return BulkIdResponseDto.fromJson(value);
|
return BulkIdResponseDto.fromJson(value);
|
||||||
case 'BulkIdsDto':
|
case 'BulkIdsDto':
|
||||||
return BulkIdsDto.fromJson(value);
|
return BulkIdsDto.fromJson(value);
|
||||||
|
case 'CLIPConfig':
|
||||||
|
return CLIPConfig.fromJson(value);
|
||||||
|
case 'CLIPMode':
|
||||||
|
return CLIPModeTypeTransformer().decode(value);
|
||||||
case 'ChangePasswordDto':
|
case 'ChangePasswordDto':
|
||||||
return ChangePasswordDto.fromJson(value);
|
return ChangePasswordDto.fromJson(value);
|
||||||
case 'CheckDuplicateAssetDto':
|
case 'CheckDuplicateAssetDto':
|
||||||
|
@ -245,6 +249,8 @@ class ApiClient {
|
||||||
return CheckExistingAssetsDto.fromJson(value);
|
return CheckExistingAssetsDto.fromJson(value);
|
||||||
case 'CheckExistingAssetsResponseDto':
|
case 'CheckExistingAssetsResponseDto':
|
||||||
return CheckExistingAssetsResponseDto.fromJson(value);
|
return CheckExistingAssetsResponseDto.fromJson(value);
|
||||||
|
case 'ClassificationConfig':
|
||||||
|
return ClassificationConfig.fromJson(value);
|
||||||
case 'CreateAlbumDto':
|
case 'CreateAlbumDto':
|
||||||
return CreateAlbumDto.fromJson(value);
|
return CreateAlbumDto.fromJson(value);
|
||||||
case 'CreateProfileImageResponseDto':
|
case 'CreateProfileImageResponseDto':
|
||||||
|
@ -299,6 +305,8 @@ class ApiClient {
|
||||||
return MemoryLaneResponseDto.fromJson(value);
|
return MemoryLaneResponseDto.fromJson(value);
|
||||||
case 'MergePersonDto':
|
case 'MergePersonDto':
|
||||||
return MergePersonDto.fromJson(value);
|
return MergePersonDto.fromJson(value);
|
||||||
|
case 'ModelType':
|
||||||
|
return ModelTypeTypeTransformer().decode(value);
|
||||||
case 'OAuthCallbackDto':
|
case 'OAuthCallbackDto':
|
||||||
return OAuthCallbackDto.fromJson(value);
|
return OAuthCallbackDto.fromJson(value);
|
||||||
case 'OAuthConfigDto':
|
case 'OAuthConfigDto':
|
||||||
|
@ -317,6 +325,8 @@ class ApiClient {
|
||||||
return PersonUpdateDto.fromJson(value);
|
return PersonUpdateDto.fromJson(value);
|
||||||
case 'QueueStatusDto':
|
case 'QueueStatusDto':
|
||||||
return QueueStatusDto.fromJson(value);
|
return QueueStatusDto.fromJson(value);
|
||||||
|
case 'RecognitionConfig':
|
||||||
|
return RecognitionConfig.fromJson(value);
|
||||||
case 'SearchAlbumResponseDto':
|
case 'SearchAlbumResponseDto':
|
||||||
return SearchAlbumResponseDto.fromJson(value);
|
return SearchAlbumResponseDto.fromJson(value);
|
||||||
case 'SearchAssetDto':
|
case 'SearchAssetDto':
|
||||||
|
|
6
mobile/openapi/lib/api_helper.dart
generated
6
mobile/openapi/lib/api_helper.dart
generated
|
@ -64,6 +64,9 @@ String parameterToString(dynamic value) {
|
||||||
if (value is AudioCodec) {
|
if (value is AudioCodec) {
|
||||||
return AudioCodecTypeTransformer().encode(value).toString();
|
return AudioCodecTypeTransformer().encode(value).toString();
|
||||||
}
|
}
|
||||||
|
if (value is CLIPMode) {
|
||||||
|
return CLIPModeTypeTransformer().encode(value).toString();
|
||||||
|
}
|
||||||
if (value is DeleteAssetStatus) {
|
if (value is DeleteAssetStatus) {
|
||||||
return DeleteAssetStatusTypeTransformer().encode(value).toString();
|
return DeleteAssetStatusTypeTransformer().encode(value).toString();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +79,9 @@ String parameterToString(dynamic value) {
|
||||||
if (value is JobName) {
|
if (value is JobName) {
|
||||||
return JobNameTypeTransformer().encode(value).toString();
|
return JobNameTypeTransformer().encode(value).toString();
|
||||||
}
|
}
|
||||||
|
if (value is ModelType) {
|
||||||
|
return ModelTypeTypeTransformer().encode(value).toString();
|
||||||
|
}
|
||||||
if (value is SharedLinkType) {
|
if (value is SharedLinkType) {
|
||||||
return SharedLinkTypeTypeTransformer().encode(value).toString();
|
return SharedLinkTypeTypeTransformer().encode(value).toString();
|
||||||
}
|
}
|
||||||
|
|
131
mobile/openapi/lib/model/classification_config.dart
generated
Normal file
131
mobile/openapi/lib/model/classification_config.dart
generated
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
class ClassificationConfig {
|
||||||
|
/// Returns a new [ClassificationConfig] instance.
|
||||||
|
ClassificationConfig({
|
||||||
|
required this.enabled,
|
||||||
|
required this.minScore,
|
||||||
|
required this.modelName,
|
||||||
|
this.modelType,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
int minScore;
|
||||||
|
|
||||||
|
String modelName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
ModelType? modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is ClassificationConfig &&
|
||||||
|
other.enabled == enabled &&
|
||||||
|
other.minScore == minScore &&
|
||||||
|
other.modelName == modelName &&
|
||||||
|
other.modelType == modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(enabled.hashCode) +
|
||||||
|
(minScore.hashCode) +
|
||||||
|
(modelName.hashCode) +
|
||||||
|
(modelType == null ? 0 : modelType!.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ClassificationConfig[enabled=$enabled, minScore=$minScore, modelName=$modelName, modelType=$modelType]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'enabled'] = this.enabled;
|
||||||
|
json[r'minScore'] = this.minScore;
|
||||||
|
json[r'modelName'] = this.modelName;
|
||||||
|
if (this.modelType != null) {
|
||||||
|
json[r'modelType'] = this.modelType;
|
||||||
|
} else {
|
||||||
|
// json[r'modelType'] = null;
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [ClassificationConfig] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static ClassificationConfig? fromJson(dynamic value) {
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return ClassificationConfig(
|
||||||
|
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||||
|
minScore: mapValueOfType<int>(json, r'minScore')!,
|
||||||
|
modelName: mapValueOfType<String>(json, r'modelName')!,
|
||||||
|
modelType: ModelType.fromJson(json[r'modelType']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<ClassificationConfig> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <ClassificationConfig>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = ClassificationConfig.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, ClassificationConfig> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, ClassificationConfig>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = ClassificationConfig.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of ClassificationConfig-objects as value to a dart map
|
||||||
|
static Map<String, List<ClassificationConfig>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<ClassificationConfig>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = ClassificationConfig.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'enabled',
|
||||||
|
'minScore',
|
||||||
|
'modelName',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
140
mobile/openapi/lib/model/clip_config.dart
generated
Normal file
140
mobile/openapi/lib/model/clip_config.dart
generated
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
class CLIPConfig {
|
||||||
|
/// Returns a new [CLIPConfig] instance.
|
||||||
|
CLIPConfig({
|
||||||
|
required this.enabled,
|
||||||
|
this.mode,
|
||||||
|
required this.modelName,
|
||||||
|
this.modelType,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
CLIPMode? mode;
|
||||||
|
|
||||||
|
String modelName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
ModelType? modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is CLIPConfig &&
|
||||||
|
other.enabled == enabled &&
|
||||||
|
other.mode == mode &&
|
||||||
|
other.modelName == modelName &&
|
||||||
|
other.modelType == modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(enabled.hashCode) +
|
||||||
|
(mode == null ? 0 : mode!.hashCode) +
|
||||||
|
(modelName.hashCode) +
|
||||||
|
(modelType == null ? 0 : modelType!.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'CLIPConfig[enabled=$enabled, mode=$mode, modelName=$modelName, modelType=$modelType]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'enabled'] = this.enabled;
|
||||||
|
if (this.mode != null) {
|
||||||
|
json[r'mode'] = this.mode;
|
||||||
|
} else {
|
||||||
|
// json[r'mode'] = null;
|
||||||
|
}
|
||||||
|
json[r'modelName'] = this.modelName;
|
||||||
|
if (this.modelType != null) {
|
||||||
|
json[r'modelType'] = this.modelType;
|
||||||
|
} else {
|
||||||
|
// json[r'modelType'] = null;
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [CLIPConfig] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static CLIPConfig? fromJson(dynamic value) {
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return CLIPConfig(
|
||||||
|
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||||
|
mode: CLIPMode.fromJson(json[r'mode']),
|
||||||
|
modelName: mapValueOfType<String>(json, r'modelName')!,
|
||||||
|
modelType: ModelType.fromJson(json[r'modelType']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CLIPConfig> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <CLIPConfig>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = CLIPConfig.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, CLIPConfig> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, CLIPConfig>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = CLIPConfig.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of CLIPConfig-objects as value to a dart map
|
||||||
|
static Map<String, List<CLIPConfig>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<CLIPConfig>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = CLIPConfig.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'enabled',
|
||||||
|
'modelName',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
85
mobile/openapi/lib/model/clip_mode.dart
generated
Normal file
85
mobile/openapi/lib/model/clip_mode.dart
generated
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
|
||||||
|
class CLIPMode {
|
||||||
|
/// Instantiate a new enum with the provided [value].
|
||||||
|
const CLIPMode._(this.value);
|
||||||
|
|
||||||
|
/// The underlying value of this enum member.
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => value;
|
||||||
|
|
||||||
|
String toJson() => value;
|
||||||
|
|
||||||
|
static const vision = CLIPMode._(r'vision');
|
||||||
|
static const text = CLIPMode._(r'text');
|
||||||
|
|
||||||
|
/// List of all possible values in this [enum][CLIPMode].
|
||||||
|
static const values = <CLIPMode>[
|
||||||
|
vision,
|
||||||
|
text,
|
||||||
|
];
|
||||||
|
|
||||||
|
static CLIPMode? fromJson(dynamic value) => CLIPModeTypeTransformer().decode(value);
|
||||||
|
|
||||||
|
static List<CLIPMode>? listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <CLIPMode>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = CLIPMode.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transformation class that can [encode] an instance of [CLIPMode] to String,
|
||||||
|
/// and [decode] dynamic data back to [CLIPMode].
|
||||||
|
class CLIPModeTypeTransformer {
|
||||||
|
factory CLIPModeTypeTransformer() => _instance ??= const CLIPModeTypeTransformer._();
|
||||||
|
|
||||||
|
const CLIPModeTypeTransformer._();
|
||||||
|
|
||||||
|
String encode(CLIPMode data) => data.value;
|
||||||
|
|
||||||
|
/// Decodes a [dynamic value][data] to a CLIPMode.
|
||||||
|
///
|
||||||
|
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||||
|
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||||
|
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||||
|
///
|
||||||
|
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||||
|
/// and users are still using an old app with the old code.
|
||||||
|
CLIPMode? decode(dynamic data, {bool allowNull = true}) {
|
||||||
|
if (data != null) {
|
||||||
|
switch (data) {
|
||||||
|
case r'vision': return CLIPMode.vision;
|
||||||
|
case r'text': return CLIPMode.text;
|
||||||
|
default:
|
||||||
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Singleton [CLIPModeTypeTransformer] instance.
|
||||||
|
static CLIPModeTypeTransformer? _instance;
|
||||||
|
}
|
||||||
|
|
88
mobile/openapi/lib/model/model_type.dart
generated
Normal file
88
mobile/openapi/lib/model/model_type.dart
generated
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
|
||||||
|
class ModelType {
|
||||||
|
/// Instantiate a new enum with the provided [value].
|
||||||
|
const ModelType._(this.value);
|
||||||
|
|
||||||
|
/// The underlying value of this enum member.
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => value;
|
||||||
|
|
||||||
|
String toJson() => value;
|
||||||
|
|
||||||
|
static const imageClassification = ModelType._(r'image-classification');
|
||||||
|
static const facialRecognition = ModelType._(r'facial-recognition');
|
||||||
|
static const clip = ModelType._(r'clip');
|
||||||
|
|
||||||
|
/// List of all possible values in this [enum][ModelType].
|
||||||
|
static const values = <ModelType>[
|
||||||
|
imageClassification,
|
||||||
|
facialRecognition,
|
||||||
|
clip,
|
||||||
|
];
|
||||||
|
|
||||||
|
static ModelType? fromJson(dynamic value) => ModelTypeTypeTransformer().decode(value);
|
||||||
|
|
||||||
|
static List<ModelType>? listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <ModelType>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = ModelType.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transformation class that can [encode] an instance of [ModelType] to String,
|
||||||
|
/// and [decode] dynamic data back to [ModelType].
|
||||||
|
class ModelTypeTypeTransformer {
|
||||||
|
factory ModelTypeTypeTransformer() => _instance ??= const ModelTypeTypeTransformer._();
|
||||||
|
|
||||||
|
const ModelTypeTypeTransformer._();
|
||||||
|
|
||||||
|
String encode(ModelType data) => data.value;
|
||||||
|
|
||||||
|
/// Decodes a [dynamic value][data] to a ModelType.
|
||||||
|
///
|
||||||
|
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||||
|
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||||
|
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||||
|
///
|
||||||
|
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||||
|
/// and users are still using an old app with the old code.
|
||||||
|
ModelType? decode(dynamic data, {bool allowNull = true}) {
|
||||||
|
if (data != null) {
|
||||||
|
switch (data) {
|
||||||
|
case r'image-classification': return ModelType.imageClassification;
|
||||||
|
case r'facial-recognition': return ModelType.facialRecognition;
|
||||||
|
case r'clip': return ModelType.clip;
|
||||||
|
default:
|
||||||
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Singleton [ModelTypeTypeTransformer] instance.
|
||||||
|
static ModelTypeTypeTransformer? _instance;
|
||||||
|
}
|
||||||
|
|
139
mobile/openapi/lib/model/recognition_config.dart
generated
Normal file
139
mobile/openapi/lib/model/recognition_config.dart
generated
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
part of openapi.api;
|
||||||
|
|
||||||
|
class RecognitionConfig {
|
||||||
|
/// Returns a new [RecognitionConfig] instance.
|
||||||
|
RecognitionConfig({
|
||||||
|
required this.enabled,
|
||||||
|
required this.maxDistance,
|
||||||
|
required this.minScore,
|
||||||
|
required this.modelName,
|
||||||
|
this.modelType,
|
||||||
|
});
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
int maxDistance;
|
||||||
|
|
||||||
|
int minScore;
|
||||||
|
|
||||||
|
String modelName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
ModelType? modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => identical(this, other) || other is RecognitionConfig &&
|
||||||
|
other.enabled == enabled &&
|
||||||
|
other.maxDistance == maxDistance &&
|
||||||
|
other.minScore == minScore &&
|
||||||
|
other.modelName == modelName &&
|
||||||
|
other.modelType == modelType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
// ignore: unnecessary_parenthesis
|
||||||
|
(enabled.hashCode) +
|
||||||
|
(maxDistance.hashCode) +
|
||||||
|
(minScore.hashCode) +
|
||||||
|
(modelName.hashCode) +
|
||||||
|
(modelType == null ? 0 : modelType!.hashCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'RecognitionConfig[enabled=$enabled, maxDistance=$maxDistance, minScore=$minScore, modelName=$modelName, modelType=$modelType]';
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{};
|
||||||
|
json[r'enabled'] = this.enabled;
|
||||||
|
json[r'maxDistance'] = this.maxDistance;
|
||||||
|
json[r'minScore'] = this.minScore;
|
||||||
|
json[r'modelName'] = this.modelName;
|
||||||
|
if (this.modelType != null) {
|
||||||
|
json[r'modelType'] = this.modelType;
|
||||||
|
} else {
|
||||||
|
// json[r'modelType'] = null;
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [RecognitionConfig] instance and imports its values from
|
||||||
|
/// [value] if it's a [Map], null otherwise.
|
||||||
|
// ignore: prefer_constructors_over_static_methods
|
||||||
|
static RecognitionConfig? fromJson(dynamic value) {
|
||||||
|
if (value is Map) {
|
||||||
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
|
return RecognitionConfig(
|
||||||
|
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||||
|
maxDistance: mapValueOfType<int>(json, r'maxDistance')!,
|
||||||
|
minScore: mapValueOfType<int>(json, r'minScore')!,
|
||||||
|
modelName: mapValueOfType<String>(json, r'modelName')!,
|
||||||
|
modelType: ModelType.fromJson(json[r'modelType']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<RecognitionConfig> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <RecognitionConfig>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = RecognitionConfig.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<String, RecognitionConfig> mapFromJson(dynamic json) {
|
||||||
|
final map = <String, RecognitionConfig>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
final value = RecognitionConfig.fromJson(entry.value);
|
||||||
|
if (value != null) {
|
||||||
|
map[entry.key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maps a json object with a list of RecognitionConfig-objects as value to a dart map
|
||||||
|
static Map<String, List<RecognitionConfig>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final map = <String, List<RecognitionConfig>>{};
|
||||||
|
if (json is Map && json.isNotEmpty) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
json = json.cast<String, dynamic>();
|
||||||
|
for (final entry in json.entries) {
|
||||||
|
map[entry.key] = RecognitionConfig.listFromJson(entry.value, growable: growable,);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The list of required keys that must be present in a JSON.
|
||||||
|
static const requiredKeys = <String>{
|
||||||
|
'enabled',
|
||||||
|
'maxDistance',
|
||||||
|
'minScore',
|
||||||
|
'modelName',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -13,49 +13,49 @@ part of openapi.api;
|
||||||
class SystemConfigMachineLearningDto {
|
class SystemConfigMachineLearningDto {
|
||||||
/// Returns a new [SystemConfigMachineLearningDto] instance.
|
/// Returns a new [SystemConfigMachineLearningDto] instance.
|
||||||
SystemConfigMachineLearningDto({
|
SystemConfigMachineLearningDto({
|
||||||
required this.clipEncodeEnabled,
|
required this.classification,
|
||||||
|
required this.clip,
|
||||||
required this.enabled,
|
required this.enabled,
|
||||||
required this.facialRecognitionEnabled,
|
required this.facialRecognition,
|
||||||
required this.tagImageEnabled,
|
|
||||||
required this.url,
|
required this.url,
|
||||||
});
|
});
|
||||||
|
|
||||||
bool clipEncodeEnabled;
|
ClassificationConfig classification;
|
||||||
|
|
||||||
|
CLIPConfig clip;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|
||||||
bool facialRecognitionEnabled;
|
RecognitionConfig facialRecognition;
|
||||||
|
|
||||||
bool tagImageEnabled;
|
|
||||||
|
|
||||||
String url;
|
String url;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is SystemConfigMachineLearningDto &&
|
bool operator ==(Object other) => identical(this, other) || other is SystemConfigMachineLearningDto &&
|
||||||
other.clipEncodeEnabled == clipEncodeEnabled &&
|
other.classification == classification &&
|
||||||
|
other.clip == clip &&
|
||||||
other.enabled == enabled &&
|
other.enabled == enabled &&
|
||||||
other.facialRecognitionEnabled == facialRecognitionEnabled &&
|
other.facialRecognition == facialRecognition &&
|
||||||
other.tagImageEnabled == tagImageEnabled &&
|
|
||||||
other.url == url;
|
other.url == url;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(clipEncodeEnabled.hashCode) +
|
(classification.hashCode) +
|
||||||
|
(clip.hashCode) +
|
||||||
(enabled.hashCode) +
|
(enabled.hashCode) +
|
||||||
(facialRecognitionEnabled.hashCode) +
|
(facialRecognition.hashCode) +
|
||||||
(tagImageEnabled.hashCode) +
|
|
||||||
(url.hashCode);
|
(url.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SystemConfigMachineLearningDto[clipEncodeEnabled=$clipEncodeEnabled, enabled=$enabled, facialRecognitionEnabled=$facialRecognitionEnabled, tagImageEnabled=$tagImageEnabled, url=$url]';
|
String toString() => 'SystemConfigMachineLearningDto[classification=$classification, clip=$clip, enabled=$enabled, facialRecognition=$facialRecognition, url=$url]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
json[r'clipEncodeEnabled'] = this.clipEncodeEnabled;
|
json[r'classification'] = this.classification;
|
||||||
|
json[r'clip'] = this.clip;
|
||||||
json[r'enabled'] = this.enabled;
|
json[r'enabled'] = this.enabled;
|
||||||
json[r'facialRecognitionEnabled'] = this.facialRecognitionEnabled;
|
json[r'facialRecognition'] = this.facialRecognition;
|
||||||
json[r'tagImageEnabled'] = this.tagImageEnabled;
|
|
||||||
json[r'url'] = this.url;
|
json[r'url'] = this.url;
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
@ -68,10 +68,10 @@ class SystemConfigMachineLearningDto {
|
||||||
final json = value.cast<String, dynamic>();
|
final json = value.cast<String, dynamic>();
|
||||||
|
|
||||||
return SystemConfigMachineLearningDto(
|
return SystemConfigMachineLearningDto(
|
||||||
clipEncodeEnabled: mapValueOfType<bool>(json, r'clipEncodeEnabled')!,
|
classification: ClassificationConfig.fromJson(json[r'classification'])!,
|
||||||
|
clip: CLIPConfig.fromJson(json[r'clip'])!,
|
||||||
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||||
facialRecognitionEnabled: mapValueOfType<bool>(json, r'facialRecognitionEnabled')!,
|
facialRecognition: RecognitionConfig.fromJson(json[r'facialRecognition'])!,
|
||||||
tagImageEnabled: mapValueOfType<bool>(json, r'tagImageEnabled')!,
|
|
||||||
url: mapValueOfType<String>(json, r'url')!,
|
url: mapValueOfType<String>(json, r'url')!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,10 @@ class SystemConfigMachineLearningDto {
|
||||||
|
|
||||||
/// The list of required keys that must be present in a JSON.
|
/// The list of required keys that must be present in a JSON.
|
||||||
static const requiredKeys = <String>{
|
static const requiredKeys = <String>{
|
||||||
'clipEncodeEnabled',
|
'classification',
|
||||||
|
'clip',
|
||||||
'enabled',
|
'enabled',
|
||||||
'facialRecognitionEnabled',
|
'facialRecognition',
|
||||||
'tagImageEnabled',
|
|
||||||
'url',
|
'url',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
42
mobile/openapi/test/classification_config_test.dart
generated
Normal file
42
mobile/openapi/test/classification_config_test.dart
generated
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for ClassificationConfig
|
||||||
|
void main() {
|
||||||
|
// final instance = ClassificationConfig();
|
||||||
|
|
||||||
|
group('test ClassificationConfig', () {
|
||||||
|
// bool enabled
|
||||||
|
test('to test the property `enabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// int minScore
|
||||||
|
test('to test the property `minScore`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// String modelName
|
||||||
|
test('to test the property `modelName`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// ModelType modelType
|
||||||
|
test('to test the property `modelType`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
42
mobile/openapi/test/clip_config_test.dart
generated
Normal file
42
mobile/openapi/test/clip_config_test.dart
generated
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for CLIPConfig
|
||||||
|
void main() {
|
||||||
|
// final instance = CLIPConfig();
|
||||||
|
|
||||||
|
group('test CLIPConfig', () {
|
||||||
|
// bool enabled
|
||||||
|
test('to test the property `enabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// CLIPMode mode
|
||||||
|
test('to test the property `mode`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// String modelName
|
||||||
|
test('to test the property `modelName`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// ModelType modelType
|
||||||
|
test('to test the property `modelType`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
21
mobile/openapi/test/clip_mode_test.dart
generated
Normal file
21
mobile/openapi/test/clip_mode_test.dart
generated
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for CLIPMode
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
group('test CLIPMode', () {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
21
mobile/openapi/test/model_type_test.dart
generated
Normal file
21
mobile/openapi/test/model_type_test.dart
generated
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for ModelType
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
group('test ModelType', () {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
47
mobile/openapi/test/recognition_config_test.dart
generated
Normal file
47
mobile/openapi/test/recognition_config_test.dart
generated
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||||
|
//
|
||||||
|
// @dart=2.12
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element, unused_import
|
||||||
|
// ignore_for_file: always_put_required_named_parameters_first
|
||||||
|
// ignore_for_file: constant_identifier_names
|
||||||
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:openapi/api.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// tests for RecognitionConfig
|
||||||
|
void main() {
|
||||||
|
// final instance = RecognitionConfig();
|
||||||
|
|
||||||
|
group('test RecognitionConfig', () {
|
||||||
|
// bool enabled
|
||||||
|
test('to test the property `enabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// int maxDistance
|
||||||
|
test('to test the property `maxDistance`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// int minScore
|
||||||
|
test('to test the property `minScore`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// String modelName
|
||||||
|
test('to test the property `modelName`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// ModelType modelType
|
||||||
|
test('to test the property `modelType`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
|
@ -16,8 +16,13 @@ void main() {
|
||||||
// final instance = SystemConfigMachineLearningDto();
|
// final instance = SystemConfigMachineLearningDto();
|
||||||
|
|
||||||
group('test SystemConfigMachineLearningDto', () {
|
group('test SystemConfigMachineLearningDto', () {
|
||||||
// bool clipEncodeEnabled
|
// ClassificationConfig classification
|
||||||
test('to test the property `clipEncodeEnabled`', () async {
|
test('to test the property `classification`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
// CLIPConfig clip
|
||||||
|
test('to test the property `clip`', () async {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -26,13 +31,8 @@ void main() {
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
// bool facialRecognitionEnabled
|
// RecognitionConfig facialRecognition
|
||||||
test('to test the property `facialRecognitionEnabled`', () async {
|
test('to test the property `facialRecognition`', () async {
|
||||||
// TODO
|
|
||||||
});
|
|
||||||
|
|
||||||
// bool tagImageEnabled
|
|
||||||
test('to test the property `tagImageEnabled`', () async {
|
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "immich",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
|
@ -5354,6 +5354,34 @@
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"CLIPConfig": {
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"$ref": "#/components/schemas/CLIPMode"
|
||||||
|
},
|
||||||
|
"modelName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"modelType": {
|
||||||
|
"$ref": "#/components/schemas/ModelType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enabled",
|
||||||
|
"modelName"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"CLIPMode": {
|
||||||
|
"enum": [
|
||||||
|
"vision",
|
||||||
|
"text"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"ChangePasswordDto": {
|
"ChangePasswordDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"newPassword": {
|
"newPassword": {
|
||||||
|
@ -5432,6 +5460,28 @@
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"ClassificationConfig": {
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"minScore": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"modelName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"modelType": {
|
||||||
|
"$ref": "#/components/schemas/ModelType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"minScore",
|
||||||
|
"enabled",
|
||||||
|
"modelName"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"CreateAlbumDto": {
|
"CreateAlbumDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"albumName": {
|
"albumName": {
|
||||||
|
@ -6144,6 +6194,14 @@
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"ModelType": {
|
||||||
|
"enum": [
|
||||||
|
"image-classification",
|
||||||
|
"facial-recognition",
|
||||||
|
"clip"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"OAuthCallbackDto": {
|
"OAuthCallbackDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"url": {
|
"url": {
|
||||||
|
@ -6323,6 +6381,32 @@
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"RecognitionConfig": {
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"maxDistance": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"minScore": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"modelName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"modelType": {
|
||||||
|
"$ref": "#/components/schemas/ModelType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"minScore",
|
||||||
|
"maxDistance",
|
||||||
|
"enabled",
|
||||||
|
"modelName"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"SearchAlbumResponseDto": {
|
"SearchAlbumResponseDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"count": {
|
"count": {
|
||||||
|
@ -6968,17 +7052,17 @@
|
||||||
},
|
},
|
||||||
"SystemConfigMachineLearningDto": {
|
"SystemConfigMachineLearningDto": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"clipEncodeEnabled": {
|
"classification": {
|
||||||
"type": "boolean"
|
"$ref": "#/components/schemas/ClassificationConfig"
|
||||||
|
},
|
||||||
|
"clip": {
|
||||||
|
"$ref": "#/components/schemas/CLIPConfig"
|
||||||
},
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"facialRecognitionEnabled": {
|
"facialRecognition": {
|
||||||
"type": "boolean"
|
"$ref": "#/components/schemas/RecognitionConfig"
|
||||||
},
|
|
||||||
"tagImageEnabled": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -6987,9 +7071,9 @@
|
||||||
"required": [
|
"required": [
|
||||||
"enabled",
|
"enabled",
|
||||||
"url",
|
"url",
|
||||||
"clipEncodeEnabled",
|
"classification",
|
||||||
"facialRecognitionEnabled",
|
"clip",
|
||||||
"tagImageEnabled"
|
"facialRecognition"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
|
11589
server/package-lock.json
generated
11589
server/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -39,89 +39,90 @@
|
||||||
"api:generate": "node ./bin/sync-spec-version.js && bash ./bin/generate-open-api.sh"
|
"api:generate": "node ./bin/sync-spec-version.js && bash ./bin/generate-open-api.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.13",
|
"@babel/runtime": "^7.22.11",
|
||||||
"@nestjs/bullmq": "^1.1.0",
|
"@nestjs/bullmq": "^10.0.1",
|
||||||
"@nestjs/common": "^9.2.1",
|
"@nestjs/common": "^10.2.2",
|
||||||
"@nestjs/config": "^2.2.0",
|
"@nestjs/config": "^3.0.0",
|
||||||
"@nestjs/core": "^9.2.1",
|
"@nestjs/core": "^10.2.2",
|
||||||
"@nestjs/platform-express": "^9.2.1",
|
"@nestjs/platform-express": "^10.2.2",
|
||||||
"@nestjs/platform-socket.io": "^9.2.1",
|
"@nestjs/platform-socket.io": "^10.2.2",
|
||||||
"@nestjs/schedule": "^2.1.0",
|
"@nestjs/schedule": "^3.0.3",
|
||||||
"@nestjs/swagger": "^6.1.4",
|
"@nestjs/swagger": "^7.1.8",
|
||||||
"@nestjs/typeorm": "^9.0.1",
|
"@nestjs/typeorm": "^10.0.0",
|
||||||
"@nestjs/websockets": "^9.2.1",
|
"@nestjs/websockets": "^10.2.2",
|
||||||
"@socket.io/redis-adapter": "^8.0.1",
|
"@socket.io/redis-adapter": "^8.2.1",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^6.0.0",
|
||||||
"axios": "^0.26.0",
|
"axios": "^1.5.0",
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.1.1",
|
||||||
"bullmq": "^3.14.1",
|
"bullmq": "^4.8.0",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.0",
|
"class-validator": "^0.14.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"exiftool-vendored": "^22.0.0",
|
"exiftool-vendored": "^22.0.0",
|
||||||
"exiftool-vendored.pl": "^12.54.0",
|
"exiftool-vendored.pl": "^12.62.0",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"handlebars": "^4.7.7",
|
"handlebars": "^4.7.8",
|
||||||
"i18n-iso-countries": "^7.5.0",
|
"i18n-iso-countries": "^7.6.0",
|
||||||
"immich": "^0.41.0",
|
"immich": "^0.41.0",
|
||||||
"ioredis": "^5.3.1",
|
"ioredis": "^5.3.2",
|
||||||
"joi": "^17.5.0",
|
"joi": "^17.10.0",
|
||||||
"local-reverse-geocoder": "0.12.5",
|
"local-reverse-geocoder": "0.16.5",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"luxon": "^3.0.3",
|
"luxon": "^3.4.2",
|
||||||
"mv": "^2.1.1",
|
"mv": "^2.1.1",
|
||||||
"nest-commander": "^3.3.0",
|
"nest-commander": "^3.11.1",
|
||||||
"openid-client": "^5.2.1",
|
"openid-client": "^5.4.3",
|
||||||
"pg": "^8.8.0",
|
"pg": "^8.11.3",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.8.1",
|
||||||
"sanitize-filename": "^1.6.3",
|
"sanitize-filename": "^1.6.3",
|
||||||
"sharp": "^0.31.3",
|
"sharp": "^0.31.3",
|
||||||
"thumbhash": "^0.1.1",
|
"thumbhash": "^0.1.1",
|
||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.17",
|
||||||
"typesense": "^1.5.3",
|
"typesense": "^1.7.1",
|
||||||
"ua-parser-js": "^1.0.35"
|
"ua-parser-js": "^1.0.35"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^9.1.8",
|
"@nestjs/cli": "^10.1.16",
|
||||||
"@nestjs/schematics": "^9.0.4",
|
"@nestjs/schematics": "^10.0.2",
|
||||||
"@nestjs/testing": "^9.2.1",
|
"@nestjs/testing": "^10.2.2",
|
||||||
"@openapitools/openapi-generator-cli": "2.5.2",
|
"@openapitools/openapi-generator-cli": "2.7.0",
|
||||||
"@types/archiver": "^5.3.1",
|
"@testcontainers/postgresql": "^10.2.1",
|
||||||
|
"@types/archiver": "^5.3.2",
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
"@types/cron": "^2.0.0",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.17",
|
||||||
"@types/fluent-ffmpeg": "^2.1.20",
|
"@types/fluent-ffmpeg": "^2.1.21",
|
||||||
"@types/imagemin": "^8.0.0",
|
"@types/imagemin": "^8.0.1",
|
||||||
"@types/jest": "27.0.2",
|
"@types/jest": "29.5.4",
|
||||||
"@types/jest-when": "^3.5.2",
|
"@types/jest-when": "^3.5.2",
|
||||||
"@types/lodash": "^4.14.178",
|
"@types/lodash": "^4.14.197",
|
||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
"@types/mv": "^2.1.2",
|
"@types/mv": "^2.1.2",
|
||||||
"@types/node": "^18.0.0",
|
"@types/node": "^20.5.7",
|
||||||
"@types/sharp": "^0.30.2",
|
"@types/sharp": "^0.31.1",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.12",
|
||||||
"@types/ua-parser-js": "^0.7.36",
|
"@types/ua-parser-js": "^0.7.36",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||||
"@typescript-eslint/parser": "^5.48.1",
|
"@typescript-eslint/parser": "^6.4.1",
|
||||||
"dotenv": "^14.2.0",
|
"dotenv": "^16.3.1",
|
||||||
"eslint": "^8.31.0",
|
"eslint": "^8.48.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"jest": "^27.2.5",
|
"jest": "^29.6.4",
|
||||||
"jest-when": "^3.5.2",
|
"jest-when": "^3.6.0",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^3.0.2",
|
||||||
"prettier-plugin-organize-imports": "^3.2.2",
|
"prettier-plugin-organize-imports": "^3.2.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^5.0.1",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.21",
|
||||||
"supertest": "^6.1.3",
|
"supertest": "^6.3.3",
|
||||||
"testcontainers": "^9.9.1",
|
"testcontainers": "^10.2.1",
|
||||||
"ts-jest": "^27.0.3",
|
"ts-jest": "^29.1.1",
|
||||||
"ts-loader": "^9.2.3",
|
"ts-loader": "^9.4.4",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.9.1",
|
||||||
"tsconfig-paths": "^3.10.1",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^4.9.4"
|
"typescript": "^5.2.2"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"clearMocks": true,
|
"clearMocks": true,
|
||||||
|
|
|
@ -6,7 +6,10 @@ import { Command, CommandRunner, InquirerService, Question, QuestionSet } from '
|
||||||
description: 'Reset the admin password',
|
description: 'Reset the admin password',
|
||||||
})
|
})
|
||||||
export class ResetAdminPasswordCommand extends CommandRunner {
|
export class ResetAdminPasswordCommand extends CommandRunner {
|
||||||
constructor(private userService: UserService, private readonly inquirer: InquirerService) {
|
constructor(
|
||||||
|
private userService: UserService,
|
||||||
|
private readonly inquirer: InquirerService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ export class AlbumService {
|
||||||
ownerId: authUser.id,
|
ownerId: authUser.id,
|
||||||
albumName: dto.albumName,
|
albumName: dto.albumName,
|
||||||
description: dto.description,
|
description: dto.description,
|
||||||
sharedUsers: dto.sharedWithUserIds?.map((value) => ({ id: value } as UserEntity)) ?? [],
|
sharedUsers: dto.sharedWithUserIds?.map((value) => ({ id: value }) as UserEntity) ?? [],
|
||||||
assets: (dto.assetIds || []).map((id) => ({ id } as AssetEntity)),
|
assets: (dto.assetIds || []).map((id) => ({ id }) as AssetEntity),
|
||||||
albumThumbnailAssetId: dto.assetIds?.[0] || null,
|
albumThumbnailAssetId: dto.assetIds?.[0] || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ const sidecar: Record<string, string[]> = {
|
||||||
const isType = (filename: string, r: Record<string, string[]>) => extname(filename).toLowerCase() in r;
|
const isType = (filename: string, r: Record<string, string[]>) => extname(filename).toLowerCase() in r;
|
||||||
|
|
||||||
const lookup = (filename: string) =>
|
const lookup = (filename: string) =>
|
||||||
({ ...image, ...video, ...sidecar }[extname(filename).toLowerCase()]?.[0] ?? 'application/octet-stream');
|
({ ...image, ...video, ...sidecar })[extname(filename).toLowerCase()]?.[0] ?? 'application/octet-stream';
|
||||||
|
|
||||||
export const mimeTypes = {
|
export const mimeTypes = {
|
||||||
image,
|
image,
|
||||||
|
|
|
@ -115,6 +115,7 @@ describe(FacialRecognitionService.name, () => {
|
||||||
personMock = newPersonRepositoryMock();
|
personMock = newPersonRepositoryMock();
|
||||||
searchMock = newSearchRepositoryMock();
|
searchMock = newSearchRepositoryMock();
|
||||||
storageMock = newStorageRepositoryMock();
|
storageMock = newStorageRepositoryMock();
|
||||||
|
configMock = newSystemConfigRepositoryMock();
|
||||||
|
|
||||||
mediaMock.crop.mockResolvedValue(croppedFace);
|
mediaMock.crop.mockResolvedValue(croppedFace);
|
||||||
|
|
||||||
|
@ -179,9 +180,18 @@ describe(FacialRecognitionService.name, () => {
|
||||||
machineLearningMock.detectFaces.mockResolvedValue([]);
|
machineLearningMock.detectFaces.mockResolvedValue([]);
|
||||||
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
assetMock.getByIds.mockResolvedValue([assetStub.image]);
|
||||||
await sut.handleRecognizeFaces({ id: assetStub.image.id });
|
await sut.handleRecognizeFaces({ id: assetStub.image.id });
|
||||||
expect(machineLearningMock.detectFaces).toHaveBeenCalledWith('http://immich-machine-learning:3003', {
|
expect(machineLearningMock.detectFaces).toHaveBeenCalledWith(
|
||||||
imagePath: assetStub.image.resizePath,
|
'http://immich-machine-learning:3003',
|
||||||
});
|
{
|
||||||
|
imagePath: assetStub.image.resizePath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
maxDistance: 0.6,
|
||||||
|
minScore: 0.7,
|
||||||
|
modelName: 'buffalo_l',
|
||||||
|
},
|
||||||
|
);
|
||||||
expect(faceMock.create).not.toHaveBeenCalled();
|
expect(faceMock.create).not.toHaveBeenCalled();
|
||||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class FacialRecognitionService {
|
||||||
|
|
||||||
async handleQueueRecognizeFaces({ force }: IBaseJob) {
|
async handleQueueRecognizeFaces({ force }: IBaseJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.facialRecognitionEnabled) {
|
if (!machineLearning.enabled || !machineLearning.facialRecognition.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export class FacialRecognitionService {
|
||||||
|
|
||||||
async handleRecognizeFaces({ id }: IEntityJob) {
|
async handleRecognizeFaces({ id }: IEntityJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.facialRecognitionEnabled) {
|
if (!machineLearning.enabled || !machineLearning.facialRecognition.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,11 @@ export class FacialRecognitionService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const faces = await this.machineLearning.detectFaces(machineLearning.url, { imagePath: asset.resizePath });
|
const faces = await this.machineLearning.detectFaces(
|
||||||
|
machineLearning.url,
|
||||||
|
{ imagePath: asset.resizePath },
|
||||||
|
machineLearning.facialRecognition,
|
||||||
|
);
|
||||||
|
|
||||||
this.logger.debug(`${faces.length} faces detected in ${asset.resizePath}`);
|
this.logger.debug(`${faces.length} faces detected in ${asset.resizePath}`);
|
||||||
this.logger.verbose(faces.map((face) => ({ ...face, embedding: `float[${face.embedding.length}]` })));
|
this.logger.verbose(faces.map((face) => ({ ...face, embedding: `float[${face.embedding.length}]` })));
|
||||||
|
@ -80,7 +84,7 @@ export class FacialRecognitionService {
|
||||||
|
|
||||||
// try to find a matching face and link to the associated person
|
// try to find a matching face and link to the associated person
|
||||||
// The closer to 0, the better the match. Range is from 0 to 2
|
// The closer to 0, the better the match. Range is from 0 to 2
|
||||||
if (faceSearchResult.total && faceSearchResult.distances[0] < 0.6) {
|
if (faceSearchResult.total && faceSearchResult.distances[0] <= machineLearning.facialRecognition.maxDistance) {
|
||||||
this.logger.verbose(`Match face with distance ${faceSearchResult.distances[0]}`);
|
this.logger.verbose(`Match face with distance ${faceSearchResult.distances[0]}`);
|
||||||
personId = faceSearchResult.items[0].personId;
|
personId = faceSearchResult.items[0].personId;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +119,7 @@ export class FacialRecognitionService {
|
||||||
|
|
||||||
async handleGenerateFaceThumbnail(data: IFaceThumbnailJob) {
|
async handleGenerateFaceThumbnail(data: IFaceThumbnailJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.facialRecognitionEnabled) {
|
if (!machineLearning.enabled || !machineLearning.facialRecognition.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ export interface ResizeOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoStreamInfo {
|
export interface VideoStreamInfo {
|
||||||
|
index: number;
|
||||||
height: number;
|
height: number;
|
||||||
width: number;
|
width: number;
|
||||||
rotation: number;
|
rotation: number;
|
||||||
|
@ -18,8 +19,10 @@ export interface VideoStreamInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AudioStreamInfo {
|
export interface AudioStreamInfo {
|
||||||
|
index: number;
|
||||||
codecName?: string;
|
codecName?: string;
|
||||||
codecType?: string;
|
codecType?: string;
|
||||||
|
frameCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoFormat {
|
export interface VideoFormat {
|
||||||
|
@ -55,7 +58,7 @@ export interface BitrateDistribution {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoCodecSWConfig {
|
export interface VideoCodecSWConfig {
|
||||||
getOptions(stream: VideoStreamInfo): TranscodeOptions;
|
getOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo): TranscodeOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoCodecHWConfig extends VideoCodecSWConfig {
|
export interface VideoCodecHWConfig extends VideoCodecSWConfig {
|
||||||
|
|
|
@ -311,8 +311,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -350,8 +350,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -374,8 +374,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -401,8 +401,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -426,8 +426,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -451,8 +451,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -476,8 +476,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -525,8 +525,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -555,8 +555,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -582,8 +582,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -611,8 +611,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec vp9',
|
'-c:v:0 vp9',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -642,8 +642,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec vp9',
|
'-c:v:0 vp9',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -672,8 +672,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec vp9',
|
'-c:v:0 vp9',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -701,8 +701,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec vp9',
|
'-c:v:0 vp9',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -729,8 +729,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -757,8 +757,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -785,8 +785,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec hevc',
|
'-c:v:0 hevc',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -816,8 +816,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec hevc',
|
'-c:v:0 hevc',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -876,7 +876,6 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_nvenc`,
|
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
'-g 250',
|
'-g 250',
|
||||||
|
@ -886,7 +885,8 @@ describe(MediaService.name, () => {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_nvenc`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -916,7 +916,6 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_nvenc`,
|
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
'-g 250',
|
'-g 250',
|
||||||
|
@ -926,7 +925,8 @@ describe(MediaService.name, () => {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_nvenc`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -952,7 +952,6 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_nvenc`,
|
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
'-g 250',
|
'-g 250',
|
||||||
|
@ -962,7 +961,8 @@ describe(MediaService.name, () => {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_nvenc`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -989,7 +989,6 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_nvenc`,
|
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
'-g 250',
|
'-g 250',
|
||||||
|
@ -999,7 +998,8 @@ describe(MediaService.name, () => {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_nvenc`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1022,7 +1022,6 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
inputOptions: ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_nvenc`,
|
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
'-g 250',
|
'-g 250',
|
||||||
|
@ -1032,7 +1031,8 @@ describe(MediaService.name, () => {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_nvenc`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1060,12 +1060,12 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_qsv`,
|
|
||||||
'-g 256',
|
'-g 256',
|
||||||
'-extbrc 1',
|
'-extbrc 1',
|
||||||
'-refs 5',
|
'-refs 5',
|
||||||
'-bf 7',
|
'-bf 7',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_qsv`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1095,12 +1095,12 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_qsv`,
|
|
||||||
'-g 256',
|
'-g 256',
|
||||||
'-extbrc 1',
|
'-extbrc 1',
|
||||||
'-refs 5',
|
'-refs 5',
|
||||||
'-bf 7',
|
'-bf 7',
|
||||||
'-acodec aac',
|
`-c:v:0 h264_qsv`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1127,12 +1127,12 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
inputOptions: ['-init_hw_device qsv=hw', '-filter_hw_device hw'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec vp9_qsv`,
|
|
||||||
'-g 256',
|
'-g 256',
|
||||||
'-extbrc 1',
|
'-extbrc 1',
|
||||||
'-refs 5',
|
'-refs 5',
|
||||||
'-bf 7',
|
'-bf 7',
|
||||||
'-acodec aac',
|
`-c:v:0 vp9_qsv`,
|
||||||
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-low_power 1',
|
'-low_power 1',
|
||||||
|
@ -1170,8 +1170,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_vaapi`,
|
`-c:v:0 h264_vaapi`,
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1199,8 +1199,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_vaapi`,
|
`-c:v:0 h264_vaapi`,
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1230,8 +1230,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD128', '-filter_hw_device accel'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_vaapi`,
|
`-c:v:0 h264_vaapi`,
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1257,8 +1257,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/card1', '-filter_hw_device accel'],
|
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/card1', '-filter_hw_device accel'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_vaapi`,
|
`-c:v:0 h264_vaapi`,
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1280,8 +1280,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD129', '-filter_hw_device accel'],
|
inputOptions: ['-init_hw_device vaapi=accel:/dev/dri/renderD129', '-filter_hw_device accel'],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
`-vcodec h264_vaapi`,
|
`-c:v:0 h264_vaapi`,
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1310,8 +1310,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1345,8 +1345,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1370,8 +1370,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
@ -1395,8 +1395,8 @@ describe(MediaService.name, () => {
|
||||||
{
|
{
|
||||||
inputOptions: [],
|
inputOptions: [],
|
||||||
outputOptions: [
|
outputOptions: [
|
||||||
'-vcodec h264',
|
'-c:v:0 h264',
|
||||||
'-acodec aac',
|
'-c:a:0 aac',
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
'-fps_mode passthrough',
|
'-fps_mode passthrough',
|
||||||
'-v verbose',
|
'-v verbose',
|
||||||
|
|
|
@ -73,15 +73,16 @@ export class MediaService {
|
||||||
this.logger.log(`Successfully generated image thumbnail ${asset.id}`);
|
this.logger.log(`Successfully generated image thumbnail ${asset.id}`);
|
||||||
break;
|
break;
|
||||||
case AssetType.VIDEO:
|
case AssetType.VIDEO:
|
||||||
const { videoStreams } = await this.mediaRepository.probe(asset.originalPath);
|
const { audioStreams, videoStreams } = await this.mediaRepository.probe(asset.originalPath);
|
||||||
const mainVideoStream = this.getMainVideoStream(videoStreams);
|
const mainVideoStream = this.getMainStream(videoStreams);
|
||||||
if (!mainVideoStream) {
|
if (!mainVideoStream) {
|
||||||
this.logger.error(`Could not extract thumbnail for asset ${asset.id}: no video streams found`);
|
this.logger.error(`Could not extract thumbnail for asset ${asset.id}: no video streams found`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const mainAudioStream = this.getMainStream(audioStreams);
|
||||||
const { ffmpeg } = await this.configCore.getConfig();
|
const { ffmpeg } = await this.configCore.getConfig();
|
||||||
const config = { ...ffmpeg, targetResolution: thumbnail.jpegSize.toString(), twoPass: false };
|
const config = { ...ffmpeg, targetResolution: thumbnail.jpegSize.toString(), twoPass: false };
|
||||||
const options = new ThumbnailConfig(config).getOptions(mainVideoStream);
|
const options = new ThumbnailConfig(config).getOptions(mainVideoStream, mainAudioStream);
|
||||||
await this.mediaRepository.transcode(asset.originalPath, jpegThumbnailPath, options);
|
await this.mediaRepository.transcode(asset.originalPath, jpegThumbnailPath, options);
|
||||||
this.logger.log(`Successfully generated video thumbnail ${asset.id}`);
|
this.logger.log(`Successfully generated video thumbnail ${asset.id}`);
|
||||||
break;
|
break;
|
||||||
|
@ -149,8 +150,8 @@ export class MediaService {
|
||||||
this.storageRepository.mkdirSync(outputFolder);
|
this.storageRepository.mkdirSync(outputFolder);
|
||||||
|
|
||||||
const { videoStreams, audioStreams, format } = await this.mediaRepository.probe(input);
|
const { videoStreams, audioStreams, format } = await this.mediaRepository.probe(input);
|
||||||
const mainVideoStream = this.getMainVideoStream(videoStreams);
|
const mainVideoStream = this.getMainStream(videoStreams);
|
||||||
const mainAudioStream = this.getMainAudioStream(audioStreams);
|
const mainAudioStream = this.getMainStream(audioStreams);
|
||||||
const containerExtension = format.formatName;
|
const containerExtension = format.formatName;
|
||||||
if (!mainVideoStream || !containerExtension) {
|
if (!mainVideoStream || !containerExtension) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -165,7 +166,7 @@ export class MediaService {
|
||||||
|
|
||||||
let transcodeOptions;
|
let transcodeOptions;
|
||||||
try {
|
try {
|
||||||
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream));
|
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream, mainAudioStream));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(`An error occurred while configuring transcoding options: ${err}`);
|
this.logger.error(`An error occurred while configuring transcoding options: ${err}`);
|
||||||
return false;
|
return false;
|
||||||
|
@ -176,13 +177,13 @@ export class MediaService {
|
||||||
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(err);
|
this.logger.error(err);
|
||||||
if (config.accel && config.accel !== TranscodeHWAccel.DISABLED) {
|
if (config.accel !== TranscodeHWAccel.DISABLED) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`Error occurred during transcoding. Retrying with ${config.accel.toUpperCase()} acceleration disabled.`,
|
`Error occurred during transcoding. Retrying with ${config.accel.toUpperCase()} acceleration disabled.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
config.accel = TranscodeHWAccel.DISABLED;
|
config.accel = TranscodeHWAccel.DISABLED;
|
||||||
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream));
|
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream, mainAudioStream));
|
||||||
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,14 +194,10 @@ export class MediaService {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMainVideoStream(streams: VideoStreamInfo[]): VideoStreamInfo | null {
|
private getMainStream<T extends VideoStreamInfo | AudioStreamInfo>(streams: T[]): T {
|
||||||
return streams.sort((stream1, stream2) => stream2.frameCount - stream1.frameCount)[0];
|
return streams.sort((stream1, stream2) => stream2.frameCount - stream1.frameCount)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMainAudioStream(streams: AudioStreamInfo[]): AudioStreamInfo | null {
|
|
||||||
return streams[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private isTranscodeRequired(
|
private isTranscodeRequired(
|
||||||
asset: AssetEntity,
|
asset: AssetEntity,
|
||||||
videoStream: VideoStreamInfo,
|
videoStream: VideoStreamInfo,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { ToneMapping, TranscodeHWAccel, VideoCodec } from '@app/infra/entities';
|
import { ToneMapping, TranscodeHWAccel, VideoCodec } from '@app/infra/entities';
|
||||||
import { SystemConfigFFmpegDto } from '../system-config/dto';
|
import { SystemConfigFFmpegDto } from '../system-config/dto';
|
||||||
import {
|
import {
|
||||||
|
AudioStreamInfo,
|
||||||
BitrateDistribution,
|
BitrateDistribution,
|
||||||
TranscodeOptions,
|
TranscodeOptions,
|
||||||
VideoCodecHWConfig,
|
VideoCodecHWConfig,
|
||||||
|
@ -10,13 +11,13 @@ import {
|
||||||
class BaseConfig implements VideoCodecSWConfig {
|
class BaseConfig implements VideoCodecSWConfig {
|
||||||
constructor(protected config: SystemConfigFFmpegDto) {}
|
constructor(protected config: SystemConfigFFmpegDto) {}
|
||||||
|
|
||||||
getOptions(stream: VideoStreamInfo) {
|
getOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo) {
|
||||||
const options = {
|
const options = {
|
||||||
inputOptions: this.getBaseInputOptions(),
|
inputOptions: this.getBaseInputOptions(),
|
||||||
outputOptions: this.getBaseOutputOptions().concat('-v verbose'),
|
outputOptions: this.getBaseOutputOptions(videoStream, audioStream).concat('-v verbose'),
|
||||||
twoPass: this.eligibleForTwoPass(),
|
twoPass: this.eligibleForTwoPass(),
|
||||||
} as TranscodeOptions;
|
} as TranscodeOptions;
|
||||||
const filters = this.getFilterOptions(stream);
|
const filters = this.getFilterOptions(videoStream);
|
||||||
if (filters.length > 0) {
|
if (filters.length > 0) {
|
||||||
options.outputOptions.push(`-vf ${filters.join(',')}`);
|
options.outputOptions.push(`-vf ${filters.join(',')}`);
|
||||||
}
|
}
|
||||||
|
@ -31,9 +32,10 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseOutputOptions() {
|
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo) {
|
||||||
return [
|
return [
|
||||||
`-acodec ${this.config.targetAudioCodec}`,
|
`-c:v:${videoStream.index} ${this.getVideoCodec()}`,
|
||||||
|
`-c:a:${audioStream.index} ${this.getAudioCodec()}`,
|
||||||
// Makes a second pass moving the moov atom to the
|
// Makes a second pass moving the moov atom to the
|
||||||
// beginning of the file for improved playback speed.
|
// beginning of the file for improved playback speed.
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
|
@ -41,13 +43,13 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilterOptions(stream: VideoStreamInfo) {
|
getFilterOptions(videoStream: VideoStreamInfo) {
|
||||||
const options = [];
|
const options = [];
|
||||||
if (this.shouldScale(stream)) {
|
if (this.shouldScale(videoStream)) {
|
||||||
options.push(`scale=${this.getScaling(stream)}`);
|
options.push(`scale=${this.getScaling(videoStream)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shouldToneMap(stream)) {
|
if (this.shouldToneMap(videoStream)) {
|
||||||
options.push(...this.getToneMapping());
|
options.push(...this.getToneMapping());
|
||||||
}
|
}
|
||||||
options.push('format=yuv420p');
|
options.push('format=yuv420p');
|
||||||
|
@ -103,34 +105,34 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
return { max, target, min, unit } as BitrateDistribution;
|
return { max, target, min, unit } as BitrateDistribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTargetResolution(stream: VideoStreamInfo) {
|
getTargetResolution(videoStream: VideoStreamInfo) {
|
||||||
if (this.config.targetResolution === 'original') {
|
if (this.config.targetResolution === 'original') {
|
||||||
return Math.min(stream.height, stream.width);
|
return Math.min(videoStream.height, videoStream.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Number.parseInt(this.config.targetResolution);
|
return Number.parseInt(this.config.targetResolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldScale(stream: VideoStreamInfo) {
|
shouldScale(videoStream: VideoStreamInfo) {
|
||||||
return Math.min(stream.height, stream.width) > this.getTargetResolution(stream);
|
return Math.min(videoStream.height, videoStream.width) > this.getTargetResolution(videoStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldToneMap(stream: VideoStreamInfo) {
|
shouldToneMap(videoStream: VideoStreamInfo) {
|
||||||
return stream.isHDR && this.config.tonemap !== ToneMapping.DISABLED;
|
return videoStream.isHDR && this.config.tonemap !== ToneMapping.DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
getScaling(stream: VideoStreamInfo) {
|
getScaling(videoStream: VideoStreamInfo) {
|
||||||
const targetResolution = this.getTargetResolution(stream);
|
const targetResolution = this.getTargetResolution(videoStream);
|
||||||
const mult = this.config.accel === TranscodeHWAccel.QSV ? 1 : 2; // QSV doesn't support scaling numbers below -1
|
const mult = this.config.accel === TranscodeHWAccel.QSV ? 1 : 2; // QSV doesn't support scaling numbers below -1
|
||||||
return this.isVideoVertical(stream) ? `${targetResolution}:-${mult}` : `-${mult}:${targetResolution}`;
|
return this.isVideoVertical(videoStream) ? `${targetResolution}:-${mult}` : `-${mult}:${targetResolution}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
isVideoRotated(stream: VideoStreamInfo) {
|
isVideoRotated(videoStream: VideoStreamInfo) {
|
||||||
return Math.abs(stream.rotation) === 90;
|
return Math.abs(videoStream.rotation) === 90;
|
||||||
}
|
}
|
||||||
|
|
||||||
isVideoVertical(stream: VideoStreamInfo) {
|
isVideoVertical(videoStream: VideoStreamInfo) {
|
||||||
return stream.height > stream.width || this.isVideoRotated(stream);
|
return videoStream.height > videoStream.width || this.isVideoRotated(videoStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
isBitrateConstrained() {
|
isBitrateConstrained() {
|
||||||
|
@ -171,12 +173,23 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
`zscale=p=${colors.primaries}:t=${colors.transfer}:m=${colors.matrix}:range=pc`,
|
`zscale=p=${colors.primaries}:t=${colors.transfer}:m=${colors.matrix}:range=pc`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAudioCodec(): string {
|
||||||
|
return this.config.targetAudioCodec;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVideoCodec(): string {
|
||||||
|
return this.config.targetVideoCodec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BaseHWConfig extends BaseConfig implements VideoCodecHWConfig {
|
export class BaseHWConfig extends BaseConfig implements VideoCodecHWConfig {
|
||||||
protected devices: string[];
|
protected devices: string[];
|
||||||
|
|
||||||
constructor(protected config: SystemConfigFFmpegDto, devices: string[] = []) {
|
constructor(
|
||||||
|
protected config: SystemConfigFFmpegDto,
|
||||||
|
devices: string[] = [],
|
||||||
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
this.devices = this.validateDevices(devices);
|
this.devices = this.validateDevices(devices);
|
||||||
}
|
}
|
||||||
|
@ -199,6 +212,10 @@ export class BaseHWConfig extends BaseConfig implements VideoCodecHWConfig {
|
||||||
return -a.localeCompare(b);
|
return -a.localeCompare(b);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getVideoCodec(): string {
|
||||||
|
return `${this.config.targetVideoCodec}_${this.config.accel}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ThumbnailConfig extends BaseConfig {
|
export class ThumbnailConfig extends BaseConfig {
|
||||||
|
@ -214,9 +231,9 @@ export class ThumbnailConfig extends BaseConfig {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getScaling(stream: VideoStreamInfo) {
|
getScaling(videoStream: VideoStreamInfo) {
|
||||||
let options = super.getScaling(stream);
|
let options = super.getScaling(videoStream);
|
||||||
if (!this.shouldToneMap(stream)) {
|
if (!this.shouldToneMap(videoStream)) {
|
||||||
options += ':out_color_matrix=bt601:out_range=pc';
|
options += ':out_color_matrix=bt601:out_range=pc';
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
|
@ -233,10 +250,6 @@ export class ThumbnailConfig extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class H264Config extends BaseConfig {
|
export class H264Config extends BaseConfig {
|
||||||
getBaseOutputOptions() {
|
|
||||||
return [`-vcodec ${this.config.targetVideoCodec}`, ...super.getBaseOutputOptions()];
|
|
||||||
}
|
|
||||||
|
|
||||||
getThreadOptions() {
|
getThreadOptions() {
|
||||||
if (this.config.threads <= 0) {
|
if (this.config.threads <= 0) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -250,10 +263,6 @@ export class H264Config extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HEVCConfig extends BaseConfig {
|
export class HEVCConfig extends BaseConfig {
|
||||||
getBaseOutputOptions() {
|
|
||||||
return [`-vcodec ${this.config.targetVideoCodec}`, ...super.getBaseOutputOptions()];
|
|
||||||
}
|
|
||||||
|
|
||||||
getThreadOptions() {
|
getThreadOptions() {
|
||||||
if (this.config.threads <= 0) {
|
if (this.config.threads <= 0) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -267,10 +276,6 @@ export class HEVCConfig extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VP9Config extends BaseConfig {
|
export class VP9Config extends BaseConfig {
|
||||||
getBaseOutputOptions() {
|
|
||||||
return [`-vcodec ${this.config.targetVideoCodec}`, ...super.getBaseOutputOptions()];
|
|
||||||
}
|
|
||||||
|
|
||||||
getPresetOptions() {
|
getPresetOptions() {
|
||||||
const speed = Math.min(this.getPresetIndex(), 5); // values over 5 require realtime mode, which is its own can of worms since it overrides -crf and -threads
|
const speed = Math.min(this.getPresetIndex(), 5); // values over 5 require realtime mode, which is its own can of worms since it overrides -crf and -threads
|
||||||
if (speed >= 0) {
|
if (speed >= 0) {
|
||||||
|
@ -306,9 +311,8 @@ export class NVENCConfig extends BaseHWConfig {
|
||||||
return ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'];
|
return ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseOutputOptions() {
|
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo) {
|
||||||
return [
|
return [
|
||||||
`-vcodec ${this.config.targetVideoCodec}_nvenc`,
|
|
||||||
// below settings recommended from https://docs.nvidia.com/video-technologies/video-codec-sdk/12.0/ffmpeg-with-nvidia-gpu/index.html#command-line-for-latency-tolerant-high-quality-transcoding
|
// below settings recommended from https://docs.nvidia.com/video-technologies/video-codec-sdk/12.0/ffmpeg-with-nvidia-gpu/index.html#command-line-for-latency-tolerant-high-quality-transcoding
|
||||||
'-tune hq',
|
'-tune hq',
|
||||||
'-qmin 0',
|
'-qmin 0',
|
||||||
|
@ -319,15 +323,15 @@ export class NVENCConfig extends BaseHWConfig {
|
||||||
'-rc-lookahead 20',
|
'-rc-lookahead 20',
|
||||||
'-i_qfactor 0.75',
|
'-i_qfactor 0.75',
|
||||||
'-b_qfactor 1.1',
|
'-b_qfactor 1.1',
|
||||||
...super.getBaseOutputOptions(),
|
...super.getBaseOutputOptions(videoStream, audioStream),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilterOptions(stream: VideoStreamInfo) {
|
getFilterOptions(videoStream: VideoStreamInfo) {
|
||||||
const options = this.shouldToneMap(stream) ? this.getToneMapping() : [];
|
const options = this.shouldToneMap(videoStream) ? this.getToneMapping() : [];
|
||||||
options.push('format=nv12', 'hwupload_cuda');
|
options.push('format=nv12', 'hwupload_cuda');
|
||||||
if (this.shouldScale(stream)) {
|
if (this.shouldScale(videoStream)) {
|
||||||
options.push(`scale_cuda=${this.getScaling(stream)}`);
|
options.push(`scale_cuda=${this.getScaling(videoStream)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
@ -375,15 +379,14 @@ export class QSVConfig extends BaseHWConfig {
|
||||||
return ['-init_hw_device qsv=hw', '-filter_hw_device hw'];
|
return ['-init_hw_device qsv=hw', '-filter_hw_device hw'];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseOutputOptions() {
|
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo) {
|
||||||
// recommended from https://github.com/intel/media-delivery/blob/master/doc/benchmarks/intel-iris-xe-max-graphics/intel-iris-xe-max-graphics.md
|
// recommended from https://github.com/intel/media-delivery/blob/master/doc/benchmarks/intel-iris-xe-max-graphics/intel-iris-xe-max-graphics.md
|
||||||
const options = [
|
const options = [
|
||||||
`-vcodec ${this.config.targetVideoCodec}_qsv`,
|
|
||||||
'-g 256',
|
'-g 256',
|
||||||
'-extbrc 1',
|
'-extbrc 1',
|
||||||
'-refs 5',
|
'-refs 5',
|
||||||
'-bf 7',
|
'-bf 7',
|
||||||
...super.getBaseOutputOptions(),
|
...super.getBaseOutputOptions(videoStream, audioStream),
|
||||||
];
|
];
|
||||||
// VP9 requires enabling low power mode https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/33583803e107b6d532def0f9d949364b01b6ad5a
|
// VP9 requires enabling low power mode https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/33583803e107b6d532def0f9d949364b01b6ad5a
|
||||||
if (this.config.targetVideoCodec === VideoCodec.VP9) {
|
if (this.config.targetVideoCodec === VideoCodec.VP9) {
|
||||||
|
@ -392,11 +395,11 @@ export class QSVConfig extends BaseHWConfig {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilterOptions(stream: VideoStreamInfo) {
|
getFilterOptions(videoStream: VideoStreamInfo) {
|
||||||
const options = this.shouldToneMap(stream) ? this.getToneMapping() : [];
|
const options = this.shouldToneMap(videoStream) ? this.getToneMapping() : [];
|
||||||
options.push('format=nv12', 'hwupload=extra_hw_frames=64');
|
options.push('format=nv12', 'hwupload=extra_hw_frames=64');
|
||||||
if (this.shouldScale(stream)) {
|
if (this.shouldScale(videoStream)) {
|
||||||
options.push(`scale_qsv=${this.getScaling(stream)}`);
|
options.push(`scale_qsv=${this.getScaling(videoStream)}`);
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -434,15 +437,11 @@ export class VAAPIConfig extends BaseHWConfig {
|
||||||
return [`-init_hw_device vaapi=accel:/dev/dri/${this.devices[0]}`, '-filter_hw_device accel'];
|
return [`-init_hw_device vaapi=accel:/dev/dri/${this.devices[0]}`, '-filter_hw_device accel'];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseOutputOptions() {
|
getFilterOptions(videoStream: VideoStreamInfo) {
|
||||||
return [`-vcodec ${this.config.targetVideoCodec}_vaapi`, ...super.getBaseOutputOptions()];
|
const options = this.shouldToneMap(videoStream) ? this.getToneMapping() : [];
|
||||||
}
|
|
||||||
|
|
||||||
getFilterOptions(stream: VideoStreamInfo) {
|
|
||||||
const options = this.shouldToneMap(stream) ? this.getToneMapping() : [];
|
|
||||||
options.push('format=nv12', 'hwupload');
|
options.push('format=nv12', 'hwupload');
|
||||||
if (this.shouldScale(stream)) {
|
if (this.shouldScale(videoStream)) {
|
||||||
options.push(`scale_vaapi=${this.getScaling(stream)}`);
|
options.push(`scale_vaapi=${this.getScaling(videoStream)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
|
|
@ -86,6 +86,7 @@ export interface ISearchRepository {
|
||||||
deleteAssets(ids: string[]): Promise<void>;
|
deleteAssets(ids: string[]): Promise<void>;
|
||||||
deleteFaces(ids: string[]): Promise<void>;
|
deleteFaces(ids: string[]): Promise<void>;
|
||||||
deleteAllFaces(): Promise<number>;
|
deleteAllFaces(): Promise<number>;
|
||||||
|
updateCLIPField(num_dim: number): Promise<void>;
|
||||||
|
|
||||||
searchAlbums(query: string, filters: SearchFilter): Promise<SearchResult<AlbumEntity>>;
|
searchAlbums(query: string, filters: SearchFilter): Promise<SearchResult<AlbumEntity>>;
|
||||||
searchAssets(query: string, filters: SearchFilter): Promise<SearchResult<AssetEntity>>;
|
searchAssets(query: string, filters: SearchFilter): Promise<SearchResult<AssetEntity>>;
|
||||||
|
|
|
@ -30,7 +30,7 @@ interface SyncQueue {
|
||||||
export class SearchService {
|
export class SearchService {
|
||||||
private logger = new Logger(SearchService.name);
|
private logger = new Logger(SearchService.name);
|
||||||
private enabled = false;
|
private enabled = false;
|
||||||
private timer: NodeJS.Timer | null = null;
|
private timer: NodeJS.Timeout | null = null;
|
||||||
private configCore: SystemConfigCore;
|
private configCore: SystemConfigCore;
|
||||||
|
|
||||||
private albumQueue: SyncQueue = {
|
private albumQueue: SyncQueue = {
|
||||||
|
@ -121,15 +121,18 @@ export class SearchService {
|
||||||
await this.configCore.requireFeature(FeatureFlag.SEARCH);
|
await this.configCore.requireFeature(FeatureFlag.SEARCH);
|
||||||
|
|
||||||
const query = dto.q || dto.query || '*';
|
const query = dto.q || dto.query || '*';
|
||||||
const hasClip = machineLearning.enabled && machineLearning.clipEncodeEnabled;
|
const hasClip = machineLearning.enabled && machineLearning.clip.enabled;
|
||||||
const strategy = dto.clip && hasClip ? SearchStrategy.CLIP : SearchStrategy.TEXT;
|
const strategy = dto.clip && hasClip ? SearchStrategy.CLIP : SearchStrategy.TEXT;
|
||||||
const filters = { userId: authUser.id, ...dto };
|
const filters = { userId: authUser.id, ...dto };
|
||||||
|
|
||||||
let assets: SearchResult<AssetEntity>;
|
let assets: SearchResult<AssetEntity>;
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case SearchStrategy.CLIP:
|
case SearchStrategy.CLIP:
|
||||||
const clip = await this.machineLearning.encodeText(machineLearning.url, query);
|
const {
|
||||||
assets = await this.searchRepository.vectorSearch(clip, filters);
|
machineLearning: { clip },
|
||||||
|
} = await this.configCore.getConfig();
|
||||||
|
const embedding = await this.machineLearning.encodeText(machineLearning.url, { text: query }, clip);
|
||||||
|
assets = await this.searchRepository.vectorSearch(embedding, filters);
|
||||||
break;
|
break;
|
||||||
case SearchStrategy.TEXT:
|
case SearchStrategy.TEXT:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -65,7 +65,7 @@ export class SharedLinkService {
|
||||||
userId: authUser.id,
|
userId: authUser.id,
|
||||||
type: dto.type,
|
type: dto.type,
|
||||||
albumId: dto.albumId || null,
|
albumId: dto.albumId || null,
|
||||||
assets: (dto.assetIds || []).map((id) => ({ id } as AssetEntity)),
|
assets: (dto.assetIds || []).map((id) => ({ id }) as AssetEntity),
|
||||||
description: dto.description || null,
|
description: dto.description || null,
|
||||||
expiresAt: dto.expiresAt || null,
|
expiresAt: dto.expiresAt || null,
|
||||||
allowUpload: dto.allowUpload ?? true,
|
allowUpload: dto.allowUpload ?? true,
|
||||||
|
|
1
server/src/domain/smart-info/dto/index.ts
Normal file
1
server/src/domain/smart-info/dto/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './model-config.dto';
|
50
server/src/domain/smart-info/dto/model-config.dto.ts
Normal file
50
server/src/domain/smart-info/dto/model-config.dto.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { IsBoolean, IsEnum, IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator';
|
||||||
|
import { CLIPMode, ModelType } from '../machine-learning.interface';
|
||||||
|
|
||||||
|
export class ModelConfig {
|
||||||
|
@IsBoolean()
|
||||||
|
enabled!: boolean;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
modelName!: string;
|
||||||
|
|
||||||
|
@IsEnum(ModelType)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ enumName: 'ModelType', enum: ModelType })
|
||||||
|
modelType?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ClassificationConfig extends ModelConfig {
|
||||||
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(1)
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ type: 'integer' })
|
||||||
|
minScore!: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CLIPConfig extends ModelConfig {
|
||||||
|
@IsEnum(CLIPMode)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ enumName: 'CLIPMode', enum: CLIPMode })
|
||||||
|
mode?: CLIPMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RecognitionConfig extends ModelConfig {
|
||||||
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(1)
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ type: 'integer' })
|
||||||
|
minScore!: number;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(2)
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ type: 'integer' })
|
||||||
|
maxDistance!: number;
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from './dto';
|
||||||
export * from './machine-learning.interface';
|
export * from './machine-learning.interface';
|
||||||
export * from './smart-info.repository';
|
export * from './smart-info.repository';
|
||||||
export * from './smart-info.service';
|
export * from './smart-info.service';
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
import { ClassificationConfig, CLIPConfig, RecognitionConfig } from './dto';
|
||||||
|
|
||||||
export const IMachineLearningRepository = 'IMachineLearningRepository';
|
export const IMachineLearningRepository = 'IMachineLearningRepository';
|
||||||
|
|
||||||
export interface MachineLearningInput {
|
export interface VisionModelInput {
|
||||||
imagePath: string;
|
imagePath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TextModelInput {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface BoundingBox {
|
export interface BoundingBox {
|
||||||
x1: number;
|
x1: number;
|
||||||
y1: number;
|
y1: number;
|
||||||
|
@ -19,9 +25,20 @@ export interface DetectFaceResult {
|
||||||
embedding: number[];
|
embedding: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMachineLearningRepository {
|
export enum ModelType {
|
||||||
classifyImage(url: string, input: MachineLearningInput): Promise<string[]>;
|
IMAGE_CLASSIFICATION = 'image-classification',
|
||||||
encodeImage(url: string, input: MachineLearningInput): Promise<number[]>;
|
FACIAL_RECOGNITION = 'facial-recognition',
|
||||||
encodeText(url: string, input: string): Promise<number[]>;
|
CLIP = 'clip',
|
||||||
detectFaces(url: string, input: MachineLearningInput): Promise<DetectFaceResult[]>;
|
}
|
||||||
|
|
||||||
|
export enum CLIPMode {
|
||||||
|
VISION = 'vision',
|
||||||
|
TEXT = 'text',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMachineLearningRepository {
|
||||||
|
classifyImage(url: string, input: VisionModelInput, config: ClassificationConfig): Promise<string[]>;
|
||||||
|
encodeImage(url: string, input: VisionModelInput, config: CLIPConfig): Promise<number[]>;
|
||||||
|
encodeText(url: string, input: TextModelInput, config: CLIPConfig): Promise<number[]>;
|
||||||
|
detectFaces(url: string, input: VisionModelInput, config: RecognitionConfig): Promise<DetectFaceResult[]>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,9 +84,13 @@ describe(SmartInfoService.name, () => {
|
||||||
|
|
||||||
await sut.handleClassifyImage({ id: asset.id });
|
await sut.handleClassifyImage({ id: asset.id });
|
||||||
|
|
||||||
expect(machineMock.classifyImage).toHaveBeenCalledWith('http://immich-machine-learning:3003', {
|
expect(machineMock.classifyImage).toHaveBeenCalledWith(
|
||||||
imagePath: 'path/to/resize.ext',
|
'http://immich-machine-learning:3003',
|
||||||
});
|
{
|
||||||
|
imagePath: 'path/to/resize.ext',
|
||||||
|
},
|
||||||
|
{ enabled: true, minScore: 0.9, modelName: 'microsoft/resnet-50' },
|
||||||
|
);
|
||||||
expect(smartMock.upsert).toHaveBeenCalledWith({
|
expect(smartMock.upsert).toHaveBeenCalledWith({
|
||||||
assetId: 'asset-1',
|
assetId: 'asset-1',
|
||||||
tags: ['tag1', 'tag2', 'tag3'],
|
tags: ['tag1', 'tag2', 'tag3'],
|
||||||
|
@ -141,13 +145,16 @@ describe(SmartInfoService.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save the returned objects', async () => {
|
it('should save the returned objects', async () => {
|
||||||
|
smartMock.upsert.mockResolvedValue();
|
||||||
machineMock.encodeImage.mockResolvedValue([0.01, 0.02, 0.03]);
|
machineMock.encodeImage.mockResolvedValue([0.01, 0.02, 0.03]);
|
||||||
|
|
||||||
await sut.handleEncodeClip({ id: asset.id });
|
await sut.handleEncodeClip({ id: asset.id });
|
||||||
|
|
||||||
expect(machineMock.encodeImage).toHaveBeenCalledWith('http://immich-machine-learning:3003', {
|
expect(machineMock.encodeImage).toHaveBeenCalledWith(
|
||||||
imagePath: 'path/to/resize.ext',
|
'http://immich-machine-learning:3003',
|
||||||
});
|
{ imagePath: 'path/to/resize.ext' },
|
||||||
|
{ enabled: true, modelName: 'ViT-B-32::openai' },
|
||||||
|
);
|
||||||
expect(smartMock.upsert).toHaveBeenCalledWith({
|
expect(smartMock.upsert).toHaveBeenCalledWith({
|
||||||
assetId: 'asset-1',
|
assetId: 'asset-1',
|
||||||
clipEmbedding: [0.01, 0.02, 0.03],
|
clipEmbedding: [0.01, 0.02, 0.03],
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class SmartInfoService {
|
||||||
|
|
||||||
async handleQueueObjectTagging({ force }: IBaseJob) {
|
async handleQueueObjectTagging({ force }: IBaseJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.tagImageEnabled) {
|
if (!machineLearning.enabled || !machineLearning.classification.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ export class SmartInfoService {
|
||||||
|
|
||||||
async handleClassifyImage({ id }: IEntityJob) {
|
async handleClassifyImage({ id }: IEntityJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.tagImageEnabled) {
|
if (!machineLearning.enabled || !machineLearning.classification.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,11 @@ export class SmartInfoService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags = await this.machineLearning.classifyImage(machineLearning.url, { imagePath: asset.resizePath });
|
const tags = await this.machineLearning.classifyImage(
|
||||||
|
machineLearning.url,
|
||||||
|
{ imagePath: asset.resizePath },
|
||||||
|
machineLearning.classification,
|
||||||
|
);
|
||||||
await this.repository.upsert({ assetId: asset.id, tags });
|
await this.repository.upsert({ assetId: asset.id, tags });
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -60,7 +64,7 @@ export class SmartInfoService {
|
||||||
|
|
||||||
async handleQueueEncodeClip({ force }: IBaseJob) {
|
async handleQueueEncodeClip({ force }: IBaseJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.clipEncodeEnabled) {
|
if (!machineLearning.enabled || !machineLearning.clip.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +85,7 @@ export class SmartInfoService {
|
||||||
|
|
||||||
async handleEncodeClip({ id }: IEntityJob) {
|
async handleEncodeClip({ id }: IEntityJob) {
|
||||||
const { machineLearning } = await this.configCore.getConfig();
|
const { machineLearning } = await this.configCore.getConfig();
|
||||||
if (!machineLearning.enabled || !machineLearning.clipEncodeEnabled) {
|
if (!machineLearning.enabled || !machineLearning.clip.enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +94,12 @@ export class SmartInfoService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clipEmbedding = await this.machineLearning.encodeImage(machineLearning.url, { imagePath: asset.resizePath });
|
const clipEmbedding = await this.machineLearning.encodeImage(
|
||||||
|
machineLearning.url,
|
||||||
|
{ imagePath: asset.resizePath },
|
||||||
|
machineLearning.clip,
|
||||||
|
);
|
||||||
|
|
||||||
await this.repository.upsert({ assetId: asset.id, clipEmbedding: clipEmbedding });
|
await this.repository.upsert({ assetId: asset.id, clipEmbedding: clipEmbedding });
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { IsBoolean, IsUrl, ValidateIf } from 'class-validator';
|
import { ClassificationConfig, CLIPConfig, RecognitionConfig } from '@app/domain';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { IsBoolean, IsObject, IsUrl, ValidateIf, ValidateNested } from 'class-validator';
|
||||||
|
|
||||||
export class SystemConfigMachineLearningDto {
|
export class SystemConfigMachineLearningDto {
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ -8,12 +10,18 @@ export class SystemConfigMachineLearningDto {
|
||||||
@ValidateIf((dto) => dto.enabled)
|
@ValidateIf((dto) => dto.enabled)
|
||||||
url!: string;
|
url!: string;
|
||||||
|
|
||||||
@IsBoolean()
|
@Type(() => ClassificationConfig)
|
||||||
clipEncodeEnabled!: boolean;
|
@ValidateNested()
|
||||||
|
@IsObject()
|
||||||
|
classification!: ClassificationConfig;
|
||||||
|
|
||||||
@IsBoolean()
|
@Type(() => CLIPConfig)
|
||||||
facialRecognitionEnabled!: boolean;
|
@ValidateNested()
|
||||||
|
@IsObject()
|
||||||
|
clip!: CLIPConfig;
|
||||||
|
|
||||||
@IsBoolean()
|
@Type(() => RecognitionConfig)
|
||||||
tagImageEnabled!: boolean;
|
@ValidateNested()
|
||||||
|
@IsObject()
|
||||||
|
facialRecognition!: RecognitionConfig;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,25 @@ export const defaults = Object.freeze<SystemConfig>({
|
||||||
[QueueName.THUMBNAIL_GENERATION]: { concurrency: 5 },
|
[QueueName.THUMBNAIL_GENERATION]: { concurrency: 5 },
|
||||||
[QueueName.VIDEO_CONVERSION]: { concurrency: 1 },
|
[QueueName.VIDEO_CONVERSION]: { concurrency: 1 },
|
||||||
},
|
},
|
||||||
|
|
||||||
machineLearning: {
|
machineLearning: {
|
||||||
enabled: process.env.IMMICH_MACHINE_LEARNING_ENABLED !== 'false',
|
enabled: process.env.IMMICH_MACHINE_LEARNING_ENABLED !== 'false',
|
||||||
url: process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003',
|
url: process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003',
|
||||||
facialRecognitionEnabled: true,
|
classification: {
|
||||||
tagImageEnabled: true,
|
enabled: true,
|
||||||
clipEncodeEnabled: true,
|
modelName: 'microsoft/resnet-50',
|
||||||
|
minScore: 0.9,
|
||||||
|
},
|
||||||
|
clip: {
|
||||||
|
enabled: true,
|
||||||
|
modelName: 'ViT-B-32::openai',
|
||||||
|
},
|
||||||
|
facialRecognition: {
|
||||||
|
enabled: true,
|
||||||
|
modelName: 'buffalo_l',
|
||||||
|
minScore: 0.7,
|
||||||
|
maxDistance: 0.6,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
oauth: {
|
oauth: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
@ -143,9 +156,9 @@ export class SystemConfigCore {
|
||||||
const mlEnabled = config.machineLearning.enabled;
|
const mlEnabled = config.machineLearning.enabled;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[FeatureFlag.CLIP_ENCODE]: mlEnabled && config.machineLearning.clipEncodeEnabled,
|
[FeatureFlag.CLIP_ENCODE]: mlEnabled && config.machineLearning.clip.enabled,
|
||||||
[FeatureFlag.FACIAL_RECOGNITION]: mlEnabled && config.machineLearning.facialRecognitionEnabled,
|
[FeatureFlag.FACIAL_RECOGNITION]: mlEnabled && config.machineLearning.facialRecognition.enabled,
|
||||||
[FeatureFlag.TAG_IMAGE]: mlEnabled && config.machineLearning.tagImageEnabled,
|
[FeatureFlag.TAG_IMAGE]: mlEnabled && config.machineLearning.classification.enabled,
|
||||||
[FeatureFlag.SIDECAR]: true,
|
[FeatureFlag.SIDECAR]: true,
|
||||||
[FeatureFlag.SEARCH]: process.env.TYPESENSE_ENABLED !== 'false',
|
[FeatureFlag.SEARCH]: process.env.TYPESENSE_ENABLED !== 'false',
|
||||||
|
|
||||||
|
@ -230,7 +243,7 @@ export class SystemConfigCore {
|
||||||
_.set(config, key, value);
|
_.set(config, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.defaultsDeep(config, defaults) as SystemConfig;
|
return plainToClass(SystemConfigDto, _.defaultsDeep(config, defaults));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadFromFile(filepath: string, force = false) {
|
private async loadFromFile(filepath: string, force = false) {
|
||||||
|
|
|
@ -49,9 +49,21 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
||||||
machineLearning: {
|
machineLearning: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
url: 'http://immich-machine-learning:3003',
|
url: 'http://immich-machine-learning:3003',
|
||||||
facialRecognitionEnabled: true,
|
classification: {
|
||||||
tagImageEnabled: true,
|
enabled: true,
|
||||||
clipEncodeEnabled: true,
|
modelName: 'microsoft/resnet-50',
|
||||||
|
minScore: 0.9,
|
||||||
|
},
|
||||||
|
clip: {
|
||||||
|
enabled: true,
|
||||||
|
modelName: 'ViT-B-32::openai',
|
||||||
|
},
|
||||||
|
facialRecognition: {
|
||||||
|
enabled: true,
|
||||||
|
modelName: 'buffalo_l',
|
||||||
|
minScore: 0.7,
|
||||||
|
maxDistance: 0.6,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
oauth: {
|
oauth: {
|
||||||
autoLaunch: true,
|
autoLaunch: true,
|
||||||
|
|
|
@ -16,7 +16,10 @@ import { IUserRepository, UserListFilter } from './user.repository';
|
||||||
const SALT_ROUNDS = 10;
|
const SALT_ROUNDS = 10;
|
||||||
|
|
||||||
export class UserCore {
|
export class UserCore {
|
||||||
constructor(private userRepository: IUserRepository, private cryptoRepository: ICryptoRepository) {}
|
constructor(
|
||||||
|
private userRepository: IUserRepository,
|
||||||
|
private cryptoRepository: ICryptoRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
async updateUser(authUser: AuthUserDto, id: string, dto: Partial<UserEntity>): Promise<UserEntity> {
|
async updateUser(authUser: AuthUserDto, id: string, dto: Partial<UserEntity>): Promise<UserEntity> {
|
||||||
if (!authUser.isAdmin && authUser.id !== id) {
|
if (!authUser.isAdmin && authUser.id !== id) {
|
||||||
|
|
|
@ -5,7 +5,10 @@ import { IAssetRepository } from './asset-repository';
|
||||||
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto';
|
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto';
|
||||||
|
|
||||||
export class AssetCore {
|
export class AssetCore {
|
||||||
constructor(private repository: IAssetRepository, private jobRepository: IJobRepository) {}
|
constructor(
|
||||||
|
private repository: IAssetRepository,
|
||||||
|
private jobRepository: IJobRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
async create(
|
async create(
|
||||||
authUser: AuthUserDto,
|
authUser: AuthUserDto,
|
||||||
|
|
|
@ -80,7 +80,10 @@ export interface AuthRequest extends Request {
|
||||||
export class AppGuard implements CanActivate {
|
export class AppGuard implements CanActivate {
|
||||||
private logger = new Logger(AppGuard.name);
|
private logger = new Logger(AppGuard.name);
|
||||||
|
|
||||||
constructor(private reflector: Reflector, private authService: AuthService) {}
|
constructor(
|
||||||
|
private reflector: Reflector,
|
||||||
|
private authService: AuthService,
|
||||||
|
) {}
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const targets = [context.getHandler(), context.getClass()];
|
const targets = [context.getHandler(), context.getClass()];
|
||||||
|
|
|
@ -60,7 +60,10 @@ export class FileUploadInterceptor implements NestInterceptor {
|
||||||
};
|
};
|
||||||
private defaultStorage: StorageEngine;
|
private defaultStorage: StorageEngine;
|
||||||
|
|
||||||
constructor(private reflect: Reflector, private assetService: AssetService) {
|
constructor(
|
||||||
|
private reflect: Reflector,
|
||||||
|
private assetService: AssetService,
|
||||||
|
) {
|
||||||
this.defaultStorage = diskStorage({
|
this.defaultStorage = diskStorage({
|
||||||
filename: this.filename.bind(this),
|
filename: this.filename.bind(this),
|
||||||
destination: this.destination.bind(this),
|
destination: this.destination.bind(this),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { QueueName } from '@app/domain/job/job.constants';
|
import { QueueName } from '@app/domain';
|
||||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('system_config')
|
@Entity('system_config')
|
||||||
|
@ -39,9 +39,18 @@ export enum SystemConfigKey {
|
||||||
|
|
||||||
MACHINE_LEARNING_ENABLED = 'machineLearning.enabled',
|
MACHINE_LEARNING_ENABLED = 'machineLearning.enabled',
|
||||||
MACHINE_LEARNING_URL = 'machineLearning.url',
|
MACHINE_LEARNING_URL = 'machineLearning.url',
|
||||||
MACHINE_LEARNING_FACIAL_RECOGNITION_ENABLED = 'machineLearning.facialRecognitionEnabled',
|
|
||||||
MACHINE_LEARNING_TAG_IMAGE_ENABLED = 'machineLearning.tagImageEnabled',
|
MACHINE_LEARNING_CLASSIFICATION_ENABLED = 'machineLearning.classification.enabled',
|
||||||
MACHINE_LEARNING_CLIP_ENCODE_ENABLED = 'machineLearning.clipEncodeEnabled',
|
MACHINE_LEARNING_CLASSIFICATION_MODEL_NAME = 'machineLearning.classification.modelName',
|
||||||
|
MACHINE_LEARNING_CLASSIFICATION_MIN_SCORE = 'machineLearning.classification.minScore',
|
||||||
|
|
||||||
|
MACHINE_LEARNING_CLIP_ENABLED = 'machineLearning.clip.enabled',
|
||||||
|
MACHINE_LEARNING_CLIP_MODEL_NAME = 'machineLearning.clip.modelName',
|
||||||
|
|
||||||
|
MACHINE_LEARNING_FACIAL_RECOGNITION_ENABLED = 'machineLearning.facialRecognition.enabled',
|
||||||
|
MACHINE_LEARNING_FACIAL_RECOGNITION_MODEL_NAME = 'machineLearning.facialRecognition.modelName',
|
||||||
|
MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_SCORE = 'machineLearning.facialRecognition.minScore',
|
||||||
|
MACHINE_LEARNING_FACIAL_RECOGNITION_MAX_DISTANCE = 'machineLearning.facialRecognition.maxDistance',
|
||||||
|
|
||||||
OAUTH_ENABLED = 'oauth.enabled',
|
OAUTH_ENABLED = 'oauth.enabled',
|
||||||
OAUTH_ISSUER_URL = 'oauth.issuerUrl',
|
OAUTH_ISSUER_URL = 'oauth.issuerUrl',
|
||||||
|
@ -114,9 +123,21 @@ export interface SystemConfig {
|
||||||
machineLearning: {
|
machineLearning: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
url: string;
|
url: string;
|
||||||
clipEncodeEnabled: boolean;
|
classification: {
|
||||||
facialRecognitionEnabled: boolean;
|
enabled: boolean;
|
||||||
tagImageEnabled: boolean;
|
modelName: string;
|
||||||
|
minScore: number;
|
||||||
|
};
|
||||||
|
clip: {
|
||||||
|
enabled: boolean;
|
||||||
|
modelName: string;
|
||||||
|
};
|
||||||
|
facialRecognition: {
|
||||||
|
enabled: boolean;
|
||||||
|
modelName: string;
|
||||||
|
minScore: number;
|
||||||
|
maxDistance: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
oauth: {
|
oauth: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
|
||||||
|
export class RenameMLEnableFlags1693236627291 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
UPDATE system_config SET key = CASE
|
||||||
|
WHEN key = 'ffmpeg.classificationEnabled' THEN 'ffmpeg.classification.enabled'
|
||||||
|
WHEN key = 'ffmpeg.clipEnabled' THEN 'ffmpeg.clip.enabled'
|
||||||
|
WHEN key = 'ffmpeg.facialRecognitionEnabled' THEN 'ffmpeg.facialRecognition.enabled'
|
||||||
|
ELSE key
|
||||||
|
END
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
UPDATE system_config SET key = CASE
|
||||||
|
WHEN key = 'ffmpeg.classification.enabled' THEN 'ffmpeg.classificationEnabled'
|
||||||
|
WHEN key = 'ffmpeg.clip.enabled' THEN 'ffmpeg.clipEnabled'
|
||||||
|
WHEN key = 'ffmpeg.facialRecognition.enabled' THEN 'ffmpeg.facialRecognitionEnabled'
|
||||||
|
ELSE key
|
||||||
|
END
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,65 @@
|
||||||
import { DetectFaceResult, IMachineLearningRepository, MachineLearningInput } from '@app/domain';
|
import {
|
||||||
|
ClassificationConfig,
|
||||||
|
CLIPConfig,
|
||||||
|
CLIPMode,
|
||||||
|
DetectFaceResult,
|
||||||
|
IMachineLearningRepository,
|
||||||
|
ModelConfig,
|
||||||
|
ModelType,
|
||||||
|
RecognitionConfig,
|
||||||
|
TextModelInput,
|
||||||
|
VisionModelInput,
|
||||||
|
} from '@app/domain';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import axios from 'axios';
|
import { readFile } from 'fs/promises';
|
||||||
import { createReadStream } from 'fs';
|
|
||||||
|
|
||||||
const client = axios.create();
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MachineLearningRepository implements IMachineLearningRepository {
|
export class MachineLearningRepository implements IMachineLearningRepository {
|
||||||
private post<T>(input: MachineLearningInput, endpoint: string): Promise<T> {
|
private async post<T>(url: string, input: TextModelInput | VisionModelInput, config: ModelConfig): Promise<T> {
|
||||||
return client.post<T>(endpoint, createReadStream(input.imagePath)).then((res) => res.data);
|
const formData = await this.getFormData(input, config);
|
||||||
|
const res = await fetch(`${url}/predict`, { method: 'POST', body: formData });
|
||||||
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
classifyImage(url: string, input: MachineLearningInput): Promise<string[]> {
|
classifyImage(url: string, input: VisionModelInput, config: ClassificationConfig): Promise<string[]> {
|
||||||
return this.post<string[]>(input, `${url}/image-classifier/tag-image`);
|
return this.post<string[]>(url, input, { ...config, modelType: ModelType.IMAGE_CLASSIFICATION });
|
||||||
}
|
}
|
||||||
|
|
||||||
detectFaces(url: string, input: MachineLearningInput): Promise<DetectFaceResult[]> {
|
detectFaces(url: string, input: VisionModelInput, config: RecognitionConfig): Promise<DetectFaceResult[]> {
|
||||||
return this.post<DetectFaceResult[]>(input, `${url}/facial-recognition/detect-faces`);
|
return this.post<DetectFaceResult[]>(url, input, { ...config, modelType: ModelType.FACIAL_RECOGNITION });
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeImage(url: string, input: MachineLearningInput): Promise<number[]> {
|
encodeImage(url: string, input: VisionModelInput, config: CLIPConfig): Promise<number[]> {
|
||||||
return this.post<number[]>(input, `${url}/sentence-transformer/encode-image`);
|
return this.post<number[]>(url, input, {
|
||||||
|
...config,
|
||||||
|
modelType: ModelType.CLIP,
|
||||||
|
mode: CLIPMode.VISION,
|
||||||
|
} as CLIPConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeText(url: string, input: string): Promise<number[]> {
|
encodeText(url: string, input: TextModelInput, config: CLIPConfig): Promise<number[]> {
|
||||||
return client.post<number[]>(`${url}/sentence-transformer/encode-text`, { text: input }).then((res) => res.data);
|
return this.post<number[]>(url, input, { ...config, modelType: ModelType.CLIP, mode: CLIPMode.TEXT } as CLIPConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFormData(input: TextModelInput | VisionModelInput, config: ModelConfig): Promise<FormData> {
|
||||||
|
const formData = new FormData();
|
||||||
|
const { modelName, modelType, ...options } = config;
|
||||||
|
|
||||||
|
formData.append('modelName', modelName);
|
||||||
|
if (modelType) {
|
||||||
|
formData.append('modelType', modelType);
|
||||||
|
}
|
||||||
|
if (options) {
|
||||||
|
formData.append('options', JSON.stringify(options));
|
||||||
|
}
|
||||||
|
if ('imagePath' in input) {
|
||||||
|
formData.append('image', new Blob([await readFile(input.imagePath)]));
|
||||||
|
} else if ('text' in input) {
|
||||||
|
formData.append('text', input.text);
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid input');
|
||||||
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ export class MediaRepository implements IMediaRepository {
|
||||||
videoStreams: results.streams
|
videoStreams: results.streams
|
||||||
.filter((stream) => stream.codec_type === 'video')
|
.filter((stream) => stream.codec_type === 'video')
|
||||||
.map((stream) => ({
|
.map((stream) => ({
|
||||||
|
index: stream.index,
|
||||||
height: stream.height || 0,
|
height: stream.height || 0,
|
||||||
width: stream.width || 0,
|
width: stream.width || 0,
|
||||||
codecName: stream.codec_name === 'h265' ? 'hevc' : stream.codec_name,
|
codecName: stream.codec_name === 'h265' ? 'hevc' : stream.codec_name,
|
||||||
|
@ -53,8 +54,10 @@ export class MediaRepository implements IMediaRepository {
|
||||||
audioStreams: results.streams
|
audioStreams: results.streams
|
||||||
.filter((stream) => stream.codec_type === 'audio')
|
.filter((stream) => stream.codec_type === 'audio')
|
||||||
.map((stream) => ({
|
.map((stream) => ({
|
||||||
|
index: stream.index,
|
||||||
codecType: stream.codec_type,
|
codecType: stream.codec_type,
|
||||||
codecName: stream.codec_name,
|
codecName: stream.codec_name,
|
||||||
|
frameCount: Number.parseInt(stream.nb_frames ?? '0'),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ export class TypesenseRepository implements ISearchRepository {
|
||||||
private logger = new Logger(TypesenseRepository.name);
|
private logger = new Logger(TypesenseRepository.name);
|
||||||
|
|
||||||
private _client: Client | null = null;
|
private _client: Client | null = null;
|
||||||
|
private _updateCLIPLock = false;
|
||||||
|
|
||||||
private get client(): Client {
|
private get client(): Client {
|
||||||
if (!this._client) {
|
if (!this._client) {
|
||||||
throw new Error('Typesense client not available (no apiKey was provided)');
|
throw new Error('Typesense client not available (no apiKey was provided)');
|
||||||
|
@ -141,7 +143,7 @@ export class TypesenseRepository implements ISearchRepository {
|
||||||
await this.updateAlias(collection);
|
await this.updateAlias(collection);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
this.handleError(error);
|
await this.handleError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +223,30 @@ export class TypesenseRepository implements ISearchRepository {
|
||||||
return records.num_deleted;
|
return records.num_deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteAllAssets(): Promise<number> {
|
||||||
|
const records = await this.client.collections(assetSchema.name).documents().delete({ filter_by: 'ownerId:!=null' });
|
||||||
|
return records.num_deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCLIPField(num_dim: number): Promise<void> {
|
||||||
|
const clipField = assetSchema.fields?.find((field) => field.name === 'smartInfo.clipEmbedding');
|
||||||
|
if (clipField && !this._updateCLIPLock) {
|
||||||
|
try {
|
||||||
|
this._updateCLIPLock = true;
|
||||||
|
clipField.num_dim = num_dim;
|
||||||
|
await this.deleteAllAssets();
|
||||||
|
await this.client
|
||||||
|
.collections(assetSchema.name)
|
||||||
|
.update({ fields: [{ name: 'smartInfo.clipEmbedding', drop: true } as any, clipField] });
|
||||||
|
this.logger.log(`Successfully updated CLIP dimensions to ${num_dim}`);
|
||||||
|
} catch (err: any) {
|
||||||
|
this.logger.error(`Error while updating CLIP field: ${err.message}`);
|
||||||
|
} finally {
|
||||||
|
this._updateCLIPLock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async delete(collection: SearchCollection, ids: string[]): Promise<void> {
|
async delete(collection: SearchCollection, ids: string[]): Promise<void> {
|
||||||
await this.client
|
await this.client
|
||||||
.collections(schemaMap[collection].name)
|
.collections(schemaMap[collection].name)
|
||||||
|
@ -326,21 +352,34 @@ export class TypesenseRepository implements ISearchRepository {
|
||||||
} as SearchResult<T>;
|
} as SearchResult<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleError(error: any) {
|
private async handleError(error: any) {
|
||||||
this.logger.error('Unable to index documents');
|
this.logger.error('Unable to index documents');
|
||||||
const results = error.importResults || [];
|
const results = error.importResults || [];
|
||||||
|
let dimsChanged = false;
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
try {
|
try {
|
||||||
result.document = JSON.parse(result.document);
|
result.document = JSON.parse(result.document);
|
||||||
|
if (result.error.includes('Field `smartInfo.clipEmbedding` must have')) {
|
||||||
|
dimsChanged = true;
|
||||||
|
this.logger.warn(
|
||||||
|
`CLIP embedding dimensions have changed, now ${result.document.smartInfo.clipEmbedding.length} dims. Updating schema...`,
|
||||||
|
);
|
||||||
|
await this.updateCLIPField(result.document.smartInfo.clipEmbedding.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.document?.smartInfo?.clipEmbedding) {
|
if (result.document?.smartInfo?.clipEmbedding) {
|
||||||
result.document.smartInfo.clipEmbedding = '<truncated>';
|
result.document.smartInfo.clipEmbedding = '<truncated>';
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch (err: any) {
|
||||||
|
this.logger.error(`Error while updating CLIP field: ${(err.message, err.stack)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose(JSON.stringify(results, null, 2));
|
if (!dimsChanged) {
|
||||||
|
this.logger.log(JSON.stringify(results, null, 2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateAlias(collection: SearchCollection) {
|
private async updateAlias(collection: SearchCollection) {
|
||||||
const schema = schemaMap[collection];
|
const schema = schemaMap[collection];
|
||||||
const alias = await this.client
|
const alias = await this.client
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GenericContainer, PostgreSqlContainer } from 'testcontainers';
|
import { PostgreSqlContainer } from '@testcontainers/postgresql';
|
||||||
|
import { GenericContainer } from 'testcontainers';
|
||||||
export default async () => {
|
export default async () => {
|
||||||
process.env.NODE_ENV = 'development';
|
process.env.NODE_ENV = 'development';
|
||||||
process.env.TYPESENSE_API_KEY = 'abc123';
|
process.env.TYPESENSE_API_KEY = 'abc123';
|
||||||
|
|
23
server/test/fixtures/media.stub.ts
vendored
23
server/test/fixtures/media.stub.ts
vendored
|
@ -7,10 +7,21 @@ const probeStubDefaultFormat: VideoFormat = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const probeStubDefaultVideoStream: VideoStreamInfo[] = [
|
const probeStubDefaultVideoStream: VideoStreamInfo[] = [
|
||||||
{ height: 1080, width: 1920, codecName: 'hevc', codecType: 'video', frameCount: 100, rotation: 0, isHDR: false },
|
{
|
||||||
|
index: 0,
|
||||||
|
height: 1080,
|
||||||
|
width: 1920,
|
||||||
|
codecName: 'hevc',
|
||||||
|
codecType: 'video',
|
||||||
|
frameCount: 100,
|
||||||
|
rotation: 0,
|
||||||
|
isHDR: false,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const probeStubDefaultAudioStream: AudioStreamInfo[] = [{ codecName: 'aac', codecType: 'audio' }];
|
const probeStubDefaultAudioStream: AudioStreamInfo[] = [
|
||||||
|
{ index: 0, codecName: 'aac', codecType: 'audio', frameCount: 100 },
|
||||||
|
];
|
||||||
|
|
||||||
const probeStubDefault: VideoInfo = {
|
const probeStubDefault: VideoInfo = {
|
||||||
format: probeStubDefaultFormat,
|
format: probeStubDefaultFormat,
|
||||||
|
@ -25,6 +36,7 @@ export const probeStub = {
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
videoStreams: [
|
videoStreams: [
|
||||||
{
|
{
|
||||||
|
index: 0,
|
||||||
height: 1080,
|
height: 1080,
|
||||||
width: 400,
|
width: 400,
|
||||||
codecName: 'hevc',
|
codecName: 'hevc',
|
||||||
|
@ -34,6 +46,7 @@ export const probeStub = {
|
||||||
isHDR: false,
|
isHDR: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
index: 1,
|
||||||
height: 1080,
|
height: 1080,
|
||||||
width: 400,
|
width: 400,
|
||||||
codecName: 'h7000',
|
codecName: 'h7000',
|
||||||
|
@ -48,6 +61,7 @@ export const probeStub = {
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
videoStreams: [
|
videoStreams: [
|
||||||
{
|
{
|
||||||
|
index: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
width: 400,
|
width: 400,
|
||||||
codecName: 'hevc',
|
codecName: 'hevc',
|
||||||
|
@ -62,6 +76,7 @@ export const probeStub = {
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
videoStreams: [
|
videoStreams: [
|
||||||
{
|
{
|
||||||
|
index: 0,
|
||||||
height: 2160,
|
height: 2160,
|
||||||
width: 3840,
|
width: 3840,
|
||||||
codecName: 'h264',
|
codecName: 'h264',
|
||||||
|
@ -76,6 +91,7 @@ export const probeStub = {
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
videoStreams: [
|
videoStreams: [
|
||||||
{
|
{
|
||||||
|
index: 0,
|
||||||
height: 480,
|
height: 480,
|
||||||
width: 480,
|
width: 480,
|
||||||
codecName: 'h264',
|
codecName: 'h264',
|
||||||
|
@ -90,6 +106,7 @@ export const probeStub = {
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
videoStreams: [
|
videoStreams: [
|
||||||
{
|
{
|
||||||
|
index: 0,
|
||||||
height: 2160,
|
height: 2160,
|
||||||
width: 3840,
|
width: 3840,
|
||||||
codecName: 'h264',
|
codecName: 'h264',
|
||||||
|
@ -102,7 +119,7 @@ export const probeStub = {
|
||||||
}),
|
}),
|
||||||
audioStreamMp3: Object.freeze<VideoInfo>({
|
audioStreamMp3: Object.freeze<VideoInfo>({
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
audioStreams: [{ codecType: 'audio', codecName: 'aac' }],
|
audioStreams: [{ index: 0, codecType: 'audio', codecName: 'aac', frameCount: 100 }],
|
||||||
}),
|
}),
|
||||||
matroskaContainer: Object.freeze<VideoInfo>({
|
matroskaContainer: Object.freeze<VideoInfo>({
|
||||||
...probeStubDefault,
|
...probeStubDefault,
|
||||||
|
|
|
@ -11,6 +11,7 @@ export const newSearchRepositoryMock = (): jest.Mocked<ISearchRepository> => {
|
||||||
deleteAssets: jest.fn(),
|
deleteAssets: jest.fn(),
|
||||||
deleteFaces: jest.fn(),
|
deleteFaces: jest.fn(),
|
||||||
deleteAllFaces: jest.fn(),
|
deleteAllFaces: jest.fn(),
|
||||||
|
updateCLIPField: jest.fn(),
|
||||||
searchAssets: jest.fn(),
|
searchAssets: jest.fn(),
|
||||||
searchAlbums: jest.fn(),
|
searchAlbums: jest.fn(),
|
||||||
vectorSearch: jest.fn(),
|
vectorSearch: jest.fn(),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "Node16",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
|
@ -17,15 +17,35 @@
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@test": ["test"],
|
"@test": [
|
||||||
"@test/*": ["test/*"],
|
"test"
|
||||||
"@app/immich": ["src/immich"],
|
],
|
||||||
"@app/immich/*": ["src/immich/*"],
|
"@test/*": [
|
||||||
"@app/infra": ["src/infra"],
|
"test/*"
|
||||||
"@app/infra/*": ["src/infra/*"],
|
],
|
||||||
"@app/domain": ["src/domain"],
|
"@app/immich": [
|
||||||
"@app/domain/*": ["src/domain/*"]
|
"src/immich"
|
||||||
|
],
|
||||||
|
"@app/immich/*": [
|
||||||
|
"src/immich/*"
|
||||||
|
],
|
||||||
|
"@app/infra": [
|
||||||
|
"src/infra"
|
||||||
|
],
|
||||||
|
"@app/infra/*": [
|
||||||
|
"src/infra/*"
|
||||||
|
],
|
||||||
|
"@app/domain": [
|
||||||
|
"src/domain"
|
||||||
|
],
|
||||||
|
"@app/domain/*": [
|
||||||
|
"src/domain/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["dist", "node_modules", "upload"]
|
"exclude": [
|
||||||
}
|
"dist",
|
||||||
|
"node_modules",
|
||||||
|
"upload"
|
||||||
|
]
|
||||||
|
}
|
154
web/src/api/open-api/api.ts
generated
154
web/src/api/open-api/api.ts
generated
|
@ -862,6 +862,53 @@ export interface BulkIdsDto {
|
||||||
*/
|
*/
|
||||||
'ids': Array<string>;
|
'ids': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface CLIPConfig
|
||||||
|
*/
|
||||||
|
export interface CLIPConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {CLIPMode}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'mode'?: CLIPMode;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof CLIPConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const CLIPMode = {
|
||||||
|
Vision: 'vision',
|
||||||
|
Text: 'text'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type CLIPMode = typeof CLIPMode[keyof typeof CLIPMode];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -951,6 +998,39 @@ export interface CheckExistingAssetsResponseDto {
|
||||||
*/
|
*/
|
||||||
'existingIds': Array<string>;
|
'existingIds': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ClassificationConfig
|
||||||
|
*/
|
||||||
|
export interface ClassificationConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'minScore': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof ClassificationConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -1766,6 +1846,21 @@ export interface MergePersonDto {
|
||||||
*/
|
*/
|
||||||
'ids': Array<string>;
|
'ids': Array<string>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const ModelType = {
|
||||||
|
ImageClassification: 'image-classification',
|
||||||
|
FacialRecognition: 'facial-recognition',
|
||||||
|
Clip: 'clip'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type ModelType = typeof ModelType[keyof typeof ModelType];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -1991,6 +2086,45 @@ export interface QueueStatusDto {
|
||||||
*/
|
*/
|
||||||
'isPaused': boolean;
|
'isPaused': boolean;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface RecognitionConfig
|
||||||
|
*/
|
||||||
|
export interface RecognitionConfig {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'enabled': boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'maxDistance': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'minScore': number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'modelName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ModelType}
|
||||||
|
* @memberof RecognitionConfig
|
||||||
|
*/
|
||||||
|
'modelType'?: ModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -2803,10 +2937,16 @@ export interface SystemConfigJobDto {
|
||||||
export interface SystemConfigMachineLearningDto {
|
export interface SystemConfigMachineLearningDto {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {ClassificationConfig}
|
||||||
* @memberof SystemConfigMachineLearningDto
|
* @memberof SystemConfigMachineLearningDto
|
||||||
*/
|
*/
|
||||||
'clipEncodeEnabled': boolean;
|
'classification': ClassificationConfig;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {CLIPConfig}
|
||||||
|
* @memberof SystemConfigMachineLearningDto
|
||||||
|
*/
|
||||||
|
'clip': CLIPConfig;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
|
@ -2815,16 +2955,10 @@ export interface SystemConfigMachineLearningDto {
|
||||||
'enabled': boolean;
|
'enabled': boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {RecognitionConfig}
|
||||||
* @memberof SystemConfigMachineLearningDto
|
* @memberof SystemConfigMachineLearningDto
|
||||||
*/
|
*/
|
||||||
'facialRecognitionEnabled': boolean;
|
'facialRecognition': RecognitionConfig;
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof SystemConfigMachineLearningDto
|
|
||||||
*/
|
|
||||||
'tagImageEnabled': boolean;
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
import SettingSwitch from '../setting-switch.svelte';
|
import SettingSwitch from '../setting-switch.svelte';
|
||||||
import type { SystemConfigMachineLearningDto } from '@api';
|
import type { SystemConfigMachineLearningDto } from '@api';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import SettingAccordion from '../setting-accordion.svelte';
|
||||||
|
import SettingSelect from '../setting-select.svelte';
|
||||||
|
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
|
|
||||||
|
@ -28,62 +30,157 @@
|
||||||
|
|
||||||
async function resetToDefault() {
|
async function resetToDefault() {
|
||||||
machineLearningConfig = { ...machineLearningDefault };
|
machineLearningConfig = { ...machineLearningDefault };
|
||||||
|
notificationController.show({ message: 'Reset settings to defaults', type: NotificationType.Info });
|
||||||
notificationController.show({
|
|
||||||
message: 'Reset storage template to default',
|
|
||||||
type: NotificationType.Info,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<div in:fade={{ duration: 500 }}>
|
<div in:fade={{ duration: 500 }}>
|
||||||
<form autocomplete="off" on:submit|preventDefault class="mx-4 flex flex-col gap-4 py-4">
|
<form autocomplete="off" on:submit|preventDefault class="mx-4 mt-4">
|
||||||
<SettingSwitch
|
<div class="flex flex-col gap-4">
|
||||||
title="Enabled"
|
<SettingSwitch
|
||||||
subtitle="Use machine learning features"
|
title="ENABLED"
|
||||||
{disabled}
|
subtitle="If disabled, all ML features will be disabled regardless of the below settings."
|
||||||
bind:checked={machineLearningConfig.enabled}
|
{disabled}
|
||||||
/>
|
bind:checked={machineLearningConfig.enabled}
|
||||||
|
/>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<SettingInputField
|
<SettingInputField
|
||||||
inputType={SettingInputFieldType.TEXT}
|
inputType={SettingInputFieldType.TEXT}
|
||||||
label="URL"
|
label="URL"
|
||||||
desc="URL of machine learning server"
|
desc="URL of the machine learning server"
|
||||||
bind:value={machineLearningConfig.url}
|
bind:value={machineLearningConfig.url}
|
||||||
required={true}
|
required={true}
|
||||||
disabled={disabled || !machineLearningConfig.enabled}
|
disabled={disabled || !machineLearningConfig.enabled}
|
||||||
isEdited={!(machineLearningConfig.url === machineLearningConfig.url)}
|
isEdited={machineLearningConfig.url !== savedConfig.url}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<SettingSwitch
|
<SettingAccordion title="Image Tagging" subtitle="Tag and classify images with object labels">
|
||||||
title="SMART SEARCH"
|
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||||
subtitle="Extract CLIP embeddings for smart search"
|
<SettingSwitch
|
||||||
bind:checked={machineLearningConfig.clipEncodeEnabled}
|
title="ENABLED"
|
||||||
disabled={disabled || !machineLearningConfig.enabled}
|
subtitle="If disabled, images will not be tagged. This affects the Things section in the Explore page as well as 'm:' searches."
|
||||||
/>
|
bind:checked={machineLearningConfig.classification.enabled}
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled}
|
||||||
|
/>
|
||||||
|
|
||||||
<SettingSwitch
|
<hr />
|
||||||
title="FACIAL RECOGNITION"
|
|
||||||
subtitle="Recognize and group faces in photos"
|
|
||||||
disabled={disabled || !machineLearningConfig.enabled}
|
|
||||||
bind:checked={machineLearningConfig.facialRecognitionEnabled}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SettingSwitch
|
<SettingInputField
|
||||||
title="IMAGE TAGGING"
|
inputType={SettingInputFieldType.TEXT}
|
||||||
subtitle="Tag and classify images"
|
label="IMAGE CLASSIFICATION MODEL"
|
||||||
disabled={disabled || !machineLearningConfig.enabled}
|
bind:value={machineLearningConfig.classification.modelName}
|
||||||
bind:checked={machineLearningConfig.tagImageEnabled}
|
required={true}
|
||||||
/>
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.classification.enabled}
|
||||||
|
isEdited={machineLearningConfig.classification.modelName !== savedConfig.classification.modelName}
|
||||||
|
>
|
||||||
|
<p slot="desc" class="immich-form-label pb-2 text-sm">
|
||||||
|
The name of an image classification model listed <a
|
||||||
|
href="https://huggingface.co/models?pipeline_tag=image-classification&sort=trending"><u>here</u></a
|
||||||
|
>. It must be tagged with the 'Image Classification' task and must support ONNX conversion.
|
||||||
|
</p>
|
||||||
|
</SettingInputField>
|
||||||
|
|
||||||
|
<SettingInputField
|
||||||
|
inputType={SettingInputFieldType.NUMBER}
|
||||||
|
label="IMAGE CLASSIFICATION THRESHOLD"
|
||||||
|
desc="Minimum confidence score to add a particular object tag. Lower values will add more tags to images, but may result in more false positives. Will not have any effect until the Tag Objects job is re-run."
|
||||||
|
bind:value={machineLearningConfig.classification.minScore}
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.classification.enabled}
|
||||||
|
isEdited={machineLearningConfig.classification.minScore !== savedConfig.classification.minScore}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</SettingAccordion>
|
||||||
|
|
||||||
|
<SettingAccordion title="Smart Search" subtitle="Search for images semantically using CLIP embeddings">
|
||||||
|
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||||
|
<SettingSwitch
|
||||||
|
title="ENABLED"
|
||||||
|
subtitle="If disabled, images will not be encoded for smart search."
|
||||||
|
bind:checked={machineLearningConfig.clip.enabled}
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<SettingInputField
|
||||||
|
inputType={SettingInputFieldType.TEXT}
|
||||||
|
label="CLIP MODEL"
|
||||||
|
bind:value={machineLearningConfig.clip.modelName}
|
||||||
|
required={true}
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.clip.enabled}
|
||||||
|
isEdited={machineLearningConfig.clip.modelName !== savedConfig.clip.modelName}
|
||||||
|
>
|
||||||
|
<p slot="desc" class="immich-form-label pb-2 text-sm">
|
||||||
|
The name of a CLIP model listed <a
|
||||||
|
href="https://clip-as-service.jina.ai/user-guides/benchmark/#size-and-efficiency"><u>here</u></a
|
||||||
|
>. Note that you must re-run the 'Encode CLIP' job for all images upon changing a model.
|
||||||
|
</p>
|
||||||
|
</SettingInputField>
|
||||||
|
</div>
|
||||||
|
</SettingAccordion>
|
||||||
|
|
||||||
|
<SettingAccordion title="Facial Recognition" subtitle="Detect, recognize and group faces in images">
|
||||||
|
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||||
|
<SettingSwitch
|
||||||
|
title="ENABLED"
|
||||||
|
subtitle="If disabled, images will not be encoded for facial recognition and will not populate the People section in the Explore page."
|
||||||
|
bind:checked={machineLearningConfig.facialRecognition.enabled}
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<SettingSelect
|
||||||
|
label="FACIAL RECOGNITION MODEL"
|
||||||
|
desc="Smaller models are faster and use less memory, but perform worse. Note that you must re-run the Recognize Faces job for all images upon changing a model."
|
||||||
|
name="facial-recognition-model"
|
||||||
|
bind:value={machineLearningConfig.facialRecognition.modelName}
|
||||||
|
options={[
|
||||||
|
{ value: 'buffalo_l', text: 'buffalo_l' },
|
||||||
|
{ value: 'buffalo_s', text: 'buffalo_s' },
|
||||||
|
]}
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.facialRecognition.enabled}
|
||||||
|
isEdited={machineLearningConfig.facialRecognition.modelName !== savedConfig.facialRecognition.modelName}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingInputField
|
||||||
|
inputType={SettingInputFieldType.NUMBER}
|
||||||
|
label="MIN DETECTION SCORE"
|
||||||
|
desc="Minimum confidence score for a face to be detected from 0-1. Lower values will detect more faces but may result in false positives."
|
||||||
|
bind:value={machineLearningConfig.facialRecognition.minScore}
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.facialRecognition.enabled}
|
||||||
|
isEdited={machineLearningConfig.facialRecognition.minScore !== savedConfig.facialRecognition.minScore}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingInputField
|
||||||
|
inputType={SettingInputFieldType.NUMBER}
|
||||||
|
label="MAX RECOGNITION DISTANCE"
|
||||||
|
desc="Maximum distance between two faces to be considered the same person, ranging from 0-2. Lowering this can prevent labeling two people as the same person, while raising it can prevent labeling the same person as two different people. Note that it is easier to merge two people than to split one person in two, so err on the side of a lower threshold when possible."
|
||||||
|
bind:value={machineLearningConfig.facialRecognition.maxDistance}
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
max="2"
|
||||||
|
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.facialRecognition.enabled}
|
||||||
|
isEdited={machineLearningConfig.facialRecognition.maxDistance !== savedConfig.facialRecognition.maxDistance}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</SettingAccordion>
|
||||||
|
|
||||||
<SettingButtonsRow
|
<SettingButtonsRow
|
||||||
on:reset={reset}
|
on:reset={reset}
|
||||||
on:save={() => dispatch('save', machineLearningConfig)}
|
on:save={() => dispatch('save', machineLearningConfig)}
|
||||||
on:reset-to-default={resetToDefault}
|
on:reset-to-default={resetToDefault}
|
||||||
showResetToDefault={!isEqual(machineLearningConfig, machineLearningDefault)}
|
showResetToDefault={!isEqual(savedConfig, machineLearningConfig)}
|
||||||
{disabled}
|
{disabled}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
|
|
||||||
export let inputType: SettingInputFieldType;
|
export let inputType: SettingInputFieldType;
|
||||||
export let value: string | number;
|
export let value: string | number;
|
||||||
|
export let min = Number.MIN_VALUE.toString();
|
||||||
|
export let max = Number.MAX_VALUE.toString();
|
||||||
|
export let step = '1';
|
||||||
export let label = '';
|
export let label = '';
|
||||||
export let desc = '';
|
export let desc = '';
|
||||||
export let required = false;
|
export let required = false;
|
||||||
|
@ -48,6 +51,8 @@
|
||||||
<p class="immich-form-label pb-2 text-sm" id="{label}-desc">
|
<p class="immich-form-label pb-2 text-sm" id="{label}-desc">
|
||||||
{desc}
|
{desc}
|
||||||
</p>
|
</p>
|
||||||
|
{:else}
|
||||||
|
<slot name="desc" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
@ -57,6 +62,9 @@
|
||||||
id={label}
|
id={label}
|
||||||
name={label}
|
name={label}
|
||||||
type={inputType}
|
type={inputType}
|
||||||
|
{min}
|
||||||
|
{max}
|
||||||
|
{step}
|
||||||
{required}
|
{required}
|
||||||
{value}
|
{value}
|
||||||
on:input={handleInput}
|
on:input={handleInput}
|
||||||
|
|
|
@ -207,14 +207,16 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if asset.exifInfo?.fNumber}
|
{#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.fNumber}
|
||||||
<div class="flex gap-4 py-4">
|
<div class="flex gap-4 py-4">
|
||||||
<div><CameraIris size="24" /></div>
|
<div><CameraIris size="24" /></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>{asset.exifInfo.make || ''} {asset.exifInfo.model || ''}</p>
|
<p>{asset.exifInfo.make || ''} {asset.exifInfo.model || ''}</p>
|
||||||
<div class="flex gap-2 text-sm">
|
<div class="flex gap-2 text-sm">
|
||||||
<p>{`ƒ/${asset.exifInfo.fNumber.toLocaleString($locale)}` || ''}</p>
|
{#if asset.exifInfo?.fNumber}
|
||||||
|
<p>{`ƒ/${asset.exifInfo.fNumber.toLocaleString($locale)}` || ''}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if asset.exifInfo.exposureTime}
|
{#if asset.exifInfo.exposureTime}
|
||||||
<p>{`${asset.exifInfo.exposureTime}`}</p>
|
<p>{`${asset.exifInfo.exposureTime}`}</p>
|
||||||
|
@ -226,7 +228,7 @@
|
||||||
|
|
||||||
{#if asset.exifInfo.iso}
|
{#if asset.exifInfo.iso}
|
||||||
<p>
|
<p>
|
||||||
{`ISO${asset.exifInfo.iso}`}
|
{`ISO ${asset.exifInfo.iso}`}
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue