openchecks package

Module contents

class openchecks.AsyncBaseCheck(*args, **kwargs)

Bases: CheckMetadata

The base check class to be inherited from for async code.

This is responsible for validating the input data and returning a result such as pass or fail. It can also provide extra data such as what caused the status (for example, the scene nodes that are named incorrectly).

If the check supports it, then the data being validated can be automatically fixed.

Example

Simple Check

class IsEvenCheck(AsyncBaseCheck):
    def __init__(self, value: int) -> None:
        self.__value = value
        super().__init__()

    def title(self) -> str:
        return "Is Even Check"

    def description(self) -> str:
        return "Check if the number is even."

    async def async_check(self) -> CheckResult:
        if self.__value % 2 == 0:
            return CheckResult.passed("Number is even.")
        else:
            return CheckResult.failed("Number is not even.")

async def main():
    check = IsEvenCheck(2)
    result = await async_run(check)
    assert result.status() == Status.Passed

asyncio.run(main())

Check with Automatic Fix

class IsZeroCheck(AsyncBaseCheck):
    def __init__(self, value: int) -> None:
        self.__value = value
        super().__init__()

    def title(self) -> str:
        return "Is Zero Check"

    def description(self) -> str:
        return "Check if the number is zero."

    async def async_check(self) -> CheckResult:
        if self.__value == 0:
            return CheckResult.passed("Number is zero.")
        else:
            return CheckResult.failed("Number is not zero.", can_fix=True)

    async def async_auto_fix(self) -> None:
        self.__value = 0

async def main():
    check = IsZeroCheck(1)
    result = await async_run(check)
    assert result.status() == Status.Failed

    if result.can_fix():
        result = await async_auto_fix(check)
        assert result.status() == Status.Passed

asyncio.run(main())
async_auto_fix()

Automatically fix the issue detected by the AsyncCheck.async_check method.

async_check()

Run a validation on the input data and output the result of the validation.

Returns:

The result of the check.

Return type:

CheckResult[T]

class openchecks.AsyncBaseScheduler(*args, **kwargs)

Bases: object

A base class for building asynchronous schedulers.

A type implementing the scheduler should avoid requiring any state except for the most absolute bare necessities such as thread or worker count. The methods of this class should also do as little work as possible and just handle taking in a list of checks and outputting the results of the checks/fixes.

async_auto_fix(checks)

Run the auto fix for all of the input checks and return back the checks and the associated result.

This should call the async_auto_fix function to handle attempting to fix the issue and getting the result from the check.

async_run(checks)

Run all of the input checks and return back the checks and the associated result.

This should call the async_run function to handle getting the result from the check.

class openchecks.BaseCheck(*args, **kwargs)

Bases: CheckMetadata

The base check class to be inherited from.

This is responsible for validating the input data and returning a result such as pass or fail. It can also provide extra data such as what caused the status (for example, the scene nodes that are named incorrectly).

If the check supports it, then the data being validated can be automatically fixed.

Example

Simple Check

class IsEvenCheck(BaseCheck):
    def __init__(self, value: int) -> None:
        self.__value = value
        super().__init__()

    def title(self) -> str:
        return "Is Even Check"

    def description(self) -> str:
        return "Check if the number is even."

    def check(self) -> CheckResult:
        if self.__value % 2 == 0:
            return CheckResult.passed("Number is even.")
        else:
            return CheckResult.failed("Number is not even.")

check = IsEvenCheck(2)
result = run(check)
assert result.status() == Status.Passed

Check with Automatic Fix

class IsZeroCheck(BaseCheck):
    def __init__(self, value: int) -> None:
        self.__value = value
        super().__init__()

    def title(self) -> str:
        return "Is Zero Check"

    def description(self) -> str:
        return "Check if the number is zero."

    def check(self) -> CheckResult:
        if self.__value == 0:
            return CheckResult.passed("Number is zero.")
        else:
            return CheckResult.failed("Number is not zero.", can_fix=True)

    def auto_fix(self) -> None:
        self.__value = 0

check = IsZeroCheck(1)
result = run(check)
assert result.status() == Status.Failed

if result.can_fix():
    result = auto_fix(check)
    assert result.status() == Status.Passed
auto_fix()

Automatically fix the issue detected by the Check.check method.

Raises:

NotImplementedError – The automatic fix has not been implemented.

check()

Run a validation on the input data and output the result of the validation.

Raises:

NotImplementedError – The check has not been implemented.

Returns:

The result of the check.

Return type:

CheckResult[T]

class openchecks.BaseScheduler(*args, **kwargs)

Bases: object

A base class for building schedulers.

A type implementing the scheduler should avoid requiring any state except for the most absolute bare necessities such as thread or worker count. The methods of this class should also do as little work as possible and just handle taking in a list of checks and outputting the results of the checks/fixes.

auto_fix(checks)

Run the auto fix for all of the input checks and return back the checks and the associated result.

This should call the auto_fix function to handle attempting to fix the issue and getting the result from the check.

run(checks)

Run all of the input checks and return back the checks and the associated result.

This should call the run function to handle getting the result from the check.

exception openchecks.CheckError

Bases: Exception

class openchecks.CheckHint

Bases: object

The check hint flags contains useful information such as whether the check should support auto-fixing issues.

  • NONE: The check supports no extra features. This should be considered the most conservative check feature. For example, no auto-fix, check cannot be skipped before running, etc.

  • AUTO_FIX: The check supports auto-fixing. This does not guarantee that the auto-fix is implemented, but instead that the auto-fix should be implemented.

AUTO_FIX = CheckHint.CheckHint(AUTO_FIX)
NONE = CheckHint.CheckHint(0x0)
static all()

All of the check hint flags.

Returns:

All of the check hint flags.

Return type:

CheckHint

class openchecks.CheckMetadata(*args, **kwargs)

Bases: object

The check metadata.

This stores the information about the check that is either useful for humans (the title) and description) or useful for systems that uses the check (hint). For example, a user interface could use the title and description to render information for an artist to inform them about what the check will validate and how it will fix issues (if supported). The hint then could be used to render other useful information such as whether the check supports automatic fixes in general, whether it could be overridden by a supervisor, etc.

This should not be inherited directly. Use BaseCheck or AsyncBaseCheck instead.

description()

The human readable description for the check.

This should include information about what the check is looking for, what are the conditions for the different statuses it supports, and if there’s an auto-fix, what the auto-fix will do.

Returns:

The description for the check.

Return type:

str

hint()

The hint gives information about what features the check supports.

Returns:

The hint for the check.

Return type:

CheckHint

title()

The human readable title for the check.

User interfaces should use the title for displaying the check.

Returns:

The title for the check.

Return type:

str

class openchecks.CheckResult(status, message, items=None, can_fix=False, can_skip=False, error=None)

Bases: object

A check result contains all of the information needed to know the status of a check.

It contains useful information such as…

  • Status: A machine readable value that can be used to quickly tell whether the test passed, failed, or is pending.

  • Message: A human readable description of the status. If the status failed, this should contain information on what happened, and how to fix the issue.

  • Items: An iterable of items that caused the result. For example, if a check that validates if objects are named correctly failed, then the items would include the offending objects.

  • Can fix: Whether the check can be fixed or not. For example, if a check requires textures to be no larger than a certain size, includes a method to resize the textures, and failed, the result could be marked as fixable so the user could press an “auto-fix” button in a user interface to resize the textures.

  • Can skip: Usually, a validation system should not let any checks that failed to go forward with, for example, publishing an asset. Sometimes a company might decide that the error isn’t critical enough to always fail if a supervisor approves the fail to pass through.

  • Error: If the status is Status.SystemError, then it may also contain the error that caused the result. Other statuses shouldn’t contain an error.

  • Check duration: A diagnostic tool that could be exposed in a user interface to let the user know how long it took to run the check.

  • Fix duration: A diagnostic tool that could be exposed in a user interface to let the user know how long it took to run the auto-fix.

It is suggested to use one of the other constructor methods such as CheckResult.passed for convenience.

Parameters:
  • status (Status) – The status for the check.

  • message (str) – The human readable description of the status.

  • items (Optional[List[Item[T]]]) – The items that caused the result.

  • can_fix (bool) – Whether the check can be fixed or not.

  • can_skip (bool) – Whether the check can be skipped or not.

  • error (Optional[BaseException]) – The error for the status.

can_fix()

Whether the result can be fixed or not.

If the status is Status.SystemError, then the check can never be fixed without fixing the issue with the validation system.

Returns:

Whether the check can be fixed or not.

Return type:

bool

can_skip()

Whether the result can be skipped or not.

A result should only be skipped if the company decides that letting the failed check pass will not cause serious issues to the next department. Also, it is recommended that check results are not skipped unless a supervisor overrides the skip.

If the status is Status.SystemError, then the check can never be skipped without fixing the issue with the validation system.

check_duration()

The duration of a check.

This is not settable outside of the check runner. It can be exposed to a user to let them know how long a check took to run, or be used as a diagnostics tool to improve check performance.

Returns:

The check duration.

Return type:

float

error()

The error that caused the result.

This only really applies to the Status.SystemError status. Other results should not include the error object.

Returns:

The error for the status.

Return type:

Optional[BaseException]

static failed(message, items=None, can_fix=False, can_skip=False)

Create a new result that failed a check.

Failed checks in a validation system should not let the following process continue forward unless the check can be skipped/overridden by a supervisor, or is fixed and later passes, or passes with a warning.

Parameters:
  • message (str) – The human readable description of the status.

  • items (Optional[List[Item[T]]]) – The items that caused the result.

  • can_fix (bool) – Whether the check can be fixed or not.

  • can_skip (bool) – Whether the check can be skipped or not.

Returns:

The failed result.

Return type:

CheckResult

fix_duration()

The duration of an auto-fix.

This is not settable outside of the auto-fix runner. It can be exposed to a user to let them know how long an auto-fix took to run, or be used as a diagnostics tool to improve check performance.

Returns:

The auto-fix duration.

Return type:

float

items()

The items that caused the result.

Returns:

The items that caused the result.

Return type:

Optional[List[Item[T]]]

message()

A human readable message for the result.

If a check has issues, then this should include information about what happened and how to fix the issue.

Returns:

The result message.

Return type:

str

static passed(message, items=None, can_fix=False, can_skip=False)

Create a new result that passed a check.

Parameters:
  • message (str) – The human readable description of the status.

  • items (Optional[List[Item[T]]]) – The items that caused the result.

  • can_fix (bool) – Whether the check can be fixed or not.

  • can_skip (bool) – Whether the check can be skipped or not.

Returns:

The passed result.

Return type:

CheckResult

static skipped(message, items=None, can_fix=False, can_skip=False)

Create a new result that skipped a check.

Parameters:
  • message (str) – The human readable description of the status.

  • items (Optional[List[Item[T]]]) – The items that caused the result.

  • can_fix (bool) – Whether the check can be fixed or not.

  • can_skip (bool) – Whether the check can be skipped or not.

Returns:

The skipped result.

Return type:

CheckResult

status()

The status of the result.

Returns:

The result status.

Return type:

Status

static warning(message, items=None, can_fix=False, can_skip=False)

Create a new result that passed a check, but with a warning.

Warnings should be considered as passes, but with notes saying that there may be an issue. For example, textures could be any resolution, but anything over 4096x4096 could be marked as a potential performance issue.

Parameters:
  • message (str) – The human readable description of the status.

  • items (Optional[List[Item[T]]]) – The items that caused the result.

  • can_fix (bool) – Whether the check can be fixed or not.

  • can_skip (bool) – Whether the check can be skipped or not.

Returns:

The passed with a warning result.

Return type:

CheckResult

class openchecks.DiscoveryRegistry

Bases: object

The discovery registry allows checks to be discovered based on the input context.

The registry accepts two functions. The query function that is responsible for querying if the context is valid, and the generate function that will take the context and transform it into checks to be validated against.

gather(context)

Return the checks that should be run for the given context.

If the result is None, then nothing was found that will return valid checks.

If two query functions were to return a valid set of checks, then the first one that was registered will return the associated checks.

gather_async(context)

Return the async checks that should be run for the given context.

If the result is None, then nothing was found that will return valid checks.

If two query functions were to return a valid set of checks, then the first one that was registered will return the associated checks.

register(query, generator)

Register the functions that will find the checks to be run.

The query function is responsible for querying if the gather method for the registry will return the contents of the generator function. The generator function is responsible for returning a list of checks for the given context.

register_async(query, generator)

Register the functions that will find the checks to be run in async.

The query function is responsible for querying if the gather method for the registry will return the contents of the generator function. The generator function is responsible for returning a list of checks for the given context.

class openchecks.Item(value, type_hint=None)

Bases: object

The item is a wrapper to make a result item more user interface friendly.

Result items represent the objects that caused a result. For example, if a check failed because the bones in a character rig are not properly named, then the items would contain the bones that are named incorrectly.

The item wrapper makes the use of items user interface friendly because it implements item sorting and a string representation of the item.

Example

class SceneItem(Item):
    def __str__(self) -> str:
        return self.value().name()

    def __eq__(self, other: SceneItem) -> bool:
        return self.value().name() == other.value().name()

    def __lt__(self, other: SceneItem) -> bool:
        return self.value().name() < other.value().name()

a = SceneItem(SceneNode("a"))
b = SceneItem(SceneNode("b"))

assert a != b
assert a < b
assert str(a) == "a"
type_hint()

A type hint can be used to add a hint to a system that the given type represents something else. For example, the value could be a string, but this is a scene path.

A user interface could use this hint to select the item in the application.

value()

The wrapped value

class openchecks.Scheduler(*args, **kwargs)

Bases: BaseScheduler

auto_fix(checks)

Run the auto fix for all of the input checks and return back the checks and the associated result.

This should call the auto_fix function to handle attempting to fix the issue and getting the result from the check.

run(checks)

Run all of the input checks and return back the checks and the associated result.

This should call the run function to handle getting the result from the check.

class openchecks.Status

Bases: object

The status enum represents a result status.

  • Pending: The check is waiting to run. A check should not return this status, but instead this can be used by a user interface to let a user know that the check is ready to run.

  • Skipped: The check has been skipped. A check might return this to let the user know that an element it depends on is invalid (such as a file doesn’t) exist, or a check scheduler may make child checks return this status if a check fails.

  • Passed: The check has successfully passed without issue.

  • Warning: There were issues found, but they are not deemed failures. This can be treated the same as a pass.

  • Failed: The check found an issue that caused it to fail. A validation system should block the process following the validations to have the issue fixed, unless the result allows skipping the check.

  • SystemError: There was an issue with a check or runner itself. For example, code that the check depends on has an error, or the check is otherwise invalid. If a validation process finds a result with this status, then the process should not let the next process after run at all until the check has been fixed by a developer.

Failed = Status.Failed
Passed = Status.Passed
Pending = Status.Pending
Skipped = Status.Skipped
SystemError = Status.SystemError
Warning = Status.Warning
has_failed()

Return if a check has failed.

Returns:

Whether the check has failed or not.

Return type:

bool

has_passed()

Return if a check has passed.

Returns:

Whether the check has passed or not.

Return type:

bool

is_pending()

Return if a check is waiting to be run.

Returns:

Whether the check is waiting to run.

Return type:

bool

openchecks.async_auto_fix(check)

Automatically fix an issue found by a check in an async context.

This function should only be run after the async_run returns a result, and that result can be fixed. Otherwise, the fix might try to fix an already “good” object, causing issues with the object.

The auto-fix will re-run the async_run to validate that it has actually fixed the issue.

This will return a result with the Status.SystemError status if the check does not have the CheckHint.AUTO_FIX flag set, or an auto-fix returned an error. In the case of the latter, it will include the error with the check result.

async def main():
    check = IsZeroCheck(1)
    result = run(check)
    assert result.status() == Status.Failed

    if result.can_fix():
        result = auto_fix(check)
        assert result.status() == Status.Passed

asyncio.run(main())
openchecks.async_run(check)

Run a check in an async context.

Running a check should never fail, but instead return a failure check result. The run function might return a Status.SystemError if the system runs into an error that must be resolved by the team supporting and implementing the checks.

Example

async def main():
    check = IsEvenCheck(2)
    result = run(check)
    assert result.status() == Status.Passed

asyncio.run(main())
openchecks.auto_fix(check)

Automatically fix an issue found by a check.

This function should only be run after the run returns a result, and that result can be fixed. Otherwise, the fix might try to fix an already “good” object, causing issues with the object.

The auto-fix will re-run the run to validate that it has actually fixed the issue.

This will return a result with the Status.SystemError status if the check does not have the CheckHint.AUTO_FIX flag set, or an auto-fix returned an error. In the case of the latter, it will include the error with the check result.

check = IsZeroCheck(1)
result = run(check)
assert result.status() == Status.Failed

if result.can_fix():
    result = auto_fix(check)
    assert result.status() == Status.Passed
openchecks.run(check)

Run a check.

Running a check should never fail, but instead return a failure check result. The run function might return a Status.SystemError if the system runs into an error that must be resolved by the team supporting and implementing the checks.

Example

check = IsEvenCheck(2)
result = run(check)
assert result.status() == Status.Passed