-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: update ml system related UI #12334
base: master
Are you sure you want to change the base?
feat: update ml system related UI #12334
Conversation
<Typography.Title level={3}>Model Details</Typography.Title> | ||
<InfoItemContainer justifyContent="left"> | ||
{/* TODO: should use versionProperties? */} | ||
<InfoItem title="Version"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RyanHolstien should we use the versionProperties.version for this as well? are we going to deprecate the properties.version?
""" | ||
Represents lineage information for ML entities. | ||
""" | ||
type MLModelLineageInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me know if this is valid approach @shirshanka
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks right, just needs to have the backend mapping on the resolvers.
}; | ||
|
||
const renderTrainingJobs = () => { | ||
const lineageTrainingJobs = model?.properties?.mlModelLineageInfo?.trainingJobs || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me know if this is a valid approach @shirshanka
would there be any difference between pulling properties > trainingjobs or pulling relationships > trained by?
</InfoItem> | ||
<InfoItem title="Aliases"> | ||
<InfoItemContent> | ||
{/* use versionProperties for aliases */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commenting this out until this get merged : #12166
…at/update-mlflow-ui
|
||
|
||
@dataclass | ||
class Container: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at first glance, it took me some time to associate container to experiment. does it make sense to change class name to Experiement? unless there is reason to keep generic term "container"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
// status, | ||
// startTime, | ||
{ | ||
duration, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asikowitz we're adding some of the properties that are specific to data process instance in preview -- let me know if this makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in v2 UI we have a different method of passing values down that I prefer. That method isn't supported in v1 so we can just do this here, but we'll have to coordinate with Chris on getting this to v2.
@@ -270,7 +312,9 @@ export default function DefaultPreviewCard({ | |||
event.stopPropagation(); | |||
}; | |||
|
|||
const shouldShowRightColumn = (topUsers && topUsers.length > 0) || (owners && owners.length > 0); | |||
const statusPillColor = status === 'SUCCESS' ? 'green' : 'red'; | |||
const shouldShowRightColumn = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asikowitz added additional condition to shouldShowRightColumn
-- lmk if this makes sense
@@ -317,7 +317,7 @@ def test_lineage_backend(mock_emit, inlets, outlets, capture_executions): | |||
assert all(map(lambda let: isinstance(let, Dataset), op2.outlets)) | |||
|
|||
# Check that the right things were emitted. | |||
assert mock_emitter.emit.call_count == 19 if capture_executions else 11 | |||
assert mock_emitter.emit.call_count == 20 if capture_executions else 11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asikowitz we're modifyng this test since we have dataplatforminstance in the mock calls
@@ -619,206 +619,178 @@ def test_emit_flow( | |||
mock_emitter.method_calls[11][1][0].entityUrn | |||
== "urn:li:dataProcessInstance:56231547bcc2781e0c14182ceab6c9ac" | |||
) | |||
assert mock_emitter.method_calls[12][1][0].aspectName == "dataPlatformInstance" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asikowitz same here -- assertion has been pushed back by 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is kinda awkward to change. Maybe we could just check if the method calls has certain entries, rather than requiring a specific index to be a certain call
dataProduct={getDataProduct(genericProperties?.dataProduct)} | ||
externalUrl={data.properties?.externalUrl} | ||
parentContainers={data.parentContainers} | ||
parentEntities={parentEntities} | ||
parentEntities={parentEntities as unknown as PreviewEntity[]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asikowitz this was my attempt to fix the yarn type-check -- let me know if this makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fixed once you change the type. You can add:
import { Entity as GraphQLEntity } from '@types';
```
and use that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Hyejin, great work on getting this all working! This is a big PR so I left a lot of comments; it'd probably be good to break this up into a few PRs, e.g. ingestion, backend, and frontend, to be able to go through a smaller set of comments. Most comments are just about style, because we have a lot of ways of doing things, and some are more outdated / no longer recommended. Happy to talk through anything if you have any questions, and feel free to disagree with any of the comments if you have a different opinion.
@@ -380,6 +419,39 @@ export default function DefaultPreviewCard({ | |||
</LeftColumn> | |||
{shouldShowRightColumn && ( | |||
<RightColumn key="right-column"> | |||
{startTime && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this new code is only for data process, maybe we can put it in a separate function and describe it as such
@@ -206,3 +206,39 @@ export function getTimeRangeDescription(startDate: moment.Moment | null, endDate | |||
|
|||
return 'Unknown time range'; | |||
} | |||
|
|||
export function formatDuration(durationMs: number): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't exactly line up, but you could also use moment.js for this: https://momentjs.com/docs/#/durations/humanize/
const hours = Math.floor(durationMs / 1000 / 3600); | ||
|
||
if (hours === 0 && minutes === 0) { | ||
return `${seconds}secs`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space in between?
@@ -88,7 +88,8 @@ private SearchUtils() {} | |||
EntityType.DATA_PRODUCT, | |||
EntityType.NOTEBOOK, | |||
EntityType.BUSINESS_ATTRIBUTE, | |||
EntityType.SCHEMA_FIELD); | |||
EntityType.SCHEMA_FIELD, | |||
EntityType.DATA_PROCESS_INSTANCE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want these to appear in search?
com.linkedin.datahub.graphql.generated.AuditStamp created = | ||
AuditStampMapper.map(context, dataProcessInstanceProperties.getCreated()); | ||
properties.setCreated(created); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can revert
@@ -619,206 +619,178 @@ def test_emit_flow( | |||
mock_emitter.method_calls[11][1][0].entityUrn | |||
== "urn:li:dataProcessInstance:56231547bcc2781e0c14182ceab6c9ac" | |||
) | |||
assert mock_emitter.method_calls[12][1][0].aspectName == "dataPlatformInstance" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is kinda awkward to change. Maybe we could just check if the method calls has certain entries, rather than requiring a specific index to be a certain call
|
||
|
||
@dataclass | ||
class Container: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
@@ -71,6 +77,10 @@ class DataProcessInstance: | |||
_template_object: Optional[Union[DataJob, DataFlow]] = field( | |||
init=False, default=None, repr=False | |||
) | |||
data_platform: Optional[str] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally we call this just platform
. Also, perhaps confusing that we allow specifying both orchestrator
and data_platform
. I think we should only allow one, or we should have validation that only lets you set one.
if self.data_plaform_instance is None and self.cluster is not None: | ||
self.data_plaform_instance = self.cluster |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think cluster
and data_platform_instance
are the same concept
:param clone_inlets: (bool) whether to clone datajob's inlets | ||
:param clone_outlets: (bool) whether to clone datajob's outlets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want these params in this method? Feels like the data process instance doesn't have much meaning without these
Checklist