inMotion Python SDK

 1from inmotion.api import (
 2    InMotionSession,
 3    InMotionAccounts,
 4    InMotionActivities,
 5    InMotionActivityConfig,
 6    InMotionApiKeys,
 7    InMotionAudit,
 8    InMotionDataStream,
 9    InMotionDevKeys,
10    InMotionEvents,
11    InMotionFolio,
12    InMotionModel,
13    InMotionMqttDeployment,
14    InMotionRasterOverlay,
15    InMotionShape,
16    InMotionShapeGenerator,
17    InMotionUpload,
18    InMotionUser,
19)
20
21__all__ = [
22    "InMotionSession",
23    "InMotionAccounts",
24    "InMotionActivities",
25    "InMotionActivityConfig",
26    "InMotionApiKeys",
27    "InMotionAudit",
28    "InMotionDataStream",
29    "InMotionDevKeys",
30    "InMotionEvents",
31    "InMotionFolio",
32    "InMotionModel",
33    "InMotionMqttDeployment",
34    "InMotionRasterOverlay",
35    "InMotionShape",
36    "InMotionShapeGenerator",
37    "InMotionUpload",
38    "InMotionUser",
39]
class InMotionSession(abc.ABC):
2481class InMotionSession(ABC):
2482    @abstractmethod
2483    def disconnect(self) -> None:
2484        """ Disconnect the session """
2485        pass
2486
2487    @abstractmethod
2488    def activities(self) -> InMotionActivities:
2489        """ Retrieve the activities interface for the session
2490
2491        :return: The activities interface
2492        :rtype: InMotionActivities
2493        """
2494        pass
2495
2496    @abstractmethod
2497    def accounts(self) -> InMotionAccounts:
2498        """ Retrieve the account management interface for the session
2499
2500        :return: The account management interface
2501        :rtype: InMotionAccounts
2502        """
2503        pass
2504
2505    @abstractmethod
2506    def events(self) -> InMotionEvents:
2507        """ Retrieve the event management interface for the session
2508
2509        :return: The event management interface
2510        :rtype: InMotionEvents
2511        """
2512        pass
2513
2514    @abstractmethod
2515    def dev_keys(self) -> InMotionDevKeys:
2516        """ Retrieve the developer key management interface for the session
2517
2518        :return: The developer key management interface
2519        :rtype: InMotionDevKeys
2520        """
2521        pass
2522
2523    @abstractmethod
2524    def api_keys(self) -> InMotionApiKeys:
2525        """ Retrieve the API key management interface for the session
2526
2527        :return: The API key management interface
2528        :rtype: InMotionApiKeys
2529        """
2530        pass
2531
2532    @abstractmethod
2533    def user(self) -> InMotionUser:
2534        """ Retrieve the user management interface for the session
2535
2536        :return: The user management interface
2537        :rtype: InMotionUser
2538        """
2539        pass
2540
2541    @abstractmethod
2542    def activity_config(self) -> InMotionActivityConfig:
2543        """ Retrieve the activity configuration interface for the session
2544
2545        :return: The activity configuration interface
2546        :rtype: InMotionActivityConfig
2547        """
2548        pass
2549
2550    @abstractmethod
2551    def upload(self) -> InMotionUpload:
2552        """ Retrieve the upload management interface for the session
2553
2554        :return: The upload management interface
2555        :rtype: InMotionUpload
2556        """
2557        pass
2558
2559    @abstractmethod
2560    def folio(self) -> InMotionFolio:
2561        """ Retrieve the folio management interface for the session
2562
2563        :return: The folio management interface
2564        :rtype: InMotionFolio
2565        """
2566        pass
2567
2568    @abstractmethod
2569    def data_stream(self) -> InMotionDataStream:
2570        """ Retrieve the data stream management interface for the session
2571
2572        :return: The data stream management interface
2573        :rtype: InMotionDataStream
2574        """
2575        pass
2576
2577    @abstractmethod
2578    def shape(self) -> InMotionShape:
2579        """ Retrieve the shape management interface for the session
2580
2581        :return: The shape management interface
2582        :rtype: InMotionShape
2583        """
2584        pass
2585
2586    @abstractmethod
2587    def shape_generator(self) -> InMotionShapeGenerator:
2588        """ Retrieve the shape generator management interface for the session
2589
2590        :return: The shape generator management interface
2591        :rtype: InMotionShapeGenerator
2592        """
2593        pass
2594
2595    @abstractmethod
2596    def raster_overlay(self) -> InMotionRasterOverlay:
2597        """ Retrieve the raster overlay management interface for the session
2598
2599        :return: The raster overlay management interface
2600        :rtype: InMotionRasterOverlay
2601        """
2602        pass
2603
2604    @abstractmethod
2605    def audit(self) -> InMotionAudit:
2606        """ Retrieve the external audit interface for the session
2607
2608        :return: The external audit interface
2609        :rtype: InMotionAudit
2610        """
2611        pass
2612
2613    @abstractmethod
2614    def model(self) -> InMotionModel:
2615        """ Retrieve the model catalogue interface for the session
2616
2617        :return: The model catalogue interface
2618        :rtype: InMotionModel
2619        """
2620        pass
2621
2622    @abstractmethod
2623    def mqtt_deployment(self) -> InMotionMqttDeployment:
2624        """ Retrieve the MQTT ingestion deployment interface for the session
2625
2626        :return: The MQTT ingestion deployment interface
2627        :rtype: InMotionMqttDeployment
2628        """
2629        pass
2630
2631    @property
2632    @abstractmethod
2633    def is_connected(self) -> bool:
2634        """ Determine if the session is connected
2635
2636        :return: True if the session is connected, False otherwise
2637        :rtype: bool
2638        """
2639        pass
2640
2641    @property
2642    @abstractmethod
2643    def base_url(self) -> str:
2644        """ The base URL for the inMotion instance
2645
2646        :return: The base URL
2647        :rtype: str
2648        """
2649        pass
2650
2651    @property
2652    @abstractmethod
2653    def api_path(self) -> str:
2654        """ The API path for the inMotion instance
2655
2656        :return: The API path
2657        :rtype: str
2658        """
2659        pass
2660
2661    @property
2662    @abstractmethod
2663    def account(self) -> str:
2664        """ The account associated with the session
2665
2666        :return: The account
2667        :rtype: str
2668        """
2669        pass
2670
2671    @abstractmethod
2672    def build_headers(self, content: str) -> dict[str, str]:
2673        """ Build the headers for a request to inMotion
2674
2675        :param str content: The content to be sent in the request
2676        :return: The headers for the request
2677        :rtype: dict[str, str]
2678        """
2679        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def disconnect(self) -> None:
2482    @abstractmethod
2483    def disconnect(self) -> None:
2484        """ Disconnect the session """
2485        pass

Disconnect the session

@abstractmethod
def activities(self) -> InMotionActivities:
2487    @abstractmethod
2488    def activities(self) -> InMotionActivities:
2489        """ Retrieve the activities interface for the session
2490
2491        :return: The activities interface
2492        :rtype: InMotionActivities
2493        """
2494        pass

Retrieve the activities interface for the session

Returns

The activities interface

@abstractmethod
def accounts(self) -> InMotionAccounts:
2496    @abstractmethod
2497    def accounts(self) -> InMotionAccounts:
2498        """ Retrieve the account management interface for the session
2499
2500        :return: The account management interface
2501        :rtype: InMotionAccounts
2502        """
2503        pass

Retrieve the account management interface for the session

Returns

The account management interface

@abstractmethod
def events(self) -> InMotionEvents:
2505    @abstractmethod
2506    def events(self) -> InMotionEvents:
2507        """ Retrieve the event management interface for the session
2508
2509        :return: The event management interface
2510        :rtype: InMotionEvents
2511        """
2512        pass

Retrieve the event management interface for the session

Returns

The event management interface

@abstractmethod
def dev_keys(self) -> InMotionDevKeys:
2514    @abstractmethod
2515    def dev_keys(self) -> InMotionDevKeys:
2516        """ Retrieve the developer key management interface for the session
2517
2518        :return: The developer key management interface
2519        :rtype: InMotionDevKeys
2520        """
2521        pass

Retrieve the developer key management interface for the session

Returns

The developer key management interface

@abstractmethod
def api_keys(self) -> InMotionApiKeys:
2523    @abstractmethod
2524    def api_keys(self) -> InMotionApiKeys:
2525        """ Retrieve the API key management interface for the session
2526
2527        :return: The API key management interface
2528        :rtype: InMotionApiKeys
2529        """
2530        pass

Retrieve the API key management interface for the session

Returns

The API key management interface

@abstractmethod
def user(self) -> InMotionUser:
2532    @abstractmethod
2533    def user(self) -> InMotionUser:
2534        """ Retrieve the user management interface for the session
2535
2536        :return: The user management interface
2537        :rtype: InMotionUser
2538        """
2539        pass

Retrieve the user management interface for the session

Returns

The user management interface

@abstractmethod
def activity_config(self) -> InMotionActivityConfig:
2541    @abstractmethod
2542    def activity_config(self) -> InMotionActivityConfig:
2543        """ Retrieve the activity configuration interface for the session
2544
2545        :return: The activity configuration interface
2546        :rtype: InMotionActivityConfig
2547        """
2548        pass

Retrieve the activity configuration interface for the session

Returns

The activity configuration interface

@abstractmethod
def upload(self) -> InMotionUpload:
2550    @abstractmethod
2551    def upload(self) -> InMotionUpload:
2552        """ Retrieve the upload management interface for the session
2553
2554        :return: The upload management interface
2555        :rtype: InMotionUpload
2556        """
2557        pass

Retrieve the upload management interface for the session

Returns

The upload management interface

@abstractmethod
def folio(self) -> InMotionFolio:
2559    @abstractmethod
2560    def folio(self) -> InMotionFolio:
2561        """ Retrieve the folio management interface for the session
2562
2563        :return: The folio management interface
2564        :rtype: InMotionFolio
2565        """
2566        pass

Retrieve the folio management interface for the session

Returns

The folio management interface

@abstractmethod
def data_stream(self) -> InMotionDataStream:
2568    @abstractmethod
2569    def data_stream(self) -> InMotionDataStream:
2570        """ Retrieve the data stream management interface for the session
2571
2572        :return: The data stream management interface
2573        :rtype: InMotionDataStream
2574        """
2575        pass

Retrieve the data stream management interface for the session

Returns

The data stream management interface

@abstractmethod
def shape(self) -> InMotionShape:
2577    @abstractmethod
2578    def shape(self) -> InMotionShape:
2579        """ Retrieve the shape management interface for the session
2580
2581        :return: The shape management interface
2582        :rtype: InMotionShape
2583        """
2584        pass

Retrieve the shape management interface for the session

Returns

The shape management interface

@abstractmethod
def shape_generator(self) -> InMotionShapeGenerator:
2586    @abstractmethod
2587    def shape_generator(self) -> InMotionShapeGenerator:
2588        """ Retrieve the shape generator management interface for the session
2589
2590        :return: The shape generator management interface
2591        :rtype: InMotionShapeGenerator
2592        """
2593        pass

Retrieve the shape generator management interface for the session

Returns

The shape generator management interface

@abstractmethod
def raster_overlay(self) -> InMotionRasterOverlay:
2595    @abstractmethod
2596    def raster_overlay(self) -> InMotionRasterOverlay:
2597        """ Retrieve the raster overlay management interface for the session
2598
2599        :return: The raster overlay management interface
2600        :rtype: InMotionRasterOverlay
2601        """
2602        pass

Retrieve the raster overlay management interface for the session

Returns

The raster overlay management interface

@abstractmethod
def audit(self) -> InMotionAudit:
2604    @abstractmethod
2605    def audit(self) -> InMotionAudit:
2606        """ Retrieve the external audit interface for the session
2607
2608        :return: The external audit interface
2609        :rtype: InMotionAudit
2610        """
2611        pass

Retrieve the external audit interface for the session

Returns

The external audit interface

@abstractmethod
def model(self) -> InMotionModel:
2613    @abstractmethod
2614    def model(self) -> InMotionModel:
2615        """ Retrieve the model catalogue interface for the session
2616
2617        :return: The model catalogue interface
2618        :rtype: InMotionModel
2619        """
2620        pass

Retrieve the model catalogue interface for the session

Returns

The model catalogue interface

@abstractmethod
def mqtt_deployment(self) -> InMotionMqttDeployment:
2622    @abstractmethod
2623    def mqtt_deployment(self) -> InMotionMqttDeployment:
2624        """ Retrieve the MQTT ingestion deployment interface for the session
2625
2626        :return: The MQTT ingestion deployment interface
2627        :rtype: InMotionMqttDeployment
2628        """
2629        pass

Retrieve the MQTT ingestion deployment interface for the session

Returns

The MQTT ingestion deployment interface

is_connected: bool
2631    @property
2632    @abstractmethod
2633    def is_connected(self) -> bool:
2634        """ Determine if the session is connected
2635
2636        :return: True if the session is connected, False otherwise
2637        :rtype: bool
2638        """
2639        pass

Determine if the session is connected

Returns

True if the session is connected, False otherwise

base_url: str
2641    @property
2642    @abstractmethod
2643    def base_url(self) -> str:
2644        """ The base URL for the inMotion instance
2645
2646        :return: The base URL
2647        :rtype: str
2648        """
2649        pass

The base URL for the inMotion instance

Returns

The base URL

api_path: str
2651    @property
2652    @abstractmethod
2653    def api_path(self) -> str:
2654        """ The API path for the inMotion instance
2655
2656        :return: The API path
2657        :rtype: str
2658        """
2659        pass

The API path for the inMotion instance

Returns

The API path

account: str
2661    @property
2662    @abstractmethod
2663    def account(self) -> str:
2664        """ The account associated with the session
2665
2666        :return: The account
2667        :rtype: str
2668        """
2669        pass

The account associated with the session

Returns

The account

@abstractmethod
def build_headers(self, content: str) -> dict[str, str]:
2671    @abstractmethod
2672    def build_headers(self, content: str) -> dict[str, str]:
2673        """ Build the headers for a request to inMotion
2674
2675        :param str content: The content to be sent in the request
2676        :return: The headers for the request
2677        :rtype: dict[str, str]
2678        """
2679        pass

Build the headers for a request to inMotion

Parameters
  • str content: The content to be sent in the request
Returns

The headers for the request

class InMotionAccounts(abc.ABC):
 672class InMotionAccounts(ABC):
 673    @abstractmethod
 674    def find_account(self, account_key: str) -> AccountDetailsModel:
 675        """ Find an account by its unique key
 676
 677        :param str account_key: The unique key of the account
 678        :return: The account details
 679        :rtype: AccountDetailsModel
 680        """
 681        pass
 682
 683    @abstractmethod
 684    def find_account_tags(self, account_key: str) -> AccountTagsModel:
 685        """ Find the tags associated with an account
 686
 687        :param str account_key: The unique key of the account
 688        :return: The account's tags
 689        :rtype: AccountTagsModel
 690        """
 691        pass
 692
 693    @abstractmethod
 694    def update_account(self, account_key: str, account: AccountModel) -> AccountDetailsModel:
 695        """ Update the details of an existing account
 696
 697        :param str account_key: The unique key of the account to update
 698        :param AccountModel account: The updated account definition
 699        :return: The updated account details
 700        :rtype: AccountDetailsModel
 701        """
 702        pass
 703
 704    @abstractmethod
 705    def find_account_users(self, account_key: str) -> list[AccountUserSummaryModel]:
 706        """ Retrieve the users associated with an account
 707
 708        :param str account_key: The unique key of the account
 709        :return: The users linked to the account
 710        :rtype: list[AccountUserSummaryModel]
 711        """
 712        pass
 713
 714    @abstractmethod
 715    def register_account_user(self, account_key: str, user_key: str, privileges: AccountPrivilegesModel) -> list[AccountUserSummaryModel]:
 716        """ Register a user to an account
 717
 718        :param str account_key: The unique key of the account
 719        :param str user_key: The unique key of the user to register
 720        :param AccountPrivilegesModel privileges: The privileges to grant the user on the account
 721        :return: The users linked to the account after registration
 722        :rtype: list[AccountUserSummaryModel]
 723        """
 724        pass
 725
 726    @abstractmethod
 727    def unregister_account_user(self, account_key: str, user_key: str) -> AccountUserUnregisteredModel:
 728        """ Unregister a user from an account
 729
 730        :param str account_key: The unique key of the account
 731        :param str user_key: The unique key of the user to unregister
 732        :return: The result of the unregister operation
 733        :rtype: AccountUserUnregisteredModel
 734        """
 735        pass
 736
 737    @abstractmethod
 738    def batch_update_account_users(self, account_key: str, commands: list[AccountUpdateBatchCommandModel]) -> AccountUpdateBatchResultsModel:
 739        """ Apply a batch of register, unregister, or update actions to the users of an account
 740
 741        :param str account_key: The unique key of the account
 742        :param list[AccountUpdateBatchCommandModel] commands: The batch of commands to apply
 743        :return: The results of the batch update
 744        :rtype: AccountUpdateBatchResultsModel
 745        """
 746        pass
 747
 748    @abstractmethod
 749    def create_account_only(self, account: AccountModel) -> AccountDetailsModel:
 750        """ Create a new free personal account that is not yet associated with any user
 751
 752        :param AccountModel account: The definition of the account to create
 753        :return: The created account's details
 754        :rtype: AccountDetailsModel
 755        """
 756        pass
 757
 758    @abstractmethod
 759    def mark_account_for_deletion(self, account_key: str, and_user: bool) -> AccountMarkedForDeletionModel:
 760        """ Mark an account for deletion
 761
 762        :param str account_key: The unique key of the account to mark for deletion
 763        :param bool and_user: Whether the associated user should also be marked for deletion
 764        :return: The result of the mark-for-deletion operation
 765        :rtype: AccountMarkedForDeletionModel
 766        """
 767        pass
 768
 769    @abstractmethod
 770    def find_my_accounts(self) -> dict[str, UserAccountSummaryModel]:
 771        """ Fetch the accounts associated with the authenticated user
 772
 773        :return: A map of account key to the caller's summary of that account
 774        :rtype: dict[str, UserAccountSummaryModel]
 775        """
 776        pass
 777
 778    @abstractmethod
 779    def fetch_global_device_configs(self) -> dict:
 780        """ Fetch the system-wide default Device Configs (global tier), for runtime consumers to
 781        merge with an account's own tier themselves - never merged here. Not account-scoped.
 782
 783        :return: A raw dict shaped `{ deviceConfigs: [{name, version, yaml}] }`
 784        :rtype: dict
 785        """
 786        pass
 787
 788    @abstractmethod
 789    def sync_device_configs(self, request: DeviceConfigSyncRequestModel) -> DeviceConfigSyncResultModel:
 790        """ Fetch only the Device Config changes (global tier and a set of accounts) since a
 791        given time, in one call
 792
 793        :param DeviceConfigSyncRequestModel request: The sync window and accounts to include
 794        :return: The delta - entries changed since `since`, plus tombstones
 795        :rtype: DeviceConfigSyncResultModel
 796        """
 797        pass
 798
 799    @abstractmethod
 800    def list_standard_data_types(self, account_key: str) -> list[dict]:
 801        """ List every Standard Data Type entry (global and account, each tagged its own
 802        `source`) visible to an account. Requires the "custom-sdt" account feature.
 803
 804        :param str account_key: The unique key of the account
 805        :return: Every Standard Data Type entry, as raw dicts (no fixed schema is declared server-side)
 806        :rtype: list[dict]
 807        """
 808        pass
 809
 810    @abstractmethod
 811    def create_standard_data_type(self, account_key: str, yaml_document: str) -> dict:
 812        """ Create an account-scoped Standard Data Type override. Requires the "custom-sdt"
 813        account feature. Fails if the account already has an override at the document's own
 814        `key`, or the document references an unknown `variant-type`.
 815
 816        :param str account_key: The unique key of the account
 817        :param str yaml_document: A standalone single-entry YAML document; its identity is its own `key` field
 818        :return: The created Standard Data Type entry, as a raw dict
 819        :rtype: dict
 820        """
 821        pass
 822
 823    @abstractmethod
 824    def update_standard_data_type(self, account_key: str, key: str, yaml_document: str) -> dict:
 825        """ Update an account-scoped Standard Data Type override. Fails if no override exists yet
 826        at `key` (use create instead), or if the document's own `key` field doesn't match.
 827        Requires the "custom-sdt" account feature.
 828
 829        :param str account_key: The unique key of the account
 830        :param str key: The key of the Standard Data Type override to update
 831        :param str yaml_document: The replacement standalone single-entry YAML document
 832        :return: The updated Standard Data Type entry, as a raw dict
 833        :rtype: dict
 834        """
 835        pass
 836
 837    @abstractmethod
 838    def delete_standard_data_type(self, account_key: str, key: str) -> None:
 839        """ Delete an account-scoped Standard Data Type override. Idempotent. Requires the
 840        "custom-sdt" account feature.
 841
 842        :param str account_key: The unique key of the account
 843        :param str key: The key of the Standard Data Type override to delete
 844        """
 845        pass
 846
 847    @abstractmethod
 848    def list_standard_data_variant_types(self, account_key: str) -> list[dict]:
 849        """ List every Standard Data Variant Type entry (global and account, each tagged its own
 850        `source`) visible to an account. Requires the "custom-sdt" account feature.
 851
 852        :param str account_key: The unique key of the account
 853        :return: Every Standard Data Variant Type entry, as raw dicts
 854        :rtype: list[dict]
 855        """
 856        pass
 857
 858    @abstractmethod
 859    def create_standard_data_variant_type(self, account_key: str, yaml_document: str) -> dict:
 860        """ Create an account-scoped Standard Data Variant Type override. Requires the
 861        "custom-sdt" account feature. Fails if the account already has an override at the
 862        document's own `key`.
 863
 864        :param str account_key: The unique key of the account
 865        :param str yaml_document: A standalone single-entry YAML document; its identity is its own `key` field
 866        :return: The created Standard Data Variant Type entry, as a raw dict
 867        :rtype: dict
 868        """
 869        pass
 870
 871    @abstractmethod
 872    def update_standard_data_variant_type(self, account_key: str, key: str, yaml_document: str) -> dict:
 873        """ Update an account-scoped Standard Data Variant Type override. Fails if no override
 874        exists yet at `key`, or if the document's own `key` field doesn't match. Requires the
 875        "custom-sdt" account feature.
 876
 877        :param str account_key: The unique key of the account
 878        :param str key: The key of the Standard Data Variant Type override to update
 879        :param str yaml_document: The replacement standalone single-entry YAML document
 880        :return: The updated Standard Data Variant Type entry, as a raw dict
 881        :rtype: dict
 882        """
 883        pass
 884
 885    @abstractmethod
 886    def delete_standard_data_variant_type(self, account_key: str, key: str) -> None:
 887        """ Delete an account-scoped Standard Data Variant Type override. Fails, naming the
 888        referencing Data Type keys, if any of the account's own Data Types currently reference
 889        this variant type. Idempotent otherwise. Requires the "custom-sdt" account feature.
 890
 891        :param str account_key: The unique key of the account
 892        :param str key: The key of the Standard Data Variant Type override to delete
 893        """
 894        pass
 895
 896    @abstractmethod
 897    def fetch_device_configs(self, account_key: str, preview: bool = False) -> dict:
 898        """ Fetch an account's own tier of Device Configs, for runtime consumers to merge with
 899        the global tier themselves - never merged here. Always succeeds with an empty list if
 900        nothing has been published yet.
 901
 902        :param str account_key: The unique key of the account
 903        :param bool preview: If True, serves the in-progress development version per name where
 904            one exists (falling back to published) - restricted to the account's admins/owners
 905        :return: A raw dict shaped `{ deviceConfigs: [{name, version, yaml}] }`
 906        :rtype: dict
 907        """
 908        pass
 909
 910    @abstractmethod
 911    def list_device_configs(self, account_key: str) -> dict:
 912        """ List every version of every one of the account's named Device Configs, for an
 913        editing UI. Requires the "custom-device-config" account feature.
 914
 915        :param str account_key: The unique key of the account
 916        :return: A raw dict shaped `{ deviceConfigs: [...] }`
 917        :rtype: dict
 918        """
 919        pass
 920
 921    @abstractmethod
 922    def create_device_config(self, account_key: str, yaml_document: str) -> dict:
 923        """ Validate and create a brand-new Device Config at version 1, status development.
 924        Requires the "custom-device-config" account feature. Fails if a Device Config with that
 925        name already exists for this account.
 926
 927        :param str account_key: The unique key of the account
 928        :param str yaml_document: The Device Config document; its identity is its own `profile.name` field
 929        :return: The new Device Config's id/version/status/yaml/updatedAt/updatedBy, as a raw dict
 930        :rtype: dict
 931        """
 932        pass
 933
 934    @abstractmethod
 935    def save_device_config(self, account_key: str, name: str, yaml_document: str) -> dict:
 936        """ Validate and save new content to the current development version of a named Device
 937        Config, in place. Requires the "custom-device-config" account feature. Fails if no
 938        development version is in progress.
 939
 940        :param str account_key: The unique key of the account
 941        :param str name: The name of the Device Config
 942        :param str yaml_document: The replacement Device Config document
 943        :return: The updated Device Config version, as a raw dict
 944        :rtype: dict
 945        """
 946        pass
 947
 948    @abstractmethod
 949    def delete_device_config(self, account_key: str, name: str) -> None:
 950        """ Delete every version of a named Device Config. Requires the "custom-device-config"
 951        account feature. Idempotent.
 952
 953        :param str account_key: The unique key of the account
 954        :param str name: The name of the Device Config to delete
 955        """
 956        pass
 957
 958    @abstractmethod
 959    def start_device_config_development(self, account_key: str, name: str) -> dict:
 960        """ Branch a new development version off the current published one for an existing name.
 961        Requires the "custom-device-config" account feature. Fails if the name does not exist yet
 962        (use create), a development version is already in progress, or there is no published
 963        version to branch from.
 964
 965        :param str account_key: The unique key of the account
 966        :param str name: The name of the Device Config
 967        :return: The new development version, as a raw dict
 968        :rtype: dict
 969        """
 970        pass
 971
 972    @abstractmethod
 973    def discard_device_config_development(self, account_key: str, name: str) -> None:
 974        """ Delete the current development version outright, without publishing it. Requires the
 975        "custom-device-config" account feature. Idempotent - succeeds even if none is in progress.
 976
 977        :param str account_key: The unique key of the account
 978        :param str name: The name of the Device Config
 979        """
 980        pass
 981
 982    @abstractmethod
 983    def publish_device_config(self, account_key: str, name: str, semantic_version: str) -> dict:
 984        """ Flip the current development version's status to published in place. Requires the
 985        "custom-device-config" account feature. Fails if no development version is in progress,
 986        or if `semantic_version` is not strictly greater than this name's current published
 987        semantic version (if any).
 988
 989        :param str account_key: The unique key of the account
 990        :param str name: The name of the Device Config
 991        :param str semantic_version: The human-authored major.minor.patch version for this publish
 992        :return: The now-published version, as a raw dict
 993        :rtype: dict
 994        """
 995        pass
 996
 997    @abstractmethod
 998    def withdraw_device_config(self, account_key: str, name: str, version: int) -> dict:
 999        """ Hide one published Device Config version from consumer-facing fetch/sync/search/
1000        download without deleting it. Requires the "custom-device-config" account feature. Fails
1001        if that version isn't published.
1002
1003        :param str account_key: The unique key of the account
1004        :param str name: The name of the Device Config
1005        :param int version: The published version to withdraw
1006        :return: The now-withdrawn version, as a raw dict
1007        :rtype: dict
1008        """
1009        pass
1010
1011    @abstractmethod
1012    def republish_device_config(self, account_key: str, name: str, version: int) -> dict:
1013        """ Reverse a withdraw. Requires the "custom-device-config" account feature. Idempotent -
1014        succeeds even if the version wasn't withdrawn.
1015
1016        :param str account_key: The unique key of the account
1017        :param str name: The name of the Device Config
1018        :param int version: The withdrawn version to republish
1019        :return: The now-republished version, as a raw dict
1020        :rtype: dict
1021        """
1022        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def find_account(self, account_key: str) -> inmotion.models.AccountDetailsModel:
673    @abstractmethod
674    def find_account(self, account_key: str) -> AccountDetailsModel:
675        """ Find an account by its unique key
676
677        :param str account_key: The unique key of the account
678        :return: The account details
679        :rtype: AccountDetailsModel
680        """
681        pass

Find an account by its unique key

Parameters
  • str account_key: The unique key of the account
Returns

The account details

@abstractmethod
def find_account_tags(self, account_key: str) -> inmotion.models.AccountTagsModel:
683    @abstractmethod
684    def find_account_tags(self, account_key: str) -> AccountTagsModel:
685        """ Find the tags associated with an account
686
687        :param str account_key: The unique key of the account
688        :return: The account's tags
689        :rtype: AccountTagsModel
690        """
691        pass

Find the tags associated with an account

Parameters
  • str account_key: The unique key of the account
Returns

The account's tags

@abstractmethod
def update_account( self, account_key: str, account: inmotion.models.AccountModel) -> inmotion.models.AccountDetailsModel:
693    @abstractmethod
694    def update_account(self, account_key: str, account: AccountModel) -> AccountDetailsModel:
695        """ Update the details of an existing account
696
697        :param str account_key: The unique key of the account to update
698        :param AccountModel account: The updated account definition
699        :return: The updated account details
700        :rtype: AccountDetailsModel
701        """
702        pass

Update the details of an existing account

Parameters
  • str account_key: The unique key of the account to update
  • AccountModel account: The updated account definition
Returns

The updated account details

@abstractmethod
def find_account_users(self, account_key: str) -> list[inmotion.models.AccountUserSummaryModel]:
704    @abstractmethod
705    def find_account_users(self, account_key: str) -> list[AccountUserSummaryModel]:
706        """ Retrieve the users associated with an account
707
708        :param str account_key: The unique key of the account
709        :return: The users linked to the account
710        :rtype: list[AccountUserSummaryModel]
711        """
712        pass

Retrieve the users associated with an account

Parameters
  • str account_key: The unique key of the account
Returns

The users linked to the account

@abstractmethod
def register_account_user( self, account_key: str, user_key: str, privileges: inmotion.models.AccountPrivilegesModel) -> list[inmotion.models.AccountUserSummaryModel]:
714    @abstractmethod
715    def register_account_user(self, account_key: str, user_key: str, privileges: AccountPrivilegesModel) -> list[AccountUserSummaryModel]:
716        """ Register a user to an account
717
718        :param str account_key: The unique key of the account
719        :param str user_key: The unique key of the user to register
720        :param AccountPrivilegesModel privileges: The privileges to grant the user on the account
721        :return: The users linked to the account after registration
722        :rtype: list[AccountUserSummaryModel]
723        """
724        pass

Register a user to an account

Parameters
  • str account_key: The unique key of the account
  • str user_key: The unique key of the user to register
  • AccountPrivilegesModel privileges: The privileges to grant the user on the account
Returns

The users linked to the account after registration

@abstractmethod
def unregister_account_user( self, account_key: str, user_key: str) -> inmotion.models.AccountUserUnregisteredModel:
726    @abstractmethod
727    def unregister_account_user(self, account_key: str, user_key: str) -> AccountUserUnregisteredModel:
728        """ Unregister a user from an account
729
730        :param str account_key: The unique key of the account
731        :param str user_key: The unique key of the user to unregister
732        :return: The result of the unregister operation
733        :rtype: AccountUserUnregisteredModel
734        """
735        pass

Unregister a user from an account

Parameters
  • str account_key: The unique key of the account
  • str user_key: The unique key of the user to unregister
Returns

The result of the unregister operation

@abstractmethod
def batch_update_account_users( self, account_key: str, commands: list[inmotion.models.AccountUpdateBatchCommandModel]) -> inmotion.models.AccountUpdateBatchResultsModel:
737    @abstractmethod
738    def batch_update_account_users(self, account_key: str, commands: list[AccountUpdateBatchCommandModel]) -> AccountUpdateBatchResultsModel:
739        """ Apply a batch of register, unregister, or update actions to the users of an account
740
741        :param str account_key: The unique key of the account
742        :param list[AccountUpdateBatchCommandModel] commands: The batch of commands to apply
743        :return: The results of the batch update
744        :rtype: AccountUpdateBatchResultsModel
745        """
746        pass

Apply a batch of register, unregister, or update actions to the users of an account

Parameters
  • str account_key: The unique key of the account
  • list[AccountUpdateBatchCommandModel] commands: The batch of commands to apply
Returns

The results of the batch update

@abstractmethod
def create_account_only( self, account: inmotion.models.AccountModel) -> inmotion.models.AccountDetailsModel:
748    @abstractmethod
749    def create_account_only(self, account: AccountModel) -> AccountDetailsModel:
750        """ Create a new free personal account that is not yet associated with any user
751
752        :param AccountModel account: The definition of the account to create
753        :return: The created account's details
754        :rtype: AccountDetailsModel
755        """
756        pass

Create a new free personal account that is not yet associated with any user

Parameters
  • AccountModel account: The definition of the account to create
Returns

The created account's details

@abstractmethod
def mark_account_for_deletion( self, account_key: str, and_user: bool) -> inmotion.models.AccountMarkedForDeletionModel:
758    @abstractmethod
759    def mark_account_for_deletion(self, account_key: str, and_user: bool) -> AccountMarkedForDeletionModel:
760        """ Mark an account for deletion
761
762        :param str account_key: The unique key of the account to mark for deletion
763        :param bool and_user: Whether the associated user should also be marked for deletion
764        :return: The result of the mark-for-deletion operation
765        :rtype: AccountMarkedForDeletionModel
766        """
767        pass

Mark an account for deletion

Parameters
  • str account_key: The unique key of the account to mark for deletion
  • bool and_user: Whether the associated user should also be marked for deletion
Returns

The result of the mark-for-deletion operation

@abstractmethod
def find_my_accounts(self) -> dict[str, inmotion.models.UserAccountSummaryModel]:
769    @abstractmethod
770    def find_my_accounts(self) -> dict[str, UserAccountSummaryModel]:
771        """ Fetch the accounts associated with the authenticated user
772
773        :return: A map of account key to the caller's summary of that account
774        :rtype: dict[str, UserAccountSummaryModel]
775        """
776        pass

Fetch the accounts associated with the authenticated user

Returns

A map of account key to the caller's summary of that account

@abstractmethod
def fetch_global_device_configs(self) -> dict:
778    @abstractmethod
779    def fetch_global_device_configs(self) -> dict:
780        """ Fetch the system-wide default Device Configs (global tier), for runtime consumers to
781        merge with an account's own tier themselves - never merged here. Not account-scoped.
782
783        :return: A raw dict shaped `{ deviceConfigs: [{name, version, yaml}] }`
784        :rtype: dict
785        """
786        pass

Fetch the system-wide default Device Configs (global tier), for runtime consumers to merge with an account's own tier themselves - never merged here. Not account-scoped.

Returns

A raw dict shaped { deviceConfigs: [{name, version, yaml}] }

@abstractmethod
def sync_device_configs( self, request: inmotion.models.DeviceConfigSyncRequestModel) -> inmotion.models.DeviceConfigSyncResultModel:
788    @abstractmethod
789    def sync_device_configs(self, request: DeviceConfigSyncRequestModel) -> DeviceConfigSyncResultModel:
790        """ Fetch only the Device Config changes (global tier and a set of accounts) since a
791        given time, in one call
792
793        :param DeviceConfigSyncRequestModel request: The sync window and accounts to include
794        :return: The delta - entries changed since `since`, plus tombstones
795        :rtype: DeviceConfigSyncResultModel
796        """
797        pass

Fetch only the Device Config changes (global tier and a set of accounts) since a given time, in one call

Parameters
  • DeviceConfigSyncRequestModel request: The sync window and accounts to include
Returns

The delta - entries changed since since, plus tombstones

@abstractmethod
def list_standard_data_types(self, account_key: str) -> list[dict]:
799    @abstractmethod
800    def list_standard_data_types(self, account_key: str) -> list[dict]:
801        """ List every Standard Data Type entry (global and account, each tagged its own
802        `source`) visible to an account. Requires the "custom-sdt" account feature.
803
804        :param str account_key: The unique key of the account
805        :return: Every Standard Data Type entry, as raw dicts (no fixed schema is declared server-side)
806        :rtype: list[dict]
807        """
808        pass

List every Standard Data Type entry (global and account, each tagged its own source) visible to an account. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
Returns

Every Standard Data Type entry, as raw dicts (no fixed schema is declared server-side)

@abstractmethod
def create_standard_data_type(self, account_key: str, yaml_document: str) -> dict:
810    @abstractmethod
811    def create_standard_data_type(self, account_key: str, yaml_document: str) -> dict:
812        """ Create an account-scoped Standard Data Type override. Requires the "custom-sdt"
813        account feature. Fails if the account already has an override at the document's own
814        `key`, or the document references an unknown `variant-type`.
815
816        :param str account_key: The unique key of the account
817        :param str yaml_document: A standalone single-entry YAML document; its identity is its own `key` field
818        :return: The created Standard Data Type entry, as a raw dict
819        :rtype: dict
820        """
821        pass

Create an account-scoped Standard Data Type override. Requires the "custom-sdt" account feature. Fails if the account already has an override at the document's own key, or the document references an unknown variant-type.

Parameters
  • str account_key: The unique key of the account
  • str yaml_document: A standalone single-entry YAML document; its identity is its own key field
Returns

The created Standard Data Type entry, as a raw dict

@abstractmethod
def update_standard_data_type(self, account_key: str, key: str, yaml_document: str) -> dict:
823    @abstractmethod
824    def update_standard_data_type(self, account_key: str, key: str, yaml_document: str) -> dict:
825        """ Update an account-scoped Standard Data Type override. Fails if no override exists yet
826        at `key` (use create instead), or if the document's own `key` field doesn't match.
827        Requires the "custom-sdt" account feature.
828
829        :param str account_key: The unique key of the account
830        :param str key: The key of the Standard Data Type override to update
831        :param str yaml_document: The replacement standalone single-entry YAML document
832        :return: The updated Standard Data Type entry, as a raw dict
833        :rtype: dict
834        """
835        pass

Update an account-scoped Standard Data Type override. Fails if no override exists yet at key (use create instead), or if the document's own key field doesn't match. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
  • str key: The key of the Standard Data Type override to update
  • str yaml_document: The replacement standalone single-entry YAML document
Returns

The updated Standard Data Type entry, as a raw dict

@abstractmethod
def delete_standard_data_type(self, account_key: str, key: str) -> None:
837    @abstractmethod
838    def delete_standard_data_type(self, account_key: str, key: str) -> None:
839        """ Delete an account-scoped Standard Data Type override. Idempotent. Requires the
840        "custom-sdt" account feature.
841
842        :param str account_key: The unique key of the account
843        :param str key: The key of the Standard Data Type override to delete
844        """
845        pass

Delete an account-scoped Standard Data Type override. Idempotent. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
  • str key: The key of the Standard Data Type override to delete
@abstractmethod
def list_standard_data_variant_types(self, account_key: str) -> list[dict]:
847    @abstractmethod
848    def list_standard_data_variant_types(self, account_key: str) -> list[dict]:
849        """ List every Standard Data Variant Type entry (global and account, each tagged its own
850        `source`) visible to an account. Requires the "custom-sdt" account feature.
851
852        :param str account_key: The unique key of the account
853        :return: Every Standard Data Variant Type entry, as raw dicts
854        :rtype: list[dict]
855        """
856        pass

List every Standard Data Variant Type entry (global and account, each tagged its own source) visible to an account. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
Returns

Every Standard Data Variant Type entry, as raw dicts

@abstractmethod
def create_standard_data_variant_type(self, account_key: str, yaml_document: str) -> dict:
858    @abstractmethod
859    def create_standard_data_variant_type(self, account_key: str, yaml_document: str) -> dict:
860        """ Create an account-scoped Standard Data Variant Type override. Requires the
861        "custom-sdt" account feature. Fails if the account already has an override at the
862        document's own `key`.
863
864        :param str account_key: The unique key of the account
865        :param str yaml_document: A standalone single-entry YAML document; its identity is its own `key` field
866        :return: The created Standard Data Variant Type entry, as a raw dict
867        :rtype: dict
868        """
869        pass

Create an account-scoped Standard Data Variant Type override. Requires the "custom-sdt" account feature. Fails if the account already has an override at the document's own key.

Parameters
  • str account_key: The unique key of the account
  • str yaml_document: A standalone single-entry YAML document; its identity is its own key field
Returns

The created Standard Data Variant Type entry, as a raw dict

@abstractmethod
def update_standard_data_variant_type(self, account_key: str, key: str, yaml_document: str) -> dict:
871    @abstractmethod
872    def update_standard_data_variant_type(self, account_key: str, key: str, yaml_document: str) -> dict:
873        """ Update an account-scoped Standard Data Variant Type override. Fails if no override
874        exists yet at `key`, or if the document's own `key` field doesn't match. Requires the
875        "custom-sdt" account feature.
876
877        :param str account_key: The unique key of the account
878        :param str key: The key of the Standard Data Variant Type override to update
879        :param str yaml_document: The replacement standalone single-entry YAML document
880        :return: The updated Standard Data Variant Type entry, as a raw dict
881        :rtype: dict
882        """
883        pass

Update an account-scoped Standard Data Variant Type override. Fails if no override exists yet at key, or if the document's own key field doesn't match. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
  • str key: The key of the Standard Data Variant Type override to update
  • str yaml_document: The replacement standalone single-entry YAML document
Returns

The updated Standard Data Variant Type entry, as a raw dict

@abstractmethod
def delete_standard_data_variant_type(self, account_key: str, key: str) -> None:
885    @abstractmethod
886    def delete_standard_data_variant_type(self, account_key: str, key: str) -> None:
887        """ Delete an account-scoped Standard Data Variant Type override. Fails, naming the
888        referencing Data Type keys, if any of the account's own Data Types currently reference
889        this variant type. Idempotent otherwise. Requires the "custom-sdt" account feature.
890
891        :param str account_key: The unique key of the account
892        :param str key: The key of the Standard Data Variant Type override to delete
893        """
894        pass

Delete an account-scoped Standard Data Variant Type override. Fails, naming the referencing Data Type keys, if any of the account's own Data Types currently reference this variant type. Idempotent otherwise. Requires the "custom-sdt" account feature.

Parameters
  • str account_key: The unique key of the account
  • str key: The key of the Standard Data Variant Type override to delete
@abstractmethod
def fetch_device_configs(self, account_key: str, preview: bool = False) -> dict:
896    @abstractmethod
897    def fetch_device_configs(self, account_key: str, preview: bool = False) -> dict:
898        """ Fetch an account's own tier of Device Configs, for runtime consumers to merge with
899        the global tier themselves - never merged here. Always succeeds with an empty list if
900        nothing has been published yet.
901
902        :param str account_key: The unique key of the account
903        :param bool preview: If True, serves the in-progress development version per name where
904            one exists (falling back to published) - restricted to the account's admins/owners
905        :return: A raw dict shaped `{ deviceConfigs: [{name, version, yaml}] }`
906        :rtype: dict
907        """
908        pass

Fetch an account's own tier of Device Configs, for runtime consumers to merge with the global tier themselves - never merged here. Always succeeds with an empty list if nothing has been published yet.

Parameters
  • str account_key: The unique key of the account
  • bool preview: If True, serves the in-progress development version per name where one exists (falling back to published) - restricted to the account's admins/owners
Returns

A raw dict shaped { deviceConfigs: [{name, version, yaml}] }

@abstractmethod
def list_device_configs(self, account_key: str) -> dict:
910    @abstractmethod
911    def list_device_configs(self, account_key: str) -> dict:
912        """ List every version of every one of the account's named Device Configs, for an
913        editing UI. Requires the "custom-device-config" account feature.
914
915        :param str account_key: The unique key of the account
916        :return: A raw dict shaped `{ deviceConfigs: [...] }`
917        :rtype: dict
918        """
919        pass

List every version of every one of the account's named Device Configs, for an editing UI. Requires the "custom-device-config" account feature.

Parameters
  • str account_key: The unique key of the account
Returns

A raw dict shaped { deviceConfigs: [...] }

@abstractmethod
def create_device_config(self, account_key: str, yaml_document: str) -> dict:
921    @abstractmethod
922    def create_device_config(self, account_key: str, yaml_document: str) -> dict:
923        """ Validate and create a brand-new Device Config at version 1, status development.
924        Requires the "custom-device-config" account feature. Fails if a Device Config with that
925        name already exists for this account.
926
927        :param str account_key: The unique key of the account
928        :param str yaml_document: The Device Config document; its identity is its own `profile.name` field
929        :return: The new Device Config's id/version/status/yaml/updatedAt/updatedBy, as a raw dict
930        :rtype: dict
931        """
932        pass

Validate and create a brand-new Device Config at version 1, status development. Requires the "custom-device-config" account feature. Fails if a Device Config with that name already exists for this account.

Parameters
  • str account_key: The unique key of the account
  • str yaml_document: The Device Config document; its identity is its own profile.name field
Returns

The new Device Config's id/version/status/yaml/updatedAt/updatedBy, as a raw dict

@abstractmethod
def save_device_config(self, account_key: str, name: str, yaml_document: str) -> dict:
934    @abstractmethod
935    def save_device_config(self, account_key: str, name: str, yaml_document: str) -> dict:
936        """ Validate and save new content to the current development version of a named Device
937        Config, in place. Requires the "custom-device-config" account feature. Fails if no
938        development version is in progress.
939
940        :param str account_key: The unique key of the account
941        :param str name: The name of the Device Config
942        :param str yaml_document: The replacement Device Config document
943        :return: The updated Device Config version, as a raw dict
944        :rtype: dict
945        """
946        pass

Validate and save new content to the current development version of a named Device Config, in place. Requires the "custom-device-config" account feature. Fails if no development version is in progress.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
  • str yaml_document: The replacement Device Config document
Returns

The updated Device Config version, as a raw dict

@abstractmethod
def delete_device_config(self, account_key: str, name: str) -> None:
948    @abstractmethod
949    def delete_device_config(self, account_key: str, name: str) -> None:
950        """ Delete every version of a named Device Config. Requires the "custom-device-config"
951        account feature. Idempotent.
952
953        :param str account_key: The unique key of the account
954        :param str name: The name of the Device Config to delete
955        """
956        pass

Delete every version of a named Device Config. Requires the "custom-device-config" account feature. Idempotent.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config to delete
@abstractmethod
def start_device_config_development(self, account_key: str, name: str) -> dict:
958    @abstractmethod
959    def start_device_config_development(self, account_key: str, name: str) -> dict:
960        """ Branch a new development version off the current published one for an existing name.
961        Requires the "custom-device-config" account feature. Fails if the name does not exist yet
962        (use create), a development version is already in progress, or there is no published
963        version to branch from.
964
965        :param str account_key: The unique key of the account
966        :param str name: The name of the Device Config
967        :return: The new development version, as a raw dict
968        :rtype: dict
969        """
970        pass

Branch a new development version off the current published one for an existing name. Requires the "custom-device-config" account feature. Fails if the name does not exist yet (use create), a development version is already in progress, or there is no published version to branch from.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
Returns

The new development version, as a raw dict

@abstractmethod
def discard_device_config_development(self, account_key: str, name: str) -> None:
972    @abstractmethod
973    def discard_device_config_development(self, account_key: str, name: str) -> None:
974        """ Delete the current development version outright, without publishing it. Requires the
975        "custom-device-config" account feature. Idempotent - succeeds even if none is in progress.
976
977        :param str account_key: The unique key of the account
978        :param str name: The name of the Device Config
979        """
980        pass

Delete the current development version outright, without publishing it. Requires the "custom-device-config" account feature. Idempotent - succeeds even if none is in progress.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
@abstractmethod
def publish_device_config(self, account_key: str, name: str, semantic_version: str) -> dict:
982    @abstractmethod
983    def publish_device_config(self, account_key: str, name: str, semantic_version: str) -> dict:
984        """ Flip the current development version's status to published in place. Requires the
985        "custom-device-config" account feature. Fails if no development version is in progress,
986        or if `semantic_version` is not strictly greater than this name's current published
987        semantic version (if any).
988
989        :param str account_key: The unique key of the account
990        :param str name: The name of the Device Config
991        :param str semantic_version: The human-authored major.minor.patch version for this publish
992        :return: The now-published version, as a raw dict
993        :rtype: dict
994        """
995        pass

Flip the current development version's status to published in place. Requires the "custom-device-config" account feature. Fails if no development version is in progress, or if semantic_version is not strictly greater than this name's current published semantic version (if any).

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
  • str semantic_version: The human-authored major.minor.patch version for this publish
Returns

The now-published version, as a raw dict

@abstractmethod
def withdraw_device_config(self, account_key: str, name: str, version: int) -> dict:
 997    @abstractmethod
 998    def withdraw_device_config(self, account_key: str, name: str, version: int) -> dict:
 999        """ Hide one published Device Config version from consumer-facing fetch/sync/search/
1000        download without deleting it. Requires the "custom-device-config" account feature. Fails
1001        if that version isn't published.
1002
1003        :param str account_key: The unique key of the account
1004        :param str name: The name of the Device Config
1005        :param int version: The published version to withdraw
1006        :return: The now-withdrawn version, as a raw dict
1007        :rtype: dict
1008        """
1009        pass

Hide one published Device Config version from consumer-facing fetch/sync/search/ download without deleting it. Requires the "custom-device-config" account feature. Fails if that version isn't published.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
  • int version: The published version to withdraw
Returns

The now-withdrawn version, as a raw dict

@abstractmethod
def republish_device_config(self, account_key: str, name: str, version: int) -> dict:
1011    @abstractmethod
1012    def republish_device_config(self, account_key: str, name: str, version: int) -> dict:
1013        """ Reverse a withdraw. Requires the "custom-device-config" account feature. Idempotent -
1014        succeeds even if the version wasn't withdrawn.
1015
1016        :param str account_key: The unique key of the account
1017        :param str name: The name of the Device Config
1018        :param int version: The withdrawn version to republish
1019        :return: The now-republished version, as a raw dict
1020        :rtype: dict
1021        """
1022        pass

Reverse a withdraw. Requires the "custom-device-config" account feature. Idempotent - succeeds even if the version wasn't withdrawn.

Parameters
  • str account_key: The unique key of the account
  • str name: The name of the Device Config
  • int version: The withdrawn version to republish
Returns

The now-republished version, as a raw dict

class InMotionActivities(abc.ABC):
122class InMotionActivities(ABC):
123    @abstractmethod
124    def find_activities(self, act_filter: ActivitySearchFilterModel) -> ActivitiesModel:
125        """
126        Retrieve all site based activities that contain observational data
127
128        :param ActivitySearchFilterModel act_filter: The filter to apply to the search
129        :return: The activities that match the filter
130        :rtype: ActivitiesModel
131        """
132        pass
133
134    @abstractmethod
135    def find_activities_within_time_range(self, act_filter: ActivitySearchFilterModel, start: datetime, finish: datetime) -> ActivitiesModel:
136        """
137        Retrieve all site based activities that contain observational data within the specified time range.
138
139        :param ActivitySearchFilterModel act_filter: The filter to apply to the search
140        :param datetime start: The start of the time range (inclusive)
141        :param datetime finish: The end of the time range (inclusive)
142        :return: The activities that match the filter and time range
143        :rtype: ActivitiesModel
144        """
145        pass
146
147    @abstractmethod
148    def find_latest_activity_stats(self, since: datetime, max_records: int) -> LastActivitiesModel:
149        """ Retrieve the latest records for all activities since the provide date, with a maximum specified history
150
151        :param datetime since: The date/time to search from
152        :param int max_records: The maximum number of records to return
153        :return: The latest activities since the specified date
154        :rtype: LastActivitiesModel
155        """
156        pass
157
158    @abstractmethod
159    def find_latest_activity_stats_by_type(self, since: datetime, coord_conv: str) -> LastActivitiesModel:
160        """ Retrieve the latest records for all activities of a specific Coordinate Convention since the provided date
161
162        :param datetime since: The date/time to search from
163        :param str coord_conv: The Coordinate Convention to restrict results to (see CoordinateConvention)
164        :return: The latest activities since the specified date
165        :rtype: LastActivitiesModel
166        """
167        pass
168
169    @abstractmethod
170    def find_activity_master_data(self) -> MasterDataModel:
171        """ Fetch master data related to activities (profile types and activity types)
172
173        :return: The activity master data
174        :rtype: MasterDataModel
175        """
176        pass
177
178    @abstractmethod
179    def find_activity_analytics(self, request: ActivityAnalyticsRequestModel) -> ActivityAnalyticsResultModel:
180        """ Retrieve grouped activity counts across one or more accounts (or, if none are
181        supplied, every account the caller can access)
182
183        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
184        :return: The grouped activity counts
185        :rtype: ActivityAnalyticsResultModel
186        """
187        pass
188
189    @abstractmethod
190    def find_activity_track_metrics(self, request: ActivityAnalyticsRequestModel) -> ActivityTrackMetricsResultModel:
191        """ Retrieve aggregate track metrics (distance/ascent/descent/duration/speed) across one
192        or more accounts, for TRACK-kind activities only
193
194        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
195        :return: The grouped track metrics
196        :rtype: ActivityTrackMetricsResultModel
197        """
198        pass
199
200    @abstractmethod
201    def find_activity_variable_stats(self, request: ActivityAnalyticsRequestModel) -> ActivityVariableStatsResultModel:
202        """ Retrieve aggregate, per-standard-data-type variable statistics across one or more
203        accounts, for TRACK-kind activities only
204
205        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
206        :return: The grouped variable statistics
207        :rtype: ActivityVariableStatsResultModel
208        """
209        pass
210
211    @abstractmethod
212    def batch_record_update(self, commands: ActivityBatchCommandsModel) -> list[ActivityBatchResultModel]:
213        """ Apply a batch of track and/or site activity create/update commands in a single request
214
215        :param ActivityBatchCommandsModel commands: The batch of track and/or site commands to apply
216        :return: The per-command results, matched back to their command via `seqKey`
217        :rtype: list[ActivityBatchResultModel]
218        """
219        pass
220
221    @abstractmethod
222    def create_track_activity(self, activity: CreateTrackActivityModel) -> ActivityUpdateResponseModel:
223        """ Create a track activity based on the definition
224
225        :param CreateTrackActivityModel activity: The definition of the track activity to create
226        :return: The response from the creation of the activity
227        :rtype: ActivityUpdateResponseModel
228        """
229        pass
230
231    @abstractmethod
232    def update_track_activity(self, track_key: str, activity: UpdateTrackActivityModel) -> ActivityUpdateResponseModel:
233        """ Update a track activity based on the definition
234
235        :param str track_key: The unique key of the track activity to update
236        :param UpdateTrackActivityModel activity: The updated definition of the track activity
237        :return: The response from the update of the activity
238        """
239        pass
240
241    @abstractmethod
242    def find_track_activity(self, track_key: str) -> TrackActivityModel:
243        """ Retrieve the details for the requested inMotion track
244
245        :param str track_key: The unique key of the track activity to retrieve
246        :return: The details of the track activity
247        :rtype: TrackActivityDetails
248        """
249        pass
250
251    @abstractmethod
252    def delete_track_activity(self, track_key: str) -> None:
253        """ Delete a track activity and all of its associated records
254
255        :param str track_key: The unique key of the track activity to delete
256        """
257        pass
258
259    @abstractmethod
260    def unlock_track_activity(self, track_key: str) -> None:
261        """ Unlock a track activity so that it can be modified or updated
262
263        :param str track_key: The unique key of the track activity to unlock
264        """
265        pass
266
267    @abstractmethod
268    def get_track_records(self, track_key: str, start_time: Optional[datetime], end_time: Optional[datetime]) -> TrackRecordsModel:
269        """ Retrieve records from inMotion within the requested time-period
270
271        :param str track_key: The unique key of the track activity to retrieve records from
272        :param Optional[datetime] start_time: The start of the time range (inclusive)
273        :param Optional[datetime] end_time: The end of the time range (inclusive)
274        :return: The records for the track activity within the specified time range
275        :rtype: TrackRecords
276        """
277        pass
278
279    @abstractmethod
280    def find_all_track_records(self, track_key: str) -> TrackRecordsModel:
281        """ Retrieve all records for a track activity, without a time range restriction
282
283        :param str track_key: The unique key of the track activity to retrieve records from
284        :return: All records for the track activity
285        :rtype: TrackRecordsModel
286        """
287        pass
288
289    @abstractmethod
290    def publish_track_records(self, track_key: str, records: dict[str, list[int | float]]) -> ActivityUpdateResponseModel:
291        """ Publish a set of track records to inmotion
292
293        :param str track_key: The unique key of the track activity to publish records to
294        :param dict[str, list[int | float]] records: The records to publish, where the key is the field name and the value is a list of values
295        :return: The response from the publish of the records
296        :rtype: ActivityUpdateResponseModel
297        """
298        pass
299
300    @abstractmethod
301    def download_track_records(self, track_key: str, file_format: str) -> bytes:
302        """ Download the records of a track activity in the requested format
303
304        :param str track_key: The unique key of the track activity to download records from
305        :param str file_format: The format to download the records in ('csv', 'json' or 'gpx')
306        :return: The raw file content
307        :rtype: bytes
308        """
309        pass
310
311    @abstractmethod
312    def share_track_activity(self, track_key: str, kind: str) -> None:
313        """ Share a track activity
314
315        :param str track_key: The unique key of the track activity to share
316        :param str kind: The kind of sharing to apply ('any' or 'private')
317        """
318        pass
319
320    @abstractmethod
321    def unshare_track_activity(self, track_key: str, kind: str) -> None:
322        """ Remove sharing from a track activity
323
324        :param str track_key: The unique key of the track activity to unshare
325        :param str kind: The kind of sharing to revoke
326        """
327        pass
328
329    @abstractmethod
330    def find_shared_track_activity(self, track_key: str) -> TrackActivityModel:
331        """ Retrieve the details of a shared track activity
332
333        :param str track_key: The unique key of the shared track activity to retrieve
334        :return: The details of the shared track activity
335        :rtype: TrackActivityModel
336        """
337        pass
338
339    @abstractmethod
340    def find_all_shared_track_records(self, track_key: str) -> TrackRecordsModel:
341        """ Retrieve all records of a shared track activity
342
343        :param str track_key: The unique key of the shared track activity to retrieve records from
344        :return: All records for the shared track activity
345        :rtype: TrackRecordsModel
346        """
347        pass
348
349    @abstractmethod
350    def convert_track_to_route(self, track_key: str, name: Optional[str] = None) -> str:
351        """ Create a new, standalone Coverage/Route Shape from a track activity's GPS records.
352        The original track is left untouched - this is a derived record, not an in-place nature
353        change. Gated by the "track-to-shape" account feature.
354
355        :param str track_key: The unique key of the track activity to convert
356        :param Optional[str] name: An optional name for the new Route shape. Defaults to
357            "<track name> (Route)" when omitted.
358        :return: The new shape's key
359        :rtype: str
360        """
361        pass
362
363    @abstractmethod
364    def preview_track_records(self, track_key: str, qc_config: QCConfigModel) -> dict:
365        """ Retrieve records for a track activity with an ephemeral QC configuration applied. The
366        config is not saved.
367
368        :param str track_key: The unique key of the track activity to preview records for
369        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
370        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
371        :rtype: dict
372        """
373        pass
374
375    @abstractmethod
376    def preview_track_records_within_range(self, track_key: str, start_time: datetime, end_time: datetime, qc_config: QCConfigModel) -> dict:
377        """ Retrieve records for a track activity within a time range with an ephemeral QC
378        configuration applied. The config is not saved.
379
380        :param str track_key: The unique key of the track activity to preview records for
381        :param datetime start_time: The start of the time range (inclusive)
382        :param datetime end_time: The end of the time range (inclusive)
383        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
384        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
385        :rtype: dict
386        """
387        pass
388
389    @abstractmethod
390    def find_track_model_field_groups(self, track_key: str) -> list[ModelFieldGroupModel]:
391        """ Find a track activity's custom classification field values - one field group per
392        active classification tag on this track.
393
394        :param str track_key: The unique key of the track activity
395        :return: The track activity's active classification field groups
396        :rtype: list[ModelFieldGroupModel]
397        """
398        pass
399
400    @abstractmethod
401    def set_track_model_field_value(self, track_key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
402        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
403        classification field's value for one active tag on a track activity.
404
405        :param str track_key: The unique key of the track activity
406        :param SetModelFieldValueRequestModel request: The field value to set
407        :return: The track activity's active classification field groups, including the updated value
408        :rtype: list[ModelFieldGroupModel]
409        """
410        pass
411
412    @abstractmethod
413    def create_site_activity(self, activity: CreateSiteActivityModel) -> ActivityUpdateResponseModel:
414        """ Create a site activity based on the definition
415
416        :param CreateSiteActivityModel activity: The definition of the site activity to create
417        :return: The response from the creation of the activity
418        :rtype: ActivityUpdateResponseModel
419        """
420        pass
421
422    @abstractmethod
423    def update_site_activity(self, site_key: str, activity: UpdateSiteActivityModel) -> ActivityUpdateResponseModel:
424        """ Update a site activity based on the definition
425
426        :param str site_key: The unique key of the site activity to update
427        :param UpdateSiteActivityModel activity: The updated definition of the site activity
428        :return: The response from the update of the activity
429        :rtype: ActivityUpdateResponseModel
430        """
431        pass
432
433    @abstractmethod
434    def find_site_activity(self, site_key: str) -> SiteActivityModel:
435        """ Retrieve the details for the requested inMotion site
436
437        :param str site_key: The unique key of the site activity to retrieve
438        :return: The details of the site activity
439        :rtype: SiteActivityModel
440
441        """
442        pass
443
444    @abstractmethod
445    def delete_site_activity(self, site_key: str) -> None:
446        """ Delete a site activity and all of its associated records
447
448        :param str site_key: The unique key of the site activity to delete
449        """
450        pass
451
452    @abstractmethod
453    def unlock_site_activity(self, site_key: str) -> None:
454        """ Unlock a site activity so that it can be modified or updated
455
456        :param str site_key: The unique key of the site activity to unlock
457        """
458        pass
459
460    @abstractmethod
461    def get_site_records(self, site_key: str, start_time: Optional[datetime], end_time: Optional[datetime]) -> SiteRecordsModel:
462        """ Retrieve records from inMotion within the requested time-period
463
464        :param str site_key: The unique key of the site activity to retrieve records from
465        :param Optional[datetime] start_time: The start of the time range (inclusive)
466        :param Optional[datetime] end_time: The end of the time range (inclusive)
467        :return: The records for the site activity within the specified time range
468        :rtype: SiteRecords
469        """
470        pass
471
472    @abstractmethod
473    def find_all_site_records(self, site_key: str) -> SiteRecordsModel:
474        """ Retrieve all records for a site activity, without a time range restriction
475
476        :param str site_key: The unique key of the site activity to retrieve records from
477        :return: All records for the site activity
478        :rtype: SiteRecordsModel
479        """
480        pass
481
482    @abstractmethod
483    def publish_site_records(self, site_key: str, records: dict[str, list[int | float]]) -> ActivityUpdateResponseModel:
484        """ Publish a set of site records to inmotion
485
486        :param str site_key: The unique key of the site activity to publish records to
487        :param dict[str, list[int | float]] records: The records to publish, where
488        :return: The response from the publish of the records
489        :rtype: ActivityUpdateResponseModel
490        """
491        pass
492
493    @abstractmethod
494    def download_site_records(self, site_key: str, file_format: str) -> bytes:
495        """ Download the records of a site activity in the requested format
496
497        :param str site_key: The unique key of the site activity to download records from
498        :param str file_format: The format to download the records in ('csv', 'json' or 'gpx')
499        :return: The raw file content
500        :rtype: bytes
501        """
502        pass
503
504    @abstractmethod
505    def share_site_activity(self, site_key: str, kind: str) -> None:
506        """ Share a site activity
507
508        :param str site_key: The unique key of the site activity to share
509        :param str kind: The kind of sharing to apply ('any' or 'private')
510        """
511        pass
512
513    @abstractmethod
514    def unshare_site_activity(self, site_key: str, kind: str) -> None:
515        """ Remove sharing from a site activity
516
517        :param str site_key: The unique key of the site activity to unshare
518        :param str kind: The kind of sharing to revoke
519        """
520        pass
521
522    @abstractmethod
523    def find_shared_site_activity(self, site_key: str) -> SiteActivityModel:
524        """ Retrieve the details of a shared site activity
525
526        :param str site_key: The unique key of the shared site activity to retrieve
527        :return: The details of the shared site activity
528        :rtype: SiteActivityModel
529        """
530        pass
531
532    @abstractmethod
533    def find_shared_site_records(self, site_key: str, start_time: datetime, end_time: datetime) -> SiteRecordsModel:
534        """ Retrieve records of a shared site activity within the requested time-period
535
536        :param str site_key: The unique key of the shared site activity to retrieve records from
537        :param datetime start_time: The start of the time range (inclusive)
538        :param datetime end_time: The end of the time range (inclusive)
539        :return: The records for the shared site activity within the specified time range
540        :rtype: SiteRecordsModel
541        """
542        pass
543
544    @abstractmethod
545    def preview_site_records(self, site_key: str, qc_config: QCConfigModel) -> dict:
546        """ Retrieve records for a site activity with an ephemeral QC configuration applied. The
547        config is not saved.
548
549        :param str site_key: The unique key of the site activity to preview records for
550        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
551        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
552        :rtype: dict
553        """
554        pass
555
556    @abstractmethod
557    def preview_site_records_within_range(self, site_key: str, start_time: datetime, end_time: datetime, qc_config: QCConfigModel) -> dict:
558        """ Retrieve records for a site activity within a time range with an ephemeral QC
559        configuration applied. The config is not saved.
560
561        :param str site_key: The unique key of the site activity to preview records for
562        :param datetime start_time: The start of the time range (inclusive)
563        :param datetime end_time: The end of the time range (inclusive)
564        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
565        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
566        :rtype: dict
567        """
568        pass
569
570    @abstractmethod
571    def find_site_model_field_groups(self, site_key: str) -> list[ModelFieldGroupModel]:
572        """ Find a site activity's custom classification field values - one field group per
573        active classification tag on this site.
574
575        :param str site_key: The unique key of the site activity
576        :return: The site activity's active classification field groups
577        :rtype: list[ModelFieldGroupModel]
578        """
579        pass
580
581    @abstractmethod
582    def set_site_model_field_value(self, site_key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
583        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
584        classification field's value for one active tag on a site activity.
585
586        :param str site_key: The unique key of the site activity
587        :param SetModelFieldValueRequestModel request: The field value to set
588        :return: The site activity's active classification field groups, including the updated value
589        :rtype: list[ModelFieldGroupModel]
590        """
591        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def find_activities( self, act_filter: inmotion.models.ActivitySearchFilterModel) -> inmotion.models.ActivitiesModel:
123    @abstractmethod
124    def find_activities(self, act_filter: ActivitySearchFilterModel) -> ActivitiesModel:
125        """
126        Retrieve all site based activities that contain observational data
127
128        :param ActivitySearchFilterModel act_filter: The filter to apply to the search
129        :return: The activities that match the filter
130        :rtype: ActivitiesModel
131        """
132        pass

Retrieve all site based activities that contain observational data

Parameters
  • ActivitySearchFilterModel act_filter: The filter to apply to the search
Returns

The activities that match the filter

@abstractmethod
def find_activities_within_time_range( self, act_filter: inmotion.models.ActivitySearchFilterModel, start: datetime.datetime, finish: datetime.datetime) -> inmotion.models.ActivitiesModel:
134    @abstractmethod
135    def find_activities_within_time_range(self, act_filter: ActivitySearchFilterModel, start: datetime, finish: datetime) -> ActivitiesModel:
136        """
137        Retrieve all site based activities that contain observational data within the specified time range.
138
139        :param ActivitySearchFilterModel act_filter: The filter to apply to the search
140        :param datetime start: The start of the time range (inclusive)
141        :param datetime finish: The end of the time range (inclusive)
142        :return: The activities that match the filter and time range
143        :rtype: ActivitiesModel
144        """
145        pass

Retrieve all site based activities that contain observational data within the specified time range.

Parameters
  • ActivitySearchFilterModel act_filter: The filter to apply to the search
  • datetime start: The start of the time range (inclusive)
  • datetime finish: The end of the time range (inclusive)
Returns

The activities that match the filter and time range

@abstractmethod
def find_latest_activity_stats( self, since: datetime.datetime, max_records: int) -> inmotion.models.LastActivitiesModel:
147    @abstractmethod
148    def find_latest_activity_stats(self, since: datetime, max_records: int) -> LastActivitiesModel:
149        """ Retrieve the latest records for all activities since the provide date, with a maximum specified history
150
151        :param datetime since: The date/time to search from
152        :param int max_records: The maximum number of records to return
153        :return: The latest activities since the specified date
154        :rtype: LastActivitiesModel
155        """
156        pass

Retrieve the latest records for all activities since the provide date, with a maximum specified history

Parameters
  • datetime since: The date/time to search from
  • int max_records: The maximum number of records to return
Returns

The latest activities since the specified date

@abstractmethod
def find_latest_activity_stats_by_type( self, since: datetime.datetime, coord_conv: str) -> inmotion.models.LastActivitiesModel:
158    @abstractmethod
159    def find_latest_activity_stats_by_type(self, since: datetime, coord_conv: str) -> LastActivitiesModel:
160        """ Retrieve the latest records for all activities of a specific Coordinate Convention since the provided date
161
162        :param datetime since: The date/time to search from
163        :param str coord_conv: The Coordinate Convention to restrict results to (see CoordinateConvention)
164        :return: The latest activities since the specified date
165        :rtype: LastActivitiesModel
166        """
167        pass

Retrieve the latest records for all activities of a specific Coordinate Convention since the provided date

Parameters
  • datetime since: The date/time to search from
  • str coord_conv: The Coordinate Convention to restrict results to (see CoordinateConvention)
Returns

The latest activities since the specified date

@abstractmethod
def find_activity_master_data(self) -> inmotion.models.MasterDataModel:
169    @abstractmethod
170    def find_activity_master_data(self) -> MasterDataModel:
171        """ Fetch master data related to activities (profile types and activity types)
172
173        :return: The activity master data
174        :rtype: MasterDataModel
175        """
176        pass

Fetch master data related to activities (profile types and activity types)

Returns

The activity master data

@abstractmethod
def find_activity_analytics( self, request: inmotion.models.ActivityAnalyticsRequestModel) -> inmotion.models.ActivityAnalyticsResultModel:
178    @abstractmethod
179    def find_activity_analytics(self, request: ActivityAnalyticsRequestModel) -> ActivityAnalyticsResultModel:
180        """ Retrieve grouped activity counts across one or more accounts (or, if none are
181        supplied, every account the caller can access)
182
183        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
184        :return: The grouped activity counts
185        :rtype: ActivityAnalyticsResultModel
186        """
187        pass

Retrieve grouped activity counts across one or more accounts (or, if none are supplied, every account the caller can access)

Parameters
  • ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
Returns

The grouped activity counts

@abstractmethod
def find_activity_track_metrics( self, request: inmotion.models.ActivityAnalyticsRequestModel) -> inmotion.models.ActivityTrackMetricsResultModel:
189    @abstractmethod
190    def find_activity_track_metrics(self, request: ActivityAnalyticsRequestModel) -> ActivityTrackMetricsResultModel:
191        """ Retrieve aggregate track metrics (distance/ascent/descent/duration/speed) across one
192        or more accounts, for TRACK-kind activities only
193
194        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
195        :return: The grouped track metrics
196        :rtype: ActivityTrackMetricsResultModel
197        """
198        pass

Retrieve aggregate track metrics (distance/ascent/descent/duration/speed) across one or more accounts, for TRACK-kind activities only

Parameters
  • ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
Returns

The grouped track metrics

@abstractmethod
def find_activity_variable_stats( self, request: inmotion.models.ActivityAnalyticsRequestModel) -> inmotion.models.ActivityVariableStatsResultModel:
200    @abstractmethod
201    def find_activity_variable_stats(self, request: ActivityAnalyticsRequestModel) -> ActivityVariableStatsResultModel:
202        """ Retrieve aggregate, per-standard-data-type variable statistics across one or more
203        accounts, for TRACK-kind activities only
204
205        :param ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
206        :return: The grouped variable statistics
207        :rtype: ActivityVariableStatsResultModel
208        """
209        pass

Retrieve aggregate, per-standard-data-type variable statistics across one or more accounts, for TRACK-kind activities only

Parameters
  • ActivityAnalyticsRequestModel request: The accounts, filter, and grouping to apply
Returns

The grouped variable statistics

@abstractmethod
def batch_record_update( self, commands: inmotion.models.ActivityBatchCommandsModel) -> list[inmotion.models.ActivityBatchResultModel]:
211    @abstractmethod
212    def batch_record_update(self, commands: ActivityBatchCommandsModel) -> list[ActivityBatchResultModel]:
213        """ Apply a batch of track and/or site activity create/update commands in a single request
214
215        :param ActivityBatchCommandsModel commands: The batch of track and/or site commands to apply
216        :return: The per-command results, matched back to their command via `seqKey`
217        :rtype: list[ActivityBatchResultModel]
218        """
219        pass

Apply a batch of track and/or site activity create/update commands in a single request

Parameters
  • ActivityBatchCommandsModel commands: The batch of track and/or site commands to apply
Returns

The per-command results, matched back to their command via seqKey

@abstractmethod
def create_track_activity( self, activity: inmotion.models.CreateTrackActivityModel) -> inmotion.models.ActivityUpdateResponseModel:
221    @abstractmethod
222    def create_track_activity(self, activity: CreateTrackActivityModel) -> ActivityUpdateResponseModel:
223        """ Create a track activity based on the definition
224
225        :param CreateTrackActivityModel activity: The definition of the track activity to create
226        :return: The response from the creation of the activity
227        :rtype: ActivityUpdateResponseModel
228        """
229        pass

Create a track activity based on the definition

Parameters
  • CreateTrackActivityModel activity: The definition of the track activity to create
Returns

The response from the creation of the activity

@abstractmethod
def update_track_activity( self, track_key: str, activity: inmotion.models.UpdateTrackActivityModel) -> inmotion.models.ActivityUpdateResponseModel:
231    @abstractmethod
232    def update_track_activity(self, track_key: str, activity: UpdateTrackActivityModel) -> ActivityUpdateResponseModel:
233        """ Update a track activity based on the definition
234
235        :param str track_key: The unique key of the track activity to update
236        :param UpdateTrackActivityModel activity: The updated definition of the track activity
237        :return: The response from the update of the activity
238        """
239        pass

Update a track activity based on the definition

Parameters
  • str track_key: The unique key of the track activity to update
  • UpdateTrackActivityModel activity: The updated definition of the track activity
Returns

The response from the update of the activity

@abstractmethod
def find_track_activity(self, track_key: str) -> inmotion.models.TrackActivityModel:
241    @abstractmethod
242    def find_track_activity(self, track_key: str) -> TrackActivityModel:
243        """ Retrieve the details for the requested inMotion track
244
245        :param str track_key: The unique key of the track activity to retrieve
246        :return: The details of the track activity
247        :rtype: TrackActivityDetails
248        """
249        pass

Retrieve the details for the requested inMotion track

Parameters
  • str track_key: The unique key of the track activity to retrieve
Returns

The details of the track activity

@abstractmethod
def delete_track_activity(self, track_key: str) -> None:
251    @abstractmethod
252    def delete_track_activity(self, track_key: str) -> None:
253        """ Delete a track activity and all of its associated records
254
255        :param str track_key: The unique key of the track activity to delete
256        """
257        pass

Delete a track activity and all of its associated records

Parameters
  • str track_key: The unique key of the track activity to delete
@abstractmethod
def unlock_track_activity(self, track_key: str) -> None:
259    @abstractmethod
260    def unlock_track_activity(self, track_key: str) -> None:
261        """ Unlock a track activity so that it can be modified or updated
262
263        :param str track_key: The unique key of the track activity to unlock
264        """
265        pass

Unlock a track activity so that it can be modified or updated

Parameters
  • str track_key: The unique key of the track activity to unlock
@abstractmethod
def get_track_records( self, track_key: str, start_time: Optional[datetime.datetime], end_time: Optional[datetime.datetime]) -> inmotion.models.TrackRecordsModel:
267    @abstractmethod
268    def get_track_records(self, track_key: str, start_time: Optional[datetime], end_time: Optional[datetime]) -> TrackRecordsModel:
269        """ Retrieve records from inMotion within the requested time-period
270
271        :param str track_key: The unique key of the track activity to retrieve records from
272        :param Optional[datetime] start_time: The start of the time range (inclusive)
273        :param Optional[datetime] end_time: The end of the time range (inclusive)
274        :return: The records for the track activity within the specified time range
275        :rtype: TrackRecords
276        """
277        pass

Retrieve records from inMotion within the requested time-period

Parameters
  • str track_key: The unique key of the track activity to retrieve records from
  • Optional[datetime] start_time: The start of the time range (inclusive)
  • Optional[datetime] end_time: The end of the time range (inclusive)
Returns

The records for the track activity within the specified time range

@abstractmethod
def find_all_track_records(self, track_key: str) -> inmotion.models.TrackRecordsModel:
279    @abstractmethod
280    def find_all_track_records(self, track_key: str) -> TrackRecordsModel:
281        """ Retrieve all records for a track activity, without a time range restriction
282
283        :param str track_key: The unique key of the track activity to retrieve records from
284        :return: All records for the track activity
285        :rtype: TrackRecordsModel
286        """
287        pass

Retrieve all records for a track activity, without a time range restriction

Parameters
  • str track_key: The unique key of the track activity to retrieve records from
Returns

All records for the track activity

@abstractmethod
def publish_track_records( self, track_key: str, records: dict[str, list[int | float]]) -> inmotion.models.ActivityUpdateResponseModel:
289    @abstractmethod
290    def publish_track_records(self, track_key: str, records: dict[str, list[int | float]]) -> ActivityUpdateResponseModel:
291        """ Publish a set of track records to inmotion
292
293        :param str track_key: The unique key of the track activity to publish records to
294        :param dict[str, list[int | float]] records: The records to publish, where the key is the field name and the value is a list of values
295        :return: The response from the publish of the records
296        :rtype: ActivityUpdateResponseModel
297        """
298        pass

Publish a set of track records to inmotion

Parameters
  • str track_key: The unique key of the track activity to publish records to
  • dict[str, list[int | float]] records: The records to publish, where the key is the field name and the value is a list of values
Returns

The response from the publish of the records

@abstractmethod
def download_track_records(self, track_key: str, file_format: str) -> bytes:
300    @abstractmethod
301    def download_track_records(self, track_key: str, file_format: str) -> bytes:
302        """ Download the records of a track activity in the requested format
303
304        :param str track_key: The unique key of the track activity to download records from
305        :param str file_format: The format to download the records in ('csv', 'json' or 'gpx')
306        :return: The raw file content
307        :rtype: bytes
308        """
309        pass

Download the records of a track activity in the requested format

Parameters
  • str track_key: The unique key of the track activity to download records from
  • str file_format: The format to download the records in ('csv', 'json' or 'gpx')
Returns

The raw file content

@abstractmethod
def share_track_activity(self, track_key: str, kind: str) -> None:
311    @abstractmethod
312    def share_track_activity(self, track_key: str, kind: str) -> None:
313        """ Share a track activity
314
315        :param str track_key: The unique key of the track activity to share
316        :param str kind: The kind of sharing to apply ('any' or 'private')
317        """
318        pass

Share a track activity

Parameters
  • str track_key: The unique key of the track activity to share
  • str kind: The kind of sharing to apply ('any' or 'private')
@abstractmethod
def unshare_track_activity(self, track_key: str, kind: str) -> None:
320    @abstractmethod
321    def unshare_track_activity(self, track_key: str, kind: str) -> None:
322        """ Remove sharing from a track activity
323
324        :param str track_key: The unique key of the track activity to unshare
325        :param str kind: The kind of sharing to revoke
326        """
327        pass

Remove sharing from a track activity

Parameters
  • str track_key: The unique key of the track activity to unshare
  • str kind: The kind of sharing to revoke
@abstractmethod
def find_shared_track_activity(self, track_key: str) -> inmotion.models.TrackActivityModel:
329    @abstractmethod
330    def find_shared_track_activity(self, track_key: str) -> TrackActivityModel:
331        """ Retrieve the details of a shared track activity
332
333        :param str track_key: The unique key of the shared track activity to retrieve
334        :return: The details of the shared track activity
335        :rtype: TrackActivityModel
336        """
337        pass

Retrieve the details of a shared track activity

Parameters
  • str track_key: The unique key of the shared track activity to retrieve
Returns

The details of the shared track activity

@abstractmethod
def find_all_shared_track_records(self, track_key: str) -> inmotion.models.TrackRecordsModel:
339    @abstractmethod
340    def find_all_shared_track_records(self, track_key: str) -> TrackRecordsModel:
341        """ Retrieve all records of a shared track activity
342
343        :param str track_key: The unique key of the shared track activity to retrieve records from
344        :return: All records for the shared track activity
345        :rtype: TrackRecordsModel
346        """
347        pass

Retrieve all records of a shared track activity

Parameters
  • str track_key: The unique key of the shared track activity to retrieve records from
Returns

All records for the shared track activity

@abstractmethod
def convert_track_to_route(self, track_key: str, name: Optional[str] = None) -> str:
349    @abstractmethod
350    def convert_track_to_route(self, track_key: str, name: Optional[str] = None) -> str:
351        """ Create a new, standalone Coverage/Route Shape from a track activity's GPS records.
352        The original track is left untouched - this is a derived record, not an in-place nature
353        change. Gated by the "track-to-shape" account feature.
354
355        :param str track_key: The unique key of the track activity to convert
356        :param Optional[str] name: An optional name for the new Route shape. Defaults to
357            "<track name> (Route)" when omitted.
358        :return: The new shape's key
359        :rtype: str
360        """
361        pass

Create a new, standalone Coverage/Route Shape from a track activity's GPS records. The original track is left untouched - this is a derived record, not an in-place nature change. Gated by the "track-to-shape" account feature.

Parameters
  • str track_key: The unique key of the track activity to convert
  • Optional[str] name: An optional name for the new Route shape. Defaults to " (Route)" when omitted.
Returns

The new shape's key

@abstractmethod
def preview_track_records(self, track_key: str, qc_config: inmotion.models.QCConfigModel) -> dict:
363    @abstractmethod
364    def preview_track_records(self, track_key: str, qc_config: QCConfigModel) -> dict:
365        """ Retrieve records for a track activity with an ephemeral QC configuration applied. The
366        config is not saved.
367
368        :param str track_key: The unique key of the track activity to preview records for
369        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
370        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
371        :rtype: dict
372        """
373        pass

Retrieve records for a track activity with an ephemeral QC configuration applied. The config is not saved.

Parameters
  • str track_key: The unique key of the track activity to preview records for
  • QCConfigModel qc_config: The ephemeral QC configuration to apply
Returns

The previewed records, as a raw dict (no fixed schema is declared server-side)

@abstractmethod
def preview_track_records_within_range( self, track_key: str, start_time: datetime.datetime, end_time: datetime.datetime, qc_config: inmotion.models.QCConfigModel) -> dict:
375    @abstractmethod
376    def preview_track_records_within_range(self, track_key: str, start_time: datetime, end_time: datetime, qc_config: QCConfigModel) -> dict:
377        """ Retrieve records for a track activity within a time range with an ephemeral QC
378        configuration applied. The config is not saved.
379
380        :param str track_key: The unique key of the track activity to preview records for
381        :param datetime start_time: The start of the time range (inclusive)
382        :param datetime end_time: The end of the time range (inclusive)
383        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
384        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
385        :rtype: dict
386        """
387        pass

Retrieve records for a track activity within a time range with an ephemeral QC configuration applied. The config is not saved.

Parameters
  • str track_key: The unique key of the track activity to preview records for
  • datetime start_time: The start of the time range (inclusive)
  • datetime end_time: The end of the time range (inclusive)
  • QCConfigModel qc_config: The ephemeral QC configuration to apply
Returns

The previewed records, as a raw dict (no fixed schema is declared server-side)

@abstractmethod
def find_track_model_field_groups(self, track_key: str) -> list[inmotion.models.ModelFieldGroupModel]:
389    @abstractmethod
390    def find_track_model_field_groups(self, track_key: str) -> list[ModelFieldGroupModel]:
391        """ Find a track activity's custom classification field values - one field group per
392        active classification tag on this track.
393
394        :param str track_key: The unique key of the track activity
395        :return: The track activity's active classification field groups
396        :rtype: list[ModelFieldGroupModel]
397        """
398        pass

Find a track activity's custom classification field values - one field group per active classification tag on this track.

Parameters
  • str track_key: The unique key of the track activity
Returns

The track activity's active classification field groups

@abstractmethod
def set_track_model_field_value( self, track_key: str, request: inmotion.models.SetModelFieldValueRequestModel) -> list[inmotion.models.ModelFieldGroupModel]:
400    @abstractmethod
401    def set_track_model_field_value(self, track_key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
402        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
403        classification field's value for one active tag on a track activity.
404
405        :param str track_key: The unique key of the track activity
406        :param SetModelFieldValueRequestModel request: The field value to set
407        :return: The track activity's active classification field groups, including the updated value
408        :rtype: list[ModelFieldGroupModel]
409        """
410        pass

Set (or, if value is omitted/blank on an optional field, clear) one custom classification field's value for one active tag on a track activity.

Parameters
  • str track_key: The unique key of the track activity
  • SetModelFieldValueRequestModel request: The field value to set
Returns

The track activity's active classification field groups, including the updated value

@abstractmethod
def create_site_activity( self, activity: inmotion.models.CreateSiteActivityModel) -> inmotion.models.ActivityUpdateResponseModel:
412    @abstractmethod
413    def create_site_activity(self, activity: CreateSiteActivityModel) -> ActivityUpdateResponseModel:
414        """ Create a site activity based on the definition
415
416        :param CreateSiteActivityModel activity: The definition of the site activity to create
417        :return: The response from the creation of the activity
418        :rtype: ActivityUpdateResponseModel
419        """
420        pass

Create a site activity based on the definition

Parameters
  • CreateSiteActivityModel activity: The definition of the site activity to create
Returns

The response from the creation of the activity

@abstractmethod
def update_site_activity( self, site_key: str, activity: inmotion.models.UpdateSiteActivityModel) -> inmotion.models.ActivityUpdateResponseModel:
422    @abstractmethod
423    def update_site_activity(self, site_key: str, activity: UpdateSiteActivityModel) -> ActivityUpdateResponseModel:
424        """ Update a site activity based on the definition
425
426        :param str site_key: The unique key of the site activity to update
427        :param UpdateSiteActivityModel activity: The updated definition of the site activity
428        :return: The response from the update of the activity
429        :rtype: ActivityUpdateResponseModel
430        """
431        pass

Update a site activity based on the definition

Parameters
  • str site_key: The unique key of the site activity to update
  • UpdateSiteActivityModel activity: The updated definition of the site activity
Returns

The response from the update of the activity

@abstractmethod
def find_site_activity(self, site_key: str) -> inmotion.models.SiteActivityModel:
433    @abstractmethod
434    def find_site_activity(self, site_key: str) -> SiteActivityModel:
435        """ Retrieve the details for the requested inMotion site
436
437        :param str site_key: The unique key of the site activity to retrieve
438        :return: The details of the site activity
439        :rtype: SiteActivityModel
440
441        """
442        pass

Retrieve the details for the requested inMotion site

Parameters
  • str site_key: The unique key of the site activity to retrieve
Returns

The details of the site activity

@abstractmethod
def delete_site_activity(self, site_key: str) -> None:
444    @abstractmethod
445    def delete_site_activity(self, site_key: str) -> None:
446        """ Delete a site activity and all of its associated records
447
448        :param str site_key: The unique key of the site activity to delete
449        """
450        pass

Delete a site activity and all of its associated records

Parameters
  • str site_key: The unique key of the site activity to delete
@abstractmethod
def unlock_site_activity(self, site_key: str) -> None:
452    @abstractmethod
453    def unlock_site_activity(self, site_key: str) -> None:
454        """ Unlock a site activity so that it can be modified or updated
455
456        :param str site_key: The unique key of the site activity to unlock
457        """
458        pass

Unlock a site activity so that it can be modified or updated

Parameters
  • str site_key: The unique key of the site activity to unlock
@abstractmethod
def get_site_records( self, site_key: str, start_time: Optional[datetime.datetime], end_time: Optional[datetime.datetime]) -> inmotion.models.SiteRecordsModel:
460    @abstractmethod
461    def get_site_records(self, site_key: str, start_time: Optional[datetime], end_time: Optional[datetime]) -> SiteRecordsModel:
462        """ Retrieve records from inMotion within the requested time-period
463
464        :param str site_key: The unique key of the site activity to retrieve records from
465        :param Optional[datetime] start_time: The start of the time range (inclusive)
466        :param Optional[datetime] end_time: The end of the time range (inclusive)
467        :return: The records for the site activity within the specified time range
468        :rtype: SiteRecords
469        """
470        pass

Retrieve records from inMotion within the requested time-period

Parameters
  • str site_key: The unique key of the site activity to retrieve records from
  • Optional[datetime] start_time: The start of the time range (inclusive)
  • Optional[datetime] end_time: The end of the time range (inclusive)
Returns

The records for the site activity within the specified time range

@abstractmethod
def find_all_site_records(self, site_key: str) -> inmotion.models.SiteRecordsModel:
472    @abstractmethod
473    def find_all_site_records(self, site_key: str) -> SiteRecordsModel:
474        """ Retrieve all records for a site activity, without a time range restriction
475
476        :param str site_key: The unique key of the site activity to retrieve records from
477        :return: All records for the site activity
478        :rtype: SiteRecordsModel
479        """
480        pass

Retrieve all records for a site activity, without a time range restriction

Parameters
  • str site_key: The unique key of the site activity to retrieve records from
Returns

All records for the site activity

@abstractmethod
def publish_site_records( self, site_key: str, records: dict[str, list[int | float]]) -> inmotion.models.ActivityUpdateResponseModel:
482    @abstractmethod
483    def publish_site_records(self, site_key: str, records: dict[str, list[int | float]]) -> ActivityUpdateResponseModel:
484        """ Publish a set of site records to inmotion
485
486        :param str site_key: The unique key of the site activity to publish records to
487        :param dict[str, list[int | float]] records: The records to publish, where
488        :return: The response from the publish of the records
489        :rtype: ActivityUpdateResponseModel
490        """
491        pass

Publish a set of site records to inmotion

Parameters
  • str site_key: The unique key of the site activity to publish records to
  • dict[str, list[int | float]] records: The records to publish, where
Returns

The response from the publish of the records

@abstractmethod
def download_site_records(self, site_key: str, file_format: str) -> bytes:
493    @abstractmethod
494    def download_site_records(self, site_key: str, file_format: str) -> bytes:
495        """ Download the records of a site activity in the requested format
496
497        :param str site_key: The unique key of the site activity to download records from
498        :param str file_format: The format to download the records in ('csv', 'json' or 'gpx')
499        :return: The raw file content
500        :rtype: bytes
501        """
502        pass

Download the records of a site activity in the requested format

Parameters
  • str site_key: The unique key of the site activity to download records from
  • str file_format: The format to download the records in ('csv', 'json' or 'gpx')
Returns

The raw file content

@abstractmethod
def share_site_activity(self, site_key: str, kind: str) -> None:
504    @abstractmethod
505    def share_site_activity(self, site_key: str, kind: str) -> None:
506        """ Share a site activity
507
508        :param str site_key: The unique key of the site activity to share
509        :param str kind: The kind of sharing to apply ('any' or 'private')
510        """
511        pass

Share a site activity

Parameters
  • str site_key: The unique key of the site activity to share
  • str kind: The kind of sharing to apply ('any' or 'private')
@abstractmethod
def unshare_site_activity(self, site_key: str, kind: str) -> None:
513    @abstractmethod
514    def unshare_site_activity(self, site_key: str, kind: str) -> None:
515        """ Remove sharing from a site activity
516
517        :param str site_key: The unique key of the site activity to unshare
518        :param str kind: The kind of sharing to revoke
519        """
520        pass

Remove sharing from a site activity

Parameters
  • str site_key: The unique key of the site activity to unshare
  • str kind: The kind of sharing to revoke
@abstractmethod
def find_shared_site_activity(self, site_key: str) -> inmotion.models.SiteActivityModel:
522    @abstractmethod
523    def find_shared_site_activity(self, site_key: str) -> SiteActivityModel:
524        """ Retrieve the details of a shared site activity
525
526        :param str site_key: The unique key of the shared site activity to retrieve
527        :return: The details of the shared site activity
528        :rtype: SiteActivityModel
529        """
530        pass

Retrieve the details of a shared site activity

Parameters
  • str site_key: The unique key of the shared site activity to retrieve
Returns

The details of the shared site activity

@abstractmethod
def find_shared_site_records( self, site_key: str, start_time: datetime.datetime, end_time: datetime.datetime) -> inmotion.models.SiteRecordsModel:
532    @abstractmethod
533    def find_shared_site_records(self, site_key: str, start_time: datetime, end_time: datetime) -> SiteRecordsModel:
534        """ Retrieve records of a shared site activity within the requested time-period
535
536        :param str site_key: The unique key of the shared site activity to retrieve records from
537        :param datetime start_time: The start of the time range (inclusive)
538        :param datetime end_time: The end of the time range (inclusive)
539        :return: The records for the shared site activity within the specified time range
540        :rtype: SiteRecordsModel
541        """
542        pass

Retrieve records of a shared site activity within the requested time-period

Parameters
  • str site_key: The unique key of the shared site activity to retrieve records from
  • datetime start_time: The start of the time range (inclusive)
  • datetime end_time: The end of the time range (inclusive)
Returns

The records for the shared site activity within the specified time range

@abstractmethod
def preview_site_records(self, site_key: str, qc_config: inmotion.models.QCConfigModel) -> dict:
544    @abstractmethod
545    def preview_site_records(self, site_key: str, qc_config: QCConfigModel) -> dict:
546        """ Retrieve records for a site activity with an ephemeral QC configuration applied. The
547        config is not saved.
548
549        :param str site_key: The unique key of the site activity to preview records for
550        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
551        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
552        :rtype: dict
553        """
554        pass

Retrieve records for a site activity with an ephemeral QC configuration applied. The config is not saved.

Parameters
  • str site_key: The unique key of the site activity to preview records for
  • QCConfigModel qc_config: The ephemeral QC configuration to apply
Returns

The previewed records, as a raw dict (no fixed schema is declared server-side)

@abstractmethod
def preview_site_records_within_range( self, site_key: str, start_time: datetime.datetime, end_time: datetime.datetime, qc_config: inmotion.models.QCConfigModel) -> dict:
556    @abstractmethod
557    def preview_site_records_within_range(self, site_key: str, start_time: datetime, end_time: datetime, qc_config: QCConfigModel) -> dict:
558        """ Retrieve records for a site activity within a time range with an ephemeral QC
559        configuration applied. The config is not saved.
560
561        :param str site_key: The unique key of the site activity to preview records for
562        :param datetime start_time: The start of the time range (inclusive)
563        :param datetime end_time: The end of the time range (inclusive)
564        :param QCConfigModel qc_config: The ephemeral QC configuration to apply
565        :return: The previewed records, as a raw dict (no fixed schema is declared server-side)
566        :rtype: dict
567        """
568        pass

Retrieve records for a site activity within a time range with an ephemeral QC configuration applied. The config is not saved.

Parameters
  • str site_key: The unique key of the site activity to preview records for
  • datetime start_time: The start of the time range (inclusive)
  • datetime end_time: The end of the time range (inclusive)
  • QCConfigModel qc_config: The ephemeral QC configuration to apply
Returns

The previewed records, as a raw dict (no fixed schema is declared server-side)

@abstractmethod
def find_site_model_field_groups(self, site_key: str) -> list[inmotion.models.ModelFieldGroupModel]:
570    @abstractmethod
571    def find_site_model_field_groups(self, site_key: str) -> list[ModelFieldGroupModel]:
572        """ Find a site activity's custom classification field values - one field group per
573        active classification tag on this site.
574
575        :param str site_key: The unique key of the site activity
576        :return: The site activity's active classification field groups
577        :rtype: list[ModelFieldGroupModel]
578        """
579        pass

Find a site activity's custom classification field values - one field group per active classification tag on this site.

Parameters
  • str site_key: The unique key of the site activity
Returns

The site activity's active classification field groups

@abstractmethod
def set_site_model_field_value( self, site_key: str, request: inmotion.models.SetModelFieldValueRequestModel) -> list[inmotion.models.ModelFieldGroupModel]:
581    @abstractmethod
582    def set_site_model_field_value(self, site_key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
583        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
584        classification field's value for one active tag on a site activity.
585
586        :param str site_key: The unique key of the site activity
587        :param SetModelFieldValueRequestModel request: The field value to set
588        :return: The site activity's active classification field groups, including the updated value
589        :rtype: list[ModelFieldGroupModel]
590        """
591        pass

Set (or, if value is omitted/blank on an optional field, clear) one custom classification field's value for one active tag on a site activity.

Parameters
  • str site_key: The unique key of the site activity
  • SetModelFieldValueRequestModel request: The field value to set
Returns

The site activity's active classification field groups, including the updated value

class InMotionActivityConfig(abc.ABC):
1025class InMotionActivityConfig(ABC):
1026    @abstractmethod
1027    def find_activity_config(self, key: str) -> ActivityConfigModel:
1028        """ Retrieve the complete activity configuration (QC, Processing, Custom Data, and History)
1029
1030        :param str key: The unique key of the activity
1031        :return: The full activity configuration
1032        :rtype: ActivityConfigModel
1033        """
1034        pass
1035
1036    @abstractmethod
1037    def update_qc_config(self, key: str, qc_update: ActivityConfigQCUpdateModel) -> ActivityConfigModel:
1038        """ Replace the Quality Control section of an activity's configuration
1039
1040        :param str key: The unique key of the activity
1041        :param ActivityConfigQCUpdateModel qc_update: The replacement QC configuration
1042        :return: The updated full activity configuration
1043        :rtype: ActivityConfigModel
1044        """
1045        pass
1046
1047    @abstractmethod
1048    def update_processing_config(self, key: str, processing_update: ActivityConfigProcessingUpdateModel) -> ActivityConfigModel:
1049        """ Replace the Processing section of an activity's configuration
1050
1051        :param str key: The unique key of the activity
1052        :param ActivityConfigProcessingUpdateModel processing_update: The replacement processing configuration
1053        :return: The updated full activity configuration
1054        :rtype: ActivityConfigModel
1055        """
1056        pass
1057
1058    @abstractmethod
1059    def update_custom_data_config(self, key: str, custom_data_update: ActivityConfigCustomDataUpdateModel) -> ActivityConfigModel:
1060        """ Replace the Custom Data section of an activity's configuration
1061
1062        :param str key: The unique key of the activity
1063        :param ActivityConfigCustomDataUpdateModel custom_data_update: The replacement custom data entries
1064        :return: The updated full activity configuration
1065        :rtype: ActivityConfigModel
1066        """
1067        pass
1068
1069    @abstractmethod
1070    def delete_activity_config(self, key: str) -> ActivityConfigDeleteResponseModel:
1071        """ Delete the entire activity configuration for an activity
1072
1073        :param str key: The unique key of the activity
1074        :return: The result of the delete operation
1075        :rtype: ActivityConfigDeleteResponseModel
1076        """
1077        pass
1078
1079    @abstractmethod
1080    def detect_bad_periods(self, key: str, request: ActivityConfigBadPeriodDetectRequestModel) -> ActivityConfigBadPeriodDetectResultModel:
1081        """ Run GPS-spike analysis on a track activity's raw data to detect candidate bad-time periods
1082
1083        :param str key: The unique key of the (track) activity
1084        :param ActivityConfigBadPeriodDetectRequestModel request: An optional time window to constrain detection
1085        :return: The detected candidate bad periods
1086        :rtype: ActivityConfigBadPeriodDetectResultModel
1087        """
1088        pass
1089
1090    @abstractmethod
1091    def merge_bad_periods(self, key: str, request: ActivityConfigBadPeriodMergeRequestModel) -> ActivityConfigBadPeriodMergeResultModel:
1092        """ Merge bad periods into the Quality Control section of an activity's configuration
1093
1094        :param str key: The unique key of the activity
1095        :param ActivityConfigBadPeriodMergeRequestModel request: The periods to merge, and whether this is a dry run
1096        :return: The resulting QC config YAML and merge metadata
1097        :rtype: ActivityConfigBadPeriodMergeResultModel
1098        """
1099        pass
1100
1101    @abstractmethod
1102    def generate_qc_regions(self, key: str, request: ActivityConfigQCRegionGenerateRequestModel) -> ActivityConfigQCRegionGenerateResultModel:
1103        """ Analyze an activity's raw data and generate candidate, labelled QC regions
1104
1105        :param str key: The unique key of the activity
1106        :param ActivityConfigQCRegionGenerateRequestModel request: An optional time window to constrain detection
1107        :return: The generated candidate QC regions
1108        :rtype: ActivityConfigQCRegionGenerateResultModel
1109        """
1110        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def find_activity_config(self, key: str) -> inmotion.models.ActivityConfigModel:
1026    @abstractmethod
1027    def find_activity_config(self, key: str) -> ActivityConfigModel:
1028        """ Retrieve the complete activity configuration (QC, Processing, Custom Data, and History)
1029
1030        :param str key: The unique key of the activity
1031        :return: The full activity configuration
1032        :rtype: ActivityConfigModel
1033        """
1034        pass

Retrieve the complete activity configuration (QC, Processing, Custom Data, and History)

Parameters
  • str key: The unique key of the activity
Returns

The full activity configuration

@abstractmethod
def update_qc_config( self, key: str, qc_update: inmotion.models.ActivityConfigQCUpdateModel) -> inmotion.models.ActivityConfigModel:
1036    @abstractmethod
1037    def update_qc_config(self, key: str, qc_update: ActivityConfigQCUpdateModel) -> ActivityConfigModel:
1038        """ Replace the Quality Control section of an activity's configuration
1039
1040        :param str key: The unique key of the activity
1041        :param ActivityConfigQCUpdateModel qc_update: The replacement QC configuration
1042        :return: The updated full activity configuration
1043        :rtype: ActivityConfigModel
1044        """
1045        pass

Replace the Quality Control section of an activity's configuration

Parameters
  • str key: The unique key of the activity
  • ActivityConfigQCUpdateModel qc_update: The replacement QC configuration
Returns

The updated full activity configuration

@abstractmethod
def update_processing_config( self, key: str, processing_update: inmotion.models.ActivityConfigProcessingUpdateModel) -> inmotion.models.ActivityConfigModel:
1047    @abstractmethod
1048    def update_processing_config(self, key: str, processing_update: ActivityConfigProcessingUpdateModel) -> ActivityConfigModel:
1049        """ Replace the Processing section of an activity's configuration
1050
1051        :param str key: The unique key of the activity
1052        :param ActivityConfigProcessingUpdateModel processing_update: The replacement processing configuration
1053        :return: The updated full activity configuration
1054        :rtype: ActivityConfigModel
1055        """
1056        pass

Replace the Processing section of an activity's configuration

Parameters
  • str key: The unique key of the activity
  • ActivityConfigProcessingUpdateModel processing_update: The replacement processing configuration
Returns

The updated full activity configuration

@abstractmethod
def update_custom_data_config( self, key: str, custom_data_update: inmotion.models.ActivityConfigCustomDataUpdateModel) -> inmotion.models.ActivityConfigModel:
1058    @abstractmethod
1059    def update_custom_data_config(self, key: str, custom_data_update: ActivityConfigCustomDataUpdateModel) -> ActivityConfigModel:
1060        """ Replace the Custom Data section of an activity's configuration
1061
1062        :param str key: The unique key of the activity
1063        :param ActivityConfigCustomDataUpdateModel custom_data_update: The replacement custom data entries
1064        :return: The updated full activity configuration
1065        :rtype: ActivityConfigModel
1066        """
1067        pass

Replace the Custom Data section of an activity's configuration

Parameters
  • str key: The unique key of the activity
  • ActivityConfigCustomDataUpdateModel custom_data_update: The replacement custom data entries
Returns

The updated full activity configuration

@abstractmethod
def delete_activity_config(self, key: str) -> inmotion.models.ActivityConfigDeleteResponseModel:
1069    @abstractmethod
1070    def delete_activity_config(self, key: str) -> ActivityConfigDeleteResponseModel:
1071        """ Delete the entire activity configuration for an activity
1072
1073        :param str key: The unique key of the activity
1074        :return: The result of the delete operation
1075        :rtype: ActivityConfigDeleteResponseModel
1076        """
1077        pass

Delete the entire activity configuration for an activity

Parameters
  • str key: The unique key of the activity
Returns

The result of the delete operation

@abstractmethod
def detect_bad_periods( self, key: str, request: inmotion.models.ActivityConfigBadPeriodDetectRequestModel) -> inmotion.models.ActivityConfigBadPeriodDetectResultModel:
1079    @abstractmethod
1080    def detect_bad_periods(self, key: str, request: ActivityConfigBadPeriodDetectRequestModel) -> ActivityConfigBadPeriodDetectResultModel:
1081        """ Run GPS-spike analysis on a track activity's raw data to detect candidate bad-time periods
1082
1083        :param str key: The unique key of the (track) activity
1084        :param ActivityConfigBadPeriodDetectRequestModel request: An optional time window to constrain detection
1085        :return: The detected candidate bad periods
1086        :rtype: ActivityConfigBadPeriodDetectResultModel
1087        """
1088        pass

Run GPS-spike analysis on a track activity's raw data to detect candidate bad-time periods

Parameters
  • str key: The unique key of the (track) activity
  • ActivityConfigBadPeriodDetectRequestModel request: An optional time window to constrain detection
Returns

The detected candidate bad periods

@abstractmethod
def merge_bad_periods( self, key: str, request: inmotion.models.ActivityConfigBadPeriodMergeRequestModel) -> inmotion.models.ActivityConfigBadPeriodMergeResultModel:
1090    @abstractmethod
1091    def merge_bad_periods(self, key: str, request: ActivityConfigBadPeriodMergeRequestModel) -> ActivityConfigBadPeriodMergeResultModel:
1092        """ Merge bad periods into the Quality Control section of an activity's configuration
1093
1094        :param str key: The unique key of the activity
1095        :param ActivityConfigBadPeriodMergeRequestModel request: The periods to merge, and whether this is a dry run
1096        :return: The resulting QC config YAML and merge metadata
1097        :rtype: ActivityConfigBadPeriodMergeResultModel
1098        """
1099        pass

Merge bad periods into the Quality Control section of an activity's configuration

Parameters
  • str key: The unique key of the activity
  • ActivityConfigBadPeriodMergeRequestModel request: The periods to merge, and whether this is a dry run
Returns

The resulting QC config YAML and merge metadata

@abstractmethod
def generate_qc_regions( self, key: str, request: inmotion.models.ActivityConfigQCRegionGenerateRequestModel) -> inmotion.models.ActivityConfigQCRegionGenerateResultModel:
1101    @abstractmethod
1102    def generate_qc_regions(self, key: str, request: ActivityConfigQCRegionGenerateRequestModel) -> ActivityConfigQCRegionGenerateResultModel:
1103        """ Analyze an activity's raw data and generate candidate, labelled QC regions
1104
1105        :param str key: The unique key of the activity
1106        :param ActivityConfigQCRegionGenerateRequestModel request: An optional time window to constrain detection
1107        :return: The generated candidate QC regions
1108        :rtype: ActivityConfigQCRegionGenerateResultModel
1109        """
1110        pass

Analyze an activity's raw data and generate candidate, labelled QC regions

Parameters
  • str key: The unique key of the activity
  • ActivityConfigQCRegionGenerateRequestModel request: An optional time window to constrain detection
Returns

The generated candidate QC regions

class InMotionApiKeys(abc.ABC):
1170class InMotionApiKeys(ABC):
1171    @abstractmethod
1172    def find_api_keys(self, account_key: str) -> list[AccountAPIKeyModel]:
1173        """ Retrieve the API keys associated with an account
1174
1175        :param str account_key: The unique key of the account
1176        :return: The account's API keys
1177        :rtype: list[AccountAPIKeyModel]
1178        """
1179        pass
1180
1181    @abstractmethod
1182    def create_api_key(self, account_key: str, creator: AccountAPIKeyCreatorModel) -> AccountAPIKeyModel:
1183        """ Create a new API key for an account
1184
1185        :param str account_key: The unique key of the account
1186        :param AccountAPIKeyCreatorModel creator: The definition of the API key to create
1187        :return: The created API key
1188        :rtype: AccountAPIKeyModel
1189        """
1190        pass
1191
1192    @abstractmethod
1193    def update_api_key(self, account_key: str, api_key: str, updator: AccountAPIKeyUpdatorModel) -> AccountAPIKeyModel:
1194        """ Update an existing API key
1195
1196        :param str account_key: The unique key of the account
1197        :param str api_key: The API key to update
1198        :param AccountAPIKeyUpdatorModel updator: The updated fields for the API key
1199        :return: The updated API key
1200        :rtype: AccountAPIKeyModel
1201        """
1202        pass
1203
1204    @abstractmethod
1205    def delete_api_key(self, account_key: str, api_key: str) -> AccountAPIKeyResponseModel:
1206        """ Delete an API key from an account
1207
1208        :param str account_key: The unique key of the account
1209        :param str api_key: The API key to delete
1210        :return: The result of the delete operation
1211        :rtype: AccountAPIKeyResponseModel
1212        """
1213        pass
1214
1215    @abstractmethod
1216    def find_api_key(self, account_key: str, api_key: str) -> AccountAPIKeyModel:
1217        """ Find a specific API key belonging to an account
1218
1219        :param str account_key: The unique key of the account
1220        :param str api_key: The API key to retrieve
1221        :return: The API key
1222        :rtype: AccountAPIKeyModel
1223        """
1224        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def find_api_keys(self, account_key: str) -> list[inmotion.models.AccountAPIKeyModel]:
1171    @abstractmethod
1172    def find_api_keys(self, account_key: str) -> list[AccountAPIKeyModel]:
1173        """ Retrieve the API keys associated with an account
1174
1175        :param str account_key: The unique key of the account
1176        :return: The account's API keys
1177        :rtype: list[AccountAPIKeyModel]
1178        """
1179        pass

Retrieve the API keys associated with an account

Parameters
  • str account_key: The unique key of the account
Returns

The account's API keys

@abstractmethod
def create_api_key( self, account_key: str, creator: inmotion.models.AccountAPIKeyCreatorModel) -> inmotion.models.AccountAPIKeyModel:
1181    @abstractmethod
1182    def create_api_key(self, account_key: str, creator: AccountAPIKeyCreatorModel) -> AccountAPIKeyModel:
1183        """ Create a new API key for an account
1184
1185        :param str account_key: The unique key of the account
1186        :param AccountAPIKeyCreatorModel creator: The definition of the API key to create
1187        :return: The created API key
1188        :rtype: AccountAPIKeyModel
1189        """
1190        pass

Create a new API key for an account

Parameters
  • str account_key: The unique key of the account
  • AccountAPIKeyCreatorModel creator: The definition of the API key to create
Returns

The created API key

@abstractmethod
def update_api_key( self, account_key: str, api_key: str, updator: inmotion.models.AccountAPIKeyUpdatorModel) -> inmotion.models.AccountAPIKeyModel:
1192    @abstractmethod
1193    def update_api_key(self, account_key: str, api_key: str, updator: AccountAPIKeyUpdatorModel) -> AccountAPIKeyModel:
1194        """ Update an existing API key
1195
1196        :param str account_key: The unique key of the account
1197        :param str api_key: The API key to update
1198        :param AccountAPIKeyUpdatorModel updator: The updated fields for the API key
1199        :return: The updated API key
1200        :rtype: AccountAPIKeyModel
1201        """
1202        pass

Update an existing API key

Parameters
  • str account_key: The unique key of the account
  • str api_key: The API key to update
  • AccountAPIKeyUpdatorModel updator: The updated fields for the API key
Returns

The updated API key

@abstractmethod
def delete_api_key( self, account_key: str, api_key: str) -> inmotion.models.AccountAPIKeyResponseModel:
1204    @abstractmethod
1205    def delete_api_key(self, account_key: str, api_key: str) -> AccountAPIKeyResponseModel:
1206        """ Delete an API key from an account
1207
1208        :param str account_key: The unique key of the account
1209        :param str api_key: The API key to delete
1210        :return: The result of the delete operation
1211        :rtype: AccountAPIKeyResponseModel
1212        """
1213        pass

Delete an API key from an account

Parameters
  • str account_key: The unique key of the account
  • str api_key: The API key to delete
Returns

The result of the delete operation

@abstractmethod
def find_api_key( self, account_key: str, api_key: str) -> inmotion.models.AccountAPIKeyModel:
1215    @abstractmethod
1216    def find_api_key(self, account_key: str, api_key: str) -> AccountAPIKeyModel:
1217        """ Find a specific API key belonging to an account
1218
1219        :param str account_key: The unique key of the account
1220        :param str api_key: The API key to retrieve
1221        :return: The API key
1222        :rtype: AccountAPIKeyModel
1223        """
1224        pass

Find a specific API key belonging to an account

Parameters
  • str account_key: The unique key of the account
  • str api_key: The API key to retrieve
Returns

The API key

class InMotionAudit(abc.ABC):
1967class InMotionAudit(ABC):
1968    """ Write-only access to the external audit log: third-party integrations record their own
1969    audit trail entries here, distinct from inMotion's internal account/user audit trail. """
1970
1971    @abstractmethod
1972    def create_audit_batch(self, batch: ExternalAuditBatchModel) -> list[ActivityBatchResultModel]:
1973        """ Write a batch of external audit records (max 100 per batch)
1974
1975        :param ExternalAuditBatchModel batch: The records to write, optionally scoped to an account
1976        :return: One result per submitted record, in the same order, each carrying its own status
1977        :rtype: list[ActivityBatchResultModel]
1978        """
1979        pass

Write-only access to the external audit log: third-party integrations record their own audit trail entries here, distinct from inMotion's internal account/user audit trail.

@abstractmethod
def create_audit_batch( self, batch: inmotion.models.ExternalAuditBatchModel) -> list[inmotion.models.ActivityBatchResultModel]:
1971    @abstractmethod
1972    def create_audit_batch(self, batch: ExternalAuditBatchModel) -> list[ActivityBatchResultModel]:
1973        """ Write a batch of external audit records (max 100 per batch)
1974
1975        :param ExternalAuditBatchModel batch: The records to write, optionally scoped to an account
1976        :return: One result per submitted record, in the same order, each carrying its own status
1977        :rtype: list[ActivityBatchResultModel]
1978        """
1979        pass

Write a batch of external audit records (max 100 per batch)

Parameters
  • ExternalAuditBatchModel batch: The records to write, optionally scoped to an account
Returns

One result per submitted record, in the same order, each carrying its own status

class InMotionDataStream(abc.ABC):
2193class InMotionDataStream(ABC):
2194    """ Data stream management: the data stream entity itself, its hyperslab (array/gridded) data
2195    channels, and its blob (byte-oriented) data channels.
2196
2197    A handful of methods here return a raw ``dict`` rather than a typed model. This isn't a
2198    shortcut - those specific endpoints (hyperslab channel management, and hyperslab invariant/
2199    record data read and write) have no fixed JSON schema on the server: their shape is derived
2200    dynamically per data-channel definition (variable names/types), not declared as a dataclass
2201    anywhere in the server's own model layer. Modeling them as a fixed dataclass here would be
2202    guessing a schema the server itself doesn't have.
2203    """
2204
2205    @abstractmethod
2206    def create_data_stream(self, creator: DataStreamCreatorModel) -> DataStreamDetailsModel:
2207        """ Create a new data stream
2208
2209        :param DataStreamCreatorModel creator: The definition of the data stream to create
2210        :return: The created data stream's details
2211        :rtype: DataStreamDetailsModel
2212        """
2213        pass
2214
2215    @abstractmethod
2216    def update_data_stream(self, key: str, creator: DataStreamCreatorModel) -> DataStreamDetailsModel:
2217        """ Update an existing data stream
2218
2219        :param str key: The unique key of the data stream to update
2220        :param DataStreamCreatorModel creator: The updated definition of the data stream
2221        :return: The updated data stream's details
2222        :rtype: DataStreamDetailsModel
2223        """
2224        pass
2225
2226    @abstractmethod
2227    def find_data_stream(self, key: str) -> DataStreamDetailsModel:
2228        """ Find a data stream by its unique key
2229
2230        :param str key: The unique key of the data stream
2231        :return: The data stream's details
2232        :rtype: DataStreamDetailsModel
2233        """
2234        pass
2235
2236    @abstractmethod
2237    def delete_data_stream(self, key: str) -> dict:
2238        """ Delete a data stream
2239
2240        :param str key: The unique key of the data stream to delete
2241        :return: A raw dict with a 'message' key confirming deletion
2242        :rtype: dict
2243        """
2244        pass
2245
2246    @abstractmethod
2247    def unlock_data_stream(self, key: str) -> dict:
2248        """ Unlock a data stream so that it can be modified or updated
2249
2250        :param str key: The unique key of the data stream to unlock
2251        :return: A raw dict with a 'message' key confirming the unlock
2252        :rtype: dict
2253        """
2254        pass
2255
2256    @abstractmethod
2257    def find_data_streams(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamSummaryModel]:
2258        """ Find data streams matching a filter
2259
2260        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
2261        :return: Summaries of the matching data streams
2262        :rtype: list[DataStreamSummaryModel]
2263        """
2264        pass
2265
2266    @abstractmethod
2267    def find_data_streams_by_name(self, account: str, name_pattern: str) -> list[DataStreamSummaryModel]:
2268        """ Find data streams for an account matching a (partial) name
2269
2270        :param str account: The unique key of the account
2271        :param str name_pattern: A partial name to match data streams against
2272        :return: Summaries of the matching data streams
2273        :rtype: list[DataStreamSummaryModel]
2274        """
2275        pass
2276
2277    @abstractmethod
2278    def create_hyperslab_channel(self, key: str, creator: DataChannelCreatorModel) -> dict:
2279        """ Create a hyperslab (array/gridded) data channel on a data stream
2280
2281        :param str key: The unique key of the data stream
2282        :param DataChannelCreatorModel creator: The definition of the data channel to create
2283        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2284        :rtype: dict
2285        """
2286        pass
2287
2288    @abstractmethod
2289    def update_hyperslab_channel(self, key: str, channel_code: str, creator: DataChannelCreatorModel) -> dict:
2290        """ Update an existing hyperslab data channel
2291
2292        :param str key: The unique key of the data stream
2293        :param str channel_code: The code identifying the channel type to update
2294        :param DataChannelCreatorModel creator: The updated definition of the data channel
2295        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2296        :rtype: dict
2297        """
2298        pass
2299
2300    @abstractmethod
2301    def delete_hyperslab_channel(self, key: str, channel_code: str) -> dict:
2302        """ Delete a hyperslab data channel
2303
2304        :param str key: The unique key of the data stream
2305        :param str channel_code: The code identifying the channel type to delete
2306        :return: A raw dict with 'dsKey', 'channelType', and 'status' keys
2307        :rtype: dict
2308        """
2309        pass
2310
2311    @abstractmethod
2312    def find_invariant_hyperslab_data(self, key: str, channel_code: str) -> dict:
2313        """ Retrieve the invariant (static, non-time-varying) data for a hyperslab channel
2314
2315        :param str key: The unique key of the data stream
2316        :param str channel_code: The code identifying the channel type
2317        :return: A raw dict of the invariant data, shaped per the channel's own variable definitions
2318        :rtype: dict
2319        """
2320        pass
2321
2322    @abstractmethod
2323    def update_invariant_hyperslab_data(self, key: str, channel_code: str, data: dict) -> dict:
2324        """ Update the invariant (static, non-time-varying) data for a hyperslab channel
2325
2326        :param str key: The unique key of the data stream
2327        :param str channel_code: The code identifying the channel type
2328        :param dict data: The invariant data, shaped per the channel's own variable definitions
2329        :return: A raw dict with a 'message' key confirming the update
2330        :rtype: dict
2331        """
2332        pass
2333
2334    @abstractmethod
2335    def find_hyperslab_record_data(self, key: str, channel_code: str, start: datetime, end: datetime) -> dict:
2336        """ Retrieve hyperslab record (time-varying) data within a time range
2337
2338        :param str key: The unique key of the data stream
2339        :param str channel_code: The code identifying the channel type
2340        :param datetime start: The start of the time range (inclusive)
2341        :param datetime end: The end of the time range (inclusive)
2342        :return: A raw dict of the record data, shaped per the channel's own variable definitions
2343        :rtype: dict
2344        """
2345        pass
2346
2347    @abstractmethod
2348    def update_hyperslab_record_data(self, key: str, channel_code: str, data: dict) -> dict:
2349        """ Update hyperslab record (time-varying) data
2350
2351        :param str key: The unique key of the data stream
2352        :param str channel_code: The code identifying the channel type
2353        :param dict data: The record data, shaped per the channel's own variable definitions
2354        :return: A raw dict with a 'message' key confirming the update
2355        :rtype: dict
2356        """
2357        pass
2358
2359    @abstractmethod
2360    def create_blob_channel(self, key: str, creator: DataChannelCreatorModel) -> dict:
2361        """ Create a blob (byte-oriented) data channel on a data stream
2362
2363        :param str key: The unique key of the data stream
2364        :param DataChannelCreatorModel creator: The definition of the data channel to create
2365        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2366        :rtype: dict
2367        """
2368        pass
2369
2370    @abstractmethod
2371    def update_blob_channel(self, key: str, channel_code: str, creator: DataChannelCreatorModel) -> dict:
2372        """ Update an existing blob data channel
2373
2374        :param str key: The unique key of the data stream
2375        :param str channel_code: The code identifying the channel type to update
2376        :param DataChannelCreatorModel creator: The updated definition of the data channel
2377        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2378        :rtype: dict
2379        """
2380        pass
2381
2382    @abstractmethod
2383    def delete_blob_channel(self, key: str, channel_code: str) -> dict:
2384        """ Delete a blob data channel
2385
2386        :param str key: The unique key of the data stream
2387        :param str channel_code: The code identifying the channel type to delete
2388        :return: A raw dict with 'dsKey', 'channelType', and 'status' keys
2389        :rtype: dict
2390        """
2391        pass
2392
2393    @abstractmethod
2394    def find_invariant_blob_data(self, key: str, channel_code: str, profile: str) -> DataStreamInvariantBlobMetadataModel:
2395        """ Retrieve the metadata for the invariant (static) blob data of a channel/profile
2396
2397        :param str key: The unique key of the data stream
2398        :param str channel_code: The code identifying the channel type
2399        :param str profile: The storage profile to retrieve
2400        :return: The invariant blob's metadata
2401        :rtype: DataStreamInvariantBlobMetadataModel
2402        """
2403        pass
2404
2405    @abstractmethod
2406    def update_invariant_blob_data(self, key: str, channel_code: str, profile: str, data: bytes) -> DataStreamInvariantBlobMetadataModel:
2407        """ Update the invariant (static) blob data of a channel/profile
2408
2409        :param str key: The unique key of the data stream
2410        :param str channel_code: The code identifying the channel type
2411        :param str profile: The storage profile to update
2412        :param bytes data: The raw bytes to store
2413        :return: The updated invariant blob's metadata
2414        :rtype: DataStreamInvariantBlobMetadataModel
2415        """
2416        pass
2417
2418    @abstractmethod
2419    def find_blob_record_data(self, key: str, channel_code: str, start: datetime, end: datetime, profile: str) -> dict[str, DataStreamRecordsBlobMetadataModel]:
2420        """ Retrieve the metadata for blob record data within a time range
2421
2422        :param str key: The unique key of the data stream
2423        :param str channel_code: The code identifying the channel type
2424        :param datetime start: The start of the time range (inclusive)
2425        :param datetime end: The end of the time range (inclusive)
2426        :param str profile: The storage profile to retrieve
2427        :return: A map of interval identifier to the matching blob record's metadata
2428        :rtype: dict[str, DataStreamRecordsBlobMetadataModel]
2429        """
2430        pass
2431
2432    @abstractmethod
2433    def find_latest_blob_record_data(self, key: str, channel_code: str, profile: str) -> DataStreamRecordsBlobMetadataModel:
2434        """ Retrieve the metadata for the most recent blob record data of a channel/profile
2435
2436        :param str key: The unique key of the data stream
2437        :param str channel_code: The code identifying the channel type
2438        :param str profile: The storage profile to retrieve
2439        :return: The latest blob record's metadata
2440        :rtype: DataStreamRecordsBlobMetadataModel
2441        """
2442        pass
2443
2444    @abstractmethod
2445    def update_blob_record_data(self, key: str, channel_code: str, start: datetime, end: datetime, profile: str, data: bytes) -> DataStreamRecordsBlobMetadataModel:
2446        """ Update blob record data within a time range
2447
2448        :param str key: The unique key of the data stream
2449        :param str channel_code: The code identifying the channel type
2450        :param datetime start: The start of the time range (inclusive)
2451        :param datetime end: The end of the time range (inclusive)
2452        :param str profile: The storage profile to update
2453        :param bytes data: The raw bytes to store
2454        :return: The updated blob record's metadata
2455        :rtype: DataStreamRecordsBlobMetadataModel
2456        """
2457        pass
2458
2459    @abstractmethod
2460    def open_blob_stream(self, key: str, blob_key: str) -> bytes:
2461        """ Open and read a raw blob's byte stream
2462
2463        :param str key: The unique key of the data stream
2464        :param str blob_key: The unique key of the blob to read
2465        :return: The raw blob content
2466        :rtype: bytes
2467        """
2468        pass
2469
2470    @abstractmethod
2471    def find_blobs(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamBlobSummaryModel]:
2472        """ Find data stream blobs matching a filter
2473
2474        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
2475        :return: Summaries of the matching data stream blobs
2476        :rtype: list[DataStreamBlobSummaryModel]
2477        """
2478        pass

Data stream management: the data stream entity itself, its hyperslab (array/gridded) data channels, and its blob (byte-oriented) data channels.

A handful of methods here return a raw dict rather than a typed model. This isn't a shortcut - those specific endpoints (hyperslab channel management, and hyperslab invariant/ record data read and write) have no fixed JSON schema on the server: their shape is derived dynamically per data-channel definition (variable names/types), not declared as a dataclass anywhere in the server's own model layer. Modeling them as a fixed dataclass here would be guessing a schema the server itself doesn't have.

@abstractmethod
def create_data_stream( self, creator: inmotion.models.DataStreamCreatorModel) -> inmotion.models.DataStreamDetailsModel:
2205    @abstractmethod
2206    def create_data_stream(self, creator: DataStreamCreatorModel) -> DataStreamDetailsModel:
2207        """ Create a new data stream
2208
2209        :param DataStreamCreatorModel creator: The definition of the data stream to create
2210        :return: The created data stream's details
2211        :rtype: DataStreamDetailsModel
2212        """
2213        pass

Create a new data stream

Parameters
  • DataStreamCreatorModel creator: The definition of the data stream to create
Returns

The created data stream's details

@abstractmethod
def update_data_stream( self, key: str, creator: inmotion.models.DataStreamCreatorModel) -> inmotion.models.DataStreamDetailsModel:
2215    @abstractmethod
2216    def update_data_stream(self, key: str, creator: DataStreamCreatorModel) -> DataStreamDetailsModel:
2217        """ Update an existing data stream
2218
2219        :param str key: The unique key of the data stream to update
2220        :param DataStreamCreatorModel creator: The updated definition of the data stream
2221        :return: The updated data stream's details
2222        :rtype: DataStreamDetailsModel
2223        """
2224        pass

Update an existing data stream

Parameters
  • str key: The unique key of the data stream to update
  • DataStreamCreatorModel creator: The updated definition of the data stream
Returns

The updated data stream's details

@abstractmethod
def find_data_stream(self, key: str) -> inmotion.models.DataStreamDetailsModel:
2226    @abstractmethod
2227    def find_data_stream(self, key: str) -> DataStreamDetailsModel:
2228        """ Find a data stream by its unique key
2229
2230        :param str key: The unique key of the data stream
2231        :return: The data stream's details
2232        :rtype: DataStreamDetailsModel
2233        """
2234        pass

Find a data stream by its unique key

Parameters
  • str key: The unique key of the data stream
Returns

The data stream's details

@abstractmethod
def delete_data_stream(self, key: str) -> dict:
2236    @abstractmethod
2237    def delete_data_stream(self, key: str) -> dict:
2238        """ Delete a data stream
2239
2240        :param str key: The unique key of the data stream to delete
2241        :return: A raw dict with a 'message' key confirming deletion
2242        :rtype: dict
2243        """
2244        pass

Delete a data stream

Parameters
  • str key: The unique key of the data stream to delete
Returns

A raw dict with a 'message' key confirming deletion

@abstractmethod
def unlock_data_stream(self, key: str) -> dict:
2246    @abstractmethod
2247    def unlock_data_stream(self, key: str) -> dict:
2248        """ Unlock a data stream so that it can be modified or updated
2249
2250        :param str key: The unique key of the data stream to unlock
2251        :return: A raw dict with a 'message' key confirming the unlock
2252        :rtype: dict
2253        """
2254        pass

Unlock a data stream so that it can be modified or updated

Parameters
  • str key: The unique key of the data stream to unlock
Returns

A raw dict with a 'message' key confirming the unlock

@abstractmethod
def find_data_streams( self, data_stream_filter: inmotion.models.DataStreamFilterModel) -> list[inmotion.models.DataStreamSummaryModel]:
2256    @abstractmethod
2257    def find_data_streams(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamSummaryModel]:
2258        """ Find data streams matching a filter
2259
2260        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
2261        :return: Summaries of the matching data streams
2262        :rtype: list[DataStreamSummaryModel]
2263        """
2264        pass

Find data streams matching a filter

Parameters
  • DataStreamFilterModel data_stream_filter: The filter to apply to the search
Returns

Summaries of the matching data streams

@abstractmethod
def find_data_streams_by_name( self, account: str, name_pattern: str) -> list[inmotion.models.DataStreamSummaryModel]:
2266    @abstractmethod
2267    def find_data_streams_by_name(self, account: str, name_pattern: str) -> list[DataStreamSummaryModel]:
2268        """ Find data streams for an account matching a (partial) name
2269
2270        :param str account: The unique key of the account
2271        :param str name_pattern: A partial name to match data streams against
2272        :return: Summaries of the matching data streams
2273        :rtype: list[DataStreamSummaryModel]
2274        """
2275        pass

Find data streams for an account matching a (partial) name

Parameters
  • str account: The unique key of the account
  • str name_pattern: A partial name to match data streams against
Returns

Summaries of the matching data streams

@abstractmethod
def create_hyperslab_channel(self, key: str, creator: inmotion.models.DataChannelCreatorModel) -> dict:
2277    @abstractmethod
2278    def create_hyperslab_channel(self, key: str, creator: DataChannelCreatorModel) -> dict:
2279        """ Create a hyperslab (array/gridded) data channel on a data stream
2280
2281        :param str key: The unique key of the data stream
2282        :param DataChannelCreatorModel creator: The definition of the data channel to create
2283        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2284        :rtype: dict
2285        """
2286        pass

Create a hyperslab (array/gridded) data channel on a data stream

Parameters
  • str key: The unique key of the data stream
  • DataChannelCreatorModel creator: The definition of the data channel to create
Returns

A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys

@abstractmethod
def update_hyperslab_channel( self, key: str, channel_code: str, creator: inmotion.models.DataChannelCreatorModel) -> dict:
2288    @abstractmethod
2289    def update_hyperslab_channel(self, key: str, channel_code: str, creator: DataChannelCreatorModel) -> dict:
2290        """ Update an existing hyperslab data channel
2291
2292        :param str key: The unique key of the data stream
2293        :param str channel_code: The code identifying the channel type to update
2294        :param DataChannelCreatorModel creator: The updated definition of the data channel
2295        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2296        :rtype: dict
2297        """
2298        pass

Update an existing hyperslab data channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type to update
  • DataChannelCreatorModel creator: The updated definition of the data channel
Returns

A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys

@abstractmethod
def delete_hyperslab_channel(self, key: str, channel_code: str) -> dict:
2300    @abstractmethod
2301    def delete_hyperslab_channel(self, key: str, channel_code: str) -> dict:
2302        """ Delete a hyperslab data channel
2303
2304        :param str key: The unique key of the data stream
2305        :param str channel_code: The code identifying the channel type to delete
2306        :return: A raw dict with 'dsKey', 'channelType', and 'status' keys
2307        :rtype: dict
2308        """
2309        pass

Delete a hyperslab data channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type to delete
Returns

A raw dict with 'dsKey', 'channelType', and 'status' keys

@abstractmethod
def find_invariant_hyperslab_data(self, key: str, channel_code: str) -> dict:
2311    @abstractmethod
2312    def find_invariant_hyperslab_data(self, key: str, channel_code: str) -> dict:
2313        """ Retrieve the invariant (static, non-time-varying) data for a hyperslab channel
2314
2315        :param str key: The unique key of the data stream
2316        :param str channel_code: The code identifying the channel type
2317        :return: A raw dict of the invariant data, shaped per the channel's own variable definitions
2318        :rtype: dict
2319        """
2320        pass

Retrieve the invariant (static, non-time-varying) data for a hyperslab channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
Returns

A raw dict of the invariant data, shaped per the channel's own variable definitions

@abstractmethod
def update_invariant_hyperslab_data(self, key: str, channel_code: str, data: dict) -> dict:
2322    @abstractmethod
2323    def update_invariant_hyperslab_data(self, key: str, channel_code: str, data: dict) -> dict:
2324        """ Update the invariant (static, non-time-varying) data for a hyperslab channel
2325
2326        :param str key: The unique key of the data stream
2327        :param str channel_code: The code identifying the channel type
2328        :param dict data: The invariant data, shaped per the channel's own variable definitions
2329        :return: A raw dict with a 'message' key confirming the update
2330        :rtype: dict
2331        """
2332        pass

Update the invariant (static, non-time-varying) data for a hyperslab channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • dict data: The invariant data, shaped per the channel's own variable definitions
Returns

A raw dict with a 'message' key confirming the update

@abstractmethod
def find_hyperslab_record_data( self, key: str, channel_code: str, start: datetime.datetime, end: datetime.datetime) -> dict:
2334    @abstractmethod
2335    def find_hyperslab_record_data(self, key: str, channel_code: str, start: datetime, end: datetime) -> dict:
2336        """ Retrieve hyperslab record (time-varying) data within a time range
2337
2338        :param str key: The unique key of the data stream
2339        :param str channel_code: The code identifying the channel type
2340        :param datetime start: The start of the time range (inclusive)
2341        :param datetime end: The end of the time range (inclusive)
2342        :return: A raw dict of the record data, shaped per the channel's own variable definitions
2343        :rtype: dict
2344        """
2345        pass

Retrieve hyperslab record (time-varying) data within a time range

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • datetime start: The start of the time range (inclusive)
  • datetime end: The end of the time range (inclusive)
Returns

A raw dict of the record data, shaped per the channel's own variable definitions

@abstractmethod
def update_hyperslab_record_data(self, key: str, channel_code: str, data: dict) -> dict:
2347    @abstractmethod
2348    def update_hyperslab_record_data(self, key: str, channel_code: str, data: dict) -> dict:
2349        """ Update hyperslab record (time-varying) data
2350
2351        :param str key: The unique key of the data stream
2352        :param str channel_code: The code identifying the channel type
2353        :param dict data: The record data, shaped per the channel's own variable definitions
2354        :return: A raw dict with a 'message' key confirming the update
2355        :rtype: dict
2356        """
2357        pass

Update hyperslab record (time-varying) data

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • dict data: The record data, shaped per the channel's own variable definitions
Returns

A raw dict with a 'message' key confirming the update

@abstractmethod
def create_blob_channel(self, key: str, creator: inmotion.models.DataChannelCreatorModel) -> dict:
2359    @abstractmethod
2360    def create_blob_channel(self, key: str, creator: DataChannelCreatorModel) -> dict:
2361        """ Create a blob (byte-oriented) data channel on a data stream
2362
2363        :param str key: The unique key of the data stream
2364        :param DataChannelCreatorModel creator: The definition of the data channel to create
2365        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2366        :rtype: dict
2367        """
2368        pass

Create a blob (byte-oriented) data channel on a data stream

Parameters
  • str key: The unique key of the data stream
  • DataChannelCreatorModel creator: The definition of the data channel to create
Returns

A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys

@abstractmethod
def update_blob_channel( self, key: str, channel_code: str, creator: inmotion.models.DataChannelCreatorModel) -> dict:
2370    @abstractmethod
2371    def update_blob_channel(self, key: str, channel_code: str, creator: DataChannelCreatorModel) -> dict:
2372        """ Update an existing blob data channel
2373
2374        :param str key: The unique key of the data stream
2375        :param str channel_code: The code identifying the channel type to update
2376        :param DataChannelCreatorModel creator: The updated definition of the data channel
2377        :return: A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys
2378        :rtype: dict
2379        """
2380        pass

Update an existing blob data channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type to update
  • DataChannelCreatorModel creator: The updated definition of the data channel
Returns

A raw dict with 'dsKey', 'channelType', 'status', and 'dataChannel' keys

@abstractmethod
def delete_blob_channel(self, key: str, channel_code: str) -> dict:
2382    @abstractmethod
2383    def delete_blob_channel(self, key: str, channel_code: str) -> dict:
2384        """ Delete a blob data channel
2385
2386        :param str key: The unique key of the data stream
2387        :param str channel_code: The code identifying the channel type to delete
2388        :return: A raw dict with 'dsKey', 'channelType', and 'status' keys
2389        :rtype: dict
2390        """
2391        pass

Delete a blob data channel

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type to delete
Returns

A raw dict with 'dsKey', 'channelType', and 'status' keys

@abstractmethod
def find_invariant_blob_data( self, key: str, channel_code: str, profile: str) -> inmotion.models.DataStreamInvariantBlobMetadataModel:
2393    @abstractmethod
2394    def find_invariant_blob_data(self, key: str, channel_code: str, profile: str) -> DataStreamInvariantBlobMetadataModel:
2395        """ Retrieve the metadata for the invariant (static) blob data of a channel/profile
2396
2397        :param str key: The unique key of the data stream
2398        :param str channel_code: The code identifying the channel type
2399        :param str profile: The storage profile to retrieve
2400        :return: The invariant blob's metadata
2401        :rtype: DataStreamInvariantBlobMetadataModel
2402        """
2403        pass

Retrieve the metadata for the invariant (static) blob data of a channel/profile

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • str profile: The storage profile to retrieve
Returns

The invariant blob's metadata

@abstractmethod
def update_invariant_blob_data( self, key: str, channel_code: str, profile: str, data: bytes) -> inmotion.models.DataStreamInvariantBlobMetadataModel:
2405    @abstractmethod
2406    def update_invariant_blob_data(self, key: str, channel_code: str, profile: str, data: bytes) -> DataStreamInvariantBlobMetadataModel:
2407        """ Update the invariant (static) blob data of a channel/profile
2408
2409        :param str key: The unique key of the data stream
2410        :param str channel_code: The code identifying the channel type
2411        :param str profile: The storage profile to update
2412        :param bytes data: The raw bytes to store
2413        :return: The updated invariant blob's metadata
2414        :rtype: DataStreamInvariantBlobMetadataModel
2415        """
2416        pass

Update the invariant (static) blob data of a channel/profile

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • str profile: The storage profile to update
  • bytes data: The raw bytes to store
Returns

The updated invariant blob's metadata

@abstractmethod
def find_blob_record_data( self, key: str, channel_code: str, start: datetime.datetime, end: datetime.datetime, profile: str) -> dict[str, inmotion.models.DataStreamRecordsBlobMetadataModel]:
2418    @abstractmethod
2419    def find_blob_record_data(self, key: str, channel_code: str, start: datetime, end: datetime, profile: str) -> dict[str, DataStreamRecordsBlobMetadataModel]:
2420        """ Retrieve the metadata for blob record data within a time range
2421
2422        :param str key: The unique key of the data stream
2423        :param str channel_code: The code identifying the channel type
2424        :param datetime start: The start of the time range (inclusive)
2425        :param datetime end: The end of the time range (inclusive)
2426        :param str profile: The storage profile to retrieve
2427        :return: A map of interval identifier to the matching blob record's metadata
2428        :rtype: dict[str, DataStreamRecordsBlobMetadataModel]
2429        """
2430        pass

Retrieve the metadata for blob record data within a time range

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • datetime start: The start of the time range (inclusive)
  • datetime end: The end of the time range (inclusive)
  • str profile: The storage profile to retrieve
Returns

A map of interval identifier to the matching blob record's metadata

@abstractmethod
def find_latest_blob_record_data( self, key: str, channel_code: str, profile: str) -> inmotion.models.DataStreamRecordsBlobMetadataModel:
2432    @abstractmethod
2433    def find_latest_blob_record_data(self, key: str, channel_code: str, profile: str) -> DataStreamRecordsBlobMetadataModel:
2434        """ Retrieve the metadata for the most recent blob record data of a channel/profile
2435
2436        :param str key: The unique key of the data stream
2437        :param str channel_code: The code identifying the channel type
2438        :param str profile: The storage profile to retrieve
2439        :return: The latest blob record's metadata
2440        :rtype: DataStreamRecordsBlobMetadataModel
2441        """
2442        pass

Retrieve the metadata for the most recent blob record data of a channel/profile

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • str profile: The storage profile to retrieve
Returns

The latest blob record's metadata

@abstractmethod
def update_blob_record_data( self, key: str, channel_code: str, start: datetime.datetime, end: datetime.datetime, profile: str, data: bytes) -> inmotion.models.DataStreamRecordsBlobMetadataModel:
2444    @abstractmethod
2445    def update_blob_record_data(self, key: str, channel_code: str, start: datetime, end: datetime, profile: str, data: bytes) -> DataStreamRecordsBlobMetadataModel:
2446        """ Update blob record data within a time range
2447
2448        :param str key: The unique key of the data stream
2449        :param str channel_code: The code identifying the channel type
2450        :param datetime start: The start of the time range (inclusive)
2451        :param datetime end: The end of the time range (inclusive)
2452        :param str profile: The storage profile to update
2453        :param bytes data: The raw bytes to store
2454        :return: The updated blob record's metadata
2455        :rtype: DataStreamRecordsBlobMetadataModel
2456        """
2457        pass

Update blob record data within a time range

Parameters
  • str key: The unique key of the data stream
  • str channel_code: The code identifying the channel type
  • datetime start: The start of the time range (inclusive)
  • datetime end: The end of the time range (inclusive)
  • str profile: The storage profile to update
  • bytes data: The raw bytes to store
Returns

The updated blob record's metadata

@abstractmethod
def open_blob_stream(self, key: str, blob_key: str) -> bytes:
2459    @abstractmethod
2460    def open_blob_stream(self, key: str, blob_key: str) -> bytes:
2461        """ Open and read a raw blob's byte stream
2462
2463        :param str key: The unique key of the data stream
2464        :param str blob_key: The unique key of the blob to read
2465        :return: The raw blob content
2466        :rtype: bytes
2467        """
2468        pass

Open and read a raw blob's byte stream

Parameters
  • str key: The unique key of the data stream
  • str blob_key: The unique key of the blob to read
Returns

The raw blob content

@abstractmethod
def find_blobs( self, data_stream_filter: inmotion.models.DataStreamFilterModel) -> list[inmotion.models.DataStreamBlobSummaryModel]:
2470    @abstractmethod
2471    def find_blobs(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamBlobSummaryModel]:
2472        """ Find data stream blobs matching a filter
2473
2474        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
2475        :return: Summaries of the matching data stream blobs
2476        :rtype: list[DataStreamBlobSummaryModel]
2477        """
2478        pass

Find data stream blobs matching a filter

Parameters
  • DataStreamFilterModel data_stream_filter: The filter to apply to the search
Returns

Summaries of the matching data stream blobs

class InMotionDevKeys(abc.ABC):
1113class InMotionDevKeys(ABC):
1114    @abstractmethod
1115    def find_dev_keys(self, account_key: str) -> list[AccountDevKeyModel]:
1116        """ Retrieve the developer keys associated with an account
1117
1118        :param str account_key: The unique key of the account
1119        :return: The account's developer keys
1120        :rtype: list[AccountDevKeyModel]
1121        """
1122        pass
1123
1124    @abstractmethod
1125    def create_dev_key(self, account_key: str, creator: AccountDevKeyCreatorModel) -> AccountDevKeyModel:
1126        """ Create a new developer key for an account
1127
1128        :param str account_key: The unique key of the account
1129        :param AccountDevKeyCreatorModel creator: The definition of the developer key to create
1130        :return: The created developer key
1131        :rtype: AccountDevKeyModel
1132        """
1133        pass
1134
1135    @abstractmethod
1136    def update_dev_key(self, account_key: str, dev_key: str, updator: AccountDevKeyUpdatorModel) -> AccountDevKeyModel:
1137        """ Update an existing developer key
1138
1139        :param str account_key: The unique key of the account
1140        :param str dev_key: The developer key to update
1141        :param AccountDevKeyUpdatorModel updator: The updated fields for the developer key
1142        :return: The updated developer key
1143        :rtype: AccountDevKeyModel
1144        """
1145        pass
1146
1147    @abstractmethod
1148    def delete_dev_key(self, account_key: str, dev_key: str) -> AccountDevKeyResponseModel:
1149        """ Delete a developer key from an account
1150
1151        :param str account_key: The unique key of the account
1152        :param str dev_key: The developer key to delete
1153        :return: The result of the delete operation
1154        :rtype: AccountDevKeyResponseModel
1155        """
1156        pass
1157
1158    @abstractmethod
1159    def find_dev_key(self, account_key: str, dev_key: str) -> AccountDevKeyModel:
1160        """ Find a specific developer key belonging to an account
1161
1162        :param str account_key: The unique key of the account
1163        :param str dev_key: The developer key to retrieve
1164        :return: The developer key
1165        :rtype: AccountDevKeyModel
1166        """
1167        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def find_dev_keys(self, account_key: str) -> list[inmotion.models.AccountDevKeyModel]:
1114    @abstractmethod
1115    def find_dev_keys(self, account_key: str) -> list[AccountDevKeyModel]:
1116        """ Retrieve the developer keys associated with an account
1117
1118        :param str account_key: The unique key of the account
1119        :return: The account's developer keys
1120        :rtype: list[AccountDevKeyModel]
1121        """
1122        pass

Retrieve the developer keys associated with an account

Parameters
  • str account_key: The unique key of the account
Returns

The account's developer keys

@abstractmethod
def create_dev_key( self, account_key: str, creator: inmotion.models.AccountDevKeyCreatorModel) -> inmotion.models.AccountDevKeyModel:
1124    @abstractmethod
1125    def create_dev_key(self, account_key: str, creator: AccountDevKeyCreatorModel) -> AccountDevKeyModel:
1126        """ Create a new developer key for an account
1127
1128        :param str account_key: The unique key of the account
1129        :param AccountDevKeyCreatorModel creator: The definition of the developer key to create
1130        :return: The created developer key
1131        :rtype: AccountDevKeyModel
1132        """
1133        pass

Create a new developer key for an account

Parameters
  • str account_key: The unique key of the account
  • AccountDevKeyCreatorModel creator: The definition of the developer key to create
Returns

The created developer key

@abstractmethod
def update_dev_key( self, account_key: str, dev_key: str, updator: inmotion.models.AccountDevKeyUpdatorModel) -> inmotion.models.AccountDevKeyModel:
1135    @abstractmethod
1136    def update_dev_key(self, account_key: str, dev_key: str, updator: AccountDevKeyUpdatorModel) -> AccountDevKeyModel:
1137        """ Update an existing developer key
1138
1139        :param str account_key: The unique key of the account
1140        :param str dev_key: The developer key to update
1141        :param AccountDevKeyUpdatorModel updator: The updated fields for the developer key
1142        :return: The updated developer key
1143        :rtype: AccountDevKeyModel
1144        """
1145        pass

Update an existing developer key

Parameters
  • str account_key: The unique key of the account
  • str dev_key: The developer key to update
  • AccountDevKeyUpdatorModel updator: The updated fields for the developer key
Returns

The updated developer key

@abstractmethod
def delete_dev_key( self, account_key: str, dev_key: str) -> inmotion.models.AccountDevKeyResponseModel:
1147    @abstractmethod
1148    def delete_dev_key(self, account_key: str, dev_key: str) -> AccountDevKeyResponseModel:
1149        """ Delete a developer key from an account
1150
1151        :param str account_key: The unique key of the account
1152        :param str dev_key: The developer key to delete
1153        :return: The result of the delete operation
1154        :rtype: AccountDevKeyResponseModel
1155        """
1156        pass

Delete a developer key from an account

Parameters
  • str account_key: The unique key of the account
  • str dev_key: The developer key to delete
Returns

The result of the delete operation

@abstractmethod
def find_dev_key( self, account_key: str, dev_key: str) -> inmotion.models.AccountDevKeyModel:
1158    @abstractmethod
1159    def find_dev_key(self, account_key: str, dev_key: str) -> AccountDevKeyModel:
1160        """ Find a specific developer key belonging to an account
1161
1162        :param str account_key: The unique key of the account
1163        :param str dev_key: The developer key to retrieve
1164        :return: The developer key
1165        :rtype: AccountDevKeyModel
1166        """
1167        pass

Find a specific developer key belonging to an account

Parameters
  • str account_key: The unique key of the account
  • str dev_key: The developer key to retrieve
Returns

The developer key

class InMotionEvents(abc.ABC):
594class InMotionEvents(ABC):
595    """ Event management: an Activity peer of Track/Site whose payload is arbitrary (photo,
596    sqlite file, diagnostics, ...) rather than structured hyperslab data. An event is a single
597    point in space/time, optionally carrying a thumbnail/icon. """
598
599    @abstractmethod
600    def create_event(self, event: EventCreatorModel) -> EventDetailsModel:
601        """ Create an event associated with a specific account
602
603        :param EventCreatorModel event: The definition of the event to create. A captured
604            location is required; a thumbnail/icon is optional.
605        :return: The created event's details
606        :rtype: EventDetailsModel
607        """
608        pass
609
610    @abstractmethod
611    def update_event(self, key: str, event: EventUpdateModel) -> EventDetailsModel:
612        """ Update an existing event's underlying data stream metadata, and optionally its
613        captured location and/or thumbnail. Omitting `location` or `thumbnail` leaves the
614        existing value unchanged - there is no way to clear either back to unset once set.
615
616        :param str key: The unique key of the event to update
617        :param EventUpdateModel event: The updated definition of the event
618        :return: The updated event's details
619        :rtype: EventDetailsModel
620        """
621        pass
622
623    @abstractmethod
624    def find_event(self, key: str) -> EventDetailsModel:
625        """ Find an event by its unique key
626
627        :param str key: The unique key of the event
628        :return: The event's details
629        :rtype: EventDetailsModel
630        """
631        pass
632
633    @abstractmethod
634    def delete_event(self, key: str) -> None:
635        """ Delete an event by its unique key, along with all of its associated data
636
637        :param str key: The unique key of the event to delete
638        """
639        pass
640
641    @abstractmethod
642    def unlock_event(self, key: str) -> None:
643        """ Unlock an event so that it can be modified or updated again after having been locked
644
645        :param str key: The unique key of the event to unlock
646        """
647        pass
648
649    @abstractmethod
650    def find_events(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamSummaryModel]:
651        """ Find event summaries matching a data stream filter (account, name, source, etc.),
652        constrained server-side to events regardless of what's supplied
653
654        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
655        :return: Summaries of the matching events
656        :rtype: list[DataStreamSummaryModel]
657        """
658        pass
659
660    @abstractmethod
661    def find_nearby_events(self, nearby_filter: EventNearbyFilterModel) -> list[EventLocationSummaryModel]:
662        """ Find events within a spatio-temporal bounding box, constrained to a supplied set of
663        accounts (never unconstrained - an empty `accounts` list returns no results)
664
665        :param EventNearbyFilterModel nearby_filter: The accounts and spatio-temporal bounds to search
666        :return: The events found within the requested window
667        :rtype: list[EventLocationSummaryModel]
668        """
669        pass

Event management: an Activity peer of Track/Site whose payload is arbitrary (photo, sqlite file, diagnostics, ...) rather than structured hyperslab data. An event is a single point in space/time, optionally carrying a thumbnail/icon.

@abstractmethod
def create_event( self, event: inmotion.models.EventCreatorModel) -> inmotion.models.EventDetailsModel:
599    @abstractmethod
600    def create_event(self, event: EventCreatorModel) -> EventDetailsModel:
601        """ Create an event associated with a specific account
602
603        :param EventCreatorModel event: The definition of the event to create. A captured
604            location is required; a thumbnail/icon is optional.
605        :return: The created event's details
606        :rtype: EventDetailsModel
607        """
608        pass

Create an event associated with a specific account

Parameters
  • EventCreatorModel event: The definition of the event to create. A captured location is required; a thumbnail/icon is optional.
Returns

The created event's details

@abstractmethod
def update_event( self, key: str, event: inmotion.models.EventUpdateModel) -> inmotion.models.EventDetailsModel:
610    @abstractmethod
611    def update_event(self, key: str, event: EventUpdateModel) -> EventDetailsModel:
612        """ Update an existing event's underlying data stream metadata, and optionally its
613        captured location and/or thumbnail. Omitting `location` or `thumbnail` leaves the
614        existing value unchanged - there is no way to clear either back to unset once set.
615
616        :param str key: The unique key of the event to update
617        :param EventUpdateModel event: The updated definition of the event
618        :return: The updated event's details
619        :rtype: EventDetailsModel
620        """
621        pass

Update an existing event's underlying data stream metadata, and optionally its captured location and/or thumbnail. Omitting location or thumbnail leaves the existing value unchanged - there is no way to clear either back to unset once set.

Parameters
  • str key: The unique key of the event to update
  • EventUpdateModel event: The updated definition of the event
Returns

The updated event's details

@abstractmethod
def find_event(self, key: str) -> inmotion.models.EventDetailsModel:
623    @abstractmethod
624    def find_event(self, key: str) -> EventDetailsModel:
625        """ Find an event by its unique key
626
627        :param str key: The unique key of the event
628        :return: The event's details
629        :rtype: EventDetailsModel
630        """
631        pass

Find an event by its unique key

Parameters
  • str key: The unique key of the event
Returns

The event's details

@abstractmethod
def delete_event(self, key: str) -> None:
633    @abstractmethod
634    def delete_event(self, key: str) -> None:
635        """ Delete an event by its unique key, along with all of its associated data
636
637        :param str key: The unique key of the event to delete
638        """
639        pass

Delete an event by its unique key, along with all of its associated data

Parameters
  • str key: The unique key of the event to delete
@abstractmethod
def unlock_event(self, key: str) -> None:
641    @abstractmethod
642    def unlock_event(self, key: str) -> None:
643        """ Unlock an event so that it can be modified or updated again after having been locked
644
645        :param str key: The unique key of the event to unlock
646        """
647        pass

Unlock an event so that it can be modified or updated again after having been locked

Parameters
  • str key: The unique key of the event to unlock
@abstractmethod
def find_events( self, data_stream_filter: inmotion.models.DataStreamFilterModel) -> list[inmotion.models.DataStreamSummaryModel]:
649    @abstractmethod
650    def find_events(self, data_stream_filter: DataStreamFilterModel) -> list[DataStreamSummaryModel]:
651        """ Find event summaries matching a data stream filter (account, name, source, etc.),
652        constrained server-side to events regardless of what's supplied
653
654        :param DataStreamFilterModel data_stream_filter: The filter to apply to the search
655        :return: Summaries of the matching events
656        :rtype: list[DataStreamSummaryModel]
657        """
658        pass

Find event summaries matching a data stream filter (account, name, source, etc.), constrained server-side to events regardless of what's supplied

Parameters
  • DataStreamFilterModel data_stream_filter: The filter to apply to the search
Returns

Summaries of the matching events

@abstractmethod
def find_nearby_events( self, nearby_filter: inmotion.models.EventNearbyFilterModel) -> list[inmotion.models.EventLocationSummaryModel]:
660    @abstractmethod
661    def find_nearby_events(self, nearby_filter: EventNearbyFilterModel) -> list[EventLocationSummaryModel]:
662        """ Find events within a spatio-temporal bounding box, constrained to a supplied set of
663        accounts (never unconstrained - an empty `accounts` list returns no results)
664
665        :param EventNearbyFilterModel nearby_filter: The accounts and spatio-temporal bounds to search
666        :return: The events found within the requested window
667        :rtype: list[EventLocationSummaryModel]
668        """
669        pass

Find events within a spatio-temporal bounding box, constrained to a supplied set of accounts (never unconstrained - an empty accounts list returns no results)

Parameters
  • EventNearbyFilterModel nearby_filter: The accounts and spatio-temporal bounds to search
Returns

The events found within the requested window

class InMotionFolio(abc.ABC):
1469class InMotionFolio(ABC):
1470    """ Folio management: a tree-structured document attached to an account - a versioned root
1471    plus an arbitrary tree of named sections, each holding items that are either inline
1472    structured text or references to an Activity, DataStream, or another Folio. """
1473
1474    @abstractmethod
1475    def create_folio(self, folio: FolioModel) -> FolioDetailsModel:
1476        """ Create a new, top-level, account-owned folio
1477
1478        :param FolioModel folio: The definition of the folio to create. `templateYaml` may be
1479            supplied to attach a validation template, fixed for the folio's lifetime.
1480        :return: The created folio's details
1481        :rtype: FolioDetailsModel
1482        """
1483        pass
1484
1485    @abstractmethod
1486    def update_folio(self, key: str, folio: FolioModel) -> FolioDetailsModel:
1487        """ Update a folio's own metadata (name, description, folioType). Does not touch its
1488        section tree - use the section/item methods below for that.
1489
1490        :param str key: The unique key of the folio to update
1491        :param FolioModel folio: The updated definition of the folio
1492        :return: The updated folio's details
1493        :rtype: FolioDetailsModel
1494        """
1495        pass
1496
1497    @abstractmethod
1498    def set_folio_locked(self, key: str, locked: bool) -> FolioDetailsModel:
1499        """ Lock or unlock a folio against further Contributor edits, independent of how it was
1500        created. Any Contributor (or above) may call this at any time, regardless of the folio's
1501        current locked state - unlike update_folio, this is never blocked by the folio being
1502        locked or API-created.
1503
1504        :param str key: The unique key of the folio
1505        :param bool locked: True to lock, False to unlock
1506        :return: The folio's details, with its updated locked state
1507        :rtype: FolioDetailsModel
1508        """
1509        pass
1510
1511    @abstractmethod
1512    def find_folio(self, key: str) -> FolioDetailsModel:
1513        """ Find a folio by its unique key, including its full section tree
1514
1515        :param str key: The unique key of the folio
1516        :return: The folio's details
1517        :rtype: FolioDetailsModel
1518        """
1519        pass
1520
1521    @abstractmethod
1522    def delete_folio(self, key: str) -> None:
1523        """ Delete a folio by its unique key, along with its entire section tree
1524
1525        :param str key: The unique key of the folio to delete
1526        """
1527        pass
1528
1529    @abstractmethod
1530    def find_folios(self, account_key: str, name: Optional[str] = None, folio_type: Optional[str] = None) -> list[FolioSummaryModel]:
1531        """ List folio summaries for an account, optionally filtered by name and/or folio type
1532
1533        :param str account_key: The unique key of the account
1534        :param Optional[str] name: An optional name to filter by
1535        :param Optional[str] folio_type: An optional folio type to filter by
1536        :return: The matching folio summaries
1537        :rtype: list[FolioSummaryModel]
1538        """
1539        pass
1540
1541    @abstractmethod
1542    def find_folios_by_reference(self, account_key: str, ref_key: str) -> list[FolioSummaryModel]:
1543        """ List folio summaries for an account that contain at least one item (Activity,
1544        DataStream, or Folio reference) pointing at the given key
1545
1546        :param str account_key: The unique key of the account
1547        :param str ref_key: The key of the referenced Activity, DataStream, or Folio
1548        :return: The matching folio summaries
1549        :rtype: list[FolioSummaryModel]
1550        """
1551        pass
1552
1553    @abstractmethod
1554    def find_section(self, key: str, path: Optional[str] = None, deep: bool = False) -> FolioRootModel | FolioSectionModel:
1555        """ Find the root or a named section of a folio's tree, addressed by `path`
1556
1557        :param str key: The unique key of the folio
1558        :param Optional[str] path: "/"-separated section path from the root, e.g.
1559            "Eye Tests/2026-08-04". Omitted or empty addresses the root.
1560        :param bool deep: If True, include the full subtree beneath the addressed section, not
1561            just its immediate children
1562        :return: The root (if `path` addresses it) or the section at `path`
1563        :rtype: FolioRootModel | FolioSectionModel
1564        """
1565        pass
1566
1567    @abstractmethod
1568    def create_section(self, key: str, section: FolioSectionCreateModel, path: Optional[str] = None) -> None:
1569        """ Add a new named section as a child of the section (or root) addressed by `path`
1570
1571        :param str key: The unique key of the folio
1572        :param FolioSectionCreateModel section: The definition of the section to create
1573        :param Optional[str] path: "/"-separated parent section path from the root. Omitted or
1574            empty adds the new section directly beneath the root.
1575        """
1576        pass
1577
1578    @abstractmethod
1579    def update_section(self, key: str, section: FolioSectionUpdateModel, path: Optional[str] = None) -> None:
1580        """ Update the section (or root) addressed by `path`. Only the fields supplied on
1581        `section` change; omitted fields are left as-is.
1582
1583        :param str key: The unique key of the folio
1584        :param FolioSectionUpdateModel section: The fields to update
1585        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1586            addresses the root.
1587        """
1588        pass
1589
1590    @abstractmethod
1591    def delete_section(self, key: str, path: Optional[str] = None, cascade: bool = False) -> None:
1592        """ Delete the section addressed by `path` (the root itself cannot be deleted this way -
1593        use delete_folio instead)
1594
1595        :param str key: The unique key of the folio
1596        :param Optional[str] path: "/"-separated section path from the root
1597        :param bool cascade: If True, delete the section's contents (sub-sections and items)
1598            along with it - otherwise fails if the section has children
1599        """
1600        pass
1601
1602    @abstractmethod
1603    def add_items(self, key: str, items: list[FolioItemModel], path: Optional[str] = None) -> None:
1604        """ Add one or more items to the section (or root) addressed by `path`
1605
1606        :param str key: The unique key of the folio
1607        :param list[FolioItemModel] items: The items to add - each item's `kind` selects its shape
1608        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1609            addresses the root.
1610        """
1611        pass
1612
1613    @abstractmethod
1614    def delete_items(self, key: str, item_names: list[str], path: Optional[str] = None, cascade: bool = False) -> None:
1615        """ Delete one or more named items from the section (or root) addressed by `path`
1616
1617        :param str key: The unique key of the folio
1618        :param list[str] item_names: The names of the items to delete
1619        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1620            addresses the root.
1621        :param bool cascade: If True, and an item is an owned reference (Activity/DataStream/
1622            Folio), also delete the referenced entity
1623        """
1624        pass
1625
1626    @abstractmethod
1627    def update_item(self, key: str, item_name: str, item: FolioItemModel, path: Optional[str] = None) -> None:
1628        """ Replace a named item in the section (or root) addressed by `path`
1629
1630        :param str key: The unique key of the folio
1631        :param str item_name: The name of the item to replace
1632        :param FolioItemModel item: The item's replacement definition - `kind` selects its shape
1633        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1634            addresses the root.
1635        """
1636        pass
1637
1638    @abstractmethod
1639    def delete_item(self, key: str, item_name: str, path: Optional[str] = None, cascade: bool = False) -> None:
1640        """ Delete a single named item from the section (or root) addressed by `path`
1641
1642        :param str key: The unique key of the folio
1643        :param str item_name: The name of the item to delete
1644        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1645            addresses the root.
1646        :param bool cascade: If True, and the item is an owned reference (Activity/DataStream/
1647            Folio), also delete the referenced entity
1648        """
1649        pass
1650
1651    @abstractmethod
1652    def validate_folio(self, key: str, path: Optional[str] = None) -> FolioValidationReportModel:
1653        """ Check the root or section at `path` against the folio's optional template. Never
1654        fails because the folio doesn't (yet) satisfy it - an empty `issues` list means either
1655        there's no template, or it's fully satisfied at and below `path`.
1656
1657        :param str key: The unique key of the folio
1658        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1659            addresses the root.
1660        :return: The validation report
1661        :rtype: FolioValidationReportModel
1662        """
1663        pass

Folio management: a tree-structured document attached to an account - a versioned root plus an arbitrary tree of named sections, each holding items that are either inline structured text or references to an Activity, DataStream, or another Folio.

@abstractmethod
def create_folio( self, folio: inmotion.models.FolioModel) -> inmotion.models.FolioDetailsModel:
1474    @abstractmethod
1475    def create_folio(self, folio: FolioModel) -> FolioDetailsModel:
1476        """ Create a new, top-level, account-owned folio
1477
1478        :param FolioModel folio: The definition of the folio to create. `templateYaml` may be
1479            supplied to attach a validation template, fixed for the folio's lifetime.
1480        :return: The created folio's details
1481        :rtype: FolioDetailsModel
1482        """
1483        pass

Create a new, top-level, account-owned folio

Parameters
  • FolioModel folio: The definition of the folio to create. templateYaml may be supplied to attach a validation template, fixed for the folio's lifetime.
Returns

The created folio's details

@abstractmethod
def update_folio( self, key: str, folio: inmotion.models.FolioModel) -> inmotion.models.FolioDetailsModel:
1485    @abstractmethod
1486    def update_folio(self, key: str, folio: FolioModel) -> FolioDetailsModel:
1487        """ Update a folio's own metadata (name, description, folioType). Does not touch its
1488        section tree - use the section/item methods below for that.
1489
1490        :param str key: The unique key of the folio to update
1491        :param FolioModel folio: The updated definition of the folio
1492        :return: The updated folio's details
1493        :rtype: FolioDetailsModel
1494        """
1495        pass

Update a folio's own metadata (name, description, folioType). Does not touch its section tree - use the section/item methods below for that.

Parameters
  • str key: The unique key of the folio to update
  • FolioModel folio: The updated definition of the folio
Returns

The updated folio's details

@abstractmethod
def set_folio_locked(self, key: str, locked: bool) -> inmotion.models.FolioDetailsModel:
1497    @abstractmethod
1498    def set_folio_locked(self, key: str, locked: bool) -> FolioDetailsModel:
1499        """ Lock or unlock a folio against further Contributor edits, independent of how it was
1500        created. Any Contributor (or above) may call this at any time, regardless of the folio's
1501        current locked state - unlike update_folio, this is never blocked by the folio being
1502        locked or API-created.
1503
1504        :param str key: The unique key of the folio
1505        :param bool locked: True to lock, False to unlock
1506        :return: The folio's details, with its updated locked state
1507        :rtype: FolioDetailsModel
1508        """
1509        pass

Lock or unlock a folio against further Contributor edits, independent of how it was created. Any Contributor (or above) may call this at any time, regardless of the folio's current locked state - unlike update_folio, this is never blocked by the folio being locked or API-created.

Parameters
  • str key: The unique key of the folio
  • bool locked: True to lock, False to unlock
Returns

The folio's details, with its updated locked state

@abstractmethod
def find_folio(self, key: str) -> inmotion.models.FolioDetailsModel:
1511    @abstractmethod
1512    def find_folio(self, key: str) -> FolioDetailsModel:
1513        """ Find a folio by its unique key, including its full section tree
1514
1515        :param str key: The unique key of the folio
1516        :return: The folio's details
1517        :rtype: FolioDetailsModel
1518        """
1519        pass

Find a folio by its unique key, including its full section tree

Parameters
  • str key: The unique key of the folio
Returns

The folio's details

@abstractmethod
def delete_folio(self, key: str) -> None:
1521    @abstractmethod
1522    def delete_folio(self, key: str) -> None:
1523        """ Delete a folio by its unique key, along with its entire section tree
1524
1525        :param str key: The unique key of the folio to delete
1526        """
1527        pass

Delete a folio by its unique key, along with its entire section tree

Parameters
  • str key: The unique key of the folio to delete
@abstractmethod
def find_folios( self, account_key: str, name: Optional[str] = None, folio_type: Optional[str] = None) -> list[inmotion.models.FolioSummaryModel]:
1529    @abstractmethod
1530    def find_folios(self, account_key: str, name: Optional[str] = None, folio_type: Optional[str] = None) -> list[FolioSummaryModel]:
1531        """ List folio summaries for an account, optionally filtered by name and/or folio type
1532
1533        :param str account_key: The unique key of the account
1534        :param Optional[str] name: An optional name to filter by
1535        :param Optional[str] folio_type: An optional folio type to filter by
1536        :return: The matching folio summaries
1537        :rtype: list[FolioSummaryModel]
1538        """
1539        pass

List folio summaries for an account, optionally filtered by name and/or folio type

Parameters
  • str account_key: The unique key of the account
  • Optional[str] name: An optional name to filter by
  • Optional[str] folio_type: An optional folio type to filter by
Returns

The matching folio summaries

@abstractmethod
def find_folios_by_reference( self, account_key: str, ref_key: str) -> list[inmotion.models.FolioSummaryModel]:
1541    @abstractmethod
1542    def find_folios_by_reference(self, account_key: str, ref_key: str) -> list[FolioSummaryModel]:
1543        """ List folio summaries for an account that contain at least one item (Activity,
1544        DataStream, or Folio reference) pointing at the given key
1545
1546        :param str account_key: The unique key of the account
1547        :param str ref_key: The key of the referenced Activity, DataStream, or Folio
1548        :return: The matching folio summaries
1549        :rtype: list[FolioSummaryModel]
1550        """
1551        pass

List folio summaries for an account that contain at least one item (Activity, DataStream, or Folio reference) pointing at the given key

Parameters
  • str account_key: The unique key of the account
  • str ref_key: The key of the referenced Activity, DataStream, or Folio
Returns

The matching folio summaries

@abstractmethod
def find_section( self, key: str, path: Optional[str] = None, deep: bool = False) -> inmotion.models.FolioRootModel | inmotion.models.FolioSectionModel:
1553    @abstractmethod
1554    def find_section(self, key: str, path: Optional[str] = None, deep: bool = False) -> FolioRootModel | FolioSectionModel:
1555        """ Find the root or a named section of a folio's tree, addressed by `path`
1556
1557        :param str key: The unique key of the folio
1558        :param Optional[str] path: "/"-separated section path from the root, e.g.
1559            "Eye Tests/2026-08-04". Omitted or empty addresses the root.
1560        :param bool deep: If True, include the full subtree beneath the addressed section, not
1561            just its immediate children
1562        :return: The root (if `path` addresses it) or the section at `path`
1563        :rtype: FolioRootModel | FolioSectionModel
1564        """
1565        pass

Find the root or a named section of a folio's tree, addressed by path

Parameters
  • str key: The unique key of the folio
  • Optional[str] path: "/"-separated section path from the root, e.g. "Eye Tests/2026-08-04". Omitted or empty addresses the root.
  • bool deep: If True, include the full subtree beneath the addressed section, not just its immediate children
Returns

The root (if path addresses it) or the section at path

@abstractmethod
def create_section( self, key: str, section: inmotion.models.FolioSectionCreateModel, path: Optional[str] = None) -> None:
1567    @abstractmethod
1568    def create_section(self, key: str, section: FolioSectionCreateModel, path: Optional[str] = None) -> None:
1569        """ Add a new named section as a child of the section (or root) addressed by `path`
1570
1571        :param str key: The unique key of the folio
1572        :param FolioSectionCreateModel section: The definition of the section to create
1573        :param Optional[str] path: "/"-separated parent section path from the root. Omitted or
1574            empty adds the new section directly beneath the root.
1575        """
1576        pass

Add a new named section as a child of the section (or root) addressed by path

Parameters
  • str key: The unique key of the folio
  • FolioSectionCreateModel section: The definition of the section to create
  • Optional[str] path: "/"-separated parent section path from the root. Omitted or empty adds the new section directly beneath the root.
@abstractmethod
def update_section( self, key: str, section: inmotion.models.FolioSectionUpdateModel, path: Optional[str] = None) -> None:
1578    @abstractmethod
1579    def update_section(self, key: str, section: FolioSectionUpdateModel, path: Optional[str] = None) -> None:
1580        """ Update the section (or root) addressed by `path`. Only the fields supplied on
1581        `section` change; omitted fields are left as-is.
1582
1583        :param str key: The unique key of the folio
1584        :param FolioSectionUpdateModel section: The fields to update
1585        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1586            addresses the root.
1587        """
1588        pass

Update the section (or root) addressed by path. Only the fields supplied on section change; omitted fields are left as-is.

Parameters
  • str key: The unique key of the folio
  • FolioSectionUpdateModel section: The fields to update
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
@abstractmethod
def delete_section( self, key: str, path: Optional[str] = None, cascade: bool = False) -> None:
1590    @abstractmethod
1591    def delete_section(self, key: str, path: Optional[str] = None, cascade: bool = False) -> None:
1592        """ Delete the section addressed by `path` (the root itself cannot be deleted this way -
1593        use delete_folio instead)
1594
1595        :param str key: The unique key of the folio
1596        :param Optional[str] path: "/"-separated section path from the root
1597        :param bool cascade: If True, delete the section's contents (sub-sections and items)
1598            along with it - otherwise fails if the section has children
1599        """
1600        pass

Delete the section addressed by path (the root itself cannot be deleted this way - use delete_folio instead)

Parameters
  • str key: The unique key of the folio
  • Optional[str] path: "/"-separated section path from the root
  • bool cascade: If True, delete the section's contents (sub-sections and items) along with it - otherwise fails if the section has children
@abstractmethod
def add_items( self, key: str, items: list[inmotion.models.FolioItemModel], path: Optional[str] = None) -> None:
1602    @abstractmethod
1603    def add_items(self, key: str, items: list[FolioItemModel], path: Optional[str] = None) -> None:
1604        """ Add one or more items to the section (or root) addressed by `path`
1605
1606        :param str key: The unique key of the folio
1607        :param list[FolioItemModel] items: The items to add - each item's `kind` selects its shape
1608        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1609            addresses the root.
1610        """
1611        pass

Add one or more items to the section (or root) addressed by path

Parameters
  • str key: The unique key of the folio
  • list[FolioItemModel] items: The items to add - each item's kind selects its shape
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
@abstractmethod
def delete_items( self, key: str, item_names: list[str], path: Optional[str] = None, cascade: bool = False) -> None:
1613    @abstractmethod
1614    def delete_items(self, key: str, item_names: list[str], path: Optional[str] = None, cascade: bool = False) -> None:
1615        """ Delete one or more named items from the section (or root) addressed by `path`
1616
1617        :param str key: The unique key of the folio
1618        :param list[str] item_names: The names of the items to delete
1619        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1620            addresses the root.
1621        :param bool cascade: If True, and an item is an owned reference (Activity/DataStream/
1622            Folio), also delete the referenced entity
1623        """
1624        pass

Delete one or more named items from the section (or root) addressed by path

Parameters
  • str key: The unique key of the folio
  • list[str] item_names: The names of the items to delete
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
  • bool cascade: If True, and an item is an owned reference (Activity/DataStream/ Folio), also delete the referenced entity
@abstractmethod
def update_item( self, key: str, item_name: str, item: inmotion.models.FolioItemModel, path: Optional[str] = None) -> None:
1626    @abstractmethod
1627    def update_item(self, key: str, item_name: str, item: FolioItemModel, path: Optional[str] = None) -> None:
1628        """ Replace a named item in the section (or root) addressed by `path`
1629
1630        :param str key: The unique key of the folio
1631        :param str item_name: The name of the item to replace
1632        :param FolioItemModel item: The item's replacement definition - `kind` selects its shape
1633        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1634            addresses the root.
1635        """
1636        pass

Replace a named item in the section (or root) addressed by path

Parameters
  • str key: The unique key of the folio
  • str item_name: The name of the item to replace
  • FolioItemModel item: The item's replacement definition - kind selects its shape
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
@abstractmethod
def delete_item( self, key: str, item_name: str, path: Optional[str] = None, cascade: bool = False) -> None:
1638    @abstractmethod
1639    def delete_item(self, key: str, item_name: str, path: Optional[str] = None, cascade: bool = False) -> None:
1640        """ Delete a single named item from the section (or root) addressed by `path`
1641
1642        :param str key: The unique key of the folio
1643        :param str item_name: The name of the item to delete
1644        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1645            addresses the root.
1646        :param bool cascade: If True, and the item is an owned reference (Activity/DataStream/
1647            Folio), also delete the referenced entity
1648        """
1649        pass

Delete a single named item from the section (or root) addressed by path

Parameters
  • str key: The unique key of the folio
  • str item_name: The name of the item to delete
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
  • bool cascade: If True, and the item is an owned reference (Activity/DataStream/ Folio), also delete the referenced entity
@abstractmethod
def validate_folio( self, key: str, path: Optional[str] = None) -> inmotion.models.FolioValidationReportModel:
1651    @abstractmethod
1652    def validate_folio(self, key: str, path: Optional[str] = None) -> FolioValidationReportModel:
1653        """ Check the root or section at `path` against the folio's optional template. Never
1654        fails because the folio doesn't (yet) satisfy it - an empty `issues` list means either
1655        there's no template, or it's fully satisfied at and below `path`.
1656
1657        :param str key: The unique key of the folio
1658        :param Optional[str] path: "/"-separated section path from the root. Omitted or empty
1659            addresses the root.
1660        :return: The validation report
1661        :rtype: FolioValidationReportModel
1662        """
1663        pass

Check the root or section at path against the folio's optional template. Never fails because the folio doesn't (yet) satisfy it - an empty issues list means either there's no template, or it's fully satisfied at and below path.

Parameters
  • str key: The unique key of the folio
  • Optional[str] path: "/"-separated section path from the root. Omitted or empty addresses the root.
Returns

The validation report

class InMotionModel(abc.ABC):
2075class InMotionModel(ABC):
2076    """ Model catalogue: the models (equipment/sensor taxonomies) visible to or activated by an
2077    account, their node trees, and the tagging of data streams against tree nodes.
2078
2079    ``select_model``/``deselect_model``/``tag_stream``/``untag_stream`` return a raw ``dict``
2080    (e.g. ``{"selected": True}``) rather than a typed model, since the server returns an ad hoc
2081    acknowledgement object with no declared schema. """
2082
2083    @abstractmethod
2084    def find_visible_models(self, account_key: str) -> list[ModelSummaryModel]:
2085        """ List the models visible to an account
2086
2087        :param str account_key: The unique key of the account
2088        :return: Summaries of the visible models
2089        :rtype: list[ModelSummaryModel]
2090        """
2091        pass
2092
2093    @abstractmethod
2094    def find_selected_models(self, account_key: str) -> list[ModelSummaryModel]:
2095        """ List the models an account has activated
2096
2097        :param str account_key: The unique key of the account
2098        :return: Summaries of the activated models
2099        :rtype: list[ModelSummaryModel]
2100        """
2101        pass
2102
2103    @abstractmethod
2104    def find_model_tree(self, key: str, account_key: str) -> ModelTreeModel:
2105        """ Find a model's node tree
2106
2107        :param str key: The unique key of the model
2108        :param str account_key: The unique key of the account
2109        :return: The model's summary and its tree of nodes
2110        :rtype: ModelTreeModel
2111        """
2112        pass
2113
2114    @abstractmethod
2115    def select_model(self, key: str, account_key: str) -> dict:
2116        """ Activate a model for an account
2117
2118        :param str key: The unique key of the model
2119        :param str account_key: The unique key of the account
2120        :return: A raw dict acknowledging the selection, e.g. {"selected": True}
2121        :rtype: dict
2122        """
2123        pass
2124
2125    @abstractmethod
2126    def deselect_model(self, key: str, account_key: str) -> dict:
2127        """ Deactivate a model for an account
2128
2129        :param str key: The unique key of the model
2130        :param str account_key: The unique key of the account
2131        :return: A raw dict acknowledging the deselection, e.g. {"selected": False}
2132        :rtype: dict
2133        """
2134        pass
2135
2136    @abstractmethod
2137    def find_streams_for_node(self, key: str, account_key: str, path: Optional[str] = None) -> list[str]:
2138        """ Find the data stream keys tagged at a model tree node
2139
2140        :param str key: The unique key of the model
2141        :param str account_key: The unique key of the account
2142        :param Optional[str] path: An optional path to a specific node within the tree
2143        :return: The matching data stream keys
2144        :rtype: list[str]
2145        """
2146        pass
2147
2148    @abstractmethod
2149    def find_tags_for_stream(self, data_stream_key: str) -> list[StreamTagModel]:
2150        """ Find the model tree tags applied to a data stream
2151
2152        :param str data_stream_key: The unique key of the data stream
2153        :return: The matching tags
2154        :rtype: list[StreamTagModel]
2155        """
2156        pass
2157
2158    @abstractmethod
2159    def find_tags_for_account(self, account_key: str) -> list[StreamTagModel]:
2160        """ Find every model tree tag an account has made
2161
2162        :param str account_key: The unique key of the account
2163        :return: The matching tags
2164        :rtype: list[StreamTagModel]
2165        """
2166        pass
2167
2168    @abstractmethod
2169    def tag_stream(self, data_stream_key: str, account_key: str, tag: StreamTagRequestModel) -> dict:
2170        """ Tag a data stream against a model tree node
2171
2172        :param str data_stream_key: The unique key of the data stream
2173        :param str account_key: The unique key of the account
2174        :param StreamTagRequestModel tag: The model and node path to tag against
2175        :return: A raw dict acknowledging the tag, e.g. {"tagged": True}
2176        :rtype: dict
2177        """
2178        pass
2179
2180    @abstractmethod
2181    def untag_stream(self, data_stream_key: str, account_key: str, tag: StreamTagRequestModel) -> dict:
2182        """ Remove a tag from a data stream
2183
2184        :param str data_stream_key: The unique key of the data stream
2185        :param str account_key: The unique key of the account
2186        :param StreamTagRequestModel tag: The model and node path to untag
2187        :return: A raw dict acknowledging the untag, e.g. {"tagged": False}
2188        :rtype: dict
2189        """
2190        pass

Model catalogue: the models (equipment/sensor taxonomies) visible to or activated by an account, their node trees, and the tagging of data streams against tree nodes.

select_model/deselect_model/tag_stream/untag_stream return a raw dict (e.g. {"selected": True}) rather than a typed model, since the server returns an ad hoc acknowledgement object with no declared schema.

@abstractmethod
def find_visible_models(self, account_key: str) -> list[inmotion.models.ModelSummaryModel]:
2083    @abstractmethod
2084    def find_visible_models(self, account_key: str) -> list[ModelSummaryModel]:
2085        """ List the models visible to an account
2086
2087        :param str account_key: The unique key of the account
2088        :return: Summaries of the visible models
2089        :rtype: list[ModelSummaryModel]
2090        """
2091        pass

List the models visible to an account

Parameters
  • str account_key: The unique key of the account
Returns

Summaries of the visible models

@abstractmethod
def find_selected_models(self, account_key: str) -> list[inmotion.models.ModelSummaryModel]:
2093    @abstractmethod
2094    def find_selected_models(self, account_key: str) -> list[ModelSummaryModel]:
2095        """ List the models an account has activated
2096
2097        :param str account_key: The unique key of the account
2098        :return: Summaries of the activated models
2099        :rtype: list[ModelSummaryModel]
2100        """
2101        pass

List the models an account has activated

Parameters
  • str account_key: The unique key of the account
Returns

Summaries of the activated models

@abstractmethod
def find_model_tree(self, key: str, account_key: str) -> inmotion.models.ModelTreeModel:
2103    @abstractmethod
2104    def find_model_tree(self, key: str, account_key: str) -> ModelTreeModel:
2105        """ Find a model's node tree
2106
2107        :param str key: The unique key of the model
2108        :param str account_key: The unique key of the account
2109        :return: The model's summary and its tree of nodes
2110        :rtype: ModelTreeModel
2111        """
2112        pass

Find a model's node tree

Parameters
  • str key: The unique key of the model
  • str account_key: The unique key of the account
Returns

The model's summary and its tree of nodes

@abstractmethod
def select_model(self, key: str, account_key: str) -> dict:
2114    @abstractmethod
2115    def select_model(self, key: str, account_key: str) -> dict:
2116        """ Activate a model for an account
2117
2118        :param str key: The unique key of the model
2119        :param str account_key: The unique key of the account
2120        :return: A raw dict acknowledging the selection, e.g. {"selected": True}
2121        :rtype: dict
2122        """
2123        pass

Activate a model for an account

Parameters
  • str key: The unique key of the model
  • str account_key: The unique key of the account
Returns

A raw dict acknowledging the selection, e.g. {"selected": True}

@abstractmethod
def deselect_model(self, key: str, account_key: str) -> dict:
2125    @abstractmethod
2126    def deselect_model(self, key: str, account_key: str) -> dict:
2127        """ Deactivate a model for an account
2128
2129        :param str key: The unique key of the model
2130        :param str account_key: The unique key of the account
2131        :return: A raw dict acknowledging the deselection, e.g. {"selected": False}
2132        :rtype: dict
2133        """
2134        pass

Deactivate a model for an account

Parameters
  • str key: The unique key of the model
  • str account_key: The unique key of the account
Returns

A raw dict acknowledging the deselection, e.g. {"selected": False}

@abstractmethod
def find_streams_for_node( self, key: str, account_key: str, path: Optional[str] = None) -> list[str]:
2136    @abstractmethod
2137    def find_streams_for_node(self, key: str, account_key: str, path: Optional[str] = None) -> list[str]:
2138        """ Find the data stream keys tagged at a model tree node
2139
2140        :param str key: The unique key of the model
2141        :param str account_key: The unique key of the account
2142        :param Optional[str] path: An optional path to a specific node within the tree
2143        :return: The matching data stream keys
2144        :rtype: list[str]
2145        """
2146        pass

Find the data stream keys tagged at a model tree node

Parameters
  • str key: The unique key of the model
  • str account_key: The unique key of the account
  • Optional[str] path: An optional path to a specific node within the tree
Returns

The matching data stream keys

@abstractmethod
def find_tags_for_stream(self, data_stream_key: str) -> list[inmotion.models.StreamTagModel]:
2148    @abstractmethod
2149    def find_tags_for_stream(self, data_stream_key: str) -> list[StreamTagModel]:
2150        """ Find the model tree tags applied to a data stream
2151
2152        :param str data_stream_key: The unique key of the data stream
2153        :return: The matching tags
2154        :rtype: list[StreamTagModel]
2155        """
2156        pass

Find the model tree tags applied to a data stream

Parameters
  • str data_stream_key: The unique key of the data stream
Returns

The matching tags

@abstractmethod
def find_tags_for_account(self, account_key: str) -> list[inmotion.models.StreamTagModel]:
2158    @abstractmethod
2159    def find_tags_for_account(self, account_key: str) -> list[StreamTagModel]:
2160        """ Find every model tree tag an account has made
2161
2162        :param str account_key: The unique key of the account
2163        :return: The matching tags
2164        :rtype: list[StreamTagModel]
2165        """
2166        pass

Find every model tree tag an account has made

Parameters
  • str account_key: The unique key of the account
Returns

The matching tags

@abstractmethod
def tag_stream( self, data_stream_key: str, account_key: str, tag: inmotion.models.StreamTagRequestModel) -> dict:
2168    @abstractmethod
2169    def tag_stream(self, data_stream_key: str, account_key: str, tag: StreamTagRequestModel) -> dict:
2170        """ Tag a data stream against a model tree node
2171
2172        :param str data_stream_key: The unique key of the data stream
2173        :param str account_key: The unique key of the account
2174        :param StreamTagRequestModel tag: The model and node path to tag against
2175        :return: A raw dict acknowledging the tag, e.g. {"tagged": True}
2176        :rtype: dict
2177        """
2178        pass

Tag a data stream against a model tree node

Parameters
  • str data_stream_key: The unique key of the data stream
  • str account_key: The unique key of the account
  • StreamTagRequestModel tag: The model and node path to tag against
Returns

A raw dict acknowledging the tag, e.g. {"tagged": True}

@abstractmethod
def untag_stream( self, data_stream_key: str, account_key: str, tag: inmotion.models.StreamTagRequestModel) -> dict:
2180    @abstractmethod
2181    def untag_stream(self, data_stream_key: str, account_key: str, tag: StreamTagRequestModel) -> dict:
2182        """ Remove a tag from a data stream
2183
2184        :param str data_stream_key: The unique key of the data stream
2185        :param str account_key: The unique key of the account
2186        :param StreamTagRequestModel tag: The model and node path to untag
2187        :return: A raw dict acknowledging the untag, e.g. {"tagged": False}
2188        :rtype: dict
2189        """
2190        pass

Remove a tag from a data stream

Parameters
  • str data_stream_key: The unique key of the data stream
  • str account_key: The unique key of the account
  • StreamTagRequestModel tag: The model and node path to untag
Returns

A raw dict acknowledging the untag, e.g. {"tagged": False}

class InMotionMqttDeployment(abc.ABC):
1982class InMotionMqttDeployment(ABC):
1983    """ MQTT ingestion deployments: a `type: mqtt` (schema-v2) Device Config is the *class*;
1984    registering a deployment against a published version of it is what creates the backing Site
1985    activity (sensor schema from the config's `variables:` block) and mints the scoped,
1986    publish-only API key the device authenticates to the broker with.
1987
1988    Every method is admin-gated on the account. The scoped key value is returned exactly once, in
1989    the register / rotate-key response - it is not recoverable afterwards. Responses have no fixed
1990    schema, so each method returns a raw ``dict`` (or ``list[dict]``). """
1991
1992    @abstractmethod
1993    def register_mqtt_deployment(self, account_key: str, registration: MqttDeploymentRegistrationModel) -> dict:
1994        """ Register a deployment against a published `type: mqtt` device-config. Creates a Site
1995        activity from the config's `variables:` block, mints a scoped publish-only key, and
1996        returns ``{deploymentId, apiKey, keyName, keyExpiryOn, topicPrefix, brokerHost,
1997        activityKey, deviceConfigName, deviceConfigVersion, deviceConfigSemanticVersion}``. The
1998        ``apiKey`` is shown only in this response.
1999
2000        :param str account_key: The unique key of the account
2001        :param MqttDeploymentRegistrationModel registration: The deployment to register
2002        :return: The registered deployment, including its one-time publish key
2003        :rtype: dict
2004        """
2005        pass
2006
2007    @abstractmethod
2008    def list_mqtt_deployments(self, account_key: str) -> dict:
2009        """ List the account's MQTT ingestion deployments as ``{"deployments": [...]}``. Each row
2010        carries ``activityExists`` - False (or None if it could not be checked) means the backing
2011        Site activity has been deleted and the deployment must be re-registered.
2012
2013        :param str account_key: The unique key of the account
2014        :return: ``{"deployments": [...]}``
2015        :rtype: dict
2016        """
2017        pass
2018
2019    @abstractmethod
2020    def update_mqtt_deployment(self, account_key: str, deployment_id: str, update: MqttDeploymentUpdateModel) -> dict:
2021        """ Update mutable properties of a deployment (currently only ``name``). The backing Site
2022        activity is not renamed.
2023
2024        :param str account_key: The unique key of the account
2025        :param str deployment_id: The deployment's id
2026        :param MqttDeploymentUpdateModel update: The fields to change
2027        :return: ``{deploymentId, name}``
2028        :rtype: dict
2029        """
2030        pass
2031
2032    @abstractmethod
2033    def delete_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2034        """ Remove the deployment row and revoke its scoped publish key. The backing Site activity
2035        is left in place (archival is a separate action); the response reports
2036        ``{deploymentId, activityKey, activityRetained}``.
2037
2038        :param str account_key: The unique key of the account
2039        :param str deployment_id: The deployment's id
2040        :return: ``{deploymentId, activityKey, activityRetained}``
2041        :rtype: dict
2042        """
2043        pass
2044
2045    @abstractmethod
2046    def repoint_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2047        """ Move the deployment to the account's newest published version of the same
2048        device-config so the subscriber picks up its new decode/routing/scaling rules. The
2049        backing activity's variable set is fixed, so any variables a newer version adds come back
2050        in ``unmappedVariables``. Idempotent - returns ``changed=False`` when already current.
2051
2052        :param str account_key: The unique key of the account
2053        :param str deployment_id: The deployment's id
2054        :return: The re-point outcome (``changed`` plus version details, and ``unmappedVariables``
2055            when it moved)
2056        :rtype: dict
2057        """
2058        pass
2059
2060    @abstractmethod
2061    def rotate_mqtt_deployment_key(self, account_key: str, deployment_id: str) -> dict:
2062        """ Mint a fresh publish-only key and revoke the old one, for a lost or compromised
2063        credential. The ``deploymentId``, ``topicPrefix`` and backing activity are unchanged; the
2064        new key is returned once (``{deploymentId, apiKey, topicPrefix, brokerHost}``) and any
2065        live broker session on the old key is force-disconnected.
2066
2067        :param str account_key: The unique key of the account
2068        :param str deployment_id: The deployment's id
2069        :return: ``{deploymentId, apiKey, topicPrefix, brokerHost}``
2070        :rtype: dict
2071        """
2072        pass

MQTT ingestion deployments: a type: mqtt (schema-v2) Device Config is the class; registering a deployment against a published version of it is what creates the backing Site activity (sensor schema from the config's variables: block) and mints the scoped, publish-only API key the device authenticates to the broker with.

Every method is admin-gated on the account. The scoped key value is returned exactly once, in the register / rotate-key response - it is not recoverable afterwards. Responses have no fixed schema, so each method returns a raw dict (or list[dict]).

@abstractmethod
def register_mqtt_deployment( self, account_key: str, registration: inmotion.models.MqttDeploymentRegistrationModel) -> dict:
1992    @abstractmethod
1993    def register_mqtt_deployment(self, account_key: str, registration: MqttDeploymentRegistrationModel) -> dict:
1994        """ Register a deployment against a published `type: mqtt` device-config. Creates a Site
1995        activity from the config's `variables:` block, mints a scoped publish-only key, and
1996        returns ``{deploymentId, apiKey, keyName, keyExpiryOn, topicPrefix, brokerHost,
1997        activityKey, deviceConfigName, deviceConfigVersion, deviceConfigSemanticVersion}``. The
1998        ``apiKey`` is shown only in this response.
1999
2000        :param str account_key: The unique key of the account
2001        :param MqttDeploymentRegistrationModel registration: The deployment to register
2002        :return: The registered deployment, including its one-time publish key
2003        :rtype: dict
2004        """
2005        pass

Register a deployment against a published type: mqtt device-config. Creates a Site activity from the config's variables: block, mints a scoped publish-only key, and returns {deploymentId, apiKey, keyName, keyExpiryOn, topicPrefix, brokerHost, activityKey, deviceConfigName, deviceConfigVersion, deviceConfigSemanticVersion}. The apiKey is shown only in this response.

Parameters
  • str account_key: The unique key of the account
  • MqttDeploymentRegistrationModel registration: The deployment to register
Returns

The registered deployment, including its one-time publish key

@abstractmethod
def list_mqtt_deployments(self, account_key: str) -> dict:
2007    @abstractmethod
2008    def list_mqtt_deployments(self, account_key: str) -> dict:
2009        """ List the account's MQTT ingestion deployments as ``{"deployments": [...]}``. Each row
2010        carries ``activityExists`` - False (or None if it could not be checked) means the backing
2011        Site activity has been deleted and the deployment must be re-registered.
2012
2013        :param str account_key: The unique key of the account
2014        :return: ``{"deployments": [...]}``
2015        :rtype: dict
2016        """
2017        pass

List the account's MQTT ingestion deployments as {"deployments": [...]}. Each row carries activityExists - False (or None if it could not be checked) means the backing Site activity has been deleted and the deployment must be re-registered.

Parameters
  • str account_key: The unique key of the account
Returns

{"deployments": [...]}

@abstractmethod
def update_mqtt_deployment( self, account_key: str, deployment_id: str, update: inmotion.models.MqttDeploymentUpdateModel) -> dict:
2019    @abstractmethod
2020    def update_mqtt_deployment(self, account_key: str, deployment_id: str, update: MqttDeploymentUpdateModel) -> dict:
2021        """ Update mutable properties of a deployment (currently only ``name``). The backing Site
2022        activity is not renamed.
2023
2024        :param str account_key: The unique key of the account
2025        :param str deployment_id: The deployment's id
2026        :param MqttDeploymentUpdateModel update: The fields to change
2027        :return: ``{deploymentId, name}``
2028        :rtype: dict
2029        """
2030        pass

Update mutable properties of a deployment (currently only name). The backing Site activity is not renamed.

Parameters
  • str account_key: The unique key of the account
  • str deployment_id: The deployment's id
  • MqttDeploymentUpdateModel update: The fields to change
Returns

{deploymentId, name}

@abstractmethod
def delete_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2032    @abstractmethod
2033    def delete_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2034        """ Remove the deployment row and revoke its scoped publish key. The backing Site activity
2035        is left in place (archival is a separate action); the response reports
2036        ``{deploymentId, activityKey, activityRetained}``.
2037
2038        :param str account_key: The unique key of the account
2039        :param str deployment_id: The deployment's id
2040        :return: ``{deploymentId, activityKey, activityRetained}``
2041        :rtype: dict
2042        """
2043        pass

Remove the deployment row and revoke its scoped publish key. The backing Site activity is left in place (archival is a separate action); the response reports {deploymentId, activityKey, activityRetained}.

Parameters
  • str account_key: The unique key of the account
  • str deployment_id: The deployment's id
Returns

{deploymentId, activityKey, activityRetained}

@abstractmethod
def repoint_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2045    @abstractmethod
2046    def repoint_mqtt_deployment(self, account_key: str, deployment_id: str) -> dict:
2047        """ Move the deployment to the account's newest published version of the same
2048        device-config so the subscriber picks up its new decode/routing/scaling rules. The
2049        backing activity's variable set is fixed, so any variables a newer version adds come back
2050        in ``unmappedVariables``. Idempotent - returns ``changed=False`` when already current.
2051
2052        :param str account_key: The unique key of the account
2053        :param str deployment_id: The deployment's id
2054        :return: The re-point outcome (``changed`` plus version details, and ``unmappedVariables``
2055            when it moved)
2056        :rtype: dict
2057        """
2058        pass

Move the deployment to the account's newest published version of the same device-config so the subscriber picks up its new decode/routing/scaling rules. The backing activity's variable set is fixed, so any variables a newer version adds come back in unmappedVariables. Idempotent - returns changed=False when already current.

Parameters
  • str account_key: The unique key of the account
  • str deployment_id: The deployment's id
Returns

The re-point outcome (changed plus version details, and unmappedVariables when it moved)

@abstractmethod
def rotate_mqtt_deployment_key(self, account_key: str, deployment_id: str) -> dict:
2060    @abstractmethod
2061    def rotate_mqtt_deployment_key(self, account_key: str, deployment_id: str) -> dict:
2062        """ Mint a fresh publish-only key and revoke the old one, for a lost or compromised
2063        credential. The ``deploymentId``, ``topicPrefix`` and backing activity are unchanged; the
2064        new key is returned once (``{deploymentId, apiKey, topicPrefix, brokerHost}``) and any
2065        live broker session on the old key is force-disconnected.
2066
2067        :param str account_key: The unique key of the account
2068        :param str deployment_id: The deployment's id
2069        :return: ``{deploymentId, apiKey, topicPrefix, brokerHost}``
2070        :rtype: dict
2071        """
2072        pass

Mint a fresh publish-only key and revoke the old one, for a lost or compromised credential. The deploymentId, topicPrefix and backing activity are unchanged; the new key is returned once ({deploymentId, apiKey, topicPrefix, brokerHost}) and any live broker session on the old key is force-disconnected.

Parameters
  • str account_key: The unique key of the account
  • str deployment_id: The deployment's id
Returns

{deploymentId, apiKey, topicPrefix, brokerHost}

class InMotionRasterOverlay(abc.ABC):
1770class InMotionRasterOverlay(ABC):
1771    """ Raster overlay management: WMS-served raster/gridded imagery (GeoTIFF/COG today, gridded
1772    model data later), managed alongside vector Shapes. Creation is import-tool-only - no
1773    create/upload method exists here. Gated by the SHAPE_EDITOR account feature/privilege AND the
1774    global `inmotion.wms.enabled` kill-switch. """
1775
1776    @abstractmethod
1777    def find_raster_overlays(self, account_key: str) -> list[RasterOverlaySummaryModel]:
1778        """ List raster overlay summaries for an account
1779
1780        :param str account_key: The unique key of the account
1781        :return: The matching raster overlay summaries
1782        :rtype: list[RasterOverlaySummaryModel]
1783        """
1784        pass
1785
1786    @abstractmethod
1787    def find_raster_overlay(self, key: str) -> RasterOverlayDetailsModel:
1788        """ Find a raster overlay by its unique key. Metadata only - never the raw raster file.
1789
1790        :param str key: The unique key of the raster overlay
1791        :return: The raster overlay's details
1792        :rtype: RasterOverlayDetailsModel
1793        """
1794        pass
1795
1796    @abstractmethod
1797    def update_raster_overlay_style(self, key: str, style: RasterOverlayStyleUpdateModel) -> RasterOverlayDetailsModel:
1798        """ Update a raster overlay's editable metadata - style plus name/comment/tags. Omitted
1799        fields are left untouched.
1800
1801        :param str key: The unique key of the raster overlay to update
1802        :param RasterOverlayStyleUpdateModel style: The fields to update
1803        :return: The updated raster overlay's details
1804        :rtype: RasterOverlayDetailsModel
1805        """
1806        pass
1807
1808    @abstractmethod
1809    def delete_raster_overlay(self, key: str) -> None:
1810        """ Delete a raster overlay by its unique key
1811
1812        :param str key: The unique key of the raster overlay to delete
1813        """
1814        pass
1815
1816    @abstractmethod
1817    def render_map(self, key: str, bbox: tuple[float, float, float, float], width: int, height: int,
1818                   token: str, crs: str = 'EPSG:3857') -> bytes:
1819        """ Render a WMS ``GetMap``-equivalent PNG tile for a raster overlay.
1820
1821        This endpoint is gated by the ``inmotion.wms.enabled`` server kill-switch (disabled in
1822        some deployments) in addition to the SHAPE_EDITOR account feature. It is not
1823        header-authenticated: pass a short-lived ``token`` obtained from the ``mapToken`` field of
1824        a preceding ``find_raster_overlay`` or ``update_raster_overlay_style`` call (the token is
1825        re-minted on every such call and expires ~30 minutes after it was issued).
1826
1827        :param str key: The unique key of the raster overlay
1828        :param tuple bbox: ``(minX, minY, maxX, maxY)`` in the requested CRS
1829        :param int width: Output width in pixels
1830        :param int height: Output height in pixels
1831        :param str token: A current ``mapToken`` for this raster overlay
1832        :param str crs: Coordinate reference system - only ``EPSG:3857`` is served
1833        :return: The rendered tile as PNG bytes
1834        :rtype: bytes
1835        """
1836        pass
1837
1838    @abstractmethod
1839    def find_model_field_groups(self, key: str) -> list[ModelFieldGroupModel]:
1840        """ Find a raster overlay's custom classification field values - one field group per
1841        active classification tag on this raster overlay.
1842
1843        :param str key: The unique key of the raster overlay
1844        :return: The raster overlay's active classification field groups
1845        :rtype: list[ModelFieldGroupModel]
1846        """
1847        pass
1848
1849    @abstractmethod
1850    def set_model_field_value(self, key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
1851        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
1852        classification field's value for one active tag on a raster overlay.
1853
1854        :param str key: The unique key of the raster overlay
1855        :param SetModelFieldValueRequestModel request: The field value to set
1856        :return: The raster overlay's active classification field groups, including the updated value
1857        :rtype: list[ModelFieldGroupModel]
1858        """
1859        pass

Raster overlay management: WMS-served raster/gridded imagery (GeoTIFF/COG today, gridded model data later), managed alongside vector Shapes. Creation is import-tool-only - no create/upload method exists here. Gated by the SHAPE_EDITOR account feature/privilege AND the global inmotion.wms.enabled kill-switch.

@abstractmethod
def find_raster_overlays( self, account_key: str) -> list[inmotion.models.RasterOverlaySummaryModel]:
1776    @abstractmethod
1777    def find_raster_overlays(self, account_key: str) -> list[RasterOverlaySummaryModel]:
1778        """ List raster overlay summaries for an account
1779
1780        :param str account_key: The unique key of the account
1781        :return: The matching raster overlay summaries
1782        :rtype: list[RasterOverlaySummaryModel]
1783        """
1784        pass

List raster overlay summaries for an account

Parameters
  • str account_key: The unique key of the account
Returns

The matching raster overlay summaries

@abstractmethod
def find_raster_overlay(self, key: str) -> inmotion.models.RasterOverlayDetailsModel:
1786    @abstractmethod
1787    def find_raster_overlay(self, key: str) -> RasterOverlayDetailsModel:
1788        """ Find a raster overlay by its unique key. Metadata only - never the raw raster file.
1789
1790        :param str key: The unique key of the raster overlay
1791        :return: The raster overlay's details
1792        :rtype: RasterOverlayDetailsModel
1793        """
1794        pass

Find a raster overlay by its unique key. Metadata only - never the raw raster file.

Parameters
  • str key: The unique key of the raster overlay
Returns

The raster overlay's details

@abstractmethod
def update_raster_overlay_style( self, key: str, style: inmotion.models.RasterOverlayStyleUpdateModel) -> inmotion.models.RasterOverlayDetailsModel:
1796    @abstractmethod
1797    def update_raster_overlay_style(self, key: str, style: RasterOverlayStyleUpdateModel) -> RasterOverlayDetailsModel:
1798        """ Update a raster overlay's editable metadata - style plus name/comment/tags. Omitted
1799        fields are left untouched.
1800
1801        :param str key: The unique key of the raster overlay to update
1802        :param RasterOverlayStyleUpdateModel style: The fields to update
1803        :return: The updated raster overlay's details
1804        :rtype: RasterOverlayDetailsModel
1805        """
1806        pass

Update a raster overlay's editable metadata - style plus name/comment/tags. Omitted fields are left untouched.

Parameters
  • str key: The unique key of the raster overlay to update
  • RasterOverlayStyleUpdateModel style: The fields to update
Returns

The updated raster overlay's details

@abstractmethod
def delete_raster_overlay(self, key: str) -> None:
1808    @abstractmethod
1809    def delete_raster_overlay(self, key: str) -> None:
1810        """ Delete a raster overlay by its unique key
1811
1812        :param str key: The unique key of the raster overlay to delete
1813        """
1814        pass

Delete a raster overlay by its unique key

Parameters
  • str key: The unique key of the raster overlay to delete
@abstractmethod
def render_map( self, key: str, bbox: tuple[float, float, float, float], width: int, height: int, token: str, crs: str = 'EPSG:3857') -> bytes:
1816    @abstractmethod
1817    def render_map(self, key: str, bbox: tuple[float, float, float, float], width: int, height: int,
1818                   token: str, crs: str = 'EPSG:3857') -> bytes:
1819        """ Render a WMS ``GetMap``-equivalent PNG tile for a raster overlay.
1820
1821        This endpoint is gated by the ``inmotion.wms.enabled`` server kill-switch (disabled in
1822        some deployments) in addition to the SHAPE_EDITOR account feature. It is not
1823        header-authenticated: pass a short-lived ``token`` obtained from the ``mapToken`` field of
1824        a preceding ``find_raster_overlay`` or ``update_raster_overlay_style`` call (the token is
1825        re-minted on every such call and expires ~30 minutes after it was issued).
1826
1827        :param str key: The unique key of the raster overlay
1828        :param tuple bbox: ``(minX, minY, maxX, maxY)`` in the requested CRS
1829        :param int width: Output width in pixels
1830        :param int height: Output height in pixels
1831        :param str token: A current ``mapToken`` for this raster overlay
1832        :param str crs: Coordinate reference system - only ``EPSG:3857`` is served
1833        :return: The rendered tile as PNG bytes
1834        :rtype: bytes
1835        """
1836        pass

Render a WMS GetMap-equivalent PNG tile for a raster overlay.

This endpoint is gated by the inmotion.wms.enabled server kill-switch (disabled in some deployments) in addition to the SHAPE_EDITOR account feature. It is not header-authenticated: pass a short-lived token obtained from the mapToken field of a preceding find_raster_overlay or update_raster_overlay_style call (the token is re-minted on every such call and expires ~30 minutes after it was issued).

Parameters
  • str key: The unique key of the raster overlay
  • tuple bbox: (minX, minY, maxX, maxY) in the requested CRS
  • int width: Output width in pixels
  • int height: Output height in pixels
  • str token: A current mapToken for this raster overlay
  • **str crs: Coordinate reference system - only EPSG**: 3857 is served
Returns

The rendered tile as PNG bytes

@abstractmethod
def find_model_field_groups(self, key: str) -> list[inmotion.models.ModelFieldGroupModel]:
1838    @abstractmethod
1839    def find_model_field_groups(self, key: str) -> list[ModelFieldGroupModel]:
1840        """ Find a raster overlay's custom classification field values - one field group per
1841        active classification tag on this raster overlay.
1842
1843        :param str key: The unique key of the raster overlay
1844        :return: The raster overlay's active classification field groups
1845        :rtype: list[ModelFieldGroupModel]
1846        """
1847        pass

Find a raster overlay's custom classification field values - one field group per active classification tag on this raster overlay.

Parameters
  • str key: The unique key of the raster overlay
Returns

The raster overlay's active classification field groups

@abstractmethod
def set_model_field_value( self, key: str, request: inmotion.models.SetModelFieldValueRequestModel) -> list[inmotion.models.ModelFieldGroupModel]:
1849    @abstractmethod
1850    def set_model_field_value(self, key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
1851        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
1852        classification field's value for one active tag on a raster overlay.
1853
1854        :param str key: The unique key of the raster overlay
1855        :param SetModelFieldValueRequestModel request: The field value to set
1856        :return: The raster overlay's active classification field groups, including the updated value
1857        :rtype: list[ModelFieldGroupModel]
1858        """
1859        pass

Set (or, if value is omitted/blank on an optional field, clear) one custom classification field's value for one active tag on a raster overlay.

Parameters
  • str key: The unique key of the raster overlay
  • SetModelFieldValueRequestModel request: The field value to set
Returns

The raster overlay's active classification field groups, including the updated value

class InMotionShape(abc.ABC):
1666class InMotionShape(ABC):
1667    """ Shape management: a named, classified collection of polygons (which may have holes/
1668    islands), stored as a single GeoJSON FeatureCollection. Access is gated by a simple
1669    feature-flag check (an account write privilege plus the "shape-editor" account feature), not
1670    Folio's role/contributor model. """
1671
1672    @abstractmethod
1673    def create_shape(self, shape: ShapeModel) -> ShapeDetailsModel:
1674        """ Create a new, account-owned shape
1675
1676        :param ShapeModel shape: The definition of the shape to create
1677        :return: The created shape's details
1678        :rtype: ShapeDetailsModel
1679        """
1680        pass
1681
1682    @abstractmethod
1683    def find_shapes(self, account_key: str, classification: Optional[str] = None) -> list[ShapeSummaryModel]:
1684        """ List shape summaries for an account, optionally filtered by classification
1685
1686        :param str account_key: The unique key of the account
1687        :param Optional[str] classification: An optional classification to filter by
1688        :return: The matching shape summaries
1689        :rtype: list[ShapeSummaryModel]
1690        """
1691        pass
1692
1693    @abstractmethod
1694    def find_shape(self, key: str) -> ShapeDetailsModel:
1695        """ Find a shape by its unique key, including its full geojson and collection-level
1696        variables
1697
1698        :param str key: The unique key of the shape
1699        :return: The shape's details
1700        :rtype: ShapeDetailsModel
1701        """
1702        pass
1703
1704    @abstractmethod
1705    def update_shape(self, key: str, shape: ShapeUpdateModel) -> ShapeDetailsModel:
1706        """ Update a shape's metadata (name, classification, collection-level variables). Does
1707        not touch its geometry - use update_shape_geometry for that.
1708
1709        :param str key: The unique key of the shape to update
1710        :param ShapeUpdateModel shape: The fields to update
1711        :return: The updated shape's details
1712        :rtype: ShapeDetailsModel
1713        """
1714        pass
1715
1716    @abstractmethod
1717    def update_shape_geometry(self, key: str, geometry: ShapeGeometryModel) -> ShapeDetailsModel:
1718        """ Replace a shape's geojson only
1719
1720        :param str key: The unique key of the shape to update
1721        :param ShapeGeometryModel geometry: The replacement geojson
1722        :return: The updated shape's details
1723        :rtype: ShapeDetailsModel
1724        """
1725        pass
1726
1727    @abstractmethod
1728    def duplicate_shape(self, key: str) -> ShapeDetailsModel:
1729        """ Copy an existing shape's geometry and metadata into a new, independent shape owned by
1730        the caller.
1731
1732        :param str key: The unique key of the shape to duplicate
1733        :return: The new, duplicated shape's details
1734        :rtype: ShapeDetailsModel
1735        """
1736        pass
1737
1738    @abstractmethod
1739    def delete_shape(self, key: str) -> None:
1740        """ Delete a shape by its unique key
1741
1742        :param str key: The unique key of the shape to delete
1743        """
1744        pass
1745
1746    @abstractmethod
1747    def find_model_field_groups(self, key: str) -> list[ModelFieldGroupModel]:
1748        """ Find a shape's custom classification field values - one field group per active
1749        classification tag on this shape.
1750
1751        :param str key: The unique key of the shape
1752        :return: The shape's active classification field groups
1753        :rtype: list[ModelFieldGroupModel]
1754        """
1755        pass
1756
1757    @abstractmethod
1758    def set_model_field_value(self, key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
1759        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
1760        classification field's value for one active tag on a shape.
1761
1762        :param str key: The unique key of the shape
1763        :param SetModelFieldValueRequestModel request: The field value to set
1764        :return: The shape's active classification field groups, including the updated value
1765        :rtype: list[ModelFieldGroupModel]
1766        """
1767        pass

Shape management: a named, classified collection of polygons (which may have holes/ islands), stored as a single GeoJSON FeatureCollection. Access is gated by a simple feature-flag check (an account write privilege plus the "shape-editor" account feature), not Folio's role/contributor model.

@abstractmethod
def create_shape( self, shape: inmotion.models.ShapeModel) -> inmotion.models.ShapeDetailsModel:
1672    @abstractmethod
1673    def create_shape(self, shape: ShapeModel) -> ShapeDetailsModel:
1674        """ Create a new, account-owned shape
1675
1676        :param ShapeModel shape: The definition of the shape to create
1677        :return: The created shape's details
1678        :rtype: ShapeDetailsModel
1679        """
1680        pass

Create a new, account-owned shape

Parameters
  • ShapeModel shape: The definition of the shape to create
Returns

The created shape's details

@abstractmethod
def find_shapes( self, account_key: str, classification: Optional[str] = None) -> list[inmotion.models.ShapeSummaryModel]:
1682    @abstractmethod
1683    def find_shapes(self, account_key: str, classification: Optional[str] = None) -> list[ShapeSummaryModel]:
1684        """ List shape summaries for an account, optionally filtered by classification
1685
1686        :param str account_key: The unique key of the account
1687        :param Optional[str] classification: An optional classification to filter by
1688        :return: The matching shape summaries
1689        :rtype: list[ShapeSummaryModel]
1690        """
1691        pass

List shape summaries for an account, optionally filtered by classification

Parameters
  • str account_key: The unique key of the account
  • Optional[str] classification: An optional classification to filter by
Returns

The matching shape summaries

@abstractmethod
def find_shape(self, key: str) -> inmotion.models.ShapeDetailsModel:
1693    @abstractmethod
1694    def find_shape(self, key: str) -> ShapeDetailsModel:
1695        """ Find a shape by its unique key, including its full geojson and collection-level
1696        variables
1697
1698        :param str key: The unique key of the shape
1699        :return: The shape's details
1700        :rtype: ShapeDetailsModel
1701        """
1702        pass

Find a shape by its unique key, including its full geojson and collection-level variables

Parameters
  • str key: The unique key of the shape
Returns

The shape's details

@abstractmethod
def update_shape( self, key: str, shape: inmotion.models.ShapeUpdateModel) -> inmotion.models.ShapeDetailsModel:
1704    @abstractmethod
1705    def update_shape(self, key: str, shape: ShapeUpdateModel) -> ShapeDetailsModel:
1706        """ Update a shape's metadata (name, classification, collection-level variables). Does
1707        not touch its geometry - use update_shape_geometry for that.
1708
1709        :param str key: The unique key of the shape to update
1710        :param ShapeUpdateModel shape: The fields to update
1711        :return: The updated shape's details
1712        :rtype: ShapeDetailsModel
1713        """
1714        pass

Update a shape's metadata (name, classification, collection-level variables). Does not touch its geometry - use update_shape_geometry for that.

Parameters
  • str key: The unique key of the shape to update
  • ShapeUpdateModel shape: The fields to update
Returns

The updated shape's details

@abstractmethod
def update_shape_geometry( self, key: str, geometry: inmotion.models.ShapeGeometryModel) -> inmotion.models.ShapeDetailsModel:
1716    @abstractmethod
1717    def update_shape_geometry(self, key: str, geometry: ShapeGeometryModel) -> ShapeDetailsModel:
1718        """ Replace a shape's geojson only
1719
1720        :param str key: The unique key of the shape to update
1721        :param ShapeGeometryModel geometry: The replacement geojson
1722        :return: The updated shape's details
1723        :rtype: ShapeDetailsModel
1724        """
1725        pass

Replace a shape's geojson only

Parameters
  • str key: The unique key of the shape to update
  • ShapeGeometryModel geometry: The replacement geojson
Returns

The updated shape's details

@abstractmethod
def duplicate_shape(self, key: str) -> inmotion.models.ShapeDetailsModel:
1727    @abstractmethod
1728    def duplicate_shape(self, key: str) -> ShapeDetailsModel:
1729        """ Copy an existing shape's geometry and metadata into a new, independent shape owned by
1730        the caller.
1731
1732        :param str key: The unique key of the shape to duplicate
1733        :return: The new, duplicated shape's details
1734        :rtype: ShapeDetailsModel
1735        """
1736        pass

Copy an existing shape's geometry and metadata into a new, independent shape owned by the caller.

Parameters
  • str key: The unique key of the shape to duplicate
Returns

The new, duplicated shape's details

@abstractmethod
def delete_shape(self, key: str) -> None:
1738    @abstractmethod
1739    def delete_shape(self, key: str) -> None:
1740        """ Delete a shape by its unique key
1741
1742        :param str key: The unique key of the shape to delete
1743        """
1744        pass

Delete a shape by its unique key

Parameters
  • str key: The unique key of the shape to delete
@abstractmethod
def find_model_field_groups(self, key: str) -> list[inmotion.models.ModelFieldGroupModel]:
1746    @abstractmethod
1747    def find_model_field_groups(self, key: str) -> list[ModelFieldGroupModel]:
1748        """ Find a shape's custom classification field values - one field group per active
1749        classification tag on this shape.
1750
1751        :param str key: The unique key of the shape
1752        :return: The shape's active classification field groups
1753        :rtype: list[ModelFieldGroupModel]
1754        """
1755        pass

Find a shape's custom classification field values - one field group per active classification tag on this shape.

Parameters
  • str key: The unique key of the shape
Returns

The shape's active classification field groups

@abstractmethod
def set_model_field_value( self, key: str, request: inmotion.models.SetModelFieldValueRequestModel) -> list[inmotion.models.ModelFieldGroupModel]:
1757    @abstractmethod
1758    def set_model_field_value(self, key: str, request: SetModelFieldValueRequestModel) -> list[ModelFieldGroupModel]:
1759        """ Set (or, if value is omitted/blank on an optional field, clear) one custom
1760        classification field's value for one active tag on a shape.
1761
1762        :param str key: The unique key of the shape
1763        :param SetModelFieldValueRequestModel request: The field value to set
1764        :return: The shape's active classification field groups, including the updated value
1765        :rtype: list[ModelFieldGroupModel]
1766        """
1767        pass

Set (or, if value is omitted/blank on an optional field, clear) one custom classification field's value for one active tag on a shape.

Parameters
  • str key: The unique key of the shape
  • SetModelFieldValueRequestModel request: The field value to set
Returns

The shape's active classification field groups, including the updated value

class InMotionShapeGenerator(abc.ABC):
1862class InMotionShapeGenerator(ABC):
1863    """ Shape generator management: a rules-based geometry generator (Shape Editor v2). Its
1864    identity is its rules (type/params), not a piece of geometry - see `commit_shape_generator`
1865    for snapshotting its output into an independent Shape. Access is gated the same way as
1866    Shape. """
1867
1868    @abstractmethod
1869    def create_shape_generator(self, generator: ShapeGeneratorModel) -> ShapeGeneratorDetailsModel:
1870        """ Create a new, account-owned shape generator
1871
1872        :param ShapeGeneratorModel generator: The definition of the shape generator to create
1873        :return: The created shape generator's details
1874        :rtype: ShapeGeneratorDetailsModel
1875        """
1876        pass
1877
1878    @abstractmethod
1879    def find_shape_generators(self, account_key: str) -> list[ShapeGeneratorSummaryModel]:
1880        """ List shape generator summaries for an account
1881
1882        :param str account_key: The unique key of the account
1883        :return: The matching shape generator summaries
1884        :rtype: list[ShapeGeneratorSummaryModel]
1885        """
1886        pass
1887
1888    @abstractmethod
1889    def find_shape_generator(self, key: str) -> ShapeGeneratorDetailsModel:
1890        """ Find a shape generator by its unique key
1891
1892        :param str key: The unique key of the shape generator
1893        :return: The shape generator's details
1894        :rtype: ShapeGeneratorDetailsModel
1895        """
1896        pass
1897
1898    @abstractmethod
1899    def update_shape_generator(self, key: str, generator: ShapeGeneratorUpdateModel) -> ShapeGeneratorDetailsModel:
1900        """ Full-replace update of a generator's rules (name/params/boundary/label prefix). Does
1901        not itself change its cached generated geometry - see regenerate_shape_generator.
1902
1903        :param str key: The unique key of the shape generator to update
1904        :param ShapeGeneratorUpdateModel generator: The replacement definition
1905        :return: The updated shape generator's details
1906        :rtype: ShapeGeneratorDetailsModel
1907        """
1908        pass
1909
1910    @abstractmethod
1911    def regenerate_shape_generator(self, key: str) -> ShapeGeneratorDetailsModel:
1912        """ Re-run the generator's pipeline against its current rules and boundary shape, and
1913        persist the result as the new cached generated geometry.
1914
1915        :param str key: The unique key of the shape generator to regenerate
1916        :return: The shape generator's details, with its refreshed cached output
1917        :rtype: ShapeGeneratorDetailsModel
1918        """
1919        pass
1920
1921    @abstractmethod
1922    def commit_shape_generator(self, key: str) -> ShapeDetailsModel:
1923        """ Snapshot the generator's cached generated geometry into a brand-new, independent
1924        shape. The generator itself keeps running/re-tunable afterwards. Fails with a 400 if
1925        nothing has been generated yet (regenerate first).
1926
1927        :param str key: The unique key of the shape generator to commit
1928        :return: The new shape created from the generator's output
1929        :rtype: ShapeDetailsModel
1930        """
1931        pass
1932
1933    @abstractmethod
1934    def preview_shape_generator(self, key: str, seed_indices: list[int]) -> dict:
1935        """ Incrementally recompute only the cells around the given seed indices and return them
1936        as a GeoJSON FeatureCollection, without touching the generator's cached
1937        `generatedGeojson`. For instant feedback on a seed drag; voronoi generators only.
1938
1939        :param str key: The unique key of the shape generator
1940        :param list[int] seed_indices: Indices of the seed points that moved
1941        :return: A GeoJSON FeatureCollection of the recomputed cells
1942        :rtype: dict
1943        """
1944        pass
1945
1946    @abstractmethod
1947    def find_nearby_tracks(self, account_key: str, track_filter: NearbyTracksFilterModel) -> list[NearbyTrackModel]:
1948        """ Find the account's Track activities whose recorded extent overlaps a bounding box -
1949        candidate input for idw/nn shape generators.
1950
1951        :param str account_key: The unique key of the account
1952        :param NearbyTracksFilterModel track_filter: The query bounding box
1953        :return: The matching Track candidates
1954        :rtype: list[NearbyTrackModel]
1955        """
1956        pass
1957
1958    @abstractmethod
1959    def delete_shape_generator(self, key: str) -> None:
1960        """ Delete a shape generator by its unique key
1961
1962        :param str key: The unique key of the shape generator to delete
1963        """
1964        pass

Shape generator management: a rules-based geometry generator (Shape Editor v2). Its identity is its rules (type/params), not a piece of geometry - see commit_shape_generator for snapshotting its output into an independent Shape. Access is gated the same way as Shape.

@abstractmethod
def create_shape_generator( self, generator: inmotion.models.ShapeGeneratorModel) -> inmotion.models.ShapeGeneratorDetailsModel:
1868    @abstractmethod
1869    def create_shape_generator(self, generator: ShapeGeneratorModel) -> ShapeGeneratorDetailsModel:
1870        """ Create a new, account-owned shape generator
1871
1872        :param ShapeGeneratorModel generator: The definition of the shape generator to create
1873        :return: The created shape generator's details
1874        :rtype: ShapeGeneratorDetailsModel
1875        """
1876        pass

Create a new, account-owned shape generator

Parameters
  • ShapeGeneratorModel generator: The definition of the shape generator to create
Returns

The created shape generator's details

@abstractmethod
def find_shape_generators( self, account_key: str) -> list[inmotion.models.ShapeGeneratorSummaryModel]:
1878    @abstractmethod
1879    def find_shape_generators(self, account_key: str) -> list[ShapeGeneratorSummaryModel]:
1880        """ List shape generator summaries for an account
1881
1882        :param str account_key: The unique key of the account
1883        :return: The matching shape generator summaries
1884        :rtype: list[ShapeGeneratorSummaryModel]
1885        """
1886        pass

List shape generator summaries for an account

Parameters
  • str account_key: The unique key of the account
Returns

The matching shape generator summaries

@abstractmethod
def find_shape_generator(self, key: str) -> inmotion.models.ShapeGeneratorDetailsModel:
1888    @abstractmethod
1889    def find_shape_generator(self, key: str) -> ShapeGeneratorDetailsModel:
1890        """ Find a shape generator by its unique key
1891
1892        :param str key: The unique key of the shape generator
1893        :return: The shape generator's details
1894        :rtype: ShapeGeneratorDetailsModel
1895        """
1896        pass

Find a shape generator by its unique key

Parameters
  • str key: The unique key of the shape generator
Returns

The shape generator's details

@abstractmethod
def update_shape_generator( self, key: str, generator: inmotion.models.ShapeGeneratorUpdateModel) -> inmotion.models.ShapeGeneratorDetailsModel:
1898    @abstractmethod
1899    def update_shape_generator(self, key: str, generator: ShapeGeneratorUpdateModel) -> ShapeGeneratorDetailsModel:
1900        """ Full-replace update of a generator's rules (name/params/boundary/label prefix). Does
1901        not itself change its cached generated geometry - see regenerate_shape_generator.
1902
1903        :param str key: The unique key of the shape generator to update
1904        :param ShapeGeneratorUpdateModel generator: The replacement definition
1905        :return: The updated shape generator's details
1906        :rtype: ShapeGeneratorDetailsModel
1907        """
1908        pass

Full-replace update of a generator's rules (name/params/boundary/label prefix). Does not itself change its cached generated geometry - see regenerate_shape_generator.

Parameters
  • str key: The unique key of the shape generator to update
  • ShapeGeneratorUpdateModel generator: The replacement definition
Returns

The updated shape generator's details

@abstractmethod
def regenerate_shape_generator(self, key: str) -> inmotion.models.ShapeGeneratorDetailsModel:
1910    @abstractmethod
1911    def regenerate_shape_generator(self, key: str) -> ShapeGeneratorDetailsModel:
1912        """ Re-run the generator's pipeline against its current rules and boundary shape, and
1913        persist the result as the new cached generated geometry.
1914
1915        :param str key: The unique key of the shape generator to regenerate
1916        :return: The shape generator's details, with its refreshed cached output
1917        :rtype: ShapeGeneratorDetailsModel
1918        """
1919        pass

Re-run the generator's pipeline against its current rules and boundary shape, and persist the result as the new cached generated geometry.

Parameters
  • str key: The unique key of the shape generator to regenerate
Returns

The shape generator's details, with its refreshed cached output

@abstractmethod
def commit_shape_generator(self, key: str) -> inmotion.models.ShapeDetailsModel:
1921    @abstractmethod
1922    def commit_shape_generator(self, key: str) -> ShapeDetailsModel:
1923        """ Snapshot the generator's cached generated geometry into a brand-new, independent
1924        shape. The generator itself keeps running/re-tunable afterwards. Fails with a 400 if
1925        nothing has been generated yet (regenerate first).
1926
1927        :param str key: The unique key of the shape generator to commit
1928        :return: The new shape created from the generator's output
1929        :rtype: ShapeDetailsModel
1930        """
1931        pass

Snapshot the generator's cached generated geometry into a brand-new, independent shape. The generator itself keeps running/re-tunable afterwards. Fails with a 400 if nothing has been generated yet (regenerate first).

Parameters
  • str key: The unique key of the shape generator to commit
Returns

The new shape created from the generator's output

@abstractmethod
def preview_shape_generator(self, key: str, seed_indices: list[int]) -> dict:
1933    @abstractmethod
1934    def preview_shape_generator(self, key: str, seed_indices: list[int]) -> dict:
1935        """ Incrementally recompute only the cells around the given seed indices and return them
1936        as a GeoJSON FeatureCollection, without touching the generator's cached
1937        `generatedGeojson`. For instant feedback on a seed drag; voronoi generators only.
1938
1939        :param str key: The unique key of the shape generator
1940        :param list[int] seed_indices: Indices of the seed points that moved
1941        :return: A GeoJSON FeatureCollection of the recomputed cells
1942        :rtype: dict
1943        """
1944        pass

Incrementally recompute only the cells around the given seed indices and return them as a GeoJSON FeatureCollection, without touching the generator's cached generatedGeojson. For instant feedback on a seed drag; voronoi generators only.

Parameters
  • str key: The unique key of the shape generator
  • list[int] seed_indices: Indices of the seed points that moved
Returns

A GeoJSON FeatureCollection of the recomputed cells

@abstractmethod
def find_nearby_tracks( self, account_key: str, track_filter: inmotion.models.NearbyTracksFilterModel) -> list[inmotion.models.NearbyTrackModel]:
1946    @abstractmethod
1947    def find_nearby_tracks(self, account_key: str, track_filter: NearbyTracksFilterModel) -> list[NearbyTrackModel]:
1948        """ Find the account's Track activities whose recorded extent overlaps a bounding box -
1949        candidate input for idw/nn shape generators.
1950
1951        :param str account_key: The unique key of the account
1952        :param NearbyTracksFilterModel track_filter: The query bounding box
1953        :return: The matching Track candidates
1954        :rtype: list[NearbyTrackModel]
1955        """
1956        pass

Find the account's Track activities whose recorded extent overlaps a bounding box - candidate input for idw/nn shape generators.

Parameters
  • str account_key: The unique key of the account
  • NearbyTracksFilterModel track_filter: The query bounding box
Returns

The matching Track candidates

@abstractmethod
def delete_shape_generator(self, key: str) -> None:
1958    @abstractmethod
1959    def delete_shape_generator(self, key: str) -> None:
1960        """ Delete a shape generator by its unique key
1961
1962        :param str key: The unique key of the shape generator to delete
1963        """
1964        pass

Delete a shape generator by its unique key

Parameters
  • str key: The unique key of the shape generator to delete
class InMotionUpload(abc.ABC):
1370class InMotionUpload(ABC):
1371    @abstractmethod
1372    def upload_file(self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> dict[str, UploadMetadataModel]:
1373        """ Upload a file to the nominated account using a multipart form
1374
1375        :param str account: The unique key of the account to upload the file to
1376        :param str file_path: The path to the local file to upload
1377        :param str content_type: The MIME type to declare for the uploaded file
1378        :return: A map of the new upload's uuid to its metadata (one entry per uploaded file)
1379        :rtype: dict[str, UploadMetadataModel]
1380        """
1381        pass
1382
1383    @abstractmethod
1384    def find_upload_metadata(self, uuid: str) -> UploadMetadataModel:
1385        """ Retrieve the metadata for a specific file upload
1386
1387        :param str uuid: The unique identifier for the upload
1388        :return: The upload's metadata
1389        :rtype: UploadMetadataModel
1390        """
1391        pass
1392
1393    @abstractmethod
1394    def update_upload_metadata(self, uuid: str, change: UploadMetadataChangeCommandModel) -> dict[str, UploadMetadataModel]:
1395        """ Update the metadata (mime type, nature, attributes) for a specific file upload
1396
1397        :param str uuid: The unique identifier for the upload
1398        :param UploadMetadataChangeCommandModel change: The metadata changes to apply
1399        :return: A single-entry map of the upload's uuid to its updated metadata
1400        :rtype: dict[str, UploadMetadataModel]
1401        """
1402        pass
1403
1404    @abstractmethod
1405    def find_upload_preview(self, uuid: str, nature: str) -> dict:
1406        """ Retrieve a preview of an uploaded file's data, interpreted according to the given nature
1407
1408        :param str uuid: The unique identifier for the upload
1409        :param str nature: The nature to interpret the upload as (e.g. 'track', 'route', 'coverage')
1410        :return: A raw dict with 'success' and 'preview' keys - the preview shape is nature-dependent
1411        :rtype: dict
1412        """
1413        pass
1414
1415    @abstractmethod
1416    def process_upload(self, uuid: str) -> dict[str, UploadMetadataModel]:
1417        """ Commit/process an uploaded file into inMotion, based on its assigned nature
1418
1419        :param str uuid: The unique identifier for the upload
1420        :return: A single-entry map of the upload's uuid to its updated metadata
1421        :rtype: dict[str, UploadMetadataModel]
1422        """
1423        pass
1424
1425    @abstractmethod
1426    def cancel_upload(self, uuid: str) -> bool:
1427        """ Cancel an in-progress upload, removing its tracked state
1428
1429        :param str uuid: The unique identifier for the upload
1430        :return: True if the upload was successfully cancelled
1431        :rtype: bool
1432        """
1433        pass
1434
1435    @abstractmethod
1436    def delete_upload(self, uuid: str) -> bool:
1437        """ Delete an upload's tracked state
1438
1439        :param str uuid: The unique identifier for the upload
1440        :return: True if the upload was successfully deleted
1441        :rtype: bool
1442        """
1443        pass
1444
1445    @abstractmethod
1446    def find_uploads(self, account: str) -> dict[str, UploadMetadataModel]:
1447        """ Retrieve all tracked uploads for an account
1448
1449        :param str account: The unique key of the account
1450        :return: A map of upload uuid to its metadata
1451        :rtype: dict[str, UploadMetadataModel]
1452        """
1453        pass
1454
1455    @abstractmethod
1456    def upload_diagnostics(self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> list[str]:
1457        """ Upload a diagnostics file (e.g. a crash log or device dump) for a specific account,
1458        stored server-side without going through the tracked-upload/process pipeline
1459
1460        :param str account: The unique key of the account to upload the file to
1461        :param str file_path: The path to the local file to upload
1462        :param str content_type: The MIME type to declare for the uploaded file
1463        :return: The server-assigned filename(s) the diagnostics file was stored under
1464        :rtype: list[str]
1465        """
1466        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def upload_file( self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> dict[str, inmotion.models.UploadMetadataModel]:
1371    @abstractmethod
1372    def upload_file(self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> dict[str, UploadMetadataModel]:
1373        """ Upload a file to the nominated account using a multipart form
1374
1375        :param str account: The unique key of the account to upload the file to
1376        :param str file_path: The path to the local file to upload
1377        :param str content_type: The MIME type to declare for the uploaded file
1378        :return: A map of the new upload's uuid to its metadata (one entry per uploaded file)
1379        :rtype: dict[str, UploadMetadataModel]
1380        """
1381        pass

Upload a file to the nominated account using a multipart form

Parameters
  • str account: The unique key of the account to upload the file to
  • str file_path: The path to the local file to upload
  • str content_type: The MIME type to declare for the uploaded file
Returns

A map of the new upload's uuid to its metadata (one entry per uploaded file)

@abstractmethod
def find_upload_metadata(self, uuid: str) -> inmotion.models.UploadMetadataModel:
1383    @abstractmethod
1384    def find_upload_metadata(self, uuid: str) -> UploadMetadataModel:
1385        """ Retrieve the metadata for a specific file upload
1386
1387        :param str uuid: The unique identifier for the upload
1388        :return: The upload's metadata
1389        :rtype: UploadMetadataModel
1390        """
1391        pass

Retrieve the metadata for a specific file upload

Parameters
  • str uuid: The unique identifier for the upload
Returns

The upload's metadata

@abstractmethod
def update_upload_metadata( self, uuid: str, change: inmotion.models.UploadMetadataChangeCommandModel) -> dict[str, inmotion.models.UploadMetadataModel]:
1393    @abstractmethod
1394    def update_upload_metadata(self, uuid: str, change: UploadMetadataChangeCommandModel) -> dict[str, UploadMetadataModel]:
1395        """ Update the metadata (mime type, nature, attributes) for a specific file upload
1396
1397        :param str uuid: The unique identifier for the upload
1398        :param UploadMetadataChangeCommandModel change: The metadata changes to apply
1399        :return: A single-entry map of the upload's uuid to its updated metadata
1400        :rtype: dict[str, UploadMetadataModel]
1401        """
1402        pass

Update the metadata (mime type, nature, attributes) for a specific file upload

Parameters
  • str uuid: The unique identifier for the upload
  • UploadMetadataChangeCommandModel change: The metadata changes to apply
Returns

A single-entry map of the upload's uuid to its updated metadata

@abstractmethod
def find_upload_preview(self, uuid: str, nature: str) -> dict:
1404    @abstractmethod
1405    def find_upload_preview(self, uuid: str, nature: str) -> dict:
1406        """ Retrieve a preview of an uploaded file's data, interpreted according to the given nature
1407
1408        :param str uuid: The unique identifier for the upload
1409        :param str nature: The nature to interpret the upload as (e.g. 'track', 'route', 'coverage')
1410        :return: A raw dict with 'success' and 'preview' keys - the preview shape is nature-dependent
1411        :rtype: dict
1412        """
1413        pass

Retrieve a preview of an uploaded file's data, interpreted according to the given nature

Parameters
  • str uuid: The unique identifier for the upload
  • str nature: The nature to interpret the upload as (e.g. 'track', 'route', 'coverage')
Returns

A raw dict with 'success' and 'preview' keys - the preview shape is nature-dependent

@abstractmethod
def process_upload(self, uuid: str) -> dict[str, inmotion.models.UploadMetadataModel]:
1415    @abstractmethod
1416    def process_upload(self, uuid: str) -> dict[str, UploadMetadataModel]:
1417        """ Commit/process an uploaded file into inMotion, based on its assigned nature
1418
1419        :param str uuid: The unique identifier for the upload
1420        :return: A single-entry map of the upload's uuid to its updated metadata
1421        :rtype: dict[str, UploadMetadataModel]
1422        """
1423        pass

Commit/process an uploaded file into inMotion, based on its assigned nature

Parameters
  • str uuid: The unique identifier for the upload
Returns

A single-entry map of the upload's uuid to its updated metadata

@abstractmethod
def cancel_upload(self, uuid: str) -> bool:
1425    @abstractmethod
1426    def cancel_upload(self, uuid: str) -> bool:
1427        """ Cancel an in-progress upload, removing its tracked state
1428
1429        :param str uuid: The unique identifier for the upload
1430        :return: True if the upload was successfully cancelled
1431        :rtype: bool
1432        """
1433        pass

Cancel an in-progress upload, removing its tracked state

Parameters
  • str uuid: The unique identifier for the upload
Returns

True if the upload was successfully cancelled

@abstractmethod
def delete_upload(self, uuid: str) -> bool:
1435    @abstractmethod
1436    def delete_upload(self, uuid: str) -> bool:
1437        """ Delete an upload's tracked state
1438
1439        :param str uuid: The unique identifier for the upload
1440        :return: True if the upload was successfully deleted
1441        :rtype: bool
1442        """
1443        pass

Delete an upload's tracked state

Parameters
  • str uuid: The unique identifier for the upload
Returns

True if the upload was successfully deleted

@abstractmethod
def find_uploads(self, account: str) -> dict[str, inmotion.models.UploadMetadataModel]:
1445    @abstractmethod
1446    def find_uploads(self, account: str) -> dict[str, UploadMetadataModel]:
1447        """ Retrieve all tracked uploads for an account
1448
1449        :param str account: The unique key of the account
1450        :return: A map of upload uuid to its metadata
1451        :rtype: dict[str, UploadMetadataModel]
1452        """
1453        pass

Retrieve all tracked uploads for an account

Parameters
  • str account: The unique key of the account
Returns

A map of upload uuid to its metadata

@abstractmethod
def upload_diagnostics( self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> list[str]:
1455    @abstractmethod
1456    def upload_diagnostics(self, account: str, file_path: str, content_type: str = 'application/octet-stream') -> list[str]:
1457        """ Upload a diagnostics file (e.g. a crash log or device dump) for a specific account,
1458        stored server-side without going through the tracked-upload/process pipeline
1459
1460        :param str account: The unique key of the account to upload the file to
1461        :param str file_path: The path to the local file to upload
1462        :param str content_type: The MIME type to declare for the uploaded file
1463        :return: The server-assigned filename(s) the diagnostics file was stored under
1464        :rtype: list[str]
1465        """
1466        pass

Upload a diagnostics file (e.g. a crash log or device dump) for a specific account, stored server-side without going through the tracked-upload/process pipeline

Parameters
  • str account: The unique key of the account to upload the file to
  • str file_path: The path to the local file to upload
  • str content_type: The MIME type to declare for the uploaded file
Returns

The server-assigned filename(s) the diagnostics file was stored under

class InMotionUser(abc.ABC):
1227class InMotionUser(ABC):
1228    @abstractmethod
1229    def create_user_against_account(self, account_key: str, privilege_label: str, registration: UserRegistrationModel) -> AccountUserSummaryModel:
1230        """ Register a new user and grant them a privilege level against an account
1231
1232        :param str account_key: The unique key of the account to register the user against
1233        :param str privilege_label: The privilege level to grant ('view', 'contribute', or 'admin';
1234            any other value is treated as 'view' by the server)
1235        :param UserRegistrationModel registration: The definition of the user to create
1236        :return: A summary of the newly created and registered user
1237        :rtype: AccountUserSummaryModel
1238        """
1239        pass
1240
1241    @abstractmethod
1242    def request_password_reset(self, request: UserPasswordRequestModel) -> MessageResponseModel:
1243        """ Request a password reset email be sent to a user
1244
1245        :param UserPasswordRequestModel request: The username or email address of the user
1246        :return: A confirmation message
1247        :rtype: MessageResponseModel
1248        """
1249        pass
1250
1251    @abstractmethod
1252    def find_user_attributes(self) -> UserAttributesModel:
1253        """ Retrieve the attributes of the currently authenticated user
1254
1255        :return: The authenticated user's attributes
1256        :rtype: UserAttributesModel
1257        """
1258        pass
1259
1260    @abstractmethod
1261    def update_user_attributes(self, attributes: UserAttributesModel) -> dict:
1262        """ Update the attributes of the currently authenticated user
1263
1264        :param UserAttributesModel attributes: The updated attributes
1265        :return: A raw confirmation message from the server (not a re-fetch of the attributes)
1266        :rtype: dict
1267        """
1268        pass
1269
1270    @abstractmethod
1271    def unregister_from_account(self, account_key: str) -> UserUnregisteredResponseModel:
1272        """ Unregister the currently authenticated user from an account
1273
1274        :param str account_key: The unique key of the account to unregister from
1275        :return: The result of the unregister operation
1276        :rtype: UserUnregisteredResponseModel
1277        """
1278        pass
1279
1280    @abstractmethod
1281    def create_otc(self) -> OTCModel:
1282        """ Create a one-time code (OTC) key pair for the authenticated user, used to support
1283        device pairing/bootstrap flows. Requires a developer key, which is used to encrypt the
1284        returned private key.
1285
1286        :return: The new one-time code's public/private key pair
1287        :rtype: OTCModel
1288        """
1289        pass
1290
1291    @abstractmethod
1292    def find_mfa_status(self) -> MfaStatusModel:
1293        """ Retrieve MFA enrollment status (enabled, method, enrolled-at) for the authenticated user
1294
1295        :return: The authenticated user's MFA status
1296        :rtype: MfaStatusModel
1297        """
1298        pass
1299
1300    @abstractmethod
1301    def enroll_mfa(self, request: MfaEnrollRequestModel) -> MfaStatusModel:
1302        """ Begin EMAIL MFA enrollment for the authenticated user's own account: requires
1303        re-entering the current password, then emails a live code. MFA does not activate yet -
1304        follow with confirm_mfa_email. TOTP/SMS are rejected here - use begin_totp_enrollment
1305        instead.
1306
1307        :param MfaEnrollRequestModel request: The method to enroll in and the current password
1308        :return: The user's MFA status (still not enabled)
1309        :rtype: MfaStatusModel
1310        """
1311        pass
1312
1313    @abstractmethod
1314    def confirm_mfa_email(self, request: TotpConfirmRequestModel) -> MfaStatusModel:
1315        """ Confirm a pending EMAIL enrollment (from enroll_mfa) with the live code just emailed
1316        to the account. Activates MFA (method EMAIL) only on success.
1317
1318        :param TotpConfirmRequestModel request: The code that was emailed
1319        :return: The user's MFA status, now enabled if the code was valid
1320        :rtype: MfaStatusModel
1321        """
1322        pass
1323
1324    @abstractmethod
1325    def begin_totp_enrollment(self, request: TotpEnrollBeginRequestModel) -> TotpEnrollmentBeginResultModel:
1326        """ Generate a new TOTP secret and backup/recovery codes for the authenticated user's own
1327        account. Does not activate MFA yet - follow with confirm_totp_enrollment. Requires
1328        re-entering the current password. `backupCodes` are returned in plaintext exactly once.
1329
1330        :param TotpEnrollBeginRequestModel request: The current password
1331        :return: The new TOTP secret/QR URI/backup codes
1332        :rtype: TotpEnrollmentBeginResultModel
1333        """
1334        pass
1335
1336    @abstractmethod
1337    def confirm_totp_enrollment(self, request: TotpConfirmRequestModel) -> MfaStatusModel:
1338        """ Confirm a pending TOTP enrollment (from begin_totp_enrollment) with a live code from
1339        the authenticator app just configured. Activates MFA (method TOTP) only on success.
1340
1341        :param TotpConfirmRequestModel request: The code from the authenticator app
1342        :return: The user's MFA status, now enabled if the code was valid
1343        :rtype: MfaStatusModel
1344        """
1345        pass
1346
1347    @abstractmethod
1348    def regenerate_totp_backup_codes(self, request: TotpBackupCodesRegenerateRequestModel) -> MfaBackupCodesModel:
1349        """ Regenerate the authenticated user's TOTP backup/recovery codes, invalidating the
1350        previous set entirely. Requires re-entering the current password, and that TOTP is
1351        currently the account's enabled MFA method.
1352
1353        :param TotpBackupCodesRegenerateRequestModel request: The current password
1354        :return: The new set of backup/recovery codes, plaintext, shown exactly once
1355        :rtype: MfaBackupCodesModel
1356        """
1357        pass
1358
1359    @abstractmethod
1360    def disable_mfa(self, request: MfaDisableRequestModel) -> MfaStatusModel:
1361        """ Disable MFA for the caller's own account. Requires re-entering the current password.
1362
1363        :param MfaDisableRequestModel request: The current password
1364        :return: The user's MFA status, now disabled
1365        :rtype: MfaStatusModel
1366        """
1367        pass

Helper class that provides a standard way to create an ABC using inheritance.

@abstractmethod
def create_user_against_account( self, account_key: str, privilege_label: str, registration: inmotion.models.UserRegistrationModel) -> inmotion.models.AccountUserSummaryModel:
1228    @abstractmethod
1229    def create_user_against_account(self, account_key: str, privilege_label: str, registration: UserRegistrationModel) -> AccountUserSummaryModel:
1230        """ Register a new user and grant them a privilege level against an account
1231
1232        :param str account_key: The unique key of the account to register the user against
1233        :param str privilege_label: The privilege level to grant ('view', 'contribute', or 'admin';
1234            any other value is treated as 'view' by the server)
1235        :param UserRegistrationModel registration: The definition of the user to create
1236        :return: A summary of the newly created and registered user
1237        :rtype: AccountUserSummaryModel
1238        """
1239        pass

Register a new user and grant them a privilege level against an account

Parameters
  • str account_key: The unique key of the account to register the user against
  • str privilege_label: The privilege level to grant ('view', 'contribute', or 'admin'; any other value is treated as 'view' by the server)
  • UserRegistrationModel registration: The definition of the user to create
Returns

A summary of the newly created and registered user

@abstractmethod
def request_password_reset( self, request: inmotion.models.UserPasswordRequestModel) -> inmotion.models.MessageResponseModel:
1241    @abstractmethod
1242    def request_password_reset(self, request: UserPasswordRequestModel) -> MessageResponseModel:
1243        """ Request a password reset email be sent to a user
1244
1245        :param UserPasswordRequestModel request: The username or email address of the user
1246        :return: A confirmation message
1247        :rtype: MessageResponseModel
1248        """
1249        pass

Request a password reset email be sent to a user

Parameters
  • UserPasswordRequestModel request: The username or email address of the user
Returns

A confirmation message

@abstractmethod
def find_user_attributes(self) -> inmotion.models.UserAttributesModel:
1251    @abstractmethod
1252    def find_user_attributes(self) -> UserAttributesModel:
1253        """ Retrieve the attributes of the currently authenticated user
1254
1255        :return: The authenticated user's attributes
1256        :rtype: UserAttributesModel
1257        """
1258        pass

Retrieve the attributes of the currently authenticated user

Returns

The authenticated user's attributes

@abstractmethod
def update_user_attributes(self, attributes: inmotion.models.UserAttributesModel) -> dict:
1260    @abstractmethod
1261    def update_user_attributes(self, attributes: UserAttributesModel) -> dict:
1262        """ Update the attributes of the currently authenticated user
1263
1264        :param UserAttributesModel attributes: The updated attributes
1265        :return: A raw confirmation message from the server (not a re-fetch of the attributes)
1266        :rtype: dict
1267        """
1268        pass

Update the attributes of the currently authenticated user

Parameters
  • UserAttributesModel attributes: The updated attributes
Returns

A raw confirmation message from the server (not a re-fetch of the attributes)

@abstractmethod
def unregister_from_account(self, account_key: str) -> inmotion.models.UserUnregisteredResponseModel:
1270    @abstractmethod
1271    def unregister_from_account(self, account_key: str) -> UserUnregisteredResponseModel:
1272        """ Unregister the currently authenticated user from an account
1273
1274        :param str account_key: The unique key of the account to unregister from
1275        :return: The result of the unregister operation
1276        :rtype: UserUnregisteredResponseModel
1277        """
1278        pass

Unregister the currently authenticated user from an account

Parameters
  • str account_key: The unique key of the account to unregister from
Returns

The result of the unregister operation

@abstractmethod
def create_otc(self) -> inmotion.models.OTCModel:
1280    @abstractmethod
1281    def create_otc(self) -> OTCModel:
1282        """ Create a one-time code (OTC) key pair for the authenticated user, used to support
1283        device pairing/bootstrap flows. Requires a developer key, which is used to encrypt the
1284        returned private key.
1285
1286        :return: The new one-time code's public/private key pair
1287        :rtype: OTCModel
1288        """
1289        pass

Create a one-time code (OTC) key pair for the authenticated user, used to support device pairing/bootstrap flows. Requires a developer key, which is used to encrypt the returned private key.

Returns

The new one-time code's public/private key pair

@abstractmethod
def find_mfa_status(self) -> inmotion.models.MfaStatusModel:
1291    @abstractmethod
1292    def find_mfa_status(self) -> MfaStatusModel:
1293        """ Retrieve MFA enrollment status (enabled, method, enrolled-at) for the authenticated user
1294
1295        :return: The authenticated user's MFA status
1296        :rtype: MfaStatusModel
1297        """
1298        pass

Retrieve MFA enrollment status (enabled, method, enrolled-at) for the authenticated user

Returns

The authenticated user's MFA status

@abstractmethod
def enroll_mfa( self, request: inmotion.models.MfaEnrollRequestModel) -> inmotion.models.MfaStatusModel:
1300    @abstractmethod
1301    def enroll_mfa(self, request: MfaEnrollRequestModel) -> MfaStatusModel:
1302        """ Begin EMAIL MFA enrollment for the authenticated user's own account: requires
1303        re-entering the current password, then emails a live code. MFA does not activate yet -
1304        follow with confirm_mfa_email. TOTP/SMS are rejected here - use begin_totp_enrollment
1305        instead.
1306
1307        :param MfaEnrollRequestModel request: The method to enroll in and the current password
1308        :return: The user's MFA status (still not enabled)
1309        :rtype: MfaStatusModel
1310        """
1311        pass

Begin EMAIL MFA enrollment for the authenticated user's own account: requires re-entering the current password, then emails a live code. MFA does not activate yet - follow with confirm_mfa_email. TOTP/SMS are rejected here - use begin_totp_enrollment instead.

Parameters
  • MfaEnrollRequestModel request: The method to enroll in and the current password
Returns

The user's MFA status (still not enabled)

@abstractmethod
def confirm_mfa_email( self, request: inmotion.models.TotpConfirmRequestModel) -> inmotion.models.MfaStatusModel:
1313    @abstractmethod
1314    def confirm_mfa_email(self, request: TotpConfirmRequestModel) -> MfaStatusModel:
1315        """ Confirm a pending EMAIL enrollment (from enroll_mfa) with the live code just emailed
1316        to the account. Activates MFA (method EMAIL) only on success.
1317
1318        :param TotpConfirmRequestModel request: The code that was emailed
1319        :return: The user's MFA status, now enabled if the code was valid
1320        :rtype: MfaStatusModel
1321        """
1322        pass

Confirm a pending EMAIL enrollment (from enroll_mfa) with the live code just emailed to the account. Activates MFA (method EMAIL) only on success.

Parameters
  • TotpConfirmRequestModel request: The code that was emailed
Returns

The user's MFA status, now enabled if the code was valid

@abstractmethod
def begin_totp_enrollment( self, request: inmotion.models.TotpEnrollBeginRequestModel) -> inmotion.models.TotpEnrollmentBeginResultModel:
1324    @abstractmethod
1325    def begin_totp_enrollment(self, request: TotpEnrollBeginRequestModel) -> TotpEnrollmentBeginResultModel:
1326        """ Generate a new TOTP secret and backup/recovery codes for the authenticated user's own
1327        account. Does not activate MFA yet - follow with confirm_totp_enrollment. Requires
1328        re-entering the current password. `backupCodes` are returned in plaintext exactly once.
1329
1330        :param TotpEnrollBeginRequestModel request: The current password
1331        :return: The new TOTP secret/QR URI/backup codes
1332        :rtype: TotpEnrollmentBeginResultModel
1333        """
1334        pass

Generate a new TOTP secret and backup/recovery codes for the authenticated user's own account. Does not activate MFA yet - follow with confirm_totp_enrollment. Requires re-entering the current password. backupCodes are returned in plaintext exactly once.

Parameters
  • TotpEnrollBeginRequestModel request: The current password
Returns

The new TOTP secret/QR URI/backup codes

@abstractmethod
def confirm_totp_enrollment( self, request: inmotion.models.TotpConfirmRequestModel) -> inmotion.models.MfaStatusModel:
1336    @abstractmethod
1337    def confirm_totp_enrollment(self, request: TotpConfirmRequestModel) -> MfaStatusModel:
1338        """ Confirm a pending TOTP enrollment (from begin_totp_enrollment) with a live code from
1339        the authenticator app just configured. Activates MFA (method TOTP) only on success.
1340
1341        :param TotpConfirmRequestModel request: The code from the authenticator app
1342        :return: The user's MFA status, now enabled if the code was valid
1343        :rtype: MfaStatusModel
1344        """
1345        pass

Confirm a pending TOTP enrollment (from begin_totp_enrollment) with a live code from the authenticator app just configured. Activates MFA (method TOTP) only on success.

Parameters
  • TotpConfirmRequestModel request: The code from the authenticator app
Returns

The user's MFA status, now enabled if the code was valid

@abstractmethod
def regenerate_totp_backup_codes( self, request: inmotion.models.TotpBackupCodesRegenerateRequestModel) -> inmotion.models.MfaBackupCodesModel:
1347    @abstractmethod
1348    def regenerate_totp_backup_codes(self, request: TotpBackupCodesRegenerateRequestModel) -> MfaBackupCodesModel:
1349        """ Regenerate the authenticated user's TOTP backup/recovery codes, invalidating the
1350        previous set entirely. Requires re-entering the current password, and that TOTP is
1351        currently the account's enabled MFA method.
1352
1353        :param TotpBackupCodesRegenerateRequestModel request: The current password
1354        :return: The new set of backup/recovery codes, plaintext, shown exactly once
1355        :rtype: MfaBackupCodesModel
1356        """
1357        pass

Regenerate the authenticated user's TOTP backup/recovery codes, invalidating the previous set entirely. Requires re-entering the current password, and that TOTP is currently the account's enabled MFA method.

Parameters
  • TotpBackupCodesRegenerateRequestModel request: The current password
Returns

The new set of backup/recovery codes, plaintext, shown exactly once

@abstractmethod
def disable_mfa( self, request: inmotion.models.MfaDisableRequestModel) -> inmotion.models.MfaStatusModel:
1359    @abstractmethod
1360    def disable_mfa(self, request: MfaDisableRequestModel) -> MfaStatusModel:
1361        """ Disable MFA for the caller's own account. Requires re-entering the current password.
1362
1363        :param MfaDisableRequestModel request: The current password
1364        :return: The user's MFA status, now disabled
1365        :rtype: MfaStatusModel
1366        """
1367        pass

Disable MFA for the caller's own account. Requires re-entering the current password.

Parameters
  • MfaDisableRequestModel request: The current password
Returns

The user's MFA status, now disabled