-
Notifications
You must be signed in to change notification settings - Fork 49
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
DNM: fix: Clients now correctly quote/unquote ref parts #2145
Conversation
Preview this PR with FeatureBee: https://beta.wandb.ai/?betaVersion=672d9cc574b1ef2a7f0e08b74e1374d110180feb |
weave/trace_server/refs_internal.py
Outdated
@@ -29,7 +29,7 @@ class InvalidInternalRef(ValueError): | |||
pass | |||
|
|||
|
|||
def quote_select(s: str, quote_chars: tuple[str, ...] = ("/", ":", "%")) -> str: | |||
def quote_select(s: str, quote_chars: tuple[str, ...] = ("%", "/", ":")) -> str: |
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 is a legit bug fix!
@@ -7,7 +7,7 @@ export const flattenObjectPreservingWeaveTypes = (obj: { | |||
[key: string]: any; | |||
}) => { | |||
return flattenObject(obj, '', {}, (key, value) => { | |||
return typeof value !== 'object' || value == null || value._type == null; | |||
return typeof value !== 'object' || value == null || value._type !== 'CustomWeaveType'; |
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 is an unrelated fix I stumbled upon while testing
@@ -7,7 +7,11 @@ export const flattenObjectPreservingWeaveTypes = (obj: { | |||
[key: string]: any; | |||
}) => { | |||
return flattenObject(obj, '', {}, (key, value) => { | |||
return typeof value !== 'object' || value == null || value._type == null; | |||
return ( |
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 is a little followup fix from the Image PR i just put in - it is unrelated to refs
@@ -48,8 +49,13 @@ export const refUriToOpVersionKey = (refUri: RefUri): OpVersionKey => { | |||
}; | |||
|
|||
export const opVersionKeyToRefUri = (key: OpVersionKey): RefUri => { | |||
return `${WEAVE_REF_PREFIX}${key.entity}/${key.project}/op/${key.opId}:${key.versionHash}`; | |||
// return `${WANDB_ARTIFACT_REF_PREFIX}${key.entity}/${key.project}/${key.opId}:${key.versionHash}/obj`; | |||
return makeRefObject( |
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.
We have too much ref construction / parsing logic floating around, centralizing to one location.
@@ -0,0 +1,56 @@ | |||
import { |
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.
much of this file already existed - moved from weave-js/util/refs.ts
to here as this is scoped to "New Weave" (aka Browse3)
weave-js/src/util/refs.ts
Outdated
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.
Moved to weave-js/src/components/PagePanelComponents/Home/Browse3/refs.ts
wandb._wandb_module = "weave" | ||
weave_messages = wandb.sdk.internal.update.check_available(weave.__version__) | ||
wandb._wandb_module = orig_module | ||
weave_messages = 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.
This is unrelated to Refs... for some reason mypy was complaining about this.
@@ -1,4 +1,5 @@ | |||
import dataclasses |
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.
Major changes in this file are to ensure that we quote the user-controlled fields, similar to refs_internal
@@ -0,0 +1,19 @@ | |||
import {ErrorPanel} from '@wandb/weave/components/ErrorPanel'; |
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 noticed while testing that it is pretty lame when a not found error crashes the whole page. This is a common component that can be used to render not found data
@@ -92,8 +92,13 @@ export const browse2Context = { | |||
entityUrl: (entityName: 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.
Pretty much this whole file is all about encoding the url parts
</div> | ||
</div> | ||
); | ||
return <NotFoundPanel title="Call not found" />; |
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.
Moved to a common component
@@ -669,6 +670,13 @@ const useOpVersion = ( | |||
}; | |||
} | |||
|
|||
if (opVersionRes.obj == null) { |
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 block (and the one below that is similar basically handles the case when the target data is not found. before, this would create a JS error due to incorrect nulls
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.
moved to new PR
* artifacts or local artifacts. It is not exported currently, but is used for | ||
* the new Weave branch in parseRef | ||
*/ | ||
const parseWeaveTraceRef = (ref: string): WeaveObjectRef => { |
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 was extracted from parseRef
and is easier to review with whitespace hidden
entityName: string, | ||
projectName: string, | ||
noEncode?: boolean | ||
) => string; | ||
typeUIUrl: ( | ||
entityName: string, | ||
projectName: 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.
Can't we assume entityName and projectName are always safe?
@@ -7,7 +7,11 @@ export const flattenObjectPreservingWeaveTypes = (obj: { | |||
[key: string]: any; |
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.
Moved to New PR
@@ -35,7 +36,7 @@ export const OpVersionPage: React.FC<{ | |||
if (opVersion.loading) { | |||
return <CenteredAnimatedLoader />; | |||
} else if (opVersion.result == null) { | |||
return <div>Op version not found</div>; | |||
return <NotFoundPanel title="Op not found" />; |
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.
moved to new PR
@@ -59,7 +60,7 @@ export const ObjectVersionPage: React.FC<{ | |||
if (objectVersion.loading) { | |||
return <CenteredAnimatedLoader />; | |||
} else if (objectVersion.result == null) { | |||
return <div>Object not found</div>; | |||
return <NotFoundPanel title="Object not found" />; |
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.
moved to new PR
</div> | ||
</div> | ||
); | ||
return <NotFoundPanel title="Call not found" />; |
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.
moved to new PR
Summary: This PR hopefully 🤞 solves >90% of our remaining Ref/Naming issues - meaning users should be able to freely create entities/projects (as long as Gorilla accepts them) and name their objects/ops anything they want (baring a
%
symbol). Under the hood, I close a few remaining constraints / parsing issues on the server side and mostly modify the UI and Python clients to correctly read/write quoted refs.High Level Improvements:
%
in the name is still illegal. We sanitize on the python client for this specific case.Smaller Details:
Companion PR: https://github.com/wandb/core/pull/23333
This PR finishes up the Ref work to ensure we support any ref the user throws at us.
Context:
In a recent PR: #2077, I implemented a more robust parser and checker to ensure Refs and Names conform to expectations. This stopped the "bleeding" where we were storing invalid Refs.
However, our two clients Python and UI had not been updated to reflect the new rules. In fact, the Python client was still creating bad refs, and the UI was overly restrictive with what it thought a ref could be. So double edge sword. As a result, users still hit crashes (either python write time or ui read time).
Moreover, our Ref parsing logic is a mess (especially in the UI) as it is spread across many locations & riddled with legacy junk.
A little terminology note: in PY, URL escaping is called
quoting
and in TS it isencoding
. When used in this PR, they follow the language-specific convention, but logically mean the same concept.Understanding Refs:
See https://www.notion.so/wandbai/WIP-Robust-Refs-550bf06f4a244a1ab4fdd26133952e2c for more details.
The important part to understand is the ref format:
Furthermore,
entity
,project
,name
and theedgeValue
s are user-controlled.The main constraints we need to parse these refs are:
entity
cannot contain slashes/
project
cannot contain slashes/
name
cannot contain slashes/
or colons:
edgeValue
cannot contain slashes/
Therefore, we need to basically URL encode/decode each of these parts in all the places that they are used
entity
,project
, nameand
edgeValue`.Deployment
The ideal order would be: