moveai-mocap-python 0.18.3__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.
Files changed (92) hide show
  1. moveai_mocap_python-0.18.3/PKG-INFO +55 -0
  2. moveai_mocap_python-0.18.3/README.md +34 -0
  3. moveai_mocap_python-0.18.3/moveai_mocap/__init__.py +1 -0
  4. moveai_mocap_python-0.18.3/moveai_mocap/compute/__init__.py +1 -0
  5. moveai_mocap_python-0.18.3/moveai_mocap/compute/base.py +41 -0
  6. moveai_mocap_python-0.18.3/moveai_mocap/compute/ec2.py +104 -0
  7. moveai_mocap_python-0.18.3/moveai_mocap/compute/enums/__init__.py +1 -0
  8. moveai_mocap_python-0.18.3/moveai_mocap/compute/enums/ec2.py +12 -0
  9. moveai_mocap_python-0.18.3/moveai_mocap/compute/local_run.py +55 -0
  10. moveai_mocap_python-0.18.3/moveai_mocap/compute/messages.py +6 -0
  11. moveai_mocap_python-0.18.3/moveai_mocap/compute/models/__init__.py +1 -0
  12. moveai_mocap_python-0.18.3/moveai_mocap/compute/models/ec2.py +48 -0
  13. moveai_mocap_python-0.18.3/moveai_mocap/compute/models/region.py +418 -0
  14. moveai_mocap_python-0.18.3/moveai_mocap/compute/services/__init__.py +1 -0
  15. moveai_mocap_python-0.18.3/moveai_mocap/compute/services/boto3/__init__.py +1 -0
  16. moveai_mocap_python-0.18.3/moveai_mocap/compute/services/boto3/base.py +5 -0
  17. moveai_mocap_python-0.18.3/moveai_mocap/compute/services/boto3/ec2.py +105 -0
  18. moveai_mocap_python-0.18.3/moveai_mocap/compute/services/boto3/iam.py +39 -0
  19. moveai_mocap_python-0.18.3/moveai_mocap/errors/__init__.py +1 -0
  20. moveai_mocap_python-0.18.3/moveai_mocap/errors/base.py +5 -0
  21. moveai_mocap_python-0.18.3/moveai_mocap/errors/ec2.py +17 -0
  22. moveai_mocap_python-0.18.3/moveai_mocap/errors/local_run.py +7 -0
  23. moveai_mocap_python-0.18.3/moveai_mocap/logging/__init__.py +1 -0
  24. moveai_mocap_python-0.18.3/moveai_mocap/logging/logger.py +14 -0
  25. moveai_mocap_python-0.18.3/moveai_mocap/models/__init__.py +1 -0
  26. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/__init__.py +1 -0
  27. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/actor.py +24 -0
  28. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/actor_mapping.py +20 -0
  29. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/defaults.py +7 -0
  30. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/field_types.py +13 -0
  31. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/runs/__init__.py +1 -0
  32. moveai_mocap_python-0.18.3/moveai_mocap/models/actors/runs/actor_skeleton.py +54 -0
  33. moveai_mocap_python-0.18.3/moveai_mocap/models/base/__init__.py +1 -0
  34. moveai_mocap_python-0.18.3/moveai_mocap/models/base/move_model.py +13 -0
  35. moveai_mocap_python-0.18.3/moveai_mocap/models/base/run.py +92 -0
  36. moveai_mocap_python-0.18.3/moveai_mocap/models/base/volume.py +39 -0
  37. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/__init__.py +1 -0
  38. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/camera_settings.py +71 -0
  39. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/capture.py +173 -0
  40. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/capture_device.py +23 -0
  41. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/capture_input.py +34 -0
  42. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/defaults.py +10 -0
  43. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/field_types.py +15 -0
  44. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/serializers/__init__.py +1 -0
  45. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/serializers/capture_inputs.py +24 -0
  46. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/__init__.py +1 -0
  47. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/base.py +24 -0
  48. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/clap_audio.py +27 -0
  49. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/enums/__init__.py +1 -0
  50. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/enums/sync_method.py +10 -0
  51. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/sync_methods/timecode.py +17 -0
  52. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/validators/__init__.py +1 -0
  53. moveai_mocap_python-0.18.3/moveai_mocap/models/captures/validators/camera_settings.py +5 -0
  54. moveai_mocap_python-0.18.3/moveai_mocap/models/field_types.py +9 -0
  55. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/__init__.py +1 -0
  56. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/defaults.py +3 -0
  57. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/enums/__init__.py +1 -0
  58. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/enums/mocap_model.py +14 -0
  59. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/field_types.py +22 -0
  60. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/options.py +38 -0
  61. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/runs/__init__.py +1 -0
  62. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/runs/mocap.py +298 -0
  63. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/validators/__init__.py +1 -0
  64. moveai_mocap_python-0.18.3/moveai_mocap/models/motion/validators/clip_window.py +39 -0
  65. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/__init__.py +1 -0
  66. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/base.py +30 -0
  67. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/enums/__init__.py +1 -0
  68. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/enums/service.py +10 -0
  69. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/local.py +12 -0
  70. moveai_mocap_python-0.18.3/moveai_mocap/models/notifiers/sns.py +16 -0
  71. moveai_mocap_python-0.18.3/moveai_mocap/models/resources/__init__.py +1 -0
  72. moveai_mocap_python-0.18.3/moveai_mocap/models/resources/enums/__init__.py +1 -0
  73. moveai_mocap_python-0.18.3/moveai_mocap/models/resources/enums/resource_type.py +145 -0
  74. moveai_mocap_python-0.18.3/moveai_mocap/models/resources/enums/service.py +10 -0
  75. moveai_mocap_python-0.18.3/moveai_mocap/models/resources/resource.py +46 -0
  76. moveai_mocap_python-0.18.3/moveai_mocap/models/run_type.py +13 -0
  77. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/__init__.py +1 -0
  78. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/enums/__init__.py +1 -0
  79. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/enums/area.py +12 -0
  80. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/runs/__init__.py +1 -0
  81. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/runs/actor.py +21 -0
  82. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/runs/aruco.py +28 -0
  83. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/runs/checkerboard.py +12 -0
  84. moveai_mocap_python-0.18.3/moveai_mocap/models/volumes/runs/defaults.py +4 -0
  85. moveai_mocap_python-0.18.3/moveai_mocap/py.typed +0 -0
  86. moveai_mocap_python-0.18.3/moveai_mocap/settings/__init__.py +1 -0
  87. moveai_mocap_python-0.18.3/moveai_mocap/settings/base.py +35 -0
  88. moveai_mocap_python-0.18.3/moveai_mocap/utils/__init__.py +1 -0
  89. moveai_mocap_python-0.18.3/moveai_mocap/utils/duplicates.py +20 -0
  90. moveai_mocap_python-0.18.3/moveai_mocap/validators/__init__.py +1 -0
  91. moveai_mocap_python-0.18.3/moveai_mocap/validators/uri_prefix.py +17 -0
  92. moveai_mocap_python-0.18.3/pyproject.toml +54 -0
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.1
2
+ Name: moveai-mocap-python
3
+ Version: 0.18.3
4
+ Summary:
5
+ License: #
6
+ Author: Ben Hastings
7
+ Author-email: ben@move.ai
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: License :: Other/Proprietary License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: boto3 (>=1.34.48,<2.0.0)
16
+ Requires-Dist: boto3-stubs[ec2,iam] (>=1.34.49,<2.0.0)
17
+ Requires-Dist: pydantic (>=2.6.1,<3.0.0)
18
+ Requires-Dist: pydantic-settings (>=2.2.1,<3.0.0)
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Move AI Mocap SDK
22
+
23
+ This SDK allows you to use Python to define and run Move AI Engine jobs. It currently supports running jobs on AWS, based on the availability of AMIs in your EC2 environment.
24
+
25
+ ### Requirements
26
+ Python 3.10 or higher.
27
+
28
+ ### Installation
29
+
30
+ #### With poetry
31
+
32
+ ```bash
33
+ poetry add moveai-mocap-python
34
+ ```
35
+
36
+ #### With pip
37
+
38
+ ```bash
39
+ pip install moveai-mocap-python
40
+ ```
41
+
42
+ ## Quickstart
43
+
44
+ See the [docs](https://move-ai.github.io/moveai-mocap-python/) for more detailed information.
45
+
46
+ ### Examples
47
+
48
+ See the [multi camera example](https://move-ai.github.io/moveai-mocap-python/quickstart/multicam.html).
49
+
50
+ See the [single camera example](https://move-ai.github.io/moveai-mocap-python/quickstart/singlecam.html).
51
+
52
+ ## License
53
+
54
+ This project is proprietary. All rights reserved.
55
+
@@ -0,0 +1,34 @@
1
+ # Move AI Mocap SDK
2
+
3
+ This SDK allows you to use Python to define and run Move AI Engine jobs. It currently supports running jobs on AWS, based on the availability of AMIs in your EC2 environment.
4
+
5
+ ### Requirements
6
+ Python 3.10 or higher.
7
+
8
+ ### Installation
9
+
10
+ #### With poetry
11
+
12
+ ```bash
13
+ poetry add moveai-mocap-python
14
+ ```
15
+
16
+ #### With pip
17
+
18
+ ```bash
19
+ pip install moveai-mocap-python
20
+ ```
21
+
22
+ ## Quickstart
23
+
24
+ See the [docs](https://move-ai.github.io/moveai-mocap-python/) for more detailed information.
25
+
26
+ ### Examples
27
+
28
+ See the [multi camera example](https://move-ai.github.io/moveai-mocap-python/quickstart/multicam.html).
29
+
30
+ See the [single camera example](https://move-ai.github.io/moveai-mocap-python/quickstart/singlecam.html).
31
+
32
+ ## License
33
+
34
+ This project is proprietary. All rights reserved.
@@ -0,0 +1 @@
1
+ """Move.ai mocap SDK."""
@@ -0,0 +1 @@
1
+ """Models for interacting with compute."""
@@ -0,0 +1,41 @@
1
+ """Base model for compute."""
2
+
3
+ import json
4
+ from typing import Any
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from moveai_mocap.models.base.run import BaseRunModel
9
+ from moveai_mocap.models.notifiers.base import BaseNotifier
10
+
11
+
12
+ class BaseComputeManager(BaseModel):
13
+ """Base model for the engine."""
14
+
15
+ notifier: BaseNotifier
16
+
17
+ def build_run(self, run: BaseRunModel) -> str:
18
+ """For the given run model add the notifier and return the model dump as json.
19
+
20
+ Args:
21
+ run: The run to build.
22
+
23
+ Returns:
24
+ The run with the notifier class, dumped as JSON
25
+ """
26
+ # We don't use `model_dump_json` as we need to add the notifier to the model dump
27
+ dumped_run = run.as_run()
28
+ # Add the notifier to the dumped run
29
+ dumped_run["notifier"] = self.notifier.model_dump(mode="json")
30
+ return json.dumps(dumped_run)
31
+
32
+ def provision(self, run: BaseRunModel) -> Any:
33
+ """Launch a compute instance for the appropriate compute class.
34
+
35
+ Args:
36
+ run: The run object that the instance is being provisioned for
37
+
38
+ Raises:
39
+ NotImplementedError: Must be implemented by subclass.
40
+ """
41
+ raise NotImplementedError("This method must be implemented in the subclass.")
@@ -0,0 +1,104 @@
1
+ """A class that allows processing using an ec2 backend."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ from contextlib import suppress
8
+ from enum import Enum
9
+ from typing import Type, cast
10
+
11
+ from botocore.client import BaseClient
12
+ from mypy_boto3_iam import IAMClient
13
+ from pydantic import ConfigDict, Field, PrivateAttr, model_validator
14
+
15
+ from moveai_mocap.compute.base import BaseComputeManager
16
+ from moveai_mocap.compute.enums.ec2 import InstanceTypeEnum
17
+ from moveai_mocap.compute.models.region import Region
18
+ from moveai_mocap.compute.services.boto3.iam import IamBoto3Service
19
+ from moveai_mocap.errors import ec2 as ec2_errors
20
+ from moveai_mocap.errors.base import MoveError
21
+ from moveai_mocap.logging.logger import get_logger
22
+ from moveai_mocap.models.base.run import BaseRunModel
23
+
24
+
25
+ class EC2ComputeManager(BaseComputeManager):
26
+ """The ec2 compute class."""
27
+
28
+ iam_instance_profile_name: str = Field(
29
+ description="The instance profile name that the EC2 instance should use.",
30
+ )
31
+ regions: list[Region] = Field(
32
+ description="List of regions to be used.",
33
+ )
34
+ dry_run: bool = Field(
35
+ default=False,
36
+ description="Checks whether you have the required permissions for the action, without actually making the request, and provides an error response",
37
+ )
38
+ instance_initiated_shutdown_behaviour: str = Field(
39
+ default="stop",
40
+ description="Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown)",
41
+ )
42
+ instance_types: Type[Enum] = Field(
43
+ default=InstanceTypeEnum,
44
+ description="An enum of EC2 instance types. See `InstanceTypeEnum` for more information.",
45
+ )
46
+ iam_boto3_client: BaseClient = Field(
47
+ description="Boto3 client instance which points to `iam` service.",
48
+ )
49
+
50
+ model_config = ConfigDict(
51
+ # Allow arbitrary types to be assigned to the model (iam_boto3_client)
52
+ # This is because pydantic can't build its schema with iam_boto3_client by default.
53
+ arbitrary_types_allowed=True,
54
+ )
55
+
56
+ _iam_client: IamBoto3Service
57
+ _logger: logging.Logger = PrivateAttr(default_factory=get_logger)
58
+
59
+ @model_validator(mode="after")
60
+ def instantiate_private_attributes(self) -> EC2ComputeManager:
61
+ """Instantiate the private attributes used on this compute class.
62
+
63
+ Returns:
64
+ The validated object
65
+ """
66
+ self._iam_client = IamBoto3Service(
67
+ boto3_client=cast(IAMClient, self.iam_boto3_client),
68
+ )
69
+ return self
70
+
71
+ def provision(self, run: BaseRunModel) -> dict[str, str]:
72
+ """Launch an EC2 instance.
73
+
74
+ Args:
75
+ run: The run object that the instance is being provisioned for
76
+
77
+ Raises:
78
+ MoveFailedToStartEc2InstanceError: If instances cannot be started
79
+
80
+ Returns:
81
+ The response from the started instance
82
+ """
83
+ user_data = json.dumps(
84
+ {
85
+ "settings": self.build_run(run),
86
+ "shutdown": "shutdown",
87
+ },
88
+ )
89
+ instance_profile_id = self._iam_client.get_instance_profile(
90
+ instance_profile_name=self.iam_instance_profile_name,
91
+ )
92
+ for region in self.regions:
93
+ with suppress(MoveError):
94
+ return region.attempt_instance_placement(
95
+ instance_types=self.instance_types,
96
+ iam_instance_profile_name=self.iam_instance_profile_name,
97
+ instance_initiated_shutdown_behaviour=self.instance_initiated_shutdown_behaviour,
98
+ instance_profile_id=instance_profile_id,
99
+ user_data=user_data,
100
+ dry_run=self.dry_run,
101
+ ).model_dump()
102
+ raise ec2_errors.MoveFailedToStartEc2InstanceError(
103
+ "Failed to start EC2 instance in all regions, subnets and instance types.",
104
+ )
@@ -0,0 +1 @@
1
+ """Enums for use in the compute."""
@@ -0,0 +1,12 @@
1
+ """The AWS EC2 instance types to use - in order."""
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class InstanceTypeEnum(Enum):
7
+ """The AWS EC2 instance types to use - in order."""
8
+
9
+ g6_xlarge: str = "g6.xlarge"
10
+ g6_2xlarge: str = "g6.2xlarge"
11
+ g6_4xlarge: str = "g6.4xlarge"
12
+ g6_8xlarge: str = "g6.8xlarge"
@@ -0,0 +1,55 @@
1
+ """A class that allows processing using a local backend."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import subprocess # noqa: S404
7
+ import tempfile
8
+
9
+ from pydantic import ConfigDict, Field, PrivateAttr
10
+
11
+ from moveai_mocap.compute.base import BaseComputeManager
12
+ from moveai_mocap.errors import local_run as local_run_errors
13
+ from moveai_mocap.logging.logger import get_logger
14
+ from moveai_mocap.models.base.run import BaseRunModel
15
+
16
+
17
+ class LocalComputeManager(BaseComputeManager):
18
+ """The local compute class."""
19
+
20
+ dry_run: bool = Field(
21
+ default=False,
22
+ description="Checks whether you have the required permissions for the action, without actually making the request, and provides an error response",
23
+ )
24
+
25
+ model_config = ConfigDict(
26
+ # Allow arbitrary types to be assigned to the model (iam_boto3_client)
27
+ # This is because pydantic can't build its schema with iam_boto3_client by default.
28
+ arbitrary_types_allowed=True,
29
+ )
30
+
31
+ _logger: logging.Logger = PrivateAttr(default_factory=get_logger)
32
+
33
+ def provision(self, run: BaseRunModel) -> dict[str, str]:
34
+ """Launch a local instance.
35
+
36
+ Args:
37
+ run: The run object that the run is being provisioned for
38
+
39
+ Raises:
40
+ MoveFailedToStartLocalRunError: If local run cannot be started
41
+
42
+ Returns:
43
+ The response from the run
44
+ """
45
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as settings_file:
46
+ settings_file.write(self.build_run(run))
47
+ settings_file.flush()
48
+ res = subprocess.run( # noqa: S603
49
+ ["/usr/local/bin/start_pipeline", settings_file.file.name],
50
+ )
51
+ if res.returncode == 0:
52
+ return {"exit": "0"}
53
+ raise local_run_errors.MoveFailedToStartLocalRunError(
54
+ "Failed to start local run",
55
+ )
@@ -0,0 +1,6 @@
1
+ """Centralised file for storing error messages."""
2
+
3
+ FAILED_TO_START_WITHIN_REGION_MESSAGE = "{0}. {1}".format(
4
+ "Failed to start instance type {instance_type} on subnet {subnet} in region {region}",
5
+ "Attempting the next subnet.",
6
+ )
@@ -0,0 +1 @@
1
+ """Models for compute."""
@@ -0,0 +1,48 @@
1
+ """Models for EC2 compute."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+
8
+ class Filter(BaseModel):
9
+ """Filter Schema."""
10
+
11
+ Name: str
12
+ Values: List[Any]
13
+
14
+
15
+ class ModifyAttribute(BaseModel):
16
+ """Modify attribute schema."""
17
+
18
+ InstanceId: str
19
+ UserData: dict[str, Any]
20
+
21
+
22
+ class InstanceAttributes(BaseModel):
23
+ """Instance Attribute schema."""
24
+
25
+ ImageId: str
26
+ MinCount: int = Field(default=1)
27
+ MaxCount: int = Field(default=1)
28
+ InstanceType: str
29
+ DryRun: bool
30
+ SecurityGroupIds: List[str]
31
+ SubnetId: str
32
+ InstanceInitiatedShutdownBehavior: str
33
+ CapacityReservationSpecification: Dict[str, str] = Field(
34
+ default={
35
+ "CapacityReservationPreference": "open",
36
+ },
37
+ )
38
+ UserData: Optional[Any] = Field(default=None)
39
+ IamInstanceProfile: Dict[str, str]
40
+ MetadataOptions: Dict[str, str] = Field(default={"HttpTokens": "required"})
41
+
42
+
43
+ class EC2ProvisionResponse(BaseModel):
44
+ """The response from the call to `provision`."""
45
+
46
+ instance_id: str
47
+ instance_type: str
48
+ region_name: str