Skip to content

feat(dataqualityrule): added data quality rule support - #66

Open
jacopocinaark wants to merge 14 commits into
masterfrom
feature/22668-DataQualityRule
Open

feat(dataqualityrule): added data quality rule support#66
jacopocinaark wants to merge 14 commits into
masterfrom
feature/22668-DataQualityRule

Conversation

@jacopocinaark

Copy link
Copy Markdown
Contributor

ref: #22668

@jacopocinaark
jacopocinaark requested review from a team as code owners July 20, 2026 13:43
Comment thread samples/TestDataQuality.py Fixed
jacopocinaark and others added 4 commits July 20, 2026 15:45
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 12:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Data Quality Rule (DQR) support to the Python SDK’s MarketData surface, including DTOs/enums, MarketDataService endpoints, tests, and usage docs/samples.

Changes:

  • Added MarketDataService CRUD APIs for data quality rules and rule assignments, plus an assignment events feed endpoint.
  • Introduced Data Quality DTOs/enums (rule types, schedules, outlier models, paged results, assignments, events, status summary).
  • Extended tests, README documentation, and added runnable samples for rule/assignment flows.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/TestMarketDataService.py Adds unit tests for DQR CRUD and assignment CRUD.
src/Artesian/MarketData/MarketDataService.py Adds DQR and assignment endpoints to the service, including an events feed method.
src/Artesian/MarketData/_Enum/ScheduleDefinitionType.py Adds schedule definition discriminator enum.
src/Artesian/MarketData/_Enum/RuleType.py Adds DQ rule type enum (CompletenessAndFreshness/Outlier).
src/Artesian/MarketData/_Enum/PeriodPrecision.py Adds precision enum used by period-based configs.
src/Artesian/MarketData/_Enum/OutlierModel.py Adds outlier model discriminator enum.
src/Artesian/MarketData/_Enum/MarketDataTypeV2.py Adds “v2” market data type enum for DQ configs.
src/Artesian/MarketData/_Enum/CheckAggregatedStatus.py Adds aggregated status enum (OK/KO).
src/Artesian/MarketData/_Enum/init.py Updates enum package exports (currently incomplete for new public enums).
src/Artesian/MarketData/_Dto/VersionedCompletenessAndFreshnessConfigDto.py Adds versioned completeness/freshness config DTO.
src/Artesian/MarketData/_Dto/ScheduleDefinitionDto.py Adds base schedule definition DTO abstraction.
src/Artesian/MarketData/_Dto/ScheduleConfigDto.py Adds schedule config DTO (definition + maxDelay).
src/Artesian/MarketData/_Dto/RecordValidationConfigDto.py Adds record validation window DTO.
src/Artesian/MarketData/_Dto/PagedResult.py Adds paged result wrappers for DQRs and assignments.
src/Artesian/MarketData/_Dto/OutlierRefCurveConfigDto.py Adds reference-curve outlier model config DTO.
src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py Adds base outlier model config DTO (currently has constructor issue).
src/Artesian/MarketData/_Dto/OutlierConfigDto.py Adds outlier rule configuration DTO.
src/Artesian/MarketData/_Dto/OutlierAbsoluteBoundConfigDto.py Adds absolute-bounds outlier model config DTO.
src/Artesian/MarketData/_Dto/MarketDataQualityRuleAssignmentDto.py Adds rule assignment DTOs (input/output).
src/Artesian/MarketData/_Dto/DqCheckChangeEventDto.py Adds DQ change-event DTOs for assignment event feed.
src/Artesian/MarketData/_Dto/DataQualityStatusSummaryDto.py Adds status summary DTO (currently has keyword/serialization mapping risk).
src/Artesian/MarketData/_Dto/DataQualityRuleDtoOutput.py Adds rule output DTO (adds aggregatedStatus).
src/Artesian/MarketData/_Dto/DataQualityRuleDtoInput.py Adds rule input DTO.
src/Artesian/MarketData/_Dto/DataQualityRuleConfigDto.py Adds base config DTO with type discriminator.
src/Artesian/MarketData/_Dto/CronScheduleDefinitionDto.py Adds cron-based schedule definition DTO.
src/Artesian/MarketData/_Dto/CompletenessAndFreshnessConfigDto.py Adds completeness/freshness base config DTO.
src/Artesian/MarketData/_Dto/ActualCompletenessAndFreshnessConfigDto.py Adds “actual time series” completeness/freshness config DTO.
src/Artesian/MarketData/_Dto/init.py Exposes new DTOs via the DTO package exports.
samples/TestDataQualityAssignment.py Adds a manual end-to-end sample for rule assignment lifecycle.
samples/TestDataQuality.py Adds a manual sample for rule CRUD lifecycle.
README.md Documents Data Quality Rules usage and updates formatting in other sections.
Comments suppressed due to low confidence (2)

src/Artesian/MarketData/MarketDataService.py:802

  • marketDataId and ruleId are always added to query params even when None. This risks sending marketDataId=None / ruleId=None; omit them when not provided.
        params["page"] = page
        params["pageSize"] = pageSize
        params["marketDataId"] = marketDataId
        params["ruleId"] = ruleId
        if ruleName:

src/Artesian/MarketData/MarketDataService.py:795

  • Pagination validation error messages contain grammatical errors ("must to be") and report constraints inconsistently (code enforces 1-based pages). Consider clearer, structured messages.
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py
Comment thread src/Artesian/MarketData/MarketDataService.py
Comment thread src/Artesian/MarketData/MarketDataService.py Outdated
Comment thread src/Artesian/MarketData/MarketDataService.py Outdated
Comment thread src/Artesian/MarketData/_Enum/__init__.py
Comment on lines +30 to +35
lastCheckTime: Optional[datetime] = None
overallStatus: Optional[CheckAggregatedStatus] = None
activeRulesCount: int = 0
failedRulesCount: int = 0
from_: Optional[date] = None
to: Optional[date] = None
Comment on lines +951 to +955
async def readDataQualityRuleAssignmentEventsFeedAsync(
self: MarketDataService,
id: int,
afterTimestamp: Optional[datetime] = None,
) -> List[DqCheckChangeEventDtoOutput]:
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (4)

src/Artesian/MarketData/MarketDataService.py:527

  • marketDataId is always added to query params, even when it is None. With requests, this can result in marketDataId=None being sent, which changes the meaning of the request. Only include this filter when a value is provided.
        if type is not None:
            params["type"] = type.name
        params["marketDataId"] = marketDataId
        if name:

src/Artesian/MarketData/MarketDataService.py:793

  • The validation error messages here are ungrammatical/inconsistent ("must to be") and differ from the style used elsewhere in this file. Prefer the same page must be >= 1 (got X) format used in readDataQualityRuleAsync.
        if page < 1:
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

src/Artesian/MarketData/MarketDataService.py:953

  • New readDataQualityRuleAssignmentEventsFeedAsync behavior is not covered by unit tests (endpoint path and afterTimestamp query serialization). This file already has extensive request-matching tests, so this looks like an accidental gap.
    async def readDataQualityRuleAssignmentEventsFeedAsync(
        self: MarketDataService,
        id: int,
        afterTimestamp: Optional[datetime] = None,
    ) -> List[DqCheckChangeEventDtoOutput]:

src/Artesian/MarketData/_Dto/DataQualityStatusSummaryDto.py:35

  • Field name from_ will serialize to JSON key From_ with the current global key transformer (__camelToPascal only uppercases the first letter). The docstring says the API field name is From, so this DTO likely won't round-trip correctly unless the serializer strips the trailing underscore or a per-field rename is configured.
    from_: Optional[date] = None
    to: Optional[date] = None

Comment thread src/Artesian/MarketData/MarketDataService.py Outdated
Comment thread src/Artesian/MarketData/MarketDataService.py Outdated
Comment thread README.md
Comment thread README.md Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 10:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (4)

src/Artesian/MarketData/MarketDataService.py:496

  • type is documented as an optional filter, but it's a required positional argument in the signature. This forces callers to always pass a value (or explicitly pass None), which is inconsistent with the docstring and other optional query filters.
        self: MarketDataService,
        page: int,
        pageSize: int,
        type: Optional[RuleType],
        marketDataId: Optional[int] = None,

src/Artesian/MarketData/MarketDataService.py:800

  • marketDataId and ruleId are optional filters, but they are always added to the query params even when None. With requests, this can end up sending marketDataId=None / ruleId=None on the wire, which changes server-side filtering semantics.
        params = {}
        params["page"] = page
        params["pageSize"] = pageSize
        params["marketDataId"] = marketDataId
        params["ruleId"] = ruleId

src/Artesian/MarketData/MarketDataService.py:794

  • The validation error messages have grammatical issues ("must to be") and are inconsistent with the clearer f-string format used elsewhere in this file (e.g., readDataQualityRuleAsync). This is a public-facing exception message.
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

src/Artesian/MarketData/MarketDataService.py:954

  • This new API surface (readDataQualityRuleAssignmentEventsFeed*) has no unit test coverage in tests/TestMarketDataService.py, unlike the other newly added Data Quality Rule endpoints. Add a responses-based test to lock down the query param serialization (especially afterTimestamp) and the list deserialization behavior.
    async def readDataQualityRuleAssignmentEventsFeedAsync(
        self: MarketDataService,
        id: int,
        afterTimestamp: Optional[datetime] = None,
    ) -> List[DqCheckChangeEventDtoOutput]:

Comment thread src/Artesian/MarketData/MarketDataService.py
Comment thread README.md Outdated
Copilot AI review requested due to automatic review settings July 29, 2026 15:24
Comment thread tests/TestMarketDataService.py Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (8)

src/Artesian/MarketData/MarketDataService.py:796

  • Error messages for page/pageSize validation are inconsistent with other pagination methods in this file and contain grammatical errors ("must to be"). Prefer the same >= 1 (got X) format used elsewhere for clearer API errors.
        if page < 1:
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

src/Artesian/MarketData/MarketDataService.py:802

  • readDataQualityRuleAssignmentAsync currently always includes marketDataId/ruleId in query params even when they are None. That can send marketDataId=None/ruleId=None to the API and change server-side filtering behavior. Only include these params when a value is provided (same pattern as readDataQualityRuleAsync).
        params = {}
        params["page"] = page
        params["pageSize"] = pageSize
        params["marketDataId"] = marketDataId
        params["ruleId"] = ruleId

src/Artesian/MarketData/MarketDataService.py:984

  • New API surface readDataQualityRuleAssignmentEventsFeedAsync/readDataQualityRuleAssignmentEventsFeed is not covered by tests, while this module has extensive response-mocking coverage for other MarketDataService endpoints.
    async def readDataQualityRuleAssignmentEventsFeedAsync(
        self: MarketDataService,
        id: int,
        afterTimestamp: Optional[datetime] = None,
    ) -> List[DqCheckChangeEventDtoOutput]:
        """
        Retrieves the raw event feed for a specific rule assignment.

        Args:
            id: rule assignment identifier.
            afterTimestamp: optional lower bound, returns events after instant.

        Returns:
            List of DqCheckChangeEventDtoOutput (Async).
        """
        url = "/dataquality/dqruleassignment/" + str(id) + "/events"
        params = {}
        if afterTimestamp is not None:
            params["afterTimestamp"] = afterTimestamp.isoformat()
        with self.__client as c:
            res = await asyncio.gather(
                *[
                    self.__executor.exec(
                        c.exec,
                        "GET",
                        url,
                        None,
                        retcls=List[DqCheckChangeEventDtoOutput],
                        params=params,
                    )
                ]
            )
            return cast(List[DqCheckChangeEventDtoOutput], res[0])

src/Artesian/MarketData/_Dto/ScheduleDefinitionDto.py:16

  • ScheduleDefinitionDto defines type as a @Property. jsons/dataclass serialization typically only serializes dataclass fields, so the discriminator may be omitted from JSON. Make type a dataclass field (init=False) and let subclasses provide the default so the discriminator is reliably serialized.
@dataclass
class ScheduleDefinitionDto:
    """
    Base class for schedule definition DTOs.
    """

    @property
    def type(self: "ScheduleDefinitionDto") -> ScheduleDefinitionType:
        raise NotImplementedError(
            "ScheduleDefinitionDto.type must be implemented by subclasses"
        )

src/Artesian/MarketData/_Dto/CronScheduleDefinitionDto.py:24

  • CronScheduleDefinitionDto exposes the schedule discriminator via a @Property. If the API expects a type field in the payload, this may not be serialized. Prefer a dataclass field (init=False) with a default so it is always present in JSON.
@dataclass
class CronScheduleDefinitionDto(ScheduleDefinitionDto):
    """
    A schedule definition based on a cron expression, specifying recurring
    check times in a given time zone.

    Attributes:
        cronExpression: cron expression defining the schedule pattern
        timeZone: IANA time zone identifier used to evaluate cronExpression
    """

    cronExpression: Optional[str] = None
    timeZone: Optional[str] = None

    @property
    def type(self: "CronScheduleDefinitionDto") -> ScheduleDefinitionType:
        return ScheduleDefinitionType.Cron

src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py:17

  • OutlierModelConfigDto defines model as a @Property. If model is a required discriminator for outlier configs, it may be omitted from serialized JSON. Prefer a dataclass field (init=False) and let subclasses set the default discriminator value.
@dataclass
class OutlierModelConfigDto(DataQualityRuleConfigDto):
    """
    Base configuration for outlier detection rules.
    """

    @property
    def model(self: "OutlierModelConfigDto") -> OutlierModel:
        raise NotImplementedError(
            "OutlierModelConfigDto.model must be implemented by subclasses"
        )

src/Artesian/MarketData/_Dto/OutlierAbsoluteBoundConfigDto.py:25

  • OutlierAbsoluteBoundConfigDto exposes model via a @Property. If model must be part of the JSON payload for polymorphic deserialization server-side, this likely won’t be serialized. Use a dataclass field (init=False) with a default discriminator value instead.
@dataclass
class OutlierAbsoluteBoundConfigDto(OutlierModelConfigDto):
    """
    Outlier detection model using fixed absolute bounds.

    A data point is flagged as an outlier if its value falls below
    lowerBound or above upperBound.

    Attributes:
        upperBound: maximum acceptable value
        lowerBound: minimum acceptable value
    """

    upperBound: float
    lowerBound: float

    @property
    def model(self: "OutlierAbsoluteBoundConfigDto") -> OutlierModel:
        return OutlierModel.AbsoluteBound

src/Artesian/MarketData/_Dto/OutlierRefCurveConfigDto.py:25

  • OutlierRefCurveConfigDto exposes model via a @Property. If model must be present in JSON to discriminate between outlier model subtypes, it may be omitted from serialization. Use a dataclass field (init=False) with a default discriminator value instead.
@dataclass
class OutlierRefCurveConfigDto(OutlierModelConfigDto):
    """
    Outlier detection model based on a reference Market Data curve.

    A data point is flagged as an outlier if it deviates from the
    reference value by more than tolerancePerc.

    Attributes:
        referenceMarketDataId: id of the reference Market Data entity
        tolerancePerc: maximum allowed percentage deviation from reference
    """

    referenceMarketDataId: int
    tolerancePerc: float

    @property
    def model(self: "OutlierRefCurveConfigDto") -> OutlierModel:
        return OutlierModel.RefCurve

Comment thread tests/TestMarketDataService.py
Copilot AI review requested due to automatic review settings July 30, 2026 08:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 46 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

src/Artesian/MarketData/MarketDataService.py:802

  • readDataQualityRuleAssignmentAsync always includes marketDataId and ruleId in query params even when they are None. Unlike other methods in this file, this can emit unwanted query parameters (e.g. ruleId=None) and change server-side filtering behavior.
        params["marketDataId"] = marketDataId
        params["ruleId"] = ruleId

src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py:12

  • OutlierModelConfigDto inherits DataQualityRuleConfigDto, so its subclasses (e.g. OutlierAbsoluteBoundConfigDto) require callers to pass type=... even though this is always RuleType.Outlier. That’s error-prone (callers can pass the wrong discriminator) and inconsistent with other config DTOs that fix type via field(init=False, default=...).
class OutlierModelConfigDto(DataQualityRuleConfigDto):
    """
    Base configuration for outlier detection rules.
    """

src/Artesian/MarketData/_Enum/MarketDataTypeV2.py:4

  • This PR is titled/linked as adding Data Quality Rule support, but it also renames/removes the public MarketDataType enum (now MarketDataTypeV2) and updates exports. That is a potentially breaking API change unrelated to data quality rules; consider either restoring backwards compatibility (alias/stub module + re-export) or calling out the breaking change explicitly in the PR description/release notes.
    src/Artesian/MarketData/_Enum/init.py:17
  • __all__ contains MarketDataTypeV2.__name__ twice, which can lead to duplicate exports and is likely unintended.
    src/Artesian/MarketData/MarketDataService.py:796
  • Validation error messages for page/pageSize in readDataQualityRuleAssignmentAsync have grammar issues ("must to be") and are inconsistent with the clearer f-string style used elsewhere in this file (e.g. readDataQualityRuleAsync).
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 30, 2026 08:57
Comment thread src/Artesian/MarketData/MarketDataService.py Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 46 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (7)

README.md:531

  • The outlier rule example passes type=RuleType.Outlier into OutlierAbsoluteBoundConfigDto(...), but type is defined with field(init=False, ...) in the base class and will raise TypeError: __init__() got an unexpected keyword argument 'type'.
    model=OutlierAbsoluteBoundConfigDto(
      lowerBound=-10.0,
      upperBound=45.0,
      type=RuleType.Outlier
    )

src/Artesian/MarketData/MarketDataService.py:795

  • The new validation errors in readDataQualityRuleAssignmentAsync have grammatical issues ("must to be") and are inconsistent with the rest of the file (f-string + lowercase parameter names).
        """
        if page < 1:
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(

src/Artesian/MarketData/init.py:5

  • Renaming the public enum from MarketDataType to MarketDataTypeV2 is a breaking change for consumers importing MarketDataType from Artesian.MarketData. Consider providing a backward-compatible alias.
    src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py:12
  • OutlierModelConfigDto.py has duplicated imports (including duplicated dataclass import blocks). This is noisy and can trigger lint failures.
from dataclasses import dataclass, field

from .._Enum.OutlierModel import OutlierModel
from .._Enum.RuleType import RuleType
from .DataQualityRuleConfigDto import DataQualityRuleConfigDto

src/Artesian/MarketData/_Enum/init.py:17

  • MarketDataTypeV2.__name__ is duplicated in __all__, and the rename from MarketDataType to MarketDataTypeV2 is a breaking change for consumers using from Artesian.MarketData._Enum import MarketDataType. Consider exporting a backward-compatible alias.
    README.md:508
  • The "Completeness and Freshness Rule for Versioned Time Series" example is syntactically invalid (indentation/parentheses) and is missing recordRangeTo for RecordValidationConfigDto, so users can't copy/paste it successfully.

This issue also appears on line 527 of the same file.

    recordValidationConfig=RecordValidationConfigDto(
      recordRangeFrom="P0D",
    versionToleranceFrom="-PT1H",
    versionToleranceTo="PT1H",
    versionPrecision=PeriodPrecision.Hour,

tests/TestMarketDataService.py:645

  • The service passes sort to requests as a list, so the encoded query param will parse as a list (e.g. {'sort': ['Id asc']}); the mock currently expects a string ("Id asc") and may not match, causing this test to fail.

Comment thread src/Artesian/MarketData/MarketDataService.py
Copilot AI review requested due to automatic review settings July 30, 2026 09:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 46 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (6)

src/Artesian/MarketData/MarketDataService.py:986

  • No tests cover the new readDataQualityRuleAssignmentEventsFeed* APIs. The rest of MarketDataService has request/response contract tests in tests/TestMarketDataService.py, so this endpoint should also have a mocked-HTTP test to catch URL/params/serialization regressions.
    async def readDataQualityRuleAssignmentEventsFeedAsync(
        self: MarketDataService,
        id: int,
        afterTimestamp: Optional[datetime] = None,
    ) -> List[DqCheckChangeEventDtoOutput]:
        """
        Retrieves the raw event feed for a specific rule assignment.

        Args:
            id: rule assignment identifier.
            afterTimestamp: optional lower bound, returns events after instant.

        Returns:
            List of DqCheckChangeEventDtoOutput (Async).
        """
        url = "/dataquality/dqruleassignment/" + str(id) + "/events"
        params = {}
        if afterTimestamp is not None:
            params["afterTimestamp"] = afterTimestamp.isoformat()
        with self.__client as c:
            res = await asyncio.gather(
                *[
                    self.__executor.exec(
                        c.exec,
                        "GET",
                        url,
                        None,
                        retcls=List[DqCheckChangeEventDtoOutput],
                        params=params,
                    )
                ]
            )
            return cast(List[DqCheckChangeEventDtoOutput], res[0])

src/Artesian/MarketData/_Enum/init.py:18

  • __all__ exports MarketDataTypeV2 twice, which is redundant and can confuse wildcard imports / docs generation.
    src/Artesian/MarketData/MarketDataService.py:796
  • The pagination validation error messages have grammar issues ("must to be") and use inconsistent casing compared to other methods in this file (e.g. readDataQualityRuleAsync). These messages are user-facing when consumers pass invalid parameters.
        if page < 1:
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

README.md:531

  • The Outlier example passes type=RuleType.Outlier into OutlierAbsoluteBoundConfigDto(...), but that class inherits type as field(init=False, ...) so this call will raise TypeError: __init__() got an unexpected keyword argument 'type'.
    model=OutlierAbsoluteBoundConfigDto(
      lowerBound=-10.0,
      upperBound=45.0,
      type=RuleType.Outlier
    )

README.md:1021

  • The DerivedTransformQueryValidation example imports MarketDataType but uses MarketDataTypeV2 in the request payload, so the sample will fail with NameError unless MarketDataTypeV2 is imported.
            (datetime(2018, 10, 1, 1, 0), 100)
        ],
        type=MarketDataTypeV2.ActualTimeSerie,
    ),

README.md:506

  • The Versioned Completeness & Freshness example is not valid Python: RecordValidationConfigDto is missing the required recordRangeTo argument, and the versionTolerance* fields are mis-indented (they should be arguments of VersionedCompletenessAndFreshnessConfigDto, not RecordValidationConfigDto).
    recordValidationConfig=RecordValidationConfigDto(
      recordRangeFrom="P0D",
    versionToleranceFrom="-PT1H",
    versionToleranceTo="PT1H",
    versionPrecision=PeriodPrecision.Hour,

Copilot AI review requested due to automatic review settings July 30, 2026 10:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 53 out of 54 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (8)

README.md:531

  • In this README snippet, OutlierAbsoluteBoundConfigDto inherits type from OutlierModelConfigDto as field(init=False, ...), so passing type=... will raise TypeError: __init__() got an unexpected keyword argument 'type'.
    model=OutlierAbsoluteBoundConfigDto(
      lowerBound=-10.0,
      upperBound=45.0,
      type=RuleType.Outlier
    )

README.md:1021

  • This sample imports MarketDataType but the snippet uses MarketDataTypeV2. Copy/paste will fail with NameError: MarketDataTypeV2 is not defined unless the import is corrected.
        rows=[
            (datetime(2018, 10, 1, 0, 0), 100),
            (datetime(2018, 10, 1, 1, 0), 100)
        ],
        type=MarketDataTypeV2.ActualTimeSerie,
    ),

src/Artesian/MarketData/_Dto/init.py:96

  • DataQualityStatusSummaryDto is included twice in __all__, which is redundant and can lead to duplicate exports in documentation tooling.
    src/Artesian/MarketData/_Dto/MarketDataDqStatusSummaryDto.py:25
  • assignments is typed as Optional[List], which loses the element type information and makes this DTO harder to use correctly. It should reference the assignment DTO type.
    src/Artesian/MarketData/_Enum/CheckAggregatedStatus.py:6
  • There are two different CheckAggregatedStatus enums in the SDK (Artesian.CheckAggregatedStatus with string values and Artesian.MarketData._Enum.CheckAggregatedStatus with numeric values). This creates ambiguous APIs and makes it easy to pass the wrong enum type between DTOs and service methods.
    src/Artesian/MarketData/_Enum/init.py:17
  • __all__ contains MarketDataTypeV2 twice, which is redundant and can confuse wildcard imports and generated docs.
    src/Artesian/MarketData/MarketDataService.py:800
  • Validation error messages here contain grammatical issues ("must to be") and are inconsistent with the newer f-string messages used elsewhere in this file (e.g. readDataQualityRuleAsync).
        if page < 1:
            raise ValueError("Page must to be greater than 0. Page:" + str(page))
        if pageSize < 1:
            raise ValueError(
                "PageSize must to be greater than 0. Page Size:" + str(pageSize)
            )

README.md:508

  • This README code sample for VersionedCompletenessAndFreshnessConfigDto is syntactically invalid: versionToleranceFrom / versionToleranceTo are mis-indented (they appear inside RecordValidationConfigDto(...)), recordRangeTo is missing, and parentheses don’t balance. As written, users can’t copy/paste this example successfully.

This issue also appears in the following locations of the same file:

  • line 527
  • line 1016
    recordValidationConfig=RecordValidationConfigDto(
      recordRangeFrom="P0D",
    versionToleranceFrom="-PT1H",
    versionToleranceTo="PT1H",
    versionPrecision=PeriodPrecision.Hour,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants