MetaDataWithOwnership Model
Adds the concept of ownership to the base smarter.lib.django.models.MetaDataModel
model, which is used as a base for all AI resource models in the Smarter
platform. Ownership is defined in terms of a UserProfile (User + Account)
and is used to determine permissions for reading and editing resources.
Role Based Access Control (RBAC)
This model extends the base smarter.lib.django.models.MetaDataModel model to include ownership based on a UserProfile.
MetaDataWithOwnership inherits from from MetaDataModel and
then it additionally extends the base Django ORM model manager to include
readership and ownership based on a few simple concepts:
A UserProfile can be an owner of a MetaDataWithOwnership object, which grants them full permissions to that object.
A UserProfile can be a reader of any MetaDataWithOwnership object that is owns, or that is owned by a staff user of the same
smarter.apps.account.models.Account, or that is owned by the Smarter admin user.A UserProfile with staff privileges can act as an owner of any resource owned by a user of the same
smarter.apps.account.models.Account.The Smarter admin user can act as an owner of any resource in the system.
Example Usage
llm_clients_i_can_see = LLMClient.objects.with_read_permission_for(user=request.user)
llm_clients_i_can_edit = LLMClient.objects.with_ownership_permission_for(user=request.user)
llm_clients_shared_with_me = LLMClient.objects.shared_with(user=request.user)
llm_clients_i_own = LLMClient.objects.owned_by(user=request.user)
Account MetaDataWithOwnership Model
This module provides an abstract Django ORM base model and supporting classes for resource ownership and permission management within the Smarter platform. It extends the core metadata model to include ownership by user profiles and accounts, and provides permission-aware querysets and managers for filtering resources based on user access rights.
Classes
- MetaDataWithOwnershipModel
Abstract base model that adds ownership fields and logic to metadata models.
- MetaDataWithOwnershipModelManager
Custom manager that returns permission-aware querysets.
- SmarterQuerySetWithPermissions
QuerySet subclass with methods for filtering by read and ownership permissions.
Features
Ownership enforcement via foreign key to UserProfile.
Permission-based filtering for read and management (ownership) access.
Caching for optimized retrieval of model instances.
Uniqueness constraints on resource name and owner.
Integration with Smarter’s custom logging and exception handling.
Usage
This module is intended to be subclassed by concrete models that require ownership and permission logic. Do not instantiate MetaDataWithOwnershipModel directly.
class MyResource(MetaDataWithOwnershipModel):
# Define additional fields here
- class smarter.apps.account.models.metadata_with_ownership.MetaDataWithOwnershipModel(*args, **kwargs)[source]
Bases:
MetaDataModelAbstract Django ORM base model that adds Account and User ownership to a SAM Metadata model.
This model extends MetaDataModel to include a foreign key relationship to the UserProfile model, establishing ownership of resources by a specific user profile. It also enforces uniqueness constraints on the combination of user_profile and name fields,
- Parameters:
user_profile – ForeignKey to
smarter.apps.account.models.UserProfile. The user profile that owns this resource.
Note
This is an abstract base class and should not be instantiated directly.
- Parameters:
created_at (Unknown) – Created at
updated_at (Unknown) – Updated at
name (Unknown) – Name. Name in camelCase, e.g., ‘apiKey’, no special characters.
description (Unknown) – Description. A brief description of this resource. Be verbose, but not too verbose.
version (Unknown) – Version. Semantic version in the format MAJOR.MINOR.PATCH, e.g., ‘1.0.0’.
annotations (Unknown) – Annotations. Key-value pairs for annotating this resource.
Relationship fields:
- Parameters:
tags (Unknown) – Tags. Tags for categorizing and organizing this resource.
- clone(new_name=None, new_version=None, user_profile=None)[source]
Create a clone of this instance with a new name, version, and/or user profile.
- Parameters:
new_name (
Optional[str]) – The name for the cloned instance. If not provided, the original name will be suffixed with “ (clone)”.new_version (
Optional[str]) – The version for the cloned instance. If not provided, the original version will be used.user_profile (
Optional[UserProfile]) – The user profile for the cloned instance. If not provided, the original user profile will be used.
- Returns:
A new instance of MetaDataWithOwnershipModel that is a clone of this instance with the specified changes.
- Return type:
- created_at
-
Created at
Timestamp indicating when the model instance was created.
This field is automatically set to the current date and time when the instance is first created. It is indexed in the database for efficient querying.
- Type:
Type
- description
-
Description. A brief description of this resource. Be verbose, but not too verbose.
- Type:
Type
- classmethod get_cached_object(*args, invalidate=False, pk=None, name=None, user=None, user_profile=None, username=None, account=None, session_key=None, taggit=True, **kwargs)[source]
Retrieve a model instance using caching to optimize performance.
Examples of retrieval patterns:
# By primary key instance = MyModel.get_cached_object(pk=123) # By name and user profile instance = MyModel.get_cached_object(name="Resource Name", user_profile=user_profile) # By name and account instance = MyModel.get_cached_object(name="Resource Name", account=account)
- Parameters:
pk (
Optional[int]) – The primary key of the model instance to retrieve.name (
Optional[str]) – The name of the model instance to retrieve.user (
Optional[User]) – The user associated with the model instance.user_profile (
Optional[UserProfile]) – The user profile associated with the model instance.account (
Optional[Account]) – The account associated with the model instance.invalidate (
Optional[bool]) – Whether to invalidate the cache for this retrieval.
- Returns:
The model instance if found, otherwise raises
DoesNotExist.- Return type:
- classmethod get_cached_objects(invalidate=False, user_profile=None, taggit=True, **kwargs)[source]
Retrieve a list of MetaDataWithOwnershipModel instances associated with a user profile using caching.
Example usage:
# Retrieve MetaDataWithOwnershipModel instances for a user profile with caching models = MetaDataWithOwnershipModel.get_cached_objects(my_user_profile, invalidate=invalidate)
- Parameters:
invalidate (
Optional[bool]) – Whether to invalidate the cache for this retrieval.user_profile (
Optional[UserProfile]) – The user profile for which to retrieve MetaDataWithOwnershipModel instances.
- Returns:
A queryset of MetaDataWithOwnershipModel instances associated with the user profile.
- Return type:
- objects: MetaDataWithOwnershipModelManager = <smarter.apps.account.models.metadata_with_ownership.MetaDataWithOwnershipModelManager object>
- save(*args, **kwargs)[source]
Override save method to invalidate cache for this instance upon saving.
This ensures that any updates to the instance are reflected in subsequent retrievals using the caching mechanism.
- Parameters:
args – Positional arguments for the save method.
kwargs – Keyword arguments for the save method.
- tags = <taggit.managers._TaggableManager object>
- updated_at
-
Updated at
Timestamp indicating when the model instance was last updated.
This field is automatically updated to the current date and time whenever the instance is saved. It is indexed in the database for efficient querying.
- Type:
Type
- user_profile
-
User profile
- Type:
Type
- user_profile_id
Internal field, use
user_profileinstead.
- class smarter.apps.account.models.metadata_with_ownership.MetaDataWithOwnershipModelManager(*args, **kwargs)[source]
Bases:
SmarterBaseModelManagerCustom manager for MetaDataWithOwnershipModel that returns a SmarterQuerySetWithPermissions to enable permission-based filtering by user_profile.
- alias(*args, **kwargs)[source]
Returns a SmarterQuerySetWithPermissions with alias applied.
- Return type:
- annotate(*args, **kwargs)[source]
Returns a SmarterQuerySetWithPermissions with annotate applied.
- Return type:
- complex_filter(filter_obj)[source]
Returns a SmarterQuerySetWithPermissions with the applied complex filter.
- Return type:
- difference(*other_qs)[source]
Returns a SmarterQuerySetWithPermissions representing the difference of querysets.
- Return type:
- distinct(*field_names)[source]
Returns a SmarterQuerySetWithPermissions with distinct applied.
- Return type:
- exclude(*args, **kwargs)[source]
Returns a SmarterQuerySetWithPermissions with the applied exclusion.
- Return type:
- filter(*args, **kwargs)[source]
Returns a SmarterQuerySetWithPermissions with the applied filter.
- Return type:
- intersection(*other_qs)[source]
Returns a SmarterQuerySetWithPermissions representing the intersection of querysets.
- Return type:
- order_by(*field_names)[source]
Returns a SmarterQuerySetWithPermissions with order_by applied.
- Return type:
- owned_by(user)[source]
Returns a queryset of resources owned by the given user profile.
A resource is considered owned by a user profile if it is associated with that user profile through the user_profile foreign key.
- Parameters:
user (
User) – The user to check for ownership.- Return type:
- Returns:
A queryset of resources owned by the given user.
- Overloads:
self, clear (None) → SmarterQuerySetWithPermissions[_MT]
self, lookups (str | Prefetch) → SmarterQuerySetWithPermissions[_MT]
Returns a SmarterQuerySetWithPermissions with prefetch_related applied.
- select_for_update(**kwargs)[source]
Returns a SmarterQuerySetWithPermissions with select_for_update applied.
- Return type:
- Overloads:
self, clear (None) → SmarterQuerySetWithPermissions[_MT]
self, fields (str) → SmarterQuerySetWithPermissions[_MT]
Returns a SmarterQuerySetWithPermissions with select_related applied.
Returns a queryset of resources that are shared with the given user.
A resource is considered shared with a user if it is not owned by that user, but the user has read permission for it.
- Parameters:
user (
User) – The user to check for shared resources.- Return type:
- Returns:
A queryset of resources shared with the given user.
- union(*other_qs, all=False)[source]
Returns a SmarterQuerySetWithPermissions representing the union of querysets.
- Return type:
- with_ownership_permission_for(user)[source]
Returns a queryset of resources that the authenticated user in the given request has full management (ownership) permission for.
Permission logic:
If the user is not authenticated, they have no access.
If the user is a superuser, they have ownership permission for all resources.
- If the user is a staff user, they have ownership permission for resources that are:
Owned by their UserProfile, OR
Owned by any UserProfile within their Account.
If the user is a regular authenticated user, they have ownership permission only for resources they own.
- Parameters:
user (
User) –django.contrib.auth.models.UserThe user to check.- Return type:
- Returns:
django.db.models.QuerySetA queryset of this resource if the user has permission to fully manage it, or an empty queryset if not.
- with_read_permission_for(user)[source]
A custom Smarter pipeline for filtering any MetaDataWithOwnership queryset based on the Smarter permissions scheme for the authenticated user in the given request.
Returns a queryset of the resource if the user has permission to read it, or an empty queryset if not.
Permission logic:
If the user is not authenticated, they have no access.
If the user is a superuser, they have access to all resources.
- If the user is a regular authenticated user, they have access to resources that are:
Owned by their UserProfile, OR
Owned by their Account admin UserProfile, OR
Owned by the Smarter admin UserProfile.
- Parameters:
user (
User) –django.contrib.auth.models.UserThe user to check.queryset – Optional[
django.db.models.QuerySet] An optional queryset to filter. If not provided, the method will default to filtering all instances
- Return type:
- Returns:
django.db.models.QuerySetA queryset of this resource if the user has permission to read it, or an empty queryset if not.
- class smarter.apps.account.models.metadata_with_ownership.SmarterQuerySetWithPermissions(model=None, query=None, using=None, hints=None)[source]
Bases:
SmarterBaseQuerySetWithPermissionsCustom queryset for permission-based resource filtering by user profile.
This queryset adds permission-aware filtering for resources owned by a specific user profile.
See also
Django: Creating a manager with QuerySet methods <https://docs.djangoproject.com/en/6.0/topics/db/managers/#creating-a-manager-with-queryset-methods>_
django-stubs: Custom QuerySets <https://github.com/typeddjango/django-stubs>_
- owned_by(user)[source]
Returns a queryset of resources owned by the given user profile.
A resource is considered owned by a user profile if it is associated with that user profile through the user_profile foreign key.
- Parameters:
user (
User) – The user to check for ownership.- Return type:
- Returns:
A queryset of resources owned by the given user.
Returns a queryset of resources that are shared with the given user profile.
A resource is considered shared with a user profile if it is not owned by that user profile, but the user profile has read permission for it.
- Parameters:
user (
User) – The user to check for shared resources.- Return type:
- Returns:
A queryset of resources shared with the given user.
- with_ownership_permission_for(user)[source]
Returns a queryset of resources that the authenticated user in the given request has full management (ownership) permission for.
This method supports users with multiple UserProfiles. For each profile, it computes the set of resources the user can fully manage (ownership permission), and combines all such querysets into a single result using the bitwise OR (|) operator. The final queryset is the union of all resources the user can manage across all their profiles, with duplicates removed.
Only users with staff or superuser status are permitted to manage resources. Superusers receive all resources. Staff users receive resources owned by their UserProfile or by any UserProfile within their Account. Regular users receive only resources they own.
- Parameters:
user (
User) –django.contrib.auth.models.UserThe user to check.- Return type:
- Returns:
django.db.models.QuerySetA queryset of this resource if the user has permission to fully manage it, or an empty queryset if not.
Note
If the user has multiple UserProfiles, the result is the union of all resources they can manage for each profile.
- with_read_permission_for(user)[source]
Returns a queryset of resources that the authenticated user in the given request has read permission for.
This method supports users with multiple UserProfiles. For each profile, it computes the set of resources the user can read, and combines all such querysets into a single result using the bitwise OR (|) operator. The final queryset is the union of all resources the user can read across all their profiles, with duplicates removed.
Permission logic: - If the user is not authenticated, they have no access. - If the user is a superuser, they have access to all resources. - If the user is a regular authenticated user, they have access to resources that are:
Owned by their UserProfile, OR
Owned by their Account admin UserProfile, OR
Owned by the Smarter admin UserProfile.
- Parameters:
user (
User) –django.contrib.auth.models.UserThe user to check.- Return type:
- Returns:
django.db.models.QuerySetA queryset of this resource if the user has permission to read it, or an empty queryset if not.
Note
If the user has multiple UserProfiles, the result is the union of all resources they can read for each profile.