You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #1802 introduces ContentItem as a Protocol that marks the primary content types (workbooks, datasources, views, flows). These are also exactly the endpoints that support server-side name filtering via QuerySet.filter(name=...).
QuerysetEndpoint already has .filter(**kwargs) returning a lazy QuerySet. A find_by_name convenience method belongs on QuerysetEndpoint as a thin, consistent wrapper — visible wherever a consumer would naturally look for it.
Proposed API
# On QuerysetEndpoint[T]:deffind_by_name(self, name: str) ->list[T]:
returnlist(self.filter(name=name))
Returns a list (may be empty, may have multiple matches for same-name items in different projects). The caller chooses how to handle ambiguity — for example, filtering by owner_id or project on the result. A separate projects.find_by_path("Marketing/Reports/Monthly") would handle the hierarchical case (separate issue).
Why QuerysetEndpoint and not individual endpoints
All endpoints that inherit QuerysetEndpoint already support server-side name filtering. Putting find_by_name on the base class means:
One implementation, consistent across all content types
No endpoint inherits it unless it already supports name filtering (non-QuerysetEndpoint endpoints like jobs simply don't have it)
tabcmd (tabcmd/commands/server.py) has a hand-rolled get_items_by_name() that does manual pagination + RequestOptions name filter. This is the pattern every TSC client ends up writing from scratch. Moving it to QuerysetEndpoint lets tabcmd and other clients delete their own copies.
Related: #1809 (CSV user import cleanup), #1802 (ContentItem Protocol).
Background
PR #1802 introduces
ContentItemas a Protocol that marks the primary content types (workbooks, datasources, views, flows). These are also exactly the endpoints that support server-sidenamefiltering viaQuerySet.filter(name=...).QuerysetEndpointalready has.filter(**kwargs)returning a lazyQuerySet. Afind_by_nameconvenience method belongs onQuerysetEndpointas a thin, consistent wrapper — visible wherever a consumer would naturally look for it.Proposed API
Usage:
Returns a list (may be empty, may have multiple matches for same-name items in different projects). The caller chooses how to handle ambiguity — for example, filtering by
owner_idor project on the result. A separateprojects.find_by_path("Marketing/Reports/Monthly")would handle the hierarchical case (separate issue).Why QuerysetEndpoint and not individual endpoints
All endpoints that inherit
QuerysetEndpointalready support server-side name filtering. Puttingfind_by_nameon the base class means:QuerysetEndpointendpoints likejobssimply don't have it)ContentItemProtocol from Add structural Protocol types for TSC item classes #1802 —find_by_nameis meaningful precisely for the types that satisfyContentItemContext
tabcmd (
tabcmd/commands/server.py) has a hand-rolledget_items_by_name()that does manual pagination +RequestOptionsname filter. This is the pattern every TSC client ends up writing from scratch. Moving it toQuerysetEndpointlets tabcmd and other clients delete their own copies.Related: #1809 (CSV user import cleanup), #1802 (ContentItem Protocol).