feat(dataqualityrule): added data quality rule support - #66
feat(dataqualityrule): added data quality rule support#66jacopocinaark wants to merge 14 commits into
Conversation
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…Klab/Artesian.SDK-Python into feature/22668-DataQualityRule
There was a problem hiding this comment.
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
MarketDataServiceCRUD 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
marketDataIdandruleIdare always added to query params even when None. This risks sendingmarketDataId=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.
| lastCheckTime: Optional[datetime] = None | ||
| overallStatus: Optional[CheckAggregatedStatus] = None | ||
| activeRulesCount: int = 0 | ||
| failedRulesCount: int = 0 | ||
| from_: Optional[date] = None | ||
| to: Optional[date] = None |
| 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>
There was a problem hiding this comment.
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
marketDataIdis always added to query params, even when it is None. Withrequests, this can result inmarketDataId=Nonebeing 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 inreadDataQualityRuleAsync.
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
readDataQualityRuleAssignmentEventsFeedAsyncbehavior is not covered by unit tests (endpoint path andafterTimestampquery 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 keyFrom_with the current global key transformer (__camelToPascalonly uppercases the first letter). The docstring says the API field name isFrom, 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
…Klab/Artesian.SDK-Python into feature/22668-DataQualityRule
There was a problem hiding this comment.
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
typeis 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 passNone), 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
marketDataIdandruleIdare optional filters, but they are always added to the query params even whenNone. Withrequests, this can end up sendingmarketDataId=None/ruleId=Noneon 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 intests/TestMarketDataService.py, unlike the other newly added Data Quality Rule endpoints. Add aresponses-based test to lock down the query param serialization (especiallyafterTimestamp) and the list deserialization behavior.
async def readDataQualityRuleAssignmentEventsFeedAsync(
self: MarketDataService,
id: int,
afterTimestamp: Optional[datetime] = None,
) -> List[DqCheckChangeEventDtoOutput]:
There was a problem hiding this comment.
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=Noneto 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
typeas a @Property. jsons/dataclass serialization typically only serializes dataclass fields, so the discriminator may be omitted from JSON. Maketypea 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
typefield 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
modelas a @Property. Ifmodelis 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
modelvia a @Property. Ifmodelmust 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
modelvia a @Property. Ifmodelmust 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
There was a problem hiding this comment.
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
readDataQualityRuleAssignmentAsyncalways includesmarketDataIdandruleIdin query params even when they areNone. 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
OutlierModelConfigDtoinheritsDataQualityRuleConfigDto, so its subclasses (e.g.OutlierAbsoluteBoundConfigDto) require callers to passtype=...even though this is alwaysRuleType.Outlier. That’s error-prone (callers can pass the wrong discriminator) and inconsistent with other config DTOs that fixtypeviafield(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
MarketDataTypeenum (nowMarketDataTypeV2) 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__containsMarketDataTypeV2.__name__twice, which can lead to duplicate exports and is likely unintended.
src/Artesian/MarketData/MarketDataService.py:796- Validation error messages for
page/pageSizeinreadDataQualityRuleAssignmentAsynchave 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>
There was a problem hiding this comment.
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.OutlierintoOutlierAbsoluteBoundConfigDto(...), buttypeis defined withfield(init=False, ...)in the base class and will raiseTypeError: __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
readDataQualityRuleAssignmentAsynchave 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
MarketDataTypetoMarketDataTypeV2is a breaking change for consumers importingMarketDataTypefromArtesian.MarketData. Consider providing a backward-compatible alias.
src/Artesian/MarketData/_Dto/OutlierModelConfigDto.py:12 OutlierModelConfigDto.pyhas duplicated imports (including duplicateddataclassimport 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 fromMarketDataTypetoMarketDataTypeV2is a breaking change for consumers usingfrom 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
recordRangeToforRecordValidationConfigDto, 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
sorttorequestsas 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.
There was a problem hiding this comment.
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 ofMarketDataServicehas request/response contract tests intests/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__exportsMarketDataTypeV2twice, 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.OutlierintoOutlierAbsoluteBoundConfigDto(...), but that class inheritstypeasfield(init=False, ...)so this call will raiseTypeError: __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
MarketDataTypebut usesMarketDataTypeV2in the request payload, so the sample will fail withNameErrorunlessMarketDataTypeV2is imported.
(datetime(2018, 10, 1, 1, 0), 100)
],
type=MarketDataTypeV2.ActualTimeSerie,
),
README.md:506
- The Versioned Completeness & Freshness example is not valid Python:
RecordValidationConfigDtois missing the requiredrecordRangeToargument, and theversionTolerance*fields are mis-indented (they should be arguments ofVersionedCompletenessAndFreshnessConfigDto, notRecordValidationConfigDto).
recordValidationConfig=RecordValidationConfigDto(
recordRangeFrom="P0D",
versionToleranceFrom="-PT1H",
versionToleranceTo="PT1H",
versionPrecision=PeriodPrecision.Hour,
There was a problem hiding this comment.
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,
OutlierAbsoluteBoundConfigDtoinheritstypefromOutlierModelConfigDtoasfield(init=False, ...), so passingtype=...will raiseTypeError: __init__() got an unexpected keyword argument 'type'.
model=OutlierAbsoluteBoundConfigDto(
lowerBound=-10.0,
upperBound=45.0,
type=RuleType.Outlier
)
README.md:1021
- This sample imports
MarketDataTypebut the snippet usesMarketDataTypeV2. Copy/paste will fail withNameError: MarketDataTypeV2 is not definedunless 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
DataQualityStatusSummaryDtois included twice in__all__, which is redundant and can lead to duplicate exports in documentation tooling.
src/Artesian/MarketData/_Dto/MarketDataDqStatusSummaryDto.py:25assignmentsis typed asOptional[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
CheckAggregatedStatusenums in the SDK (Artesian.CheckAggregatedStatuswith string values andArtesian.MarketData._Enum.CheckAggregatedStatuswith 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__containsMarketDataTypeV2twice, 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
VersionedCompletenessAndFreshnessConfigDtois syntactically invalid:versionToleranceFrom/versionToleranceToare mis-indented (they appear insideRecordValidationConfigDto(...)),recordRangeTois 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,
ref: #22668