From 4fe753dcae8e63965420968ba87cf71ca8a79129 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 19 Jan 2024 04:29:57 +0900 Subject: [PATCH 1/8] =?UTF-8?q?OpenAPI=E3=81=AE=E3=82=B9=E3=83=8A=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=83=E3=83=88=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E8=BF=BD=E5=8A=A0=EF=BC=86=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?Query=E3=82=92=E7=9C=81=E3=81=8F=20(#992)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 不要なQueryを省く&OpenAPIのスナップショットテスト追加 * コメント追加 * lint * update openapi.json --- run.py | 24 +- ...\343\202\222\347\242\272\350\252\215.json" | 2957 +++++++++++++++++ test/e2e/conftest.py | 10 +- test/e2e/test_openapi.py | 12 + 4 files changed, 2989 insertions(+), 14 deletions(-) create mode 100644 "test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" create mode 100644 test/e2e/test_openapi.py diff --git a/run.py b/run.py index 7041028cb..1f2c0907a 100644 --- a/run.py +++ b/run.py @@ -290,7 +290,7 @@ def get_core(core_version: Optional[str]) -> CoreAdapter: ) def audio_query( text: str, - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> AudioQuery: @@ -371,7 +371,7 @@ def audio_query_from_preset( ) def accent_phrases( text: str, - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 is_kana: bool = False, core_version: str | None = None, @@ -407,7 +407,7 @@ def accent_phrases( ) def mora_data( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: @@ -425,7 +425,7 @@ def mora_data( ) def mora_length( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: @@ -443,7 +443,7 @@ def mora_length( ) def mora_pitch( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: @@ -468,7 +468,7 @@ def mora_pitch( ) def synthesis( query: AudioQuery, - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 enable_interrogative_upspeak: bool = Query( # noqa: B008 default=True, @@ -511,7 +511,7 @@ def synthesis( def cancellable_synthesis( query: AudioQuery, request: Request, - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> FileResponse: @@ -552,7 +552,7 @@ def cancellable_synthesis( ) def multi_synthesis( queries: list[AudioQuery], - style_id: StyleId | None = Query(default=None), # noqa: B008 + style_id: StyleId | None = None, speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 core_version: str | None = None, ) -> FileResponse: @@ -634,11 +634,11 @@ def morphable_targets( ) def _synthesis_morphing( query: AudioQuery, - base_style_id: StyleId | None = Query(default=None), # noqa: B008 + base_style_id: StyleId | None = None, base_speaker: (StyleId | None) = Query( # noqa: B008 default=None, deprecated=True ), - target_style_id: StyleId | None = Query(default=None), # noqa: B008 + target_style_id: StyleId | None = None, target_speaker: (StyleId | None) = Query( # noqa: B008 default=None, deprecated=True ), @@ -1032,7 +1032,7 @@ def uninstall_library(library_uuid: str) -> Response: def initialize_style_id( style_id: StyleId, skip_reinit: bool = Query( # noqa: B008 - False, description="既に初期化済みのスタイルの再初期化をスキップするかどうか" + default=False, description="既に初期化済みのスタイルの再初期化をスキップするかどうか" ), core_version: str | None = None, ) -> Response: @@ -1059,7 +1059,7 @@ def is_initialized_style_id( def initialize_speaker( speaker: StyleId, skip_reinit: bool = Query( # noqa: B008 - False, description="既に初期化済みの話者の再初期化をスキップするかどうか" + default=False, description="既に初期化済みの話者の再初期化をスキップするかどうか" ), core_version: str | None = None, ) -> Response: diff --git "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" new file mode 100644 index 000000000..0cf9b7443 --- /dev/null +++ "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" @@ -0,0 +1,2957 @@ +{ + "components": { + "schemas": { + "AccentPhrase": { + "description": "アクセント句ごとの情報", + "properties": { + "accent": { + "title": "アクセント箇所", + "type": "integer" + }, + "is_interrogative": { + "default": false, + "title": "疑問系かどうか", + "type": "boolean" + }, + "moras": { + "items": { + "$ref": "#/components/schemas/Mora" + }, + "title": "モーラのリスト", + "type": "array" + }, + "pause_mora": { + "allOf": [ + { + "$ref": "#/components/schemas/Mora" + } + ], + "title": "後ろに無音を付けるかどうか" + } + }, + "required": [ + "moras", + "accent" + ], + "title": "AccentPhrase", + "type": "object" + }, + "AudioQuery": { + "description": "音声合成用のクエリ", + "properties": { + "accent_phrases": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "アクセント句のリスト", + "type": "array" + }, + "intonationScale": { + "title": "全体の抑揚", + "type": "number" + }, + "kana": { + "title": "[読み取り専用]AquesTalk 風記法によるテキスト。音声合成用のクエリとしては無視される", + "type": "string" + }, + "outputSamplingRate": { + "title": "音声データの出力サンプリングレート", + "type": "integer" + }, + "outputStereo": { + "title": "音声データをステレオ出力するか否か", + "type": "boolean" + }, + "pitchScale": { + "title": "全体の音高", + "type": "number" + }, + "postPhonemeLength": { + "title": "音声の後の無音時間", + "type": "number" + }, + "prePhonemeLength": { + "title": "音声の前の無音時間", + "type": "number" + }, + "speedScale": { + "title": "全体の話速", + "type": "number" + }, + "volumeScale": { + "title": "全体の音量", + "type": "number" + } + }, + "required": [ + "accent_phrases", + "speedScale", + "pitchScale", + "intonationScale", + "volumeScale", + "prePhonemeLength", + "postPhonemeLength", + "outputSamplingRate", + "outputStereo" + ], + "title": "AudioQuery", + "type": "object" + }, + "BaseLibraryInfo": { + "description": "音声ライブラリの情報", + "properties": { + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers" + ], + "title": "BaseLibraryInfo", + "type": "object" + }, + "Body_setting_post_setting_post": { + "properties": { + "allow_origin": { + "title": "Allow Origin", + "type": "string" + }, + "cors_policy_mode": { + "$ref": "#/components/schemas/CorsPolicyMode" + } + }, + "required": [ + "cors_policy_mode" + ], + "title": "Body_setting_post_setting_post", + "type": "object" + }, + "CorsPolicyMode": { + "description": "CORSの許可モード", + "enum": [ + "all", + "localapps" + ], + "title": "CorsPolicyMode", + "type": "string" + }, + "DownloadableLibraryInfo": { + "description": "ダウンロード可能な音声ライブラリの情報", + "properties": { + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers" + ], + "title": "DownloadableLibraryInfo", + "type": "object" + }, + "EngineManifest": { + "description": "エンジン自体に関する情報", + "properties": { + "brand_name": { + "title": "ブランド名", + "type": "string" + }, + "default_sampling_rate": { + "title": "デフォルトのサンプリング周波数", + "type": "integer" + }, + "dependency_licenses": { + "items": { + "$ref": "#/components/schemas/LicenseInfo" + }, + "title": "依存関係のライセンス情報", + "type": "array" + }, + "icon": { + "title": "エンジンのアイコンをBASE64エンコードしたもの", + "type": "string" + }, + "manifest_version": { + "title": "マニフェストのバージョン", + "type": "string" + }, + "name": { + "title": "エンジン名", + "type": "string" + }, + "supported_features": { + "allOf": [ + { + "$ref": "#/components/schemas/SupportedFeatures" + } + ], + "title": "エンジンが持つ機能" + }, + "supported_vvlib_manifest_version": { + "title": "エンジンが対応するvvlibのバージョン", + "type": "string" + }, + "terms_of_service": { + "title": "エンジンの利用規約", + "type": "string" + }, + "update_infos": { + "items": { + "$ref": "#/components/schemas/UpdateInfo" + }, + "title": "エンジンのアップデート情報", + "type": "array" + }, + "url": { + "title": "エンジンのURL", + "type": "string" + }, + "uuid": { + "title": "エンジンのUUID", + "type": "string" + } + }, + "required": [ + "manifest_version", + "name", + "brand_name", + "uuid", + "url", + "icon", + "default_sampling_rate", + "terms_of_service", + "update_infos", + "dependency_licenses", + "supported_features" + ], + "title": "EngineManifest", + "type": "object" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "title": "Detail", + "type": "array" + } + }, + "title": "HTTPValidationError", + "type": "object" + }, + "InstalledLibraryInfo": { + "description": "インストール済み音声ライブラリの情報", + "properties": { + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array" + }, + "uninstallable": { + "title": "アンインストール可能かどうか", + "type": "boolean" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers", + "uninstallable" + ], + "title": "InstalledLibraryInfo", + "type": "object" + }, + "LibrarySpeaker": { + "description": "音声ライブラリに含まれる話者の情報", + "properties": { + "speaker": { + "allOf": [ + { + "$ref": "#/components/schemas/Speaker" + } + ], + "title": "話者情報" + }, + "speaker_info": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerInfo" + } + ], + "title": "話者の追加情報" + } + }, + "required": [ + "speaker", + "speaker_info" + ], + "title": "LibrarySpeaker", + "type": "object" + }, + "LicenseInfo": { + "description": "依存ライブラリのライセンス情報", + "properties": { + "license": { + "title": "依存ライブラリのライセンス名", + "type": "string" + }, + "name": { + "title": "依存ライブラリ名", + "type": "string" + }, + "text": { + "title": "依存ライブラリのライセンス本文", + "type": "string" + }, + "version": { + "title": "依存ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "text" + ], + "title": "LicenseInfo", + "type": "object" + }, + "Mora": { + "description": "モーラ(子音+母音)ごとの情報", + "properties": { + "consonant": { + "title": "子音の音素", + "type": "string" + }, + "consonant_length": { + "title": "子音の音長", + "type": "number" + }, + "pitch": { + "title": "音高", + "type": "number" + }, + "text": { + "title": "文字", + "type": "string" + }, + "vowel": { + "title": "母音の音素", + "type": "string" + }, + "vowel_length": { + "title": "母音の音長", + "type": "number" + } + }, + "required": [ + "text", + "vowel", + "vowel_length", + "pitch" + ], + "title": "Mora", + "type": "object" + }, + "MorphableTargetInfo": { + "properties": { + "is_morphable": { + "title": "指定した話者に対してモーフィングの可否", + "type": "boolean" + } + }, + "required": [ + "is_morphable" + ], + "title": "MorphableTargetInfo", + "type": "object" + }, + "ParseKanaBadRequest": { + "properties": { + "error_args": { + "additionalProperties": { + "type": "string" + }, + "title": "エラーを起こした箇所", + "type": "object" + }, + "error_name": { + "description": "|name|description|\n|---|---|\n| UNKNOWN_TEXT | 判別できない読み仮名があります: {text} |\n| ACCENT_TOP | 句頭にアクセントは置けません: {text} |\n| ACCENT_TWICE | 1つのアクセント句に二つ以上のアクセントは置けません: {text} |\n| ACCENT_NOTFOUND | アクセントを指定していないアクセント句があります: {text} |\n| EMPTY_PHRASE | {position}番目のアクセント句が空白です |\n| INTERROGATION_MARK_NOT_AT_END | アクセント句末以外に「?」は置けません: {text} |\n| INFINITE_LOOP | 処理時に無限ループになってしまいました...バグ報告をお願いします。 |", + "title": "エラー名", + "type": "string" + }, + "text": { + "title": "エラーメッセージ", + "type": "string" + } + }, + "required": [ + "text", + "error_name", + "error_args" + ], + "title": "ParseKanaBadRequest", + "type": "object" + }, + "Preset": { + "description": "プリセット情報", + "properties": { + "id": { + "title": "プリセットID", + "type": "integer" + }, + "intonationScale": { + "title": "全体の抑揚", + "type": "number" + }, + "name": { + "title": "プリセット名", + "type": "string" + }, + "pitchScale": { + "title": "全体の音高", + "type": "number" + }, + "postPhonemeLength": { + "title": "音声の後の無音時間", + "type": "number" + }, + "prePhonemeLength": { + "title": "音声の前の無音時間", + "type": "number" + }, + "speaker_uuid": { + "title": "話者のUUID", + "type": "string" + }, + "speedScale": { + "title": "全体の話速", + "type": "number" + }, + "style_id": { + "title": "スタイルID", + "type": "integer" + }, + "volumeScale": { + "title": "全体の音量", + "type": "number" + } + }, + "required": [ + "id", + "name", + "speaker_uuid", + "style_id", + "speedScale", + "pitchScale", + "intonationScale", + "volumeScale", + "prePhonemeLength", + "postPhonemeLength" + ], + "title": "Preset", + "type": "object" + }, + "Speaker": { + "description": "話者情報", + "properties": { + "name": { + "title": "名前", + "type": "string" + }, + "speaker_uuid": { + "title": "話者のUUID", + "type": "string" + }, + "styles": { + "items": { + "$ref": "#/components/schemas/SpeakerStyle" + }, + "title": "スタイルの一覧", + "type": "array" + }, + "supported_features": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerSupportedFeatures" + } + ], + "title": "話者の対応機能" + }, + "version": { + "default": "話者のバージョン", + "title": "Version", + "type": "string" + } + }, + "required": [ + "name", + "speaker_uuid", + "styles" + ], + "title": "Speaker", + "type": "object" + }, + "SpeakerInfo": { + "description": "話者の追加情報", + "properties": { + "policy": { + "title": "policy.md", + "type": "string" + }, + "portrait": { + "title": "portrait.pngをbase64エンコードしたもの", + "type": "string" + }, + "style_infos": { + "items": { + "$ref": "#/components/schemas/StyleInfo" + }, + "title": "スタイルの追加情報", + "type": "array" + } + }, + "required": [ + "policy", + "portrait", + "style_infos" + ], + "title": "SpeakerInfo", + "type": "object" + }, + "SpeakerStyle": { + "description": "話者のスタイル情報", + "properties": { + "id": { + "title": "スタイルID", + "type": "integer" + }, + "name": { + "title": "スタイル名", + "type": "string" + } + }, + "required": [ + "name", + "id" + ], + "title": "SpeakerStyle", + "type": "object" + }, + "SpeakerSupportPermittedSynthesisMorphing": { + "description": "An enumeration.", + "enum": [ + "ALL", + "SELF_ONLY", + "NOTHING" + ], + "title": "SpeakerSupportPermittedSynthesisMorphing", + "type": "string" + }, + "SpeakerSupportedFeatures": { + "description": "話者の対応機能の情報", + "properties": { + "permitted_synthesis_morphing": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerSupportPermittedSynthesisMorphing" + } + ], + "default": "ALL", + "title": "モーフィング機能への対応" + } + }, + "title": "SpeakerSupportedFeatures", + "type": "object" + }, + "StyleInfo": { + "description": "スタイルの追加情報", + "properties": { + "icon": { + "title": "当該スタイルのアイコンをbase64エンコードしたもの", + "type": "string" + }, + "id": { + "title": "スタイルID", + "type": "integer" + }, + "portrait": { + "title": "当該スタイルのportrait.pngをbase64エンコードしたもの", + "type": "string" + }, + "voice_samples": { + "items": { + "type": "string" + }, + "title": "voice_sampleのwavファイルをbase64エンコードしたもの", + "type": "array" + } + }, + "required": [ + "id", + "icon", + "voice_samples" + ], + "title": "StyleInfo", + "type": "object" + }, + "SupportedDevicesInfo": { + "description": "対応しているデバイスの情報", + "properties": { + "cpu": { + "title": "CPUに対応しているか", + "type": "boolean" + }, + "cuda": { + "title": "CUDA(Nvidia GPU)に対応しているか", + "type": "boolean" + }, + "dml": { + "title": "DirectML(Nvidia GPU/Radeon GPU等)に対応しているか", + "type": "boolean" + } + }, + "required": [ + "cpu", + "cuda", + "dml" + ], + "title": "SupportedDevicesInfo", + "type": "object" + }, + "SupportedFeatures": { + "description": "エンジンが持つ機能の一覧", + "properties": { + "adjust_intonation_scale": { + "title": "全体の抑揚の調整", + "type": "boolean" + }, + "adjust_mora_pitch": { + "title": "モーラごとの音高の調整", + "type": "boolean" + }, + "adjust_phoneme_length": { + "title": "音素ごとの長さの調整", + "type": "boolean" + }, + "adjust_pitch_scale": { + "title": "全体の音高の調整", + "type": "boolean" + }, + "adjust_speed_scale": { + "title": "全体の話速の調整", + "type": "boolean" + }, + "adjust_volume_scale": { + "title": "全体の音量の調整", + "type": "boolean" + }, + "interrogative_upspeak": { + "title": "疑問文の自動調整", + "type": "boolean" + }, + "manage_library": { + "title": "音声ライブラリのインストール・アンインストール", + "type": "boolean" + }, + "synthesis_morphing": { + "title": "2種類のスタイルでモーフィングした音声を合成", + "type": "boolean" + } + }, + "required": [ + "adjust_mora_pitch", + "adjust_phoneme_length", + "adjust_speed_scale", + "adjust_pitch_scale", + "adjust_intonation_scale", + "adjust_volume_scale", + "interrogative_upspeak", + "synthesis_morphing" + ], + "title": "SupportedFeatures", + "type": "object" + }, + "UpdateInfo": { + "description": "エンジンのアップデート情報", + "properties": { + "contributors": { + "items": { + "type": "string" + }, + "title": "貢献者名", + "type": "array" + }, + "descriptions": { + "items": { + "type": "string" + }, + "title": "アップデートの詳細についての説明", + "type": "array" + }, + "version": { + "title": "エンジンのバージョン名", + "type": "string" + } + }, + "required": [ + "version", + "descriptions" + ], + "title": "UpdateInfo", + "type": "object" + }, + "UserDictWord": { + "description": "辞書のコンパイルに使われる情報", + "properties": { + "accent_associative_rule": { + "title": "アクセント結合規則", + "type": "string" + }, + "accent_type": { + "title": "アクセント型", + "type": "integer" + }, + "context_id": { + "default": 1348, + "title": "文脈ID", + "type": "integer" + }, + "inflectional_form": { + "title": "活用形", + "type": "string" + }, + "inflectional_type": { + "title": "活用型", + "type": "string" + }, + "mora_count": { + "title": "モーラ数", + "type": "integer" + }, + "part_of_speech": { + "title": "品詞", + "type": "string" + }, + "part_of_speech_detail_1": { + "title": "品詞細分類1", + "type": "string" + }, + "part_of_speech_detail_2": { + "title": "品詞細分類2", + "type": "string" + }, + "part_of_speech_detail_3": { + "title": "品詞細分類3", + "type": "string" + }, + "priority": { + "maximum": 10.0, + "minimum": 0.0, + "title": "優先度", + "type": "integer" + }, + "pronunciation": { + "title": "発音", + "type": "string" + }, + "stem": { + "title": "原形", + "type": "string" + }, + "surface": { + "title": "表層形", + "type": "string" + }, + "yomi": { + "title": "読み", + "type": "string" + } + }, + "required": [ + "surface", + "priority", + "part_of_speech", + "part_of_speech_detail_1", + "part_of_speech_detail_2", + "part_of_speech_detail_3", + "inflectional_type", + "inflectional_form", + "stem", + "yomi", + "pronunciation", + "accent_type", + "accent_associative_rule" + ], + "title": "UserDictWord", + "type": "object" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "title": "Location", + "type": "array" + }, + "msg": { + "title": "Message", + "type": "string" + }, + "type": { + "title": "Error Type", + "type": "string" + } + }, + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError", + "type": "object" + }, + "VvlibManifest": { + "description": "vvlib(VOICEVOX Library)に関する情報", + "properties": { + "brand_name": { + "title": "エンジンのブランド名", + "type": "string" + }, + "engine_name": { + "title": "エンジン名", + "type": "string" + }, + "engine_uuid": { + "title": "エンジンのUUID", + "type": "string" + }, + "manifest_version": { + "title": "マニフェストバージョン", + "type": "string" + }, + "name": { + "title": "音声ライブラリ名", + "type": "string" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリバージョン", + "type": "string" + } + }, + "required": [ + "manifest_version", + "name", + "version", + "uuid", + "brand_name", + "engine_name", + "engine_uuid" + ], + "title": "VvlibManifest", + "type": "object" + }, + "WordTypes": { + "description": "fastapiでword_type引数を検証する時に使用するクラス", + "enum": [ + "PROPER_NOUN", + "COMMON_NOUN", + "VERB", + "ADJECTIVE", + "SUFFIX" + ], + "title": "WordTypes", + "type": "string" + } + } + }, + "info": { + "description": "VOICEVOXの音声合成エンジンです。", + "title": "VOICEVOX Engine", + "version": "latest" + }, + "openapi": "3.1.0", + "paths": { + "/accent_phrases": { + "post": { + "description": "テキストからアクセント句を得ます。\nis_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。\n* 全てのカナはカタカナで記述される\n* アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。\n* カナの手前に`_`を入れるとそのカナは無声化される\n* アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。\n* アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。", + "operationId": "accent_phrases_accent_phrases_post", + "parameters": [ + { + "in": "query", + "name": "text", + "required": true, + "schema": { + "title": "Text", + "type": "string" + } + }, + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "is_kana", + "required": false, + "schema": { + "default": false, + "title": "Is Kana", + "type": "boolean" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Response Accent Phrases Accent Phrases Post", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ParseKanaBadRequest" + } + } + }, + "description": "読み仮名のパースに失敗" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "テキストからアクセント句を得る", + "tags": [ + "クエリ編集" + ] + } + }, + "/add_preset": { + "post": { + "description": "新しいプリセットを追加します\n\nParameters\n-------\npreset: Preset\n 新しいプリセット。\n プリセットIDが既存のものと重複している場合は、新規のプリセットIDが採番されます。\n\nReturns\n-------\nid: int\n 追加したプリセットのプリセットID", + "operationId": "add_preset_add_preset_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Preset" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Add Preset Add Preset Post", + "type": "integer" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Add Preset", + "tags": [ + "その他" + ] + } + }, + "/audio_query": { + "post": { + "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", + "operationId": "audio_query_audio_query_post", + "parameters": [ + { + "in": "query", + "name": "text", + "required": true, + "schema": { + "title": "Text", + "type": "string" + } + }, + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "音声合成用のクエリを作成する", + "tags": [ + "クエリ作成" + ] + } + }, + "/audio_query_from_preset": { + "post": { + "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", + "operationId": "audio_query_from_preset_audio_query_from_preset_post", + "parameters": [ + { + "in": "query", + "name": "text", + "required": true, + "schema": { + "title": "Text", + "type": "string" + } + }, + { + "in": "query", + "name": "preset_id", + "required": true, + "schema": { + "title": "Preset Id", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "音声合成用のクエリをプリセットを用いて作成する", + "tags": [ + "クエリ作成" + ] + } + }, + "/cancellable_synthesis": { + "post": { + "operationId": "cancellable_synthesis_cancellable_synthesis_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "audio/wav": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "音声合成する(キャンセル可能)", + "tags": [ + "音声合成" + ] + } + }, + "/connect_waves": { + "post": { + "description": "base64エンコードされたwavデータを一纏めにし、wavファイルで返します。", + "operationId": "connect_waves_connect_waves_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "type": "string" + }, + "title": "Waves", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "audio/wav": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "base64エンコードされた複数のwavデータを一つに結合する", + "tags": [ + "その他" + ] + } + }, + "/core_versions": { + "get": { + "operationId": "core_versions_core_versions_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "type": "string" + }, + "title": "Response Core Versions Core Versions Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Core Versions", + "tags": [ + "その他" + ] + } + }, + "/delete_preset": { + "post": { + "description": "既存のプリセットを削除します\n\nParameters\n-------\nid: int\n 削除するプリセットのプリセットID", + "operationId": "delete_preset_delete_preset_post", + "parameters": [ + { + "in": "query", + "name": "id", + "required": true, + "schema": { + "title": "Id", + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Delete Preset", + "tags": [ + "その他" + ] + } + }, + "/downloadable_libraries": { + "get": { + "description": "ダウンロード可能な音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: list[DownloadableLibrary]", + "operationId": "downloadable_libraries_downloadable_libraries_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DownloadableLibraryInfo" + }, + "title": "Response Downloadable Libraries Downloadable Libraries Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Downloadable Libraries", + "tags": [ + "音声ライブラリ管理" + ] + } + }, + "/engine_manifest": { + "get": { + "operationId": "engine_manifest_engine_manifest_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EngineManifest" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Engine Manifest", + "tags": [ + "その他" + ] + } + }, + "/import_user_dict": { + "post": { + "description": "他のユーザー辞書をインポートします。\n\nParameters\n----------\nimport_dict_data: dict[str, UserDictWord]\n インポートするユーザー辞書のデータ\noverride: bool\n 重複したエントリがあった場合、上書きするかどうか", + "operationId": "import_user_dict_words_import_user_dict_post", + "parameters": [ + { + "in": "query", + "name": "override", + "required": true, + "schema": { + "title": "Override", + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/UserDictWord" + }, + "title": "Import Dict Data", + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Import User Dict Words", + "tags": [ + "ユーザー辞書" + ] + } + }, + "/initialize_speaker": { + "post": { + "deprecated": true, + "description": "こちらのAPIは非推奨です。`initialize_style_id`を利用してください。", + "operationId": "initialize_speaker_initialize_speaker_post", + "parameters": [ + { + "in": "query", + "name": "speaker", + "required": true, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "description": "既に初期化済みの話者の再初期化をスキップするかどうか", + "in": "query", + "name": "skip_reinit", + "required": false, + "schema": { + "default": false, + "description": "既に初期化済みの話者の再初期化をスキップするかどうか", + "title": "Skip Reinit", + "type": "boolean" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Initialize Speaker", + "tags": [ + "その他" + ] + } + }, + "/initialize_style_id": { + "post": { + "description": "指定されたstyle_idのスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。", + "operationId": "initialize_style_id_initialize_style_id_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": true, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", + "in": "query", + "name": "skip_reinit", + "required": false, + "schema": { + "default": false, + "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", + "title": "Skip Reinit", + "type": "boolean" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Initialize Style Id", + "tags": [ + "その他" + ] + } + }, + "/install_library/{library_uuid}": { + "post": { + "description": "音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", + "operationId": "install_library_install_library__library_uuid__post", + "parameters": [ + { + "in": "path", + "name": "library_uuid", + "required": true, + "schema": { + "title": "Library Uuid", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Install Library", + "tags": [ + "音声ライブラリ管理" + ] + } + }, + "/installed_libraries": { + "get": { + "description": "インストールした音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: dict[str, InstalledLibrary]", + "operationId": "installed_libraries_installed_libraries_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/InstalledLibraryInfo" + }, + "title": "Response Installed Libraries Installed Libraries Get", + "type": "object" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Installed Libraries", + "tags": [ + "音声ライブラリ管理" + ] + } + }, + "/is_initialized_speaker": { + "get": { + "deprecated": true, + "description": "こちらのAPIは非推奨です。`is_initialize_style_id`を利用してください。", + "operationId": "is_initialized_speaker_is_initialized_speaker_get", + "parameters": [ + { + "in": "query", + "name": "speaker", + "required": true, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Is Initialized Speaker Is Initialized Speaker Get", + "type": "boolean" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Is Initialized Speaker", + "tags": [ + "その他" + ] + } + }, + "/is_initialized_style_id": { + "get": { + "description": "指定されたstyle_idのスタイルが初期化されているかどうかを返します。", + "operationId": "is_initialized_style_id_is_initialized_style_id_get", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": true, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Is Initialized Style Id Is Initialized Style Id Get", + "type": "boolean" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Is Initialized Style Id", + "tags": [ + "その他" + ] + } + }, + "/mora_data": { + "post": { + "operationId": "mora_data_mora_data_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Accent Phrases", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Response Mora Data Mora Data Post", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "アクセント句から音高・音素長を得る", + "tags": [ + "クエリ編集" + ] + } + }, + "/mora_length": { + "post": { + "operationId": "mora_length_mora_length_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Accent Phrases", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Response Mora Length Mora Length Post", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "アクセント句から音素長を得る", + "tags": [ + "クエリ編集" + ] + } + }, + "/mora_pitch": { + "post": { + "operationId": "mora_pitch_mora_pitch_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Accent Phrases", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "title": "Response Mora Pitch Mora Pitch Post", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "アクセント句から音高を得る", + "tags": [ + "クエリ編集" + ] + } + }, + "/morphable_targets": { + "post": { + "description": "指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。\nモーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。\nプロパティが存在しない場合は、モーフィングが許可されているとみなします。\n返り値の話者はstring型なので注意。", + "operationId": "morphable_targets_morphable_targets_post", + "parameters": [ + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "type": "integer" + }, + "title": "Base Style Ids", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": { + "$ref": "#/components/schemas/MorphableTargetInfo" + }, + "type": "object" + }, + "title": "Response Morphable Targets Morphable Targets Post", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する", + "tags": [ + "音声合成" + ] + } + }, + "/multi_synthesis": { + "post": { + "operationId": "multi_synthesis_multi_synthesis_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AudioQuery" + }, + "title": "Queries", + "type": "array" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/zip": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "複数まとめて音声合成する", + "tags": [ + "音声合成" + ] + } + }, + "/presets": { + "get": { + "description": "エンジンが保持しているプリセットの設定を返します\n\nReturns\n-------\npresets: list[Preset]\n プリセットのリスト", + "operationId": "get_presets_presets_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Preset" + }, + "title": "Response Get Presets Presets Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Get Presets", + "tags": [ + "その他" + ] + } + }, + "/setting": { + "get": { + "description": "設定ページを返します。", + "operationId": "setting_get_setting_get", + "responses": { + "200": { + "description": "Successful Response" + } + }, + "summary": "Setting Get", + "tags": [ + "設定" + ] + }, + "post": { + "description": "設定を更新します。", + "operationId": "setting_post_setting_post", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Body_setting_post_setting_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Setting Post", + "tags": [ + "設定" + ] + } + }, + "/speaker_info": { + "get": { + "description": "指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。\n\nReturns\n-------\nret_data: SpeakerInfo", + "operationId": "speaker_info_speaker_info_get", + "parameters": [ + { + "in": "query", + "name": "speaker_uuid", + "required": true, + "schema": { + "title": "Speaker Uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SpeakerInfo" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Speaker Info", + "tags": [ + "その他" + ] + } + }, + "/speakers": { + "get": { + "operationId": "speakers_speakers_get", + "parameters": [ + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Speaker" + }, + "title": "Response Speakers Speakers Get", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Speakers", + "tags": [ + "その他" + ] + } + }, + "/supported_devices": { + "get": { + "operationId": "supported_devices_supported_devices_get", + "parameters": [ + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SupportedDevicesInfo" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Supported Devices", + "tags": [ + "その他" + ] + } + }, + "/synthesis": { + "post": { + "operationId": "synthesis_synthesis_post", + "parameters": [ + { + "in": "query", + "name": "style_id", + "required": false, + "schema": { + "title": "Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "speaker", + "required": false, + "schema": { + "title": "Speaker", + "type": "integer" + } + }, + { + "description": "疑問系のテキストが与えられたら語尾を自動調整する", + "in": "query", + "name": "enable_interrogative_upspeak", + "required": false, + "schema": { + "default": true, + "description": "疑問系のテキストが与えられたら語尾を自動調整する", + "title": "Enable Interrogative Upspeak", + "type": "boolean" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "audio/wav": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "音声合成する", + "tags": [ + "音声合成" + ] + } + }, + "/synthesis_morphing": { + "post": { + "description": "指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。\nモーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。", + "operationId": "_synthesis_morphing_synthesis_morphing_post", + "parameters": [ + { + "in": "query", + "name": "base_style_id", + "required": false, + "schema": { + "title": "Base Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "base_speaker", + "required": false, + "schema": { + "title": "Base Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "target_style_id", + "required": false, + "schema": { + "title": "Target Style Id", + "type": "integer" + } + }, + { + "deprecated": true, + "in": "query", + "name": "target_speaker", + "required": false, + "schema": { + "title": "Target Speaker", + "type": "integer" + } + }, + { + "in": "query", + "name": "morph_rate", + "required": true, + "schema": { + "maximum": 1.0, + "minimum": 0.0, + "title": "Morph Rate", + "type": "number" + } + }, + { + "in": "query", + "name": "core_version", + "required": false, + "schema": { + "title": "Core Version", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "audio/wav": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "2種類のスタイルでモーフィングした音声を合成する", + "tags": [ + "音声合成" + ] + } + }, + "/uninstall_library/{library_uuid}": { + "post": { + "description": "音声ライブラリをアンインストールします。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", + "operationId": "uninstall_library_uninstall_library__library_uuid__post", + "parameters": [ + { + "in": "path", + "name": "library_uuid", + "required": true, + "schema": { + "title": "Library Uuid", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Uninstall Library", + "tags": [ + "音声ライブラリ管理" + ] + } + }, + "/update_preset": { + "post": { + "description": "既存のプリセットを更新します\n\nParameters\n-------\npreset: Preset\n 更新するプリセット。\n プリセットIDが更新対象と一致している必要があります。\n\nReturns\n-------\nid: int\n 更新したプリセットのプリセットID", + "operationId": "update_preset_update_preset_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Preset" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Update Preset Update Preset Post", + "type": "integer" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Update Preset", + "tags": [ + "その他" + ] + } + }, + "/user_dict": { + "get": { + "description": "ユーザー辞書に登録されている単語の一覧を返します。\n単語の表層形(surface)は正規化済みの物を返します。\n\nReturns\n-------\ndict[str, UserDictWord]\n 単語のUUIDとその詳細", + "operationId": "get_user_dict_words_user_dict_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/UserDictWord" + }, + "title": "Response Get User Dict Words User Dict Get", + "type": "object" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Get User Dict Words", + "tags": [ + "ユーザー辞書" + ] + } + }, + "/user_dict_word": { + "post": { + "description": "ユーザー辞書に言葉を追加します。\n\nParameters\n----------\nsurface : str\n 言葉の表層形\npronunciation: str\n 言葉の発音(カタカナ)\naccent_type: int\n アクセント型(音が下がる場所を指す)\nword_type: WordTypes, optional\n PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか\npriority: int, optional\n 単語の優先度(0から10までの整数)\n 数字が大きいほど優先度が高くなる\n 1から9までの値を指定することを推奨", + "operationId": "add_user_dict_word_user_dict_word_post", + "parameters": [ + { + "in": "query", + "name": "surface", + "required": true, + "schema": { + "title": "Surface", + "type": "string" + } + }, + { + "in": "query", + "name": "pronunciation", + "required": true, + "schema": { + "title": "Pronunciation", + "type": "string" + } + }, + { + "in": "query", + "name": "accent_type", + "required": true, + "schema": { + "title": "Accent Type", + "type": "integer" + } + }, + { + "in": "query", + "name": "word_type", + "required": false, + "schema": { + "$ref": "#/components/schemas/WordTypes" + } + }, + { + "in": "query", + "name": "priority", + "required": false, + "schema": { + "maximum": 10.0, + "minimum": 0.0, + "title": "Priority", + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Add User Dict Word User Dict Word Post", + "type": "string" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Add User Dict Word", + "tags": [ + "ユーザー辞書" + ] + } + }, + "/user_dict_word/{word_uuid}": { + "delete": { + "description": "ユーザー辞書に登録されている言葉を削除します。\n\nParameters\n----------\nword_uuid: str\n 削除する言葉のUUID", + "operationId": "delete_user_dict_word_user_dict_word__word_uuid__delete", + "parameters": [ + { + "in": "path", + "name": "word_uuid", + "required": true, + "schema": { + "title": "Word Uuid", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Delete User Dict Word", + "tags": [ + "ユーザー辞書" + ] + }, + "put": { + "description": "ユーザー辞書に登録されている言葉を更新します。\n\nParameters\n----------\nsurface : str\n 言葉の表層形\npronunciation: str\n 言葉の発音(カタカナ)\naccent_type: int\n アクセント型(音が下がる場所を指す)\nword_uuid: str\n 更新する言葉のUUID\nword_type: WordTypes, optional\n PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか\npriority: int, optional\n 単語の優先度(0から10までの整数)\n 数字が大きいほど優先度が高くなる\n 1から9までの値を指定することを推奨", + "operationId": "rewrite_user_dict_word_user_dict_word__word_uuid__put", + "parameters": [ + { + "in": "path", + "name": "word_uuid", + "required": true, + "schema": { + "title": "Word Uuid", + "type": "string" + } + }, + { + "in": "query", + "name": "surface", + "required": true, + "schema": { + "title": "Surface", + "type": "string" + } + }, + { + "in": "query", + "name": "pronunciation", + "required": true, + "schema": { + "title": "Pronunciation", + "type": "string" + } + }, + { + "in": "query", + "name": "accent_type", + "required": true, + "schema": { + "title": "Accent Type", + "type": "integer" + } + }, + { + "in": "query", + "name": "word_type", + "required": false, + "schema": { + "$ref": "#/components/schemas/WordTypes" + } + }, + { + "in": "query", + "name": "priority", + "required": false, + "schema": { + "maximum": 10.0, + "minimum": 0.0, + "title": "Priority", + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Rewrite User Dict Word", + "tags": [ + "ユーザー辞書" + ] + } + }, + "/validate_kana": { + "post": { + "description": "テキストがAquesTalk 風記法に従っているかどうかを判定します。\n従っていない場合はエラーが返ります。\n\nParameters\n----------\ntext: str\n 判定する対象の文字列", + "operationId": "validate_kana_validate_kana_post", + "parameters": [ + { + "in": "query", + "name": "text", + "required": true, + "schema": { + "title": "Text", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Validate Kana Validate Kana Post", + "type": "boolean" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ParseKanaBadRequest" + } + } + }, + "description": "テキストが不正です" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "テキストがAquesTalk 風記法に従っているか判定する", + "tags": [ + "その他" + ] + } + }, + "/version": { + "get": { + "operationId": "version_version_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "title": "Response Version Version Get", + "type": "string" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Version", + "tags": [ + "その他" + ] + } + } + } +} diff --git a/test/e2e/conftest.py b/test/e2e/conftest.py index 4fbb450b4..d0de01527 100644 --- a/test/e2e/conftest.py +++ b/test/e2e/conftest.py @@ -1,6 +1,7 @@ from pathlib import Path import pytest +from fastapi import FastAPI from fastapi.testclient import TestClient from run import generate_app @@ -30,5 +31,10 @@ def app_params(): @pytest.fixture(scope="session") -def client(app_params: dict) -> TestClient: - return TestClient(generate_app(**app_params)) +def app(app_params: dict) -> FastAPI: + return generate_app(**app_params) + + +@pytest.fixture(scope="session") +def client(app: FastAPI) -> TestClient: + return TestClient(app) diff --git a/test/e2e/test_openapi.py b/test/e2e/test_openapi.py new file mode 100644 index 000000000..005d0fd1e --- /dev/null +++ b/test/e2e/test_openapi.py @@ -0,0 +1,12 @@ +from typing import Any + +from fastapi import FastAPI +from syrupy.extensions.json import JSONSnapshotExtension + + +def test_OpenAPIの形が変わっていないことを確認( + app: FastAPI, snapshot_json: JSONSnapshotExtension +) -> None: + # 変更があった場合はREADMEの「スナップショットの更新」の手順で更新可能 + openapi: Any = app.openapi() # snapshot_jsonがmypyに対応していないのでワークアラウンド + assert snapshot_json == openapi From 9e1b0f07137e67e84a766a0828f8bad10cd64cd0 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Sat, 20 Jan 2024 10:06:03 +0900 Subject: [PATCH 2/8] =?UTF-8?q?style=5Fid=E5=BC=95=E6=95=B0=E3=82=84API?= =?UTF-8?q?=E3=82=92speaker=E3=81=AB=E6=88=BB=E3=81=99=20(#1016)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style_id引数やAPIをspeakerに戻す * READMEの戻し忘れ --- README.md | 24 +- ...50\343\201\256\351\200\243\346\220\272.md" | 2 + run.py | 136 ++-------- ...\343\201\247\343\201\215\343\202\213.json" | 0 ...\343\201\247\343\201\215\343\202\213.json" | 60 ----- ...\343\202\222\347\242\272\350\252\215.json" | 238 +----------------- test/e2e/test_audio_query.py | 17 +- 7 files changed, 47 insertions(+), 430 deletions(-) rename "test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\343\202\202\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" => "test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" (100%) delete mode 100644 "test/e2e/__snapshots__/test_audio_query/test_style_id\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" diff --git a/README.md b/README.md index 6b9fb7cbb..23fda7416 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ echo -n "こんにちは、音声合成の世界へようこそ" >text.txt curl -s \ -X POST \ - "127.0.0.1:50021/audio_query?style_id=1"\ + "127.0.0.1:50021/audio_query?speaker=1"\ --get --data-urlencode text@text.txt \ > query.json @@ -65,13 +65,13 @@ curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ - "127.0.0.1:50021/synthesis?style_id=1" \ + "127.0.0.1:50021/synthesis?speaker=1" \ > audio.wav ``` 生成される音声はサンプリングレートが 24000Hz と少し特殊なため、音声プレーヤーによっては再生できない場合があります。 -`style_id` に指定する値は `/speakers` エンドポイントで得られます。 +`speaker` に指定する値は `/speakers` エンドポイントで得られる `style_id` です。互換性のために `speaker` という名前になっています。 ### 読み方を AquesTalk 風記法で取得・修正 @@ -99,7 +99,7 @@ echo -n "ディープラーニングは万能薬ではありません" >text.txt curl -s \ -X POST \ - "127.0.0.1:50021/audio_query?style_id=1" \ + "127.0.0.1:50021/audio_query?speaker=1" \ --get --data-urlencode text@text.txt \ > query.json @@ -111,7 +111,7 @@ cat query.json | grep -o -E "\"kana\":\".*\"" echo -n "ディイプラ'アニングワ/バンノ'オヤクデワ/アリマセ'ン" > kana.txt curl -s \ -X POST \ - "127.0.0.1:50021/accent_phrases?style_id=1&is_kana=true" \ + "127.0.0.1:50021/accent_phrases?speaker=1&is_kana=true" \ --get --data-urlencode text@kana.txt \ > newphrases.json @@ -122,7 +122,7 @@ curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @newquery.json \ - "127.0.0.1:50021/synthesis?style_id=1" \ + "127.0.0.1:50021/synthesis?speaker=1" \ > audio.wav ``` @@ -238,7 +238,7 @@ curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ - "127.0.0.1:50021/synthesis?style_id=$style_id" \ + "127.0.0.1:50021/synthesis?speaker=$style_id" \ > audio.wav ``` @@ -255,7 +255,7 @@ echo -n "モーフィングを利用することで、2種類の声を混ぜ curl -s \ -X POST \ - "127.0.0.1:50021/audio_query?style_id=0"\ + "127.0.0.1:50021/audio_query?speaker=8"\ --get --data-urlencode text@text.txt \ > query.json @@ -264,7 +264,7 @@ curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ - "127.0.0.1:50021/synthesis?style_id=0" \ + "127.0.0.1:50021/synthesis?speaker=8" \ > audio.wav export MORPH_RATE=0.5 @@ -274,17 +274,17 @@ curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ - "127.0.0.1:50021/synthesis_morphing?base_style_id=0&target_style_id=1&morph_rate=$MORPH_RATE" \ + "127.0.0.1:50021/synthesis_morphing?base_speaker=8&target_speaker=10&morph_rate=$MORPH_RATE" \ > audio.wav export MORPH_RATE=0.9 -# query、base_style_id、target_style_idが同じ場合はキャッシュが使用されるため比較的高速に生成される +# query、base_speaker、target_speakerが同じ場合はキャッシュが使用されるため比較的高速に生成される curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ - "127.0.0.1:50021/synthesis_morphing?base_style_id=0&target_style_id=1&morph_rate=$MORPH_RATE" \ + "127.0.0.1:50021/synthesis_morphing?base_speaker=8&target_speaker=10&morph_rate=$MORPH_RATE" \ > audio.wav ``` diff --git "a/docs/VOICEVOX\351\237\263\345\243\260\345\220\210\346\210\220\343\202\250\343\203\263\343\202\270\343\203\263\343\201\250\343\201\256\351\200\243\346\220\272.md" "b/docs/VOICEVOX\351\237\263\345\243\260\345\220\210\346\210\220\343\202\250\343\203\263\343\202\270\343\203\263\343\201\250\343\201\256\351\200\243\346\220\272.md" index 21cc6d13e..540173be1 100644 --- "a/docs/VOICEVOX\351\237\263\345\243\260\345\220\210\346\210\220\343\202\250\343\203\263\343\202\270\343\203\263\343\201\250\343\201\256\351\200\243\346\220\272.md" +++ "b/docs/VOICEVOX\351\237\263\345\243\260\345\220\210\346\210\220\343\202\250\343\203\263\343\202\270\343\203\263\343\201\250\343\201\256\351\200\243\346\220\272.md" @@ -3,3 +3,5 @@ - バージョンが上がっても、`/audio_query`で返ってくる値をそのまま`/synthesis`に POST すれば音声合成できるようにする予定です - `AudioQuery`のパラメータは増えますが、なるべくデフォルト値で以前と変わらない音声が生成されるようにします - バージョン 0.7 から音声スタイルが実装されました。スタイルの情報は`/speakers`から取得できます + - スタイルの情報にある`style_id`を`speaker`に指定することで、今まで通り音声合成ができます + - style_id の指定先が speaker なのは互換性のためです diff --git a/run.py b/run.py index 1f2c0907a..ea737353c 100644 --- a/run.py +++ b/run.py @@ -7,14 +7,13 @@ import re import sys import traceback -import warnings import zipfile from collections.abc import Awaitable, Callable from functools import lru_cache from io import BytesIO, TextIOWrapper from pathlib import Path from tempfile import NamedTemporaryFile, TemporaryFile -from typing import Annotated, Any, Optional, TypeVar +from typing import Annotated, Any, Optional import soundfile import uvicorn @@ -94,24 +93,6 @@ ) from voicevox_engine.utility.run_utility import decide_boolean_from_env -# NOTE: Python 3.12以降で[S: StyleId | list[StyleId]]に置き換えられる -S = TypeVar("S", StyleId, list[StyleId]) - - -def get_style_id_from_deprecated(style_id: S | None, deprecated_speaker: S | None) -> S: - """ - style_idとspeaker両方ともNoneかNoneでないかをチェックし、 - どちらか片方しかNoneが存在しなければstyle_idを返す - """ - if deprecated_speaker is not None and style_id is None: - warnings.warn("speakerは非推奨です。style_idを利用してください。", stacklevel=1) - return deprecated_speaker - elif style_id is not None and deprecated_speaker is None: - return style_id - raise HTTPException( - status_code=400, detail="speakerとstyle_idが両方とも存在しないか、両方とも存在しています。" - ) - def b64encode_str(s): return base64.b64encode(s).decode("utf-8") @@ -290,16 +271,12 @@ def get_core(core_version: Optional[str]) -> CoreAdapter: ) def audio_query( text: str, - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> AudioQuery: """ 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 """ - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) core = get_core(core_version) accent_phrases = engine.create_accent_phrases(text, style_id) @@ -371,8 +348,7 @@ def audio_query_from_preset( ) def accent_phrases( text: str, - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 is_kana: bool = False, core_version: str | None = None, ) -> list[AccentPhrase]: @@ -385,9 +361,6 @@ def accent_phrases( * アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 """ - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) if is_kana: try: @@ -407,13 +380,9 @@ def accent_phrases( ) def mora_data( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) return engine.update_length_and_pitch(accent_phrases, style_id) @@ -425,13 +394,9 @@ def mora_data( ) def mora_length( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) return engine.update_length(accent_phrases, style_id) @@ -443,13 +408,9 @@ def mora_length( ) def mora_pitch( accent_phrases: list[AccentPhrase], - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> list[AccentPhrase]: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) return engine.update_pitch(accent_phrases, style_id) @@ -468,17 +429,13 @@ def mora_pitch( ) def synthesis( query: AudioQuery, - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 enable_interrogative_upspeak: bool = Query( # noqa: B008 default=True, description="疑問系のテキストが与えられたら語尾を自動調整する", ), core_version: str | None = None, ) -> FileResponse: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) wave = engine.synthesize_wave( query, style_id, enable_interrogative_upspeak=enable_interrogative_upspeak @@ -511,13 +468,9 @@ def synthesis( def cancellable_synthesis( query: AudioQuery, request: Request, - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> FileResponse: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) if cancellable_engine is None: raise HTTPException( status_code=404, @@ -552,13 +505,9 @@ def cancellable_synthesis( ) def multi_synthesis( queries: list[AudioQuery], - style_id: StyleId | None = None, - speaker: StyleId | None = Query(default=None, deprecated=True), # noqa: B008 + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> FileResponse: - style_id = get_style_id_from_deprecated( - style_id=style_id, deprecated_speaker=speaker - ) engine = get_engine(core_version) sampling_rate = queries[0].outputSamplingRate @@ -634,14 +583,8 @@ def morphable_targets( ) def _synthesis_morphing( query: AudioQuery, - base_style_id: StyleId | None = None, - base_speaker: (StyleId | None) = Query( # noqa: B008 - default=None, deprecated=True - ), - target_style_id: StyleId | None = None, - target_speaker: (StyleId | None) = Query( # noqa: B008 - default=None, deprecated=True - ), + base_style_id: StyleId = Query(alias="base_speaker"), # noqa: B008 + target_style_id: StyleId = Query(alias="target_speaker"), # noqa: B008 morph_rate: float = Query(..., ge=0.0, le=1.0), # noqa: B008 core_version: str | None = None, ) -> FileResponse: @@ -649,12 +592,6 @@ def _synthesis_morphing( 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 """ - base_style_id = get_style_id_from_deprecated( - style_id=base_style_id, deprecated_speaker=base_speaker - ) - target_style_id = get_style_id_from_deprecated( - style_id=target_style_id, deprecated_speaker=target_speaker - ) engine = get_engine(core_version) core = get_core(core_version) @@ -1028,68 +965,33 @@ def uninstall_library(library_uuid: str) -> Response: library_manager.uninstall_library(library_uuid) return Response(status_code=204) - @app.post("/initialize_style_id", status_code=204, tags=["その他"]) - def initialize_style_id( - style_id: StyleId, + @app.post("/initialize_speaker", status_code=204, tags=["その他"]) + def initialize_speaker( + style_id: StyleId = Query(alias="speaker"), # noqa: B008 skip_reinit: bool = Query( # noqa: B008 default=False, description="既に初期化済みのスタイルの再初期化をスキップするかどうか" ), core_version: str | None = None, ) -> Response: """ - 指定されたstyle_idのスタイルを初期化します。 + 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 """ core = get_core(core_version) core.initialize_style_id_synthesis(style_id, skip_reinit=skip_reinit) return Response(status_code=204) - @app.get("/is_initialized_style_id", response_model=bool, tags=["その他"]) - def is_initialized_style_id( - style_id: StyleId, + @app.get("/is_initialized_speaker", response_model=bool, tags=["その他"]) + def is_initialized_speaker( + style_id: StyleId = Query(alias="speaker"), # noqa: B008 core_version: str | None = None, ) -> bool: """ - 指定されたstyle_idのスタイルが初期化されているかどうかを返します。 + 指定されたスタイルが初期化されているかどうかを返します。 """ core = get_core(core_version) return core.is_initialized_style_id_synthesis(style_id) - @app.post("/initialize_speaker", status_code=204, tags=["その他"], deprecated=True) - def initialize_speaker( - speaker: StyleId, - skip_reinit: bool = Query( # noqa: B008 - default=False, description="既に初期化済みの話者の再初期化をスキップするかどうか" - ), - core_version: str | None = None, - ) -> Response: - """ - こちらのAPIは非推奨です。`initialize_style_id`を利用してください。 - """ - warnings.warn( - "使用しているAPI(/initialize_speaker)は非推奨です。/initialized_style_idを利用してください。", - stacklevel=1, - ) - return initialize_style_id( - speaker, skip_reinit=skip_reinit, core_version=core_version - ) - - @app.get( - "/is_initialized_speaker", response_model=bool, tags=["その他"], deprecated=True - ) - def is_initialized_speaker( - speaker: StyleId, - core_version: str | None = None, - ) -> bool: - """ - こちらのAPIは非推奨です。`is_initialize_style_id`を利用してください。 - """ - warnings.warn( - "使用しているAPI(/is_initialize_speaker)は非推奨です。/is_initialized_style_idを利用してください。", - stacklevel=1, - ) - return is_initialized_style_id(speaker, core_version=core_version) - @app.get("/user_dict", response_model=dict[str, UserDictWord], tags=["ユーザー辞書"]) def get_user_dict_words() -> dict[str, UserDictWord]: """ diff --git "a/test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\343\202\202\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" "b/test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" similarity index 100% rename from "test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\343\202\202\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" rename to "test/e2e/__snapshots__/test_audio_query/test_speaker\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" diff --git "a/test/e2e/__snapshots__/test_audio_query/test_style_id\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" "b/test/e2e/__snapshots__/test_audio_query/test_style_id\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" deleted file mode 100644 index e47234dce..000000000 --- "a/test/e2e/__snapshots__/test_audio_query/test_style_id\343\202\222\346\214\207\345\256\232\343\201\227\343\201\246\351\237\263\345\243\260\345\220\210\346\210\220\343\202\257\343\202\250\343\203\252\343\201\214\345\217\226\345\276\227\343\201\247\343\201\215\343\202\213.json" +++ /dev/null @@ -1,60 +0,0 @@ -{ - "accent_phrases": [ - { - "accent": 1, - "is_interrogative": false, - "moras": [ - { - "consonant": "t", - "consonant_length": 2.31, - "pitch": 3.38, - "text": "テ", - "vowel": "e", - "vowel_length": 0.88 - }, - { - "consonant": "s", - "consonant_length": 2.19, - "pitch": 0.0, - "text": "ス", - "vowel": "U", - "vowel_length": 0.38 - }, - { - "consonant": "t", - "consonant_length": 2.31, - "pitch": 4.19, - "text": "ト", - "vowel": "o", - "vowel_length": 1.88 - }, - { - "consonant": "d", - "consonant_length": 0.75, - "pitch": 1.62, - "text": "デ", - "vowel": "e", - "vowel_length": 0.88 - }, - { - "consonant": "s", - "consonant_length": 2.19, - "pitch": 0.0, - "text": "ス", - "vowel": "U", - "vowel_length": 0.38 - } - ], - "pause_mora": null - } - ], - "intonationScale": 1.0, - "kana": "テ'_ストデ_ス", - "outputSamplingRate": 24000, - "outputStereo": false, - "pitchScale": 0.0, - "postPhonemeLength": 0.1, - "prePhonemeLength": 0.1, - "speedScale": 1.0, - "volumeScale": 1.0 -} diff --git "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" index 0cf9b7443..84083909c 100644 --- "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" +++ "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" @@ -981,19 +981,9 @@ } }, { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -1119,19 +1109,9 @@ } }, { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -1241,19 +1221,9 @@ "operationId": "cancellable_synthesis_cancellable_synthesis_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -1515,8 +1485,7 @@ }, "/initialize_speaker": { "post": { - "deprecated": true, - "description": "こちらのAPIは非推奨です。`initialize_style_id`を利用してください。", + "description": "指定されたスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。", "operationId": "initialize_speaker_initialize_speaker_post", "parameters": [ { @@ -1528,63 +1497,6 @@ "type": "integer" } }, - { - "description": "既に初期化済みの話者の再初期化をスキップするかどうか", - "in": "query", - "name": "skip_reinit", - "required": false, - "schema": { - "default": false, - "description": "既に初期化済みの話者の再初期化をスキップするかどうか", - "title": "Skip Reinit", - "type": "boolean" - } - }, - { - "in": "query", - "name": "core_version", - "required": false, - "schema": { - "title": "Core Version", - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - "description": "Validation Error" - } - }, - "summary": "Initialize Speaker", - "tags": [ - "その他" - ] - } - }, - "/initialize_style_id": { - "post": { - "description": "指定されたstyle_idのスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。", - "operationId": "initialize_style_id_initialize_style_id_post", - "parameters": [ - { - "in": "query", - "name": "style_id", - "required": true, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, { "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", "in": "query", @@ -1622,7 +1534,7 @@ "description": "Validation Error" } }, - "summary": "Initialize Style Id", + "summary": "Initialize Speaker", "tags": [ "その他" ] @@ -1692,8 +1604,7 @@ }, "/is_initialized_speaker": { "get": { - "deprecated": true, - "description": "こちらのAPIは非推奨です。`is_initialize_style_id`を利用してください。", + "description": "指定されたスタイルが初期化されているかどうかを返します。", "operationId": "is_initialized_speaker_is_initialized_speaker_get", "parameters": [ { @@ -1744,77 +1655,14 @@ ] } }, - "/is_initialized_style_id": { - "get": { - "description": "指定されたstyle_idのスタイルが初期化されているかどうかを返します。", - "operationId": "is_initialized_style_id_is_initialized_style_id_get", - "parameters": [ - { - "in": "query", - "name": "style_id", - "required": true, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "in": "query", - "name": "core_version", - "required": false, - "schema": { - "title": "Core Version", - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "title": "Response Is Initialized Style Id Is Initialized Style Id Get", - "type": "boolean" - } - } - }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - "description": "Validation Error" - } - }, - "summary": "Is Initialized Style Id", - "tags": [ - "その他" - ] - } - }, "/mora_data": { "post": { "operationId": "mora_data_mora_data_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -1881,19 +1729,9 @@ "operationId": "mora_length_mora_length_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -1960,19 +1798,9 @@ "operationId": "mora_pitch_mora_pitch_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -2103,19 +1931,9 @@ "operationId": "multi_synthesis_multi_synthesis_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -2393,19 +2211,9 @@ "operationId": "synthesis_synthesis_post", "parameters": [ { - "in": "query", - "name": "style_id", - "required": false, - "schema": { - "title": "Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "speaker", - "required": false, + "required": true, "schema": { "title": "Speaker", "type": "integer" @@ -2478,38 +2286,18 @@ "operationId": "_synthesis_morphing_synthesis_morphing_post", "parameters": [ { - "in": "query", - "name": "base_style_id", - "required": false, - "schema": { - "title": "Base Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "base_speaker", - "required": false, + "required": true, "schema": { "title": "Base Speaker", "type": "integer" } }, { - "in": "query", - "name": "target_style_id", - "required": false, - "schema": { - "title": "Target Style Id", - "type": "integer" - } - }, - { - "deprecated": true, "in": "query", "name": "target_speaker", - "required": false, + "required": true, "schema": { "title": "Target Speaker", "type": "integer" diff --git a/test/e2e/test_audio_query.py b/test/e2e/test_audio_query.py index bcab2fea1..6f8c6fa86 100644 --- a/test/e2e/test_audio_query.py +++ b/test/e2e/test_audio_query.py @@ -8,24 +8,9 @@ from syrupy.extensions.json import JSONSnapshotExtension -def test_style_idを指定して音声合成クエリが取得できる( - client: TestClient, snapshot_json: JSONSnapshotExtension -) -> None: - response = client.post("/audio_query", params={"text": "テストです", "style_id": 0}) - assert response.status_code == 200 - assert snapshot_json == round_floats(response.json(), round_value=2) - - -def test_speakerを指定しても音声合成クエリが取得できる( +def test_speakerを指定して音声合成クエリが取得できる( client: TestClient, snapshot_json: JSONSnapshotExtension ) -> None: response = client.post("/audio_query", params={"text": "テストです", "speaker": 0}) assert response.status_code == 200 assert snapshot_json == round_floats(response.json(), round_value=2) - - -def test_style_idとspeakerを両方指定するとエラー(client: TestClient) -> None: - response = client.post( - "/audio_query", params={"text": "テストです", "style_id": 0, "speaker": 0} - ) - assert response.status_code == 400 From 8203ac486dbd909919d30015ee359e310eb7e33f Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Sun, 21 Jan 2024 00:44:31 +0900 Subject: [PATCH 3/8] [release-0.15] to 0.15.0 (#1018) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ライブラリ管理機能をオフに * to 0.15.0 * 文言微調整 * 「ビルドの改善」は「開発環境の向上」と統一に * snapshotテストを更新 * テスト更新 --- engine_manifest.json | 3 +- engine_manifest_assets/update_infos.json | 33 +++ ...\343\202\222\347\242\272\350\252\215.json" | 240 ------------------ test/e2e/test_disable_api.py | 6 +- 4 files changed, 38 insertions(+), 244 deletions(-) diff --git a/engine_manifest.json b/engine_manifest.json index f4a5dfaa1..bf5db2d44 100644 --- a/engine_manifest.json +++ b/engine_manifest.json @@ -12,7 +12,6 @@ "terms_of_service": "engine_manifest_assets/terms_of_service.md", "update_infos": "engine_manifest_assets/update_infos.json", "dependency_licenses": "engine_manifest_assets/dependency_licenses.json", - "supported_vvlib_manifest_version": "0.15.0", "supported_features": { "adjust_mora_pitch": { "type": "bool", @@ -56,7 +55,7 @@ }, "manage_library": { "type": "bool", - "value": true, + "value": false, "name": "音声ライブラリのインストール・アンインストール" } } diff --git a/engine_manifest_assets/update_infos.json b/engine_manifest_assets/update_infos.json index b465a8b36..5c876d4d8 100644 --- a/engine_manifest_assets/update_infos.json +++ b/engine_manifest_assets/update_infos.json @@ -1,4 +1,37 @@ [ + { + "version": "0.15.0", + "descriptions": [ + "/validate_kana APIを追加", + "起動時のエンジン設定項目追加", + "ユーザー辞書のインポート・エクスポート機能追加", + "ビルド成果物のディレクトリ構造を変更", + "書き込み系APIを一括で無効化可能に", + "開発環境の向上", + "バグ修正" + ], + "contributors": [ + "aoirint", + "FujisakiEx", + "Hiroshiba", + "K-shir0", + "My-MC", + "nagi-miaow", + "okaits", + "raa0121", + "sabonerune", + "sevenc-nanashi", + "siketyan", + "stmtk1", + "takana-v", + "tarepan", + "tomoish", + "tuna2134", + "weweweok", + "whiteball", + "y-chan" + ] + }, { "version": "0.14.7", "descriptions": [ diff --git "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" index 84083909c..d20acdf92 100644 --- "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" +++ "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" @@ -164,48 +164,6 @@ "title": "CorsPolicyMode", "type": "string" }, - "DownloadableLibraryInfo": { - "description": "ダウンロード可能な音声ライブラリの情報", - "properties": { - "bytes": { - "title": "音声ライブラリのバイト数", - "type": "integer" - }, - "download_url": { - "title": "音声ライブラリのダウンロードURL", - "type": "string" - }, - "name": { - "title": "音声ライブラリの名前", - "type": "string" - }, - "speakers": { - "items": { - "$ref": "#/components/schemas/LibrarySpeaker" - }, - "title": "音声ライブラリに含まれる話者のリスト", - "type": "array" - }, - "uuid": { - "title": "音声ライブラリのUUID", - "type": "string" - }, - "version": { - "title": "音声ライブラリのバージョン", - "type": "string" - } - }, - "required": [ - "name", - "uuid", - "version", - "download_url", - "bytes", - "speakers" - ], - "title": "DownloadableLibraryInfo", - "type": "object" - }, "EngineManifest": { "description": "エンジン自体に関する情報", "properties": { @@ -297,80 +255,6 @@ "title": "HTTPValidationError", "type": "object" }, - "InstalledLibraryInfo": { - "description": "インストール済み音声ライブラリの情報", - "properties": { - "bytes": { - "title": "音声ライブラリのバイト数", - "type": "integer" - }, - "download_url": { - "title": "音声ライブラリのダウンロードURL", - "type": "string" - }, - "name": { - "title": "音声ライブラリの名前", - "type": "string" - }, - "speakers": { - "items": { - "$ref": "#/components/schemas/LibrarySpeaker" - }, - "title": "音声ライブラリに含まれる話者のリスト", - "type": "array" - }, - "uninstallable": { - "title": "アンインストール可能かどうか", - "type": "boolean" - }, - "uuid": { - "title": "音声ライブラリのUUID", - "type": "string" - }, - "version": { - "title": "音声ライブラリのバージョン", - "type": "string" - } - }, - "required": [ - "name", - "uuid", - "version", - "download_url", - "bytes", - "speakers", - "uninstallable" - ], - "title": "InstalledLibraryInfo", - "type": "object" - }, - "LibrarySpeaker": { - "description": "音声ライブラリに含まれる話者の情報", - "properties": { - "speaker": { - "allOf": [ - { - "$ref": "#/components/schemas/Speaker" - } - ], - "title": "話者情報" - }, - "speaker_info": { - "allOf": [ - { - "$ref": "#/components/schemas/SpeakerInfo" - } - ], - "title": "話者の追加情報" - } - }, - "required": [ - "speaker", - "speaker_info" - ], - "title": "LibrarySpeaker", - "type": "object" - }, "LicenseInfo": { "description": "依存ライブラリのライセンス情報", "properties": { @@ -1386,32 +1270,6 @@ ] } }, - "/downloadable_libraries": { - "get": { - "description": "ダウンロード可能な音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: list[DownloadableLibrary]", - "operationId": "downloadable_libraries_downloadable_libraries_get", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/DownloadableLibraryInfo" - }, - "title": "Response Downloadable Libraries Downloadable Libraries Get", - "type": "array" - } - } - }, - "description": "Successful Response" - } - }, - "summary": "Downloadable Libraries", - "tags": [ - "音声ライブラリ管理" - ] - } - }, "/engine_manifest": { "get": { "operationId": "engine_manifest_engine_manifest_get", @@ -1540,68 +1398,6 @@ ] } }, - "/install_library/{library_uuid}": { - "post": { - "description": "音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", - "operationId": "install_library_install_library__library_uuid__post", - "parameters": [ - { - "in": "path", - "name": "library_uuid", - "required": true, - "schema": { - "title": "Library Uuid", - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - "description": "Validation Error" - } - }, - "summary": "Install Library", - "tags": [ - "音声ライブラリ管理" - ] - } - }, - "/installed_libraries": { - "get": { - "description": "インストールした音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: dict[str, InstalledLibrary]", - "operationId": "installed_libraries_installed_libraries_get", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "additionalProperties": { - "$ref": "#/components/schemas/InstalledLibraryInfo" - }, - "title": "Response Installed Libraries Installed Libraries Get", - "type": "object" - } - } - }, - "description": "Successful Response" - } - }, - "summary": "Installed Libraries", - "tags": [ - "音声ライブラリ管理" - ] - } - }, "/is_initialized_speaker": { "get": { "description": "指定されたスタイルが初期化されているかどうかを返します。", @@ -2363,42 +2159,6 @@ ] } }, - "/uninstall_library/{library_uuid}": { - "post": { - "description": "音声ライブラリをアンインストールします。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", - "operationId": "uninstall_library_uninstall_library__library_uuid__post", - "parameters": [ - { - "in": "path", - "name": "library_uuid", - "required": true, - "schema": { - "title": "Library Uuid", - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - "description": "Validation Error" - } - }, - "summary": "Uninstall Library", - "tags": [ - "音声ライブラリ管理" - ] - } - }, "/update_preset": { "post": { "description": "既存のプリセットを更新します\n\nParameters\n-------\npreset: Preset\n 更新するプリセット。\n プリセットIDが更新対象と一致している必要があります。\n\nReturns\n-------\nid: int\n 更新したプリセットのプリセットID", diff --git a/test/e2e/test_disable_api.py b/test/e2e/test_disable_api.py index 27dd292f8..bdd16cbf8 100644 --- a/test/e2e/test_disable_api.py +++ b/test/e2e/test_disable_api.py @@ -36,14 +36,16 @@ def test_disable_mutable_api(app_params: dict) -> None: _assert_request_and_response_403(client, "post", "/add_preset") _assert_request_and_response_403(client, "post", "/update_preset") _assert_request_and_response_403(client, "post", "/delete_preset") - _assert_request_and_response_403(client, "post", "/install_library/dummy") - _assert_request_and_response_403(client, "post", "/uninstall_library/dummy") _assert_request_and_response_403(client, "post", "/user_dict_word") _assert_request_and_response_403(client, "put", "/user_dict_word/dummy") _assert_request_and_response_403(client, "delete", "/user_dict_word/dummy") _assert_request_and_response_403(client, "post", "/import_user_dict") _assert_request_and_response_403(client, "post", "/setting") + # FIXME: EngineManifestをDI可能にし、EngineManifestに従ってこれらのAPIを加える + # _assert_request_and_response_403(client, "post", "/install_library/dummy") + # _assert_request_and_response_403(client, "post", "/uninstall_library/dummy") + # 他のAPIは有効 response = client.get("/version") assert response.status_code == 200 From ed0cbe4fce070e327c12c2cc8063ca4a4da3bf98 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Sun, 21 Jan 2024 00:50:53 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[release-0.15]=20=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=89=E5=BE=8C=E3=83=86=E3=82=B9=E3=83=88=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E6=BC=8F=E3=82=8C=20(#1019)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ビルド後テストの修正漏れ --- build_util/check_release_build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_util/check_release_build.py b/build_util/check_release_build.py index ae14ff1af..a04c53d39 100644 --- a/build_util/check_release_build.py +++ b/build_util/check_release_build.py @@ -34,14 +34,14 @@ def test_release_build(dist_dir: Path, skip_run_process: bool) -> None: # テキスト -> クエリ text = "こんにちは、音声合成の世界へようこそ" req = Request( - base_url + "audio_query?" + urlencode({"style_id": "1", "text": text}), + base_url + "audio_query?" + urlencode({"speaker": "1", "text": text}), method="POST", ) with urlopen(req) as res: query = json.loads(res.read().decode("utf-8")) # クエリ -> 音声 - req = Request(base_url + "synthesis?style_id=1", method="POST") + req = Request(base_url + "synthesis?speaker=1", method="POST") req.add_header("Content-Type", "application/json") req.data = json.dumps(query).encode("utf-8") with urlopen(req) as res: From e9d805baaa383769fcf652aa1e59909c5bee3f1b Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Sun, 21 Jan 2024 17:17:06 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[release-0.15]=20#857=20=E3=82=92revert=20(?= =?UTF-8?q?#1023)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "BLD: PyInstallerをv6へ更新 (#857)" This reverts commit 4ef4218822de666ea1272338061a14ffd8f690a3. --- .github/workflows/build.yml | 8 +-- poetry.lock | 61 +++++++++-------- pyproject.toml | 2 +- requirements-dev.txt | 10 +-- run.py | 3 +- run.spec | 88 ++++++++++--------------- voicevox_engine/user_dict.py | 4 +- voicevox_engine/utility/__init__.py | 5 +- voicevox_engine/utility/path_utility.py | 51 ++++---------- 9 files changed, 94 insertions(+), 138 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 45cde827c..d16170dd6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -464,10 +464,10 @@ jobs: LIBONNXRUNTIME_PATH=download/onnxruntime/lib/libonnxruntime.so fi - pyinstaller --noconfirm run.spec -- \ - --libcore_path="$LIBCORE_PATH" \ - --libonnxruntime_path="$LIBONNXRUNTIME_PATH" \ - --core_model_dir_path="download/core/model" + CORE_MODEL_DIR_PATH="download/core/model" \ + LIBCORE_PATH="$LIBCORE_PATH" \ + LIBONNXRUNTIME_PATH="$LIBONNXRUNTIME_PATH" \ + pyinstaller --noconfirm run.spec - name: Gather DLL dependencies to dist/run/ (Windows) if: startsWith(matrix.os, 'windows-') diff --git a/poetry.lock b/poetry.lock index c36d1a59d..f32b58cd3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "altgraph" -version = "0.17.4" +version = "0.17.3" description = "Python graph (network) package" optional = false python-versions = "*" files = [ - {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, - {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, + {file = "altgraph-0.17.3-py2.py3-none-any.whl", hash = "sha256:c8ac1ca6772207179ed8003ce7687757c04b0b71536f81e2ac5755c6226458fe"}, + {file = "altgraph-0.17.3.tar.gz", hash = "sha256:ad33358114df7c9416cdb8fa1eaa5852166c505118717021c6a8c7c7abbd03dd"}, ] [[package]] @@ -1009,13 +1009,13 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", [[package]] name = "macholib" -version = "1.16.3" +version = "1.16.2" description = "Mach-O header analysis and editing" optional = false python-versions = "*" files = [ - {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, - {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, + {file = "macholib-1.16.2-py2.py3-none-any.whl", hash = "sha256:44c40f2cd7d6726af8fa6fe22549178d3a4dfecc35a9cd15ea916d9c83a688e0"}, + {file = "macholib-1.16.2.tar.gz", hash = "sha256:557bbfa1bb255c20e9abafe7ed6cd8046b48d9525db2f9b77d3122a63a2a8bf8"}, ] [package.dependencies] @@ -1601,47 +1601,46 @@ files = [ [[package]] name = "pyinstaller" -version = "6.2.0" +version = "5.13.2" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false -python-versions = "<3.13,>=3.8" +python-versions = "<3.13,>=3.7" files = [ - {file = "pyinstaller-6.2.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:a1adbd3cf25dc90926d783eae0f444d65cdfecc7bcdf6da522c3ae3ff47b4c25"}, - {file = "pyinstaller-6.2.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:29d164394f1e949072f78a64c1e040f1c47b7f4aff08514c7666a031c8b44996"}, - {file = "pyinstaller-6.2.0-py3-none-manylinux2014_i686.whl", hash = "sha256:ba602a38d7403de89c38b8956b221ce6de0280730d269bab522492fcad82ee33"}, - {file = "pyinstaller-6.2.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:ebac06d99b80d2035594c3cc2fb5f2612d86289edd0510dbcbeb20a873f51d5a"}, - {file = "pyinstaller-6.2.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:fcfabc0ff1d38a4262c051dea3fdc1f7f106405c1f1b491b4c79cd28df19cab6"}, - {file = "pyinstaller-6.2.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:104430686149b2f1c135b2c17aa2967c85d54ef77dc92feb4e179ec846c0c467"}, - {file = "pyinstaller-6.2.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:e87fd60292b53bb9965cb5a84122875469a2bd475fd0d0db0052a3f1be351f75"}, - {file = "pyinstaller-6.2.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:8ec9d6c98972bb922cedb16a6638257aa66e5deadd79e2953f3464696237c413"}, - {file = "pyinstaller-6.2.0-py3-none-win32.whl", hash = "sha256:e5561e9a9b946d835c8dbc11ae4c16cc21e62bc77d10cc043406dc2992dfb4c6"}, - {file = "pyinstaller-6.2.0-py3-none-win_amd64.whl", hash = "sha256:3b586196277c4c54b69880650984c39c28bb6258c2b4b64200032e6ac69d53a0"}, - {file = "pyinstaller-6.2.0-py3-none-win_arm64.whl", hash = "sha256:d0c87b605bf13c3a04dfaa1d2fa7cd36765b8137000eeadccba865e1d6a19bf0"}, - {file = "pyinstaller-6.2.0.tar.gz", hash = "sha256:1ce77043929bf525be38289d78feecde0fcf15506215eda6500176a8715c5047"}, + {file = "pyinstaller-5.13.2-py3-none-macosx_10_13_universal2.whl", hash = "sha256:16cbd66b59a37f4ee59373a003608d15df180a0d9eb1a29ff3bfbfae64b23d0f"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8f6dd0e797ae7efdd79226f78f35eb6a4981db16c13325e962a83395c0ec7420"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_i686.whl", hash = "sha256:65133ed89467edb2862036b35d7c5ebd381670412e1e4361215e289c786dd4e6"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:7d51734423685ab2a4324ab2981d9781b203dcae42839161a9ee98bfeaabdade"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:2c2fe9c52cb4577a3ac39626b84cf16cf30c2792f785502661286184f162ae0d"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c63ef6133eefe36c4b2f4daf4cfea3d6412ece2ca218f77aaf967e52a95ac9b8"}, + {file = "pyinstaller-5.13.2-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:aadafb6f213549a5906829bb252e586e2cf72a7fbdb5731810695e6516f0ab30"}, + {file = "pyinstaller-5.13.2-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b2e1c7f5cceb5e9800927ddd51acf9cc78fbaa9e79e822c48b0ee52d9ce3c892"}, + {file = "pyinstaller-5.13.2-py3-none-win32.whl", hash = "sha256:421cd24f26144f19b66d3868b49ed673176765f92fa9f7914cd2158d25b6d17e"}, + {file = "pyinstaller-5.13.2-py3-none-win_amd64.whl", hash = "sha256:ddcc2b36052a70052479a9e5da1af067b4496f43686ca3cdda99f8367d0627e4"}, + {file = "pyinstaller-5.13.2-py3-none-win_arm64.whl", hash = "sha256:27cd64e7cc6b74c5b1066cbf47d75f940b71356166031deb9778a2579bb874c6"}, + {file = "pyinstaller-5.13.2.tar.gz", hash = "sha256:c8e5d3489c3a7cc5f8401c2d1f48a70e588f9967e391c3b06ddac1f685f8d5d2"}, ] [package.dependencies] altgraph = "*" macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} -packaging = ">=22.0" pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} pyinstaller-hooks-contrib = ">=2021.4" pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} setuptools = ">=42.0.0" [package.extras] -completion = ["argcomplete"] +encryption = ["tinyaes (>=1.0.0)"] hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2023.10" +version = "2023.7" description = "Community maintained hooks for PyInstaller" optional = false python-versions = ">=3.7" files = [ - {file = "pyinstaller-hooks-contrib-2023.10.tar.gz", hash = "sha256:4b4a998036abb713774cb26534ca06b7e6e09e4c628196017a10deb11a48747f"}, - {file = "pyinstaller_hooks_contrib-2023.10-py2.py3-none-any.whl", hash = "sha256:6dc1786a8f452941245d5bb85893e2a33632ebdcbc4c23eea41f2ee08281b0c0"}, + {file = "pyinstaller-hooks-contrib-2023.7.tar.gz", hash = "sha256:0c436a4c3506020e34116a8a7ddfd854c1ad6ddca9a8cd84500bd6e69c9e68f9"}, + {file = "pyinstaller_hooks_contrib-2023.7-py2.py3-none-any.whl", hash = "sha256:3c10df14c0f71ab388dfbf1625375b087e7330d9444cbfd2b310ba027fa0cff0"}, ] [[package]] @@ -2034,19 +2033,19 @@ files = [ [[package]] name = "setuptools" -version = "69.0.2" +version = "68.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, + {file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"}, + {file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" @@ -2431,4 +2430,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "2b9225ae66f4dab6a5785858312ecd2188a972698619418e017152ac2b38f41a" +content-hash = "4635ad235914ef05225525233ce0723226417491de9f2551112682c707921365" diff --git a/pyproject.toml b/pyproject.toml index b0d75a9a1..22f0b66df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,7 @@ platformdirs = "^3.10.0" soxr = "^0.3.6" [tool.poetry.group.dev.dependencies] -pyinstaller = "^6.2.0" +pyinstaller = "^5.13" pre-commit = "^2.16.0" poetry = "^1.3.1" diff --git a/requirements-dev.txt b/requirements-dev.txt index c9a7736db..2c877c547 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -altgraph==0.17.4 ; python_version >= "3.11" and python_version < "3.12" +altgraph==0.17.3 ; python_version >= "3.11" and python_version < "3.12" anyio==3.7.1 ; python_version >= "3.11" and python_version < "3.12" asgiref==3.7.2 ; python_version >= "3.11" and python_version < "3.12" attrs==23.1.0 ; python_version >= "3.11" and python_version < "3.12" @@ -28,7 +28,7 @@ jeepney==0.8.0 ; python_version >= "3.11" and python_version < "3.12" and sys_pl jinja2==3.1.2 ; python_version >= "3.11" and python_version < "3.12" jsonschema==4.17.3 ; python_version >= "3.11" and python_version < "3.12" keyring==24.2.0 ; python_version >= "3.11" and python_version < "3.12" -macholib==1.16.3 ; python_version >= "3.11" and python_version < "3.12" and sys_platform == "darwin" +macholib==1.16.2 ; python_version >= "3.11" and python_version < "3.12" and sys_platform == "darwin" markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "3.12" more-itertools==10.1.0 ; python_version >= "3.11" and python_version < "3.12" msgpack==1.0.5 ; python_version >= "3.11" and python_version < "3.12" @@ -46,8 +46,8 @@ pre-commit==2.21.0 ; python_version >= "3.11" and python_version < "3.12" ptyprocess==0.7.0 ; python_version >= "3.11" and python_version < "3.12" pycparser==2.21 ; python_version >= "3.11" and python_version < "3.12" pydantic==1.10.12 ; python_version >= "3.11" and python_version < "3.12" -pyinstaller-hooks-contrib==2023.10 ; python_version >= "3.11" and python_version < "3.12" -pyinstaller==6.2.0 ; python_version >= "3.11" and python_version < "3.12" +pyinstaller-hooks-contrib==2023.7 ; python_version >= "3.11" and python_version < "3.12" +pyinstaller==5.13.2 ; python_version >= "3.11" and python_version < "3.12" pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@b35fc89fe42948a28e33aed886ea145a51113f88 ; python_version >= "3.11" and python_version < "3.12" pyproject-hooks==1.0.0 ; python_version >= "3.11" and python_version < "3.12" pyrsistent==0.19.3 ; python_version >= "3.11" and python_version < "3.12" @@ -60,7 +60,7 @@ requests-toolbelt==1.0.0 ; python_version >= "3.11" and python_version < "3.12" requests==2.31.0 ; python_version >= "3.11" and python_version < "3.12" secretstorage==3.3.3 ; python_version >= "3.11" and python_version < "3.12" and sys_platform == "linux" semver==3.0.1 ; python_version >= "3.11" and python_version < "3.12" -setuptools==69.0.2 ; python_version >= "3.11" and python_version < "3.12" +setuptools==68.1.2 ; python_version >= "3.11" and python_version < "3.12" shellingham==1.5.3 ; python_version >= "3.11" and python_version < "3.12" six==1.16.0 ; python_version >= "3.11" and python_version < "3.12" sniffio==1.3.0 ; python_version >= "3.11" and python_version < "3.12" diff --git a/run.py b/run.py index ea737353c..f1ccf4e2f 100644 --- a/run.py +++ b/run.py @@ -89,7 +89,6 @@ engine_root, get_latest_core_version, get_save_dir, - internal_root, ) from voicevox_engine.utility.run_utility import decide_boolean_from_env @@ -228,7 +227,7 @@ def check_disabled_mutable_api(): metas_store = MetasStore(root_dir / "speaker_info") setting_ui_template = Jinja2Templates( - directory=internal_root() / "ui_template", + directory=engine_root() / "ui_template", variable_start_string="", variable_end_string="", ) diff --git a/run.spec b/run.spec index 65642c61d..970f2adfa 100644 --- a/run.spec +++ b/run.spec @@ -1,42 +1,49 @@ # -*- mode: python ; coding: utf-8 -*- # このファイルはPyInstallerによって自動生成されたもので、それをカスタマイズして使用しています。 -from argparse import ArgumentParser -from pathlib import Path -from shutil import copy2, copytree - from PyInstaller.utils.hooks import collect_data_files - -parser = ArgumentParser() -parser.add_argument("--libcore_path", type=Path) -parser.add_argument("--libonnxruntime_path", type=Path) -parser.add_argument("--core_model_dir_path", type=Path) -options = parser.parse_args() - -libonnxruntime_path: Path | None = options.libonnxruntime_path -if libonnxruntime_path is not None and not libonnxruntime_path.is_file(): - raise Exception(f"libonnxruntime_path: {libonnxruntime_path} is not file") - -libcore_path: Path | None = options.libcore_path -if libcore_path is not None and not libcore_path.is_file(): - raise Exception(f"libcore_path: {libcore_path} is not file") - -core_model_dir_path: Path | None = options.core_model_dir_path -if core_model_dir_path is not None and not core_model_dir_path.is_dir(): - raise Exception(f"core_model_dir_path: {core_model_dir_path} is not dir") +import os datas = [ - ("default.csv", "."), - ("presets.yaml", "."), - ("ui_template", "ui_template"), + ('engine_manifest_assets', 'engine_manifest_assets'), + ('speaker_info', 'speaker_info'), + ('engine_manifest.json', '.'), + ('default.csv', '.'), + ('licenses.json', '.'), + ('presets.yaml', '.'), + ('ui_template', 'ui_template'), ] -datas += collect_data_files("pyopenjtalk") +datas += collect_data_files('pyopenjtalk') + +core_model_dir_path = os.environ.get('CORE_MODEL_DIR_PATH') +if core_model_dir_path: + print('CORE_MODEL_DIR_PATH is found:', core_model_dir_path) + if not os.path.isdir(core_model_dir_path): + raise Exception("CORE_MODEL_DIR_PATH was found, but it is not directory!") + datas += [(core_model_dir_path, "model")] + +# コアとONNX Runtimeはバイナリであるが、`binaries`に加えると +# 依存関係のパスがPyInstallerに書き換えらるので、`datas`に加える +# 参考: https://github.com/VOICEVOX/voicevox_engine/pull/446#issuecomment-1210052318 +libcore_path = os.environ.get('LIBCORE_PATH') +if libcore_path: + print('LIBCORE_PATH is found:', libcore_path) + if not os.path.isfile(libcore_path): + raise Exception("LIBCORE_PATH was found, but it is not file!") + datas += [(libcore_path, ".")] + +libonnxruntime_path = os.environ.get('LIBONNXRUNTIME_PATH') +if libonnxruntime_path: + print('LIBONNXRUNTIME_PATH is found:', libonnxruntime_path) + if not os.path.isfile(libonnxruntime_path): + raise Exception("LIBCORE_PATH was found, but it is not file!") + datas += [(libonnxruntime_path, ".")] block_cipher = None a = Analysis( - ["run.py"], + ['run.py'], pathex=[], binaries=[], datas=datas, @@ -58,7 +65,7 @@ exe = EXE( a.scripts, [], exclude_binaries=True, - name="run", + name='run', debug=False, bootloader_ignore_signals=False, strip=False, @@ -69,7 +76,6 @@ exe = EXE( target_arch=None, codesign_identity=None, entitlements_file=None, - contents_directory="engine_internal", ) coll = COLLECT( @@ -80,27 +86,5 @@ coll = COLLECT( strip=False, upx=True, upx_exclude=[], - name="run", + name='run', ) - -# 実行ファイル作成後の処理 - -# 実行ファイルと同じrootディレクトリ -target_dir = Path(DISTPATH) / "run" - -# 動的ライブラリをコピー -if libonnxruntime_path is not None: - copy2(libonnxruntime_path, target_dir) -if libcore_path is not None: - copy2(libcore_path, target_dir) -if core_model_dir_path is not None: - copytree(core_model_dir_path, target_dir / "model") - -# 互換性維持のために必要なファイルをコピー -license_file_path = Path("licenses.json") -if license_file_path.is_file(): - copy2("licenses.json", target_dir) - -copytree("speaker_info", target_dir / "speaker_info") -copy2("engine_manifest.json", target_dir) -copytree("engine_manifest_assets", target_dir / "engine_manifest_assets") diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index e931f557c..8661321f7 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -12,9 +12,9 @@ from .model import UserDictWord, WordTypes from .part_of_speech_data import MAX_PRIORITY, MIN_PRIORITY, part_of_speech_data -from .utility import get_save_dir, internal_root, mutex_wrapper +from .utility import engine_root, get_save_dir, mutex_wrapper -root_dir = internal_root() +root_dir = engine_root() save_dir = get_save_dir() if not save_dir.is_dir(): diff --git a/voicevox_engine/utility/__init__.py b/voicevox_engine/utility/__init__.py index 7ed74f118..d40fea3e6 100644 --- a/voicevox_engine/utility/__init__.py +++ b/voicevox_engine/utility/__init__.py @@ -5,7 +5,7 @@ ) from .core_version_utility import get_latest_core_version, parse_core_version from .mutex_utility import mutex_wrapper -from .path_utility import delete_file, engine_root, get_save_dir, internal_root +from .path_utility import delete_file, engine_root, get_save_dir __all__ = [ "ConnectBase64WavesException", @@ -13,9 +13,8 @@ "decode_base64_waves", "get_latest_core_version", "parse_core_version", - "mutex_wrapper", "delete_file", "engine_root", "get_save_dir", - "internal_root", + "mutex_wrapper", ] diff --git a/voicevox_engine/utility/path_utility.py b/voicevox_engine/utility/path_utility.py index 6c5c36ca2..7c46ad40b 100644 --- a/voicevox_engine/utility/path_utility.py +++ b/voicevox_engine/utility/path_utility.py @@ -2,51 +2,18 @@ import sys import traceback from pathlib import Path -from typing import Literal from platformdirs import user_data_dir -def _runtime_type() -> Literal["nuitka", "pyinstaller", "python"]: - """ - コンパイルに使用したライブラリ名を返す。 - コンパイルしていない場合は"python"を返す。 - """ - # nuitkaビルドをした際はグローバルに__compiled__が含まれる - if "__compiled__" in globals(): - return "nuitka" - - # pyinstallerでビルドをした際はsys.frozenが設定される - elif getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): - return "pyinstaller" - - return "python" - - def engine_root() -> Path: - """ - 開発環境ではリポジトリのルートディレクトリを返す。 - コンパイル後は実行ファイルがあるディレクトリを返す。 - """ - runtime = _runtime_type() - if runtime == "nuitka": - root_dir = Path(sys.argv[0]).parent - - elif runtime == "pyinstaller": - root_dir = Path(sys.executable).parent - - else: + if is_development(): root_dir = Path(__file__).parents[2] - return root_dir.resolve(strict=True) - + # Nuitka/Pyinstallerでビルドされている場合 + else: + root_dir = Path(sys.argv[0]).parent -def internal_root() -> Path: - """ - コンパイル時に収集された実行ファイル内部用のルートディレクトリを返す。 - 開発環境ではリポジトリのルートディレクトリを返す。 - """ - root_dir = Path(__file__).parents[2] return root_dir.resolve(strict=True) @@ -55,7 +22,15 @@ def is_development() -> bool: 開発版かどうか判定する関数 Nuitka/Pyinstallerでコンパイルされていない場合は開発環境とする。 """ - return _runtime_type() == "python" + # nuitkaビルドをした際はグローバルに__compiled__が含まれる + if "__compiled__" in globals(): + return False + + # pyinstallerでビルドをした際はsys.frozenが設定される + elif getattr(sys, "frozen", False): + return False + + return True def get_save_dir(): From cf014df3e5dec286df2f664116dd245436b48837 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Sun, 21 Jan 2024 17:27:58 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[release-0.15]=20RESOURCE=E3=82=920.15.0?= =?UTF-8?q?=E3=81=AB=20(#1024)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit リソースを0.15.0に --- .github/workflows/build-docker.yml | 2 +- .github/workflows/build.yml | 2 +- Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 73be54d12..11745791d 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -15,7 +15,7 @@ on: env: IMAGE_NAME: ${{ vars.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.11.3" - VOICEVOX_RESOURCE_VERSION: "0.14.5" + VOICEVOX_RESOURCE_VERSION: "0.15.0" VOICEVOX_CORE_VERSION: "0.14.6" defaults: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d16170dd6..a223b3950 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ on: env: PYTHON_VERSION: "3.11.3" - VOICEVOX_RESOURCE_VERSION: "0.14.5" + VOICEVOX_RESOURCE_VERSION: "0.15.0" VOICEVOX_CORE_VERSION: "0.14.6" defaults: diff --git a/Dockerfile b/Dockerfile index e4c4426fa..9b8f0c5a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -275,7 +275,7 @@ RUN < Date: Sun, 21 Jan 2024 23:13:05 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[release-0.15]=200.15.1=E7=94=A8=E3=81=AE?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=83=85=E5=A0=B1=E3=82=92=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20(#1025)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 0.15.1用の更新情報更新 * Mac * ビルド成果物のディレクトリ構造を元に戻した --- engine_manifest_assets/update_infos.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine_manifest_assets/update_infos.json b/engine_manifest_assets/update_infos.json index 5c876d4d8..581f41d2c 100644 --- a/engine_manifest_assets/update_infos.json +++ b/engine_manifest_assets/update_infos.json @@ -1,4 +1,9 @@ [ + { + "version": "0.15.1", + "descriptions": ["ビルド成果物のディレクトリ構造を元に戻した"], + "contributors": [] + }, { "version": "0.15.0", "descriptions": [ From eef3a17ec75fcc7a5b5f74ab7640c8f4e9e31d48 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Tue, 23 Jan 2024 00:47:53 +0900 Subject: [PATCH 8/8] =?UTF-8?q?manage=5Flibrary=E3=82=92true=E3=81=AB?= =?UTF-8?q?=E6=88=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine_manifest.json | 2 +- ...\343\202\222\347\242\272\350\252\215.json" | 240 ++++++++++++++++++ 2 files changed, 241 insertions(+), 1 deletion(-) diff --git a/engine_manifest.json b/engine_manifest.json index bf5db2d44..f6ced765e 100644 --- a/engine_manifest.json +++ b/engine_manifest.json @@ -55,7 +55,7 @@ }, "manage_library": { "type": "bool", - "value": false, + "value": true, "name": "音声ライブラリのインストール・アンインストール" } } diff --git "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" index d20acdf92..84083909c 100644 --- "a/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" +++ "b/test/e2e/__snapshots__/test_openapi/test_OpenAPI\343\201\256\345\275\242\343\201\214\345\244\211\343\202\217\343\201\243\343\201\246\343\201\204\343\201\252\343\201\204\343\201\223\343\201\250\343\202\222\347\242\272\350\252\215.json" @@ -164,6 +164,48 @@ "title": "CorsPolicyMode", "type": "string" }, + "DownloadableLibraryInfo": { + "description": "ダウンロード可能な音声ライブラリの情報", + "properties": { + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers" + ], + "title": "DownloadableLibraryInfo", + "type": "object" + }, "EngineManifest": { "description": "エンジン自体に関する情報", "properties": { @@ -255,6 +297,80 @@ "title": "HTTPValidationError", "type": "object" }, + "InstalledLibraryInfo": { + "description": "インストール済み音声ライブラリの情報", + "properties": { + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array" + }, + "uninstallable": { + "title": "アンインストール可能かどうか", + "type": "boolean" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers", + "uninstallable" + ], + "title": "InstalledLibraryInfo", + "type": "object" + }, + "LibrarySpeaker": { + "description": "音声ライブラリに含まれる話者の情報", + "properties": { + "speaker": { + "allOf": [ + { + "$ref": "#/components/schemas/Speaker" + } + ], + "title": "話者情報" + }, + "speaker_info": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerInfo" + } + ], + "title": "話者の追加情報" + } + }, + "required": [ + "speaker", + "speaker_info" + ], + "title": "LibrarySpeaker", + "type": "object" + }, "LicenseInfo": { "description": "依存ライブラリのライセンス情報", "properties": { @@ -1270,6 +1386,32 @@ ] } }, + "/downloadable_libraries": { + "get": { + "description": "ダウンロード可能な音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: list[DownloadableLibrary]", + "operationId": "downloadable_libraries_downloadable_libraries_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DownloadableLibraryInfo" + }, + "title": "Response Downloadable Libraries Downloadable Libraries Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Downloadable Libraries", + "tags": [ + "音声ライブラリ管理" + ] + } + }, "/engine_manifest": { "get": { "operationId": "engine_manifest_engine_manifest_get", @@ -1398,6 +1540,68 @@ ] } }, + "/install_library/{library_uuid}": { + "post": { + "description": "音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", + "operationId": "install_library_install_library__library_uuid__post", + "parameters": [ + { + "in": "path", + "name": "library_uuid", + "required": true, + "schema": { + "title": "Library Uuid", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Install Library", + "tags": [ + "音声ライブラリ管理" + ] + } + }, + "/installed_libraries": { + "get": { + "description": "インストールした音声ライブラリの情報を返します。\n\nReturns\n-------\nret_data: dict[str, InstalledLibrary]", + "operationId": "installed_libraries_installed_libraries_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/InstalledLibraryInfo" + }, + "title": "Response Installed Libraries Installed Libraries Get", + "type": "object" + } + } + }, + "description": "Successful Response" + } + }, + "summary": "Installed Libraries", + "tags": [ + "音声ライブラリ管理" + ] + } + }, "/is_initialized_speaker": { "get": { "description": "指定されたスタイルが初期化されているかどうかを返します。", @@ -2159,6 +2363,42 @@ ] } }, + "/uninstall_library/{library_uuid}": { + "post": { + "description": "音声ライブラリをアンインストールします。\n\nParameters\n----------\nlibrary_uuid: str\n 音声ライブラリのID", + "operationId": "uninstall_library_uninstall_library__library_uuid__post", + "parameters": [ + { + "in": "path", + "name": "library_uuid", + "required": true, + "schema": { + "title": "Library Uuid", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Uninstall Library", + "tags": [ + "音声ライブラリ管理" + ] + } + }, "/update_preset": { "post": { "description": "既存のプリセットを更新します\n\nParameters\n-------\npreset: Preset\n 更新するプリセット。\n プリセットIDが更新対象と一致している必要があります。\n\nReturns\n-------\nid: int\n 更新したプリセットのプリセットID",