dvr 0.1.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.
dvr-0.1.0/.gitignore ADDED
@@ -0,0 +1,70 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ share/python-wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+ MANIFEST
24
+
25
+ # Virtual environments
26
+ .venv/
27
+ venv/
28
+ env/
29
+ ENV/
30
+
31
+ # Hatch / generated version file
32
+ dvr/_version.py
33
+
34
+ # Testing & coverage
35
+ .pytest_cache/
36
+ .coverage
37
+ .coverage.*
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ coverage.xml
42
+ *.cover
43
+ .hypothesis/
44
+
45
+ # Type checking
46
+ .mypy_cache/
47
+ .ruff_cache/
48
+ .pyre/
49
+ .pytype/
50
+
51
+ # IDE
52
+ .idea/
53
+ .vscode/
54
+ *.swp
55
+ *.swo
56
+ *~
57
+
58
+ # OS
59
+ .DS_Store
60
+ Thumbs.db
61
+
62
+ # Project-local
63
+ *.log
64
+ .env
65
+ .env.local
66
+ scratch/
67
+ local/
68
+
69
+ # Docs
70
+ site/
dvr-0.1.0/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dvr` are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+ - Media domain: `MediaPool`, `Asset` / `MediaPoolItem`, `Bin`, `MediaStorage` with bins, import, relink, proxy linking, auto-sync
11
+ - Color domain: `ColorOps` (CDL, LUT export, magic mask, stabilization, smart reframe, versions), `NodeGraph`, `ColorGroup`
12
+ - Audio domain: voice isolation, channel mapping introspection, Fairlight presets, audio insertion
13
+ - Gallery domain: still albums, PowerGrade albums, import/export
14
+ - Fusion (per-clip): `ClipFusion` for add / load / import / export / rename / delete comps
15
+ - Takes: `Takes` for take/variant management on a clip
16
+ - Interchange: unified import/export covering 21 formats — AAF, EDL (+ CDL/SDL/missing), FCP7 XML, FCPXML 1.8/1.9/1.10, DRT, OTIO, CSV, TAB, ALE, ALE-CDL, Dolby Vision 2.9/4.0/5.1, HDR10 A/B
17
+ - Daemon: `dvr serve start/stop/status/methods` with newline-delimited JSON over a Unix socket
18
+ - MCP server: `dvr mcp serve` exposes the library as typed tools for LLM agents
19
+ - Declarative specs: `dvr plan` and `dvr apply` reconcile YAML/JSON specs against live state, with built-in HDR color presets
20
+ - CLI sub-apps for every domain: `dvr media`, `dvr serve`, `dvr mcp`, `dvr plan`, `dvr apply`
21
+ - Docs site: mkdocs-material with concept guides, CLI reference, library tour, daemon and MCP guides, declarative-spec walkthrough, auto-generated API reference
22
+
23
+ ## [0.1.0] - 2026-04-24
24
+
25
+ ### Added
26
+ - Initial scaffold: connection layer, error system, Resolve / Project / Timeline / Render core classes
27
+ - CLI entry point with structured output (JSON / table / YAML)
28
+ - Inspection-first object model
dvr-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 M Hadi
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.
dvr-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: dvr
3
+ Version: 0.1.0
4
+ Summary: The missing CLI and Python library for DaVinci Resolve. Declarative, scriptable, LLM-friendly.
5
+ Project-URL: Homepage, https://github.com/mhadifilms/dvr
6
+ Project-URL: Documentation, https://mhadifilms.github.io/dvr
7
+ Project-URL: Repository, https://github.com/mhadifilms/dvr
8
+ Project-URL: Issues, https://github.com/mhadifilms/dvr/issues
9
+ Project-URL: Changelog, https://github.com/mhadifilms/dvr/blob/main/CHANGELOG.md
10
+ Author-email: M Hadi <mhadifilms@gmail.com>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: automation,cli,color-grading,davinci-resolve,edl,fcpxml,post-production,vfx,video-editing
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: Microsoft :: Windows
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Multimedia :: Video
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Requires-Dist: pyyaml>=6.0
31
+ Requires-Dist: rich>=13.7
32
+ Requires-Dist: typer>=0.12
33
+ Provides-Extra: dev
34
+ Requires-Dist: mypy>=1.10; extra == 'dev'
35
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
36
+ Requires-Dist: pytest>=8.0; extra == 'dev'
37
+ Requires-Dist: ruff>=0.6; extra == 'dev'
38
+ Requires-Dist: types-pyyaml; extra == 'dev'
39
+ Provides-Extra: docs
40
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
41
+ Requires-Dist: mkdocs>=1.6; extra == 'docs'
42
+ Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
43
+ Provides-Extra: mcp
44
+ Requires-Dist: mcp>=1.0; extra == 'mcp'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # dvr
48
+
49
+ **The missing CLI and Python library for DaVinci Resolve.**
50
+
51
+ Declarative. Scriptable. LLM-friendly. No more silent `None` returns.
52
+
53
+ ```bash
54
+ pip install dvr
55
+ ```
56
+
57
+ ```bash
58
+ $ dvr timeline inspect
59
+ {
60
+ "name": "MyShow_207_R2",
61
+ "fps": 24.0,
62
+ "duration_frames": 86400,
63
+ "tracks": {
64
+ "video": [{"index": 1, "name": "V1", "clips": 1, "enabled": true}, ...],
65
+ "audio": [{"index": 1, "name": "A1", "clips": 4, "subtype": "stereo"}, ...]
66
+ },
67
+ "markers": [...],
68
+ "color": {"science": "DaVinci YRGB Color Managed v2", "input": "Rec.2020", ...}
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Why this exists
75
+
76
+ DaVinci Resolve has a powerful Python scripting API. It's also painful:
77
+
78
+ - **Silent failures everywhere.** `AddRenderJob()` returns `None` on success or failure — good luck.
79
+ - **String-keyed settings** with undocumented valid values.
80
+ - **No batch operators.** You loop everything.
81
+ - **macOS connection footguns.** Resolve binds to LAN IP; vanilla `scriptapp('Resolve')` returns `None`.
82
+ - **Chain navigation.** Every `.Get*()` can return `None`. One typo and you're traversing nothing.
83
+ - **20+ export formats** behind magic enum constants.
84
+
85
+ `dvr` wraps the API with a clean object model, idempotent operations, decoded errors, structured I/O, and a CLI that's pleasant for humans *and* parseable by LLM agents.
86
+
87
+ ## Three ways to use it
88
+
89
+ ### 1. Python library
90
+
91
+ ```python
92
+ from dvr import Resolve
93
+
94
+ r = Resolve() # auto-connects, handles macOS LAN-IP quirk
95
+
96
+ with r.project.use("MyShow_207"):
97
+ tl = r.timeline.current
98
+ print(tl.inspect()) # one call, full state
99
+
100
+ # Query language operates on inspected state
101
+ bad = tl.clips.where(lambda c: c.duration < 12)
102
+ for clip in bad:
103
+ clip.add_marker(color="red", note="too short")
104
+
105
+ job = r.render.submit(preset="delivery")
106
+ job.wait() # blocks with progress
107
+ print(job.output_path)
108
+ ```
109
+
110
+ ### 2. CLI
111
+
112
+ ```bash
113
+ $ dvr project ensure MyShow_207 --color rec2020_pq_4000 --fps 24
114
+ $ dvr timeline inspect | jq '.tracks.video[].clips'
115
+ $ dvr render submit --preset delivery --wait --stream
116
+ {"job_id": "abc", "status": "rendering", "pct": 12, "eta_s": 240}
117
+ {"job_id": "abc", "status": "rendering", "pct": 24, "eta_s": 210}
118
+ {"job_id": "abc", "status": "complete", "output": "/path/out.mov"}
119
+ ```
120
+
121
+ ### 3. MCP server (for LLM agents)
122
+
123
+ ```bash
124
+ $ dvr mcp serve # exposes the library as MCP tools
125
+ ```
126
+
127
+ LLM agents call typed tools directly — no shell parsing, no silent failures.
128
+
129
+ ## Five things that make it fundamentally better than the raw API
130
+
131
+ 1. **One `inspect()` call replaces ten API calls.** Full structured state in a single round-trip.
132
+ 2. **Idempotent operations.** `project.ensure()`, `timeline.ensure()`, `bin.ensure()` — re-run anything safely.
133
+ 3. **Decoded errors.** Every failure carries `cause`, `fix`, and `state`. No more `None`.
134
+ 4. **Declarative specs.** `dvr apply project.dvr.yaml` reconciles state. `kubectl apply` for DaVinci.
135
+ 5. **Persistent connection.** `dvr serve` keeps Resolve warm — sequential commands run in <100ms.
136
+
137
+ ## Install
138
+
139
+ ```bash
140
+ # stable
141
+ pip install dvr
142
+
143
+ # with MCP server for LLM agents
144
+ pip install "dvr[mcp]"
145
+
146
+ # from source
147
+ git clone https://github.com/mhadifilms/dvr
148
+ cd dvr
149
+ pip install -e ".[dev]"
150
+ ```
151
+
152
+ ### Requirements
153
+
154
+ - **Python 3.10+** (matches Resolve's embedded Python on current versions)
155
+ - **DaVinci Resolve 18.5+** (Studio or Free)
156
+ - **macOS, Windows, or Linux**
157
+
158
+ `dvr` auto-discovers Resolve's scripting library on each platform. No environment variables needed for typical installs.
159
+
160
+ ## Status
161
+
162
+ Pre-1.0. The public API may change. See [CHANGELOG.md](CHANGELOG.md) for breaking changes.
163
+
164
+ ## License
165
+
166
+ MIT — see [LICENSE](LICENSE).
167
+
168
+ ## Contributing
169
+
170
+ Issues and pull requests welcome. The project's API surface is large; contributions covering edge cases on Windows / Linux are especially valuable. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and conventions.
171
+
172
+ ---
173
+
174
+ > `dvr` is an independent open-source project. It is **not affiliated with, endorsed by, or sponsored by Blackmagic Design**. "DaVinci" and "DaVinci Resolve" are trademarks of Blackmagic Design Pty Ltd.
dvr-0.1.0/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # dvr
2
+
3
+ **The missing CLI and Python library for DaVinci Resolve.**
4
+
5
+ Declarative. Scriptable. LLM-friendly. No more silent `None` returns.
6
+
7
+ ```bash
8
+ pip install dvr
9
+ ```
10
+
11
+ ```bash
12
+ $ dvr timeline inspect
13
+ {
14
+ "name": "MyShow_207_R2",
15
+ "fps": 24.0,
16
+ "duration_frames": 86400,
17
+ "tracks": {
18
+ "video": [{"index": 1, "name": "V1", "clips": 1, "enabled": true}, ...],
19
+ "audio": [{"index": 1, "name": "A1", "clips": 4, "subtype": "stereo"}, ...]
20
+ },
21
+ "markers": [...],
22
+ "color": {"science": "DaVinci YRGB Color Managed v2", "input": "Rec.2020", ...}
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Why this exists
29
+
30
+ DaVinci Resolve has a powerful Python scripting API. It's also painful:
31
+
32
+ - **Silent failures everywhere.** `AddRenderJob()` returns `None` on success or failure — good luck.
33
+ - **String-keyed settings** with undocumented valid values.
34
+ - **No batch operators.** You loop everything.
35
+ - **macOS connection footguns.** Resolve binds to LAN IP; vanilla `scriptapp('Resolve')` returns `None`.
36
+ - **Chain navigation.** Every `.Get*()` can return `None`. One typo and you're traversing nothing.
37
+ - **20+ export formats** behind magic enum constants.
38
+
39
+ `dvr` wraps the API with a clean object model, idempotent operations, decoded errors, structured I/O, and a CLI that's pleasant for humans *and* parseable by LLM agents.
40
+
41
+ ## Three ways to use it
42
+
43
+ ### 1. Python library
44
+
45
+ ```python
46
+ from dvr import Resolve
47
+
48
+ r = Resolve() # auto-connects, handles macOS LAN-IP quirk
49
+
50
+ with r.project.use("MyShow_207"):
51
+ tl = r.timeline.current
52
+ print(tl.inspect()) # one call, full state
53
+
54
+ # Query language operates on inspected state
55
+ bad = tl.clips.where(lambda c: c.duration < 12)
56
+ for clip in bad:
57
+ clip.add_marker(color="red", note="too short")
58
+
59
+ job = r.render.submit(preset="delivery")
60
+ job.wait() # blocks with progress
61
+ print(job.output_path)
62
+ ```
63
+
64
+ ### 2. CLI
65
+
66
+ ```bash
67
+ $ dvr project ensure MyShow_207 --color rec2020_pq_4000 --fps 24
68
+ $ dvr timeline inspect | jq '.tracks.video[].clips'
69
+ $ dvr render submit --preset delivery --wait --stream
70
+ {"job_id": "abc", "status": "rendering", "pct": 12, "eta_s": 240}
71
+ {"job_id": "abc", "status": "rendering", "pct": 24, "eta_s": 210}
72
+ {"job_id": "abc", "status": "complete", "output": "/path/out.mov"}
73
+ ```
74
+
75
+ ### 3. MCP server (for LLM agents)
76
+
77
+ ```bash
78
+ $ dvr mcp serve # exposes the library as MCP tools
79
+ ```
80
+
81
+ LLM agents call typed tools directly — no shell parsing, no silent failures.
82
+
83
+ ## Five things that make it fundamentally better than the raw API
84
+
85
+ 1. **One `inspect()` call replaces ten API calls.** Full structured state in a single round-trip.
86
+ 2. **Idempotent operations.** `project.ensure()`, `timeline.ensure()`, `bin.ensure()` — re-run anything safely.
87
+ 3. **Decoded errors.** Every failure carries `cause`, `fix`, and `state`. No more `None`.
88
+ 4. **Declarative specs.** `dvr apply project.dvr.yaml` reconciles state. `kubectl apply` for DaVinci.
89
+ 5. **Persistent connection.** `dvr serve` keeps Resolve warm — sequential commands run in <100ms.
90
+
91
+ ## Install
92
+
93
+ ```bash
94
+ # stable
95
+ pip install dvr
96
+
97
+ # with MCP server for LLM agents
98
+ pip install "dvr[mcp]"
99
+
100
+ # from source
101
+ git clone https://github.com/mhadifilms/dvr
102
+ cd dvr
103
+ pip install -e ".[dev]"
104
+ ```
105
+
106
+ ### Requirements
107
+
108
+ - **Python 3.10+** (matches Resolve's embedded Python on current versions)
109
+ - **DaVinci Resolve 18.5+** (Studio or Free)
110
+ - **macOS, Windows, or Linux**
111
+
112
+ `dvr` auto-discovers Resolve's scripting library on each platform. No environment variables needed for typical installs.
113
+
114
+ ## Status
115
+
116
+ Pre-1.0. The public API may change. See [CHANGELOG.md](CHANGELOG.md) for breaking changes.
117
+
118
+ ## License
119
+
120
+ MIT — see [LICENSE](LICENSE).
121
+
122
+ ## Contributing
123
+
124
+ Issues and pull requests welcome. The project's API surface is large; contributions covering edge cases on Windows / Linux are especially valuable. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and conventions.
125
+
126
+ ---
127
+
128
+ > `dvr` is an independent open-source project. It is **not affiliated with, endorsed by, or sponsored by Blackmagic Design**. "DaVinci" and "DaVinci Resolve" are trademarks of Blackmagic Design Pty Ltd.
@@ -0,0 +1,55 @@
1
+ """dvr — the missing CLI and Python library for DaVinci Resolve.
2
+
3
+ This package exposes a small, stable public API. Internal modules are
4
+ prefixed with ``_`` and may change between releases. The two things you
5
+ almost always want are:
6
+
7
+ from dvr import Resolve, errors
8
+
9
+ Open a connection with ``r = Resolve()`` and navigate from there.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from . import audio, errors, gallery, interchange, spec
15
+ from .color import ColorGroup, ColorOps, NodeGraph
16
+ from .media import Asset, Bin, MediaPool, MediaPoolItem, MediaStorage
17
+ from .project import Project, ProjectNamespace
18
+ from .render import RenderJob, RenderNamespace
19
+ from .resolve import App, Resolve
20
+ from .timeline import Clip, ClipFusion, ClipQuery, Takes, Timeline, TimelineNamespace, Track
21
+
22
+ try:
23
+ from ._version import __version__
24
+ except ImportError: # pragma: no cover - generated at build time
25
+ __version__ = "0.0.0+local"
26
+
27
+ __all__ = [
28
+ "App",
29
+ "Asset",
30
+ "Bin",
31
+ "Clip",
32
+ "ClipFusion",
33
+ "ClipQuery",
34
+ "ColorGroup",
35
+ "ColorOps",
36
+ "MediaPool",
37
+ "MediaPoolItem",
38
+ "MediaStorage",
39
+ "NodeGraph",
40
+ "Project",
41
+ "ProjectNamespace",
42
+ "RenderJob",
43
+ "RenderNamespace",
44
+ "Resolve",
45
+ "Takes",
46
+ "Timeline",
47
+ "TimelineNamespace",
48
+ "Track",
49
+ "__version__",
50
+ "audio",
51
+ "errors",
52
+ "gallery",
53
+ "interchange",
54
+ "spec",
55
+ ]
@@ -0,0 +1,8 @@
1
+ """Make ``python -m dvr`` an alias for the CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .cli.main import main
6
+
7
+ if __name__ == "__main__":
8
+ main()
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.0'
22
+ __version_tuple__ = version_tuple = (0, 1, 0)
23
+
24
+ __commit_id__ = commit_id = None
dvr-0.1.0/dvr/_wrap.py ADDED
@@ -0,0 +1,68 @@
1
+ """Internal helpers shared by every domain wrapper.
2
+
3
+ The Resolve API is famously inconsistent: methods can return ``None`` for
4
+ "not found", "wrong page", "no current project", or genuine errors — with
5
+ no way to distinguish. The helpers here let domain wrappers collapse those
6
+ cases into a structured ``DvrError`` with a useful diagnosis.
7
+
8
+ Nothing here is part of the public API.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from collections.abc import Callable
14
+ from typing import Any, TypeVar
15
+
16
+ from . import errors
17
+
18
+ T = TypeVar("T")
19
+
20
+
21
+ def require(
22
+ value: T | None,
23
+ *,
24
+ error: type[errors.DvrError] = errors.DvrError,
25
+ message: str,
26
+ cause: str | None = None,
27
+ fix: str | None = None,
28
+ state: dict[str, Any] | None = None,
29
+ ) -> T:
30
+ """Assert ``value is not None`` or raise a structured error.
31
+
32
+ Use this around any raw API call that can return ``None`` to signal
33
+ failure. ``cause``/``fix``/``state`` flow into the resulting exception.
34
+ """
35
+ if value is None:
36
+ raise error(message, cause=cause, fix=fix, state=state)
37
+ return value
38
+
39
+
40
+ def safe_call(
41
+ fn: Callable[[], T],
42
+ *,
43
+ error: type[errors.DvrError] = errors.DvrError,
44
+ message: str,
45
+ cause: str | None = None,
46
+ fix: str | None = None,
47
+ state: dict[str, Any] | None = None,
48
+ ) -> T:
49
+ """Run a raw API call and translate exceptions into a ``DvrError``.
50
+
51
+ The Resolve API occasionally raises bare ``RuntimeError`` from C++.
52
+ Catch broadly and re-surface with diagnostic context.
53
+ """
54
+ try:
55
+ result = fn()
56
+ except errors.DvrError:
57
+ raise
58
+ except Exception as exc:
59
+ raise error(
60
+ message,
61
+ cause=cause or f"underlying API raised {type(exc).__name__}: {exc}",
62
+ fix=fix,
63
+ state=state,
64
+ ) from exc
65
+ return require(result, error=error, message=message, cause=cause, fix=fix, state=state)
66
+
67
+
68
+ __all__ = ["require", "safe_call"]