aimage-sdk 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,78 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnpm-store/
4
+
5
+ # Build outputs
6
+ dist/
7
+ .next/
8
+ .turbo/
9
+ out/
10
+ next-env.d.ts
11
+ storybook-static/
12
+
13
+ # Python
14
+ __pycache__/
15
+ *.pyc
16
+ *.pyo
17
+ .venv/
18
+ venv/
19
+ *.egg-info/
20
+
21
+ # Terraform
22
+ .terraform/
23
+ *.tfstate
24
+ *.tfstate.backup
25
+ *.tfplan
26
+ tfplan-*
27
+
28
+ # Environment
29
+ .env
30
+ .env.*
31
+ !.env.example
32
+
33
+ # IDE
34
+ .idea/
35
+ .vscode/
36
+ *.swp
37
+ *.swo
38
+
39
+ # OS
40
+ .DS_Store
41
+ Thumbs.db
42
+
43
+ # Test & coverage
44
+ coverage/
45
+ .vitest/
46
+
47
+ # Lint cache
48
+ .eslintcache
49
+
50
+ # Misc
51
+ *.log
52
+ *.tsbuildinfo
53
+
54
+
55
+ # Rust
56
+ /target
57
+ infra/tfplan
58
+
59
+ # Local-only artifacts
60
+ .claude/scheduled_tasks.lock
61
+ .claude/settings.local.json
62
+ .playwright-mcp/
63
+ insights-*.png
64
+ tsup.config.bundled_*.mjs
65
+ audit/
66
+ .aimage-video-v3-lab/
67
+ .bdd-logs/
68
+ .bdd-snapshots/
69
+
70
+ # Local scratch clones and downloads (VideoDR benchmark, ad-hoc corpora).
71
+ .tmp/
72
+ tmp/
73
+
74
+ # Bare symlink form: `node_modules/` with a slash does not match a symlink
75
+ node_modules
76
+
77
+ # Session scratchpads: per-agent notes, never repo content
78
+ scratchpad/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AI-Mage Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.5
2
+ Name: aimage-sdk
3
+ Version: 0.3.0
4
+ Summary: Python SDK for the AI-Mage Search public API
5
+ Project-URL: Documentation, https://api.search.ai-mage.jp/docs
6
+ Project-URL: Repository, https://github.com/aimagexyz/aimage-monorepo
7
+ Author: AI-Mage
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: httpx<1,>=0.28
17
+ Description-Content-Type: text/markdown
18
+
19
+ # aimage-sdk
20
+
21
+ Python SDK for the AI-Mage Search public API (`/v0`). Python 3.12+, `httpx`
22
+ is the only dependency.
23
+
24
+ ## Install
25
+
26
+ ```sh
27
+ pip install aimage-sdk
28
+ # or: uv add aimage-sdk
29
+ ```
30
+
31
+ ## Quickstart
32
+
33
+ ```python
34
+ import os
35
+
36
+ from aimage_sdk import AimageClient
37
+
38
+ client = AimageClient(
39
+ api_key=os.environ["AIMAGE_API_KEY"], # "aimage_api_..."
40
+ base_url="https://api.search.ai-mage.jp", # API server origin; the client calls {base_url}/v0/...
41
+ )
42
+
43
+ # Discover accessible projects.
44
+ me = client.me()
45
+ project_id = me["projects"][0]["id"]
46
+
47
+ # Upload a video: mints a presigned URL, PUTs the bytes, registers the video.
48
+ video = client.upload_video(
49
+ project_id=project_id,
50
+ file="./episode-01.mp4", # str | pathlib.Path | bytes (bytes need file_name=)
51
+ name="Episode 1",
52
+ season=1,
53
+ episode=1,
54
+ on_progress=print,
55
+ )
56
+
57
+ # Wait until clip extraction and AI tagging finish.
58
+ processed = client.wait_for_processing(video["id"], poll_interval_s=10, timeout_s=1800)
59
+ if processed["processing_status"] == "failed":
60
+ raise RuntimeError(processed["processing_error"])
61
+
62
+ # Search clips with a natural-language query.
63
+ result = client.search_clips(project_id=project_id, query="two characters arguing in the rain")
64
+ for clip in result["clips"]:
65
+ print(clip["start_time"], clip["subtitle"], clip["tags"], clip["characters"])
66
+ ```
67
+
68
+ ## API surface
69
+
70
+ - `ping()` / `me()`
71
+ - `list_projects()`
72
+
73
+ Videos:
74
+
75
+ - `mint_upload_url(project_id=, file_name=, content_type=)`
76
+ - `register_video(project_id=, name=, file_name=|s3_key=, season=, episode=, auto_process=)`
77
+ - `get_video(video_id)` / `list_videos(project_id=, processing_status=, order=, page=, page_size=)` / `delete_video(video_id)`
78
+ - `upload_video(project_id=, file=, name=, ...)` — full 3-step upload orchestration
79
+ - `wait_for_processing(video_id, poll_interval_s=, timeout_s=)`
80
+
81
+ Reference images:
82
+
83
+ - `mint_reference_image_upload_url(project_id=, file_name=, content_type=)`
84
+ - `register_reference_image(project_id=, file_name=|s3_key=, name=, category=, tags=, purpose=, license=, is_searchable=)`
85
+ - `list_reference_images(project_id=, page=, page_size=)` / `get_reference_image(reference_image_id)` / `delete_reference_image(reference_image_id)`
86
+ - `upload_reference_image(project_id=, file=, ...)` — full 3-step upload orchestration
87
+
88
+ Materials:
89
+
90
+ - `mint_material_upload_url(project_id=, file_name=, content_type=)`
91
+ - `register_material(project_id=, file_name=|s3_key=, name=, auto_process=)`
92
+ - `list_materials(project_id=, file_type=, material_type=, page=, page_size=)` / `get_material(material_id)` / `delete_material(material_id)`
93
+ - `upload_material(project_id=, file=, ...)` — full 3-step upload orchestration
94
+
95
+ Characters and visual assets:
96
+
97
+ - `list_characters(project_id=, page=, page_size=)` / `get_character(character_id)` — characters with their images (stable `visual_asset_id` + short-lived `download_url`)
98
+ - `list_visual_assets(project_id=, source_type=, character_id=, page=, page_size=)` / `resolve_visual_assets(project_id=, visual_asset_ids=)`
99
+
100
+ Clips and search:
101
+
102
+ - `get_clip(clip_id)` / `update_clip(clip_id, subtitle=, description=, tags=, character_ids=)`
103
+ - `search_clips(project_id=, query=, reference_image_ids=, image_importance=, page=, page_size=)` — pass `query` and/or `reference_image_ids`
104
+ - `search_moments(project_id=, query=, sources=, season=, video_ids=, limit=, offset=)` — Alaya moment index (projects whose `search_capabilities` include `moments`; 409 `MOMENT_INDEX_NOT_AVAILABLE` otherwise)
105
+
106
+ Failed API calls raise `AimageApiError` with `code`, `message`, and HTTP
107
+ `status` parsed from the `{"error": {"code", "message"}}` envelope.
108
+
109
+ ## Development
110
+
111
+ ```sh
112
+ cd sdks/python
113
+ uv sync
114
+ uv run pytest
115
+ uv run ruff check .
116
+ ```
@@ -0,0 +1,98 @@
1
+ # aimage-sdk
2
+
3
+ Python SDK for the AI-Mage Search public API (`/v0`). Python 3.12+, `httpx`
4
+ is the only dependency.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ pip install aimage-sdk
10
+ # or: uv add aimage-sdk
11
+ ```
12
+
13
+ ## Quickstart
14
+
15
+ ```python
16
+ import os
17
+
18
+ from aimage_sdk import AimageClient
19
+
20
+ client = AimageClient(
21
+ api_key=os.environ["AIMAGE_API_KEY"], # "aimage_api_..."
22
+ base_url="https://api.search.ai-mage.jp", # API server origin; the client calls {base_url}/v0/...
23
+ )
24
+
25
+ # Discover accessible projects.
26
+ me = client.me()
27
+ project_id = me["projects"][0]["id"]
28
+
29
+ # Upload a video: mints a presigned URL, PUTs the bytes, registers the video.
30
+ video = client.upload_video(
31
+ project_id=project_id,
32
+ file="./episode-01.mp4", # str | pathlib.Path | bytes (bytes need file_name=)
33
+ name="Episode 1",
34
+ season=1,
35
+ episode=1,
36
+ on_progress=print,
37
+ )
38
+
39
+ # Wait until clip extraction and AI tagging finish.
40
+ processed = client.wait_for_processing(video["id"], poll_interval_s=10, timeout_s=1800)
41
+ if processed["processing_status"] == "failed":
42
+ raise RuntimeError(processed["processing_error"])
43
+
44
+ # Search clips with a natural-language query.
45
+ result = client.search_clips(project_id=project_id, query="two characters arguing in the rain")
46
+ for clip in result["clips"]:
47
+ print(clip["start_time"], clip["subtitle"], clip["tags"], clip["characters"])
48
+ ```
49
+
50
+ ## API surface
51
+
52
+ - `ping()` / `me()`
53
+ - `list_projects()`
54
+
55
+ Videos:
56
+
57
+ - `mint_upload_url(project_id=, file_name=, content_type=)`
58
+ - `register_video(project_id=, name=, file_name=|s3_key=, season=, episode=, auto_process=)`
59
+ - `get_video(video_id)` / `list_videos(project_id=, processing_status=, order=, page=, page_size=)` / `delete_video(video_id)`
60
+ - `upload_video(project_id=, file=, name=, ...)` — full 3-step upload orchestration
61
+ - `wait_for_processing(video_id, poll_interval_s=, timeout_s=)`
62
+
63
+ Reference images:
64
+
65
+ - `mint_reference_image_upload_url(project_id=, file_name=, content_type=)`
66
+ - `register_reference_image(project_id=, file_name=|s3_key=, name=, category=, tags=, purpose=, license=, is_searchable=)`
67
+ - `list_reference_images(project_id=, page=, page_size=)` / `get_reference_image(reference_image_id)` / `delete_reference_image(reference_image_id)`
68
+ - `upload_reference_image(project_id=, file=, ...)` — full 3-step upload orchestration
69
+
70
+ Materials:
71
+
72
+ - `mint_material_upload_url(project_id=, file_name=, content_type=)`
73
+ - `register_material(project_id=, file_name=|s3_key=, name=, auto_process=)`
74
+ - `list_materials(project_id=, file_type=, material_type=, page=, page_size=)` / `get_material(material_id)` / `delete_material(material_id)`
75
+ - `upload_material(project_id=, file=, ...)` — full 3-step upload orchestration
76
+
77
+ Characters and visual assets:
78
+
79
+ - `list_characters(project_id=, page=, page_size=)` / `get_character(character_id)` — characters with their images (stable `visual_asset_id` + short-lived `download_url`)
80
+ - `list_visual_assets(project_id=, source_type=, character_id=, page=, page_size=)` / `resolve_visual_assets(project_id=, visual_asset_ids=)`
81
+
82
+ Clips and search:
83
+
84
+ - `get_clip(clip_id)` / `update_clip(clip_id, subtitle=, description=, tags=, character_ids=)`
85
+ - `search_clips(project_id=, query=, reference_image_ids=, image_importance=, page=, page_size=)` — pass `query` and/or `reference_image_ids`
86
+ - `search_moments(project_id=, query=, sources=, season=, video_ids=, limit=, offset=)` — Alaya moment index (projects whose `search_capabilities` include `moments`; 409 `MOMENT_INDEX_NOT_AVAILABLE` otherwise)
87
+
88
+ Failed API calls raise `AimageApiError` with `code`, `message`, and HTTP
89
+ `status` parsed from the `{"error": {"code", "message"}}` envelope.
90
+
91
+ ## Development
92
+
93
+ ```sh
94
+ cd sdks/python
95
+ uv sync
96
+ uv run pytest
97
+ uv run ruff check .
98
+ ```
@@ -0,0 +1,43 @@
1
+ [project]
2
+ name = "aimage-sdk"
3
+ version = "0.3.0"
4
+ description = "Python SDK for the AI-Mage Search public API"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "AI-Mage" }]
9
+ requires-python = ">=3.12"
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ "Intended Audience :: Developers",
13
+ "Programming Language :: Python :: 3.12",
14
+ "Programming Language :: Python :: 3.13",
15
+ "Typing :: Typed",
16
+ ]
17
+ dependencies = [
18
+ "httpx>=0.28,<1",
19
+ ]
20
+
21
+ [project.urls]
22
+ Documentation = "https://api.search.ai-mage.jp/docs"
23
+ Repository = "https://github.com/aimagexyz/aimage-monorepo"
24
+
25
+ [dependency-groups]
26
+ dev = [
27
+ "pytest>=9,<10",
28
+ "ruff>=0.7,<1",
29
+ ]
30
+
31
+ [tool.uv]
32
+ default-groups = ["dev"]
33
+
34
+ [build-system]
35
+ requires = ["hatchling"]
36
+ build-backend = "hatchling.build"
37
+
38
+ [tool.ruff]
39
+ line-length = 100
40
+ target-version = "py312"
41
+
42
+ [tool.ruff.lint]
43
+ select = ["E", "F", "I", "B", "UP"]
@@ -0,0 +1,98 @@
1
+ """Python SDK for the AI-Mage Search public API."""
2
+
3
+ from .client import AimageClient, ProgressStage
4
+ from .errors import AimageApiError
5
+ from .types import (
6
+ AlayaStatus,
7
+ Character,
8
+ CharacterConceptSetting,
9
+ CharacterImage,
10
+ CharacterListResponse,
11
+ Clip,
12
+ ClipCharacter,
13
+ ClipDetail,
14
+ DeleteMaterialResponse,
15
+ DeleteReferenceImageResponse,
16
+ DeleteVideoResponse,
17
+ Material,
18
+ MaterialDetail,
19
+ MaterialFileType,
20
+ MaterialListResponse,
21
+ MaterialStatus,
22
+ MeProject,
23
+ MeResponse,
24
+ Moment,
25
+ MomentProvenance,
26
+ MomentRange,
27
+ MomentSearchSource,
28
+ MomentVerification,
29
+ PingResponse,
30
+ ProcessingStatus,
31
+ ProjectListResponse,
32
+ ProjectRole,
33
+ ReferenceImage,
34
+ ReferenceImageEmbeddingStatus,
35
+ ReferenceImageLicense,
36
+ ReferenceImageListResponse,
37
+ ResolvedVisualAsset,
38
+ ResolveVisualAssetsResponse,
39
+ SearchCapability,
40
+ SearchClipsResponse,
41
+ SearchMomentsResponse,
42
+ SortOrder,
43
+ UploadUrlResponse,
44
+ Video,
45
+ VideoAlaya,
46
+ VideoListResponse,
47
+ VisualAssetListResponse,
48
+ VisualAssetSourceType,
49
+ )
50
+
51
+ __all__ = [
52
+ "AimageApiError",
53
+ "AimageClient",
54
+ "AlayaStatus",
55
+ "Character",
56
+ "CharacterConceptSetting",
57
+ "CharacterImage",
58
+ "CharacterListResponse",
59
+ "Clip",
60
+ "ClipCharacter",
61
+ "ClipDetail",
62
+ "DeleteMaterialResponse",
63
+ "DeleteReferenceImageResponse",
64
+ "DeleteVideoResponse",
65
+ "Material",
66
+ "MaterialDetail",
67
+ "MaterialFileType",
68
+ "MaterialListResponse",
69
+ "MaterialStatus",
70
+ "MeProject",
71
+ "Moment",
72
+ "MomentProvenance",
73
+ "MomentRange",
74
+ "MomentSearchSource",
75
+ "MomentVerification",
76
+ "MeResponse",
77
+ "PingResponse",
78
+ "ProcessingStatus",
79
+ "ProgressStage",
80
+ "ProjectListResponse",
81
+ "ProjectRole",
82
+ "ReferenceImage",
83
+ "ReferenceImageEmbeddingStatus",
84
+ "ReferenceImageLicense",
85
+ "ReferenceImageListResponse",
86
+ "ResolvedVisualAsset",
87
+ "ResolveVisualAssetsResponse",
88
+ "SearchCapability",
89
+ "SearchClipsResponse",
90
+ "SearchMomentsResponse",
91
+ "SortOrder",
92
+ "UploadUrlResponse",
93
+ "Video",
94
+ "VideoAlaya",
95
+ "VideoListResponse",
96
+ "VisualAssetListResponse",
97
+ "VisualAssetSourceType",
98
+ ]