Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 28 additions & 16 deletions docs/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,11 @@ When set to :python:`True`, methods return a model containing all received meta
Nested resources
================

Some resources refer to other resources. For example, users are tied to a realm which is usually not sent back
automatically. This applies to any other nested resource.
Some resources refer to other resources. For example, users are tied to a realm which is not sent back automatically.
This applies to any other nested resource.

All clients will automatically fetch all nested resources if they are available. This means that you can usually save
yourself extra API calls. Be aware that the client is not capable of fetching nested resources on any level deeper than
the resource you are requesting.
Clients need to specify nested resources in order to be able to fetch them. Be aware that the client is not capable of
fetching nested resources on any level deeper than the resource you are requesting.

.. code-block:: python

Expand All @@ -284,22 +283,35 @@ the resource you are requesting.
)
auth_client = flame_hub.AuthClient(base_url="http://localhost:3000/auth/", auth=auth)

admin_user = auth_client.find_users(filter={"name": "admin"}).pop()
admin_user = auth_client.find_users(filter={"name": "admin"}, include="realm").pop()

print(admin_user.id)
print(admin_user.realm.model_dump_json(indent=2))
print(admin_user.model_dump_json(indent=2))

.. code-block:: console

794f2375-f043-4789-bd0c-e5534e8deeaa
{
"name": "master",
"displayName": null,
"description": null,
"id": "794f2375-f043-4789-bd0c-e5534e8deeaa",
"builtIn": true,
"createdAt": "2025-05-12T09:44:08.284000Z",
"updatedAt": "2025-05-12T09:44:08.284000Z"
"name": "admin",
"displayName": "admin",
"email": null,
"active": true,
"nameLocked": true,
"firstName": null,
"lastName": null,
"id": "2e2108b3-c31d-480c-a33b-90142c0fc609",
"avatar": null,
"cover": null,
"realmId": "4b98aa93-a83e-4ff8-bed4-d8968e0b7493",
"realm": {
"name": "master",
"displayName": null,
"description": null,
"id": "4b98aa93-a83e-4ff8-bed4-d8968e0b7493",
"builtIn": true,
"createdAt": "2026-10-19T11:43:09.196000Z",
"updatedAt": "2026-10-19T11:43:09.196000Z"
},
"createdAt": "2026-10-19T11:43:09.217000Z",
"updatedAt": "2026-10-19T11:43:09.217000Z"
}

Since the realm ID is present, we can use the ``realm`` property too. And just to be extremely sure, we verify that the
Expand Down
41 changes: 15 additions & 26 deletions flame_hub/_auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
uuid_validator,
IsOptionalField,
IsIncludable,
get_includable_names,
UNSET,
UNSET_T,
ResourceListResult,
Expand Down Expand Up @@ -334,9 +333,7 @@ def create_permission(
def get_permission(
self, permission_id: Permission | uuid.UUID | str, **params: te.Unpack[GetKwargs]
) -> SingleResourceResult[Permission]:
return self._get_single_resource(
Permission, "permissions", permission_id, include=get_includable_names(Permission), **params
)
return self._get_single_resource(Permission, "permissions", permission_id, **params)

def delete_permission(self, permission_id: Permission | uuid.UUID | str, **params: te.Unpack[BaseKwargs]):
self._delete_resource("permissions", permission_id, **params)
Expand All @@ -359,10 +356,10 @@ def update_permission(
)

def get_permissions(self, **params: te.Unpack[GetKwargs]) -> ResourceListResult[Permission]:
return self._get_all_resources(Permission, "permissions", include=get_includable_names(Permission), **params)
return self._get_all_resources(Permission, "permissions", **params)

def find_permissions(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[Permission]:
return self._find_all_resources(Permission, "permissions", include=get_includable_names(Permission), **params)
return self._find_all_resources(Permission, "permissions", **params)

def create_role(
self,
Expand All @@ -379,7 +376,7 @@ def create_role(
)

def get_role(self, role_id: Role | uuid.UUID | str, **params: te.Unpack[GetKwargs]) -> SingleResourceResult[Role]:
return self._get_single_resource(Role, "roles", role_id, include=get_includable_names(Role), **params)
return self._get_single_resource(Role, "roles", role_id, **params)

def delete_role(self, role_id: Role | uuid.UUID | str, **params: te.Unpack[BaseKwargs]):
self._delete_resource("roles", role_id, **params)
Expand All @@ -401,10 +398,10 @@ def update_role(
)

def get_roles(self, **params: te.Unpack[GetKwargs]) -> ResourceListResult[Role]:
return self._get_all_resources(Role, "roles", include=get_includable_names(Role), **params)
return self._get_all_resources(Role, "roles", **params)

def find_roles(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[Role]:
return self._find_all_resources(Role, "roles", include=get_includable_names(Role), **params)
return self._find_all_resources(Role, "roles", **params)

def create_role_permission(
self,
Expand All @@ -426,7 +423,6 @@ def get_role_permission(
RolePermission,
"role-permissions",
role_permission_id,
include=get_includable_names(RolePermission),
**params,
)

Expand All @@ -441,15 +437,13 @@ def get_role_permissions(self, **params: te.Unpack[GetKwargs]) -> ResourceListRe
return self._get_all_resources(
RolePermission,
"role-permissions",
include=get_includable_names(RolePermission),
**params,
)

def find_role_permissions(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[RolePermission]:
return self._find_all_resources(
RolePermission,
"role-permissions",
include=get_includable_names(RolePermission),
**params,
)

Expand Down Expand Up @@ -480,7 +474,7 @@ def create_user(
)

def get_user(self, user_id: User | uuid.UUID | str, **params: te.Unpack[GetKwargs]) -> SingleResourceResult[User]:
return self._get_single_resource(User, "users", user_id, include=get_includable_names(User), **params)
return self._get_single_resource(User, "users", user_id, **params)

def delete_user(self, user_id: User | uuid.UUID | str, **params: te.Unpack[BaseKwargs]):
self._delete_resource("users", user_id, **params)
Expand Down Expand Up @@ -514,10 +508,10 @@ def update_user(
)

def get_users(self, **params: te.Unpack[GetKwargs]) -> ResourceListResult[User]:
return self._get_all_resources(User, "users", include=get_includable_names(User), **params)
return self._get_all_resources(User, "users", **params)

def find_users(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[User]:
return self._find_all_resources(User, "users", include=get_includable_names(User), **params)
return self._find_all_resources(User, "users", **params)

def create_user_permission(
self,
Expand All @@ -539,7 +533,6 @@ def get_user_permission(
UserPermission,
"user-permissions",
user_permission_id,
include=get_includable_names(UserPermission),
**params,
)

Expand All @@ -554,15 +547,13 @@ def get_user_permissions(self, **params: te.Unpack[GetKwargs]) -> ResourceListRe
return self._get_all_resources(
UserPermission,
"user-permissions",
include=get_includable_names(UserPermission),
**params,
)

def find_user_permissions(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[UserPermission]:
return self._find_all_resources(
UserPermission,
"user-permissions",
include=get_includable_names(UserPermission),
**params,
)

Expand All @@ -582,18 +573,16 @@ def create_user_role(
def get_user_role(
self, user_role_id: UserRole | uuid.UUID | str, **params: te.Unpack[GetKwargs]
) -> SingleResourceResult[UserRole]:
return self._get_single_resource(
UserRole, "user-roles", user_role_id, include=get_includable_names(UserRole), **params
)
return self._get_single_resource(UserRole, "user-roles", user_role_id, **params)

def delete_user_role(self, user_role_id: UserRole | uuid.UUID | str, **params: te.Unpack[BaseKwargs]):
self._delete_resource("user-roles", user_role_id, **params)

def get_user_roles(self, **params: te.Unpack[GetKwargs]) -> ResourceListResult[UserRole]:
return self._get_all_resources(UserRole, "user-roles", include=get_includable_names(UserRole), **params)
return self._get_all_resources(UserRole, "user-roles", **params)

def find_user_roles(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[UserRole]:
return self._find_all_resources(UserRole, "user-roles", include=get_includable_names(UserRole), **params)
return self._find_all_resources(UserRole, "user-roles", **params)

def create_client(
self,
Expand Down Expand Up @@ -643,13 +632,13 @@ def get_client(
client_id: Client | uuid.UUID | str,
**params: te.Unpack[GetKwargs],
) -> SingleResourceResult[Client]:
return self._get_single_resource(Client, "clients", client_id, include=get_includable_names(Client), **params)
return self._get_single_resource(Client, "clients", client_id, **params)

def get_clients(self, **params: te.Unpack[GetKwargs]) -> ResourceListResult[Client]:
return self._get_all_resources(Client, "clients", include=get_includable_names(Client), **params)
return self._get_all_resources(Client, "clients", **params)

def find_clients(self, **params: te.Unpack[FindAllKwargs]) -> ResourceListResult[Client]:
return self._find_all_resources(Client, "clients", include=get_includable_names(Client), **params)
return self._find_all_resources(Client, "clients", **params)

def update_client(
self,
Expand Down
12 changes: 6 additions & 6 deletions flame_hub/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ class GetKwargs(BaseKwargs, total=False):
:py:type:`~flame_hub.types.FieldParams`
"""

include: IncludeParams | None
fields: FieldParams | None
meta: bool

Expand Down Expand Up @@ -557,7 +558,6 @@ def _get_all_resources(
self,
resource_type: type[ResourceT],
*path: str,
include: IncludeParams | None = None,
expected_code: int = httpx.codes.OK.value,
**params: te.Unpack[GetKwargs],
) -> ResourceListResult[ResourceT]:
Expand All @@ -575,13 +575,12 @@ def _get_all_resources(
Default pagination parameters are applied as explained in the return section of :py:meth:`_find_all_resources`.
"""

return self._find_all_resources(resource_type, *path, include=include, expected_code=expected_code, **params)
return self._find_all_resources(resource_type, *path, expected_code=expected_code, **params)

def _find_all_resources(
self,
resource_type: type[ResourceT],
*path: str,
include: IncludeParams | None = None,
expected_code: int = httpx.codes.OK.value,
**params: te.Unpack[FindAllKwargs],
) -> ResourceListResult[ResourceT]:
Expand Down Expand Up @@ -631,6 +630,7 @@ def _find_all_resources(
"""

# merge processed filter and page params
include_params = params.pop("include", None)
page_params = params.pop("page", None)
filter_params = params.pop("filter", None)
sort_params = params.pop("sort", None)
Expand All @@ -641,7 +641,7 @@ def _find_all_resources(
build_page_params(page_params)
| build_filter_params(filter_params)
| build_sort_params(sort_params)
| build_include_params(include)
| build_include_params(include_params)
| build_field_params(field_params)
)

Expand Down Expand Up @@ -706,7 +706,6 @@ def _get_single_resource(
self,
resource_type: type[ResourceT],
*path: str | UuidIdentifiable,
include: IncludeParams | None = None,
expected_code: int = httpx.codes.OK.value,
**params: te.Unpack[GetKwargs],
) -> SingleResourceResult:
Expand Down Expand Up @@ -756,10 +755,11 @@ def _get_single_resource(
:py:meth:`._get_all_resources`, :py:meth:`._find_all_resources`
"""

include_params = params.pop("include", None)
field_params = params.pop("fields", None)
meta_flag = params.pop("meta", False)

request_params = build_field_params(field_params) | build_include_params(include)
request_params = build_field_params(field_params) | build_include_params(include_params)

try:
r = self._request("GET", *path, expected_code=expected_code, params=request_params, **params)
Expand Down
Loading
Loading