Skip to content

access

access

PageAccess

Bases: Access, Enum

Page sharing permissions (users and groups).

Represents the access levels that can be granted when sharing pages in Domo. Unlike accounts which have separate v1/v2 APIs, page sharing uses a unified API.

Attributes:

Name Type Description
OWNER

Full ownership with all permissions

CAN_EDIT

Can modify page content and configuration

CAN_VIEW

Read-only access to view the page

Example

access = PageAccess.CAN_VIEW access.value 'CAN_VIEW' PageAccess.get("CAN_EDIT")

add_page_owner async

add_page_owner(
    auth: DomoAuth,
    page_id_ls: list[int | str],
    group_id_ls: list[int | str] | None = None,
    user_id_ls: list[int | str] | None = None,
    note: str = "",
    send_email: bool = False,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Add owners to multiple pages.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing credentials and instance info

required
page_id_ls list[int | str]

list of page IDs to add owners to

required
group_id_ls list[int | str] | None

Optional list of group IDs to add as owners

None
user_id_ls list[int | str] | None

Optional list of user IDs to add as owners

None
note str

Optional note to include with ownership changes

''
send_email bool

Whether to send notification email

False
return_raw bool

Return raw API response without processing

False
context RouteContext | None

RouteContext for request configuration

None
**context_kwargs

Additional context parameters (session, debug_api, etc.)

{}

Returns:

Type Description
ResponseGetData

ResponseGetData object containing ownership update result

Raises:

Type Description
Page_CRUD_Error

If adding page owners fails

Source code in src/crew_dcs/routes/page/access.py
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(
        entity_extractor=DomoEntityExtractor(),
        result_processor=DomoEntityResultProcessor(),
    ),
)
async def add_page_owner(
    auth: DomoAuth,
    page_id_ls: list[int | str],
    group_id_ls: list[int | str] | None = None,
    user_id_ls: list[int | str] | None = None,
    note: str = "",
    send_email: bool = False,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """Add owners to multiple pages.

    Args:
        auth: Authentication object containing credentials and instance info
        page_id_ls: list of page IDs to add owners to
        group_id_ls: Optional list of group IDs to add as owners
        user_id_ls: Optional list of user IDs to add as owners
        note: Optional note to include with ownership changes
        send_email: Whether to send notification email
        return_raw: Return raw API response without processing
        context: RouteContext for request configuration
        **context_kwargs: Additional context parameters (session, debug_api, etc.)

    Returns:
        ResponseGetData object containing ownership update result

    Raises:
        Page_CRUD_Error: If adding page owners fails
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    page_id_ls = [str(ele) for ele in page_id_ls]
    group_id_ls = group_id_ls or []
    user_id_ls = user_id_ls or []

    url = f"https://{auth.domo_instance}.domo.com/api/content/v1/pages/bulk/owners"
    owners = []
    for group in group_id_ls:
        owners.append({"id": str(group), "type": "GROUP"})
    for user in user_id_ls:
        owners.append({"id": str(user), "type": "USER"})

    body = {
        "pageIds": page_id_ls,
        "owners": owners,
        "note": note,
        "sendEmail": send_email,
    }

    res = await gd.get_data(
        auth=auth,
        method="PUT",
        url=url,
        body=body,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        raise Page_CRUD_Error(
            operation="add owners",
            message=f"Unable to add owners to pages {', '.join(page_id_ls)}",
            res=res,
        )

    # NOTE: this string is built from the INPUT, not from a read-back. An empty
    # `owners` list produces the same sentence as a real grant — which is what
    # happens when a caller spells the argument `user_ids` instead of
    # `user_id_ls` (it is then swallowed by **context_kwargs). Callers that need
    # to know the grant landed must re-read the access list; see
    # .agents/guides/access-and-sharing.md.
    res.response = f"Successfully added owners to pages {', '.join(page_id_ls)}"

    return res

get_page_access_list async

get_page_access_list(
    auth: DomoAuth,
    page_id: str,
    is_expand_users: bool = True,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Retrieve page access list showing which users and groups have access.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing credentials and instance info

required
page_id str

Unique identifier for the page

required
is_expand_users bool

Whether to expand group memberships to include individual users

True
return_raw bool

Return raw API response without processing

False
context RouteContext | None

RouteContext for request configuration

None
**context_kwargs

Additional context parameters (session, debug_api, etc.)

{}

Returns:

Type Description
ResponseGetData

ResponseGetData object containing access list with users and groups

Raises:

Type Description
PageSharing_Error

If access list retrieval fails

SearchPageNotFoundError

If page with specified ID doesn't exist

Source code in src/crew_dcs/routes/page/access.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(
        entity_extractor=DomoEntityExtractor(),
        result_processor=DomoEntityResultProcessor(),
    ),
)
async def get_page_access_list(
    auth: DomoAuth,
    page_id: str,
    is_expand_users: bool = True,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """Retrieve page access list showing which users and groups have access.

    Args:
        auth: Authentication object containing credentials and instance info
        page_id: Unique identifier for the page
        is_expand_users: Whether to expand group memberships to include individual users
        return_raw: Return raw API response without processing
        context: RouteContext for request configuration
        **context_kwargs: Additional context parameters (session, debug_api, etc.)

    Returns:
        ResponseGetData object containing access list with users and groups

    Raises:
        PageSharing_Error: If access list retrieval fails
        SearchPageNotFoundError: If page with specified ID doesn't exist
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    url = f"https://{auth.domo_instance}.domo.com/api/content/v1/share/accesslist/page/{page_id}?expandUsers={is_expand_users}"

    res = await gd.get_data(
        url,
        method="GET",
        auth=auth,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        if res.status == 404:
            raise SearchPageNotFoundError(
                search_criteria=f"page_id: {page_id}",
                res=res,
            )
        raise PageSharing_Error(
            operation="retrieve access list",
            page_id=page_id,
            res=res,
        )

    res.response["explicitSharedUserCount"] = len(res.response.get("users"))
    for user in res.response.get("users"):
        user.update({"isExplicitShare": True})

    # add group members to users response
    if is_expand_users:
        group_users = [
            {**user, "isExplicitShare": False}
            for group in res.response.get("groups")
            for user in group.get("users")
        ]
        users = res.response.get("users") + [
            group_user
            for group_user in group_users
            if group_user.get("id")
            not in [user.get("id") for user in res.response.get("users")]
        ]
        res.response.update({"users": users})

    return res

get_page_access_test async

get_page_access_test(
    auth: DomoAuth,
    page_id: str,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Test page access permissions for the authenticated user.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing credentials and instance info

required
page_id str

Unique identifier for the page

required
return_raw bool

Return raw API response without processing

False
context RouteContext | None

RouteContext for request configuration

None
**context_kwargs

Additional context parameters (session, debug_api, etc.)

{}

Returns:

Type Description
ResponseGetData

ResponseGetData object containing page access information

Raises:

Type Description
Page_GET_Error

If access test fails

SearchPageNotFoundError

If page with specified ID doesn't exist

Source code in src/crew_dcs/routes/page/access.py
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(
        entity_extractor=DomoEntityExtractor(),
        result_processor=DomoEntityResultProcessor(),
    ),
)
async def get_page_access_test(
    auth: DomoAuth,
    page_id: str,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """Test page access permissions for the authenticated user.

    Args:
        auth: Authentication object containing credentials and instance info
        page_id: Unique identifier for the page
        return_raw: Return raw API response without processing
        context: RouteContext for request configuration
        **context_kwargs: Additional context parameters (session, debug_api, etc.)

    Returns:
        ResponseGetData object containing page access information

    Raises:
        Page_GET_Error: If access test fails
        SearchPageNotFoundError: If page with specified ID doesn't exist
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    url = f"https://{auth.domo_instance}.domo.com/api/content/v1/pages/{page_id}/access"

    res = await gd.get_data(
        url,
        method="GET",
        auth=auth,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        if res.status == 404:
            raise SearchPageNotFoundError(
                search_criteria=f"page_id: {page_id}",
                res=res,
            )
        raise Page_GET_Error(page_id=page_id, res=res)

    return res