SmarterAuthenticatedWebView
- class smarter.lib.django.views.SmarterAuthenticatedWebView(*args, **kwargs)[source]
Bases:
SmarterWebHtmlViewAn optimized view that requires authentication.
This class uses the @login_required decorator, applied via Django’s method_decorator to the dispatch method. The @login_required decorator ensures that only authenticated users can access any HTTP method (GET, POST, etc.) on this view. If an unauthenticated user attempts to access the view, they are redirected to the login page. Additionally, the dispatch method is overridden to expire any cache for anonymous users, further protecting sensitive data from being stored or leaked.
By inheriting from both Django’s
Viewand the customSmarterRequestMixin, it ensures consistent request handling and integration with Smarter-specific request features.The view also includes helpers for retrieving the account and user profile associated with the request, and will force a 404 response for users who do not have a valid profile, ensuring that only properly provisioned users can access protected resources.
By enforcing authentication at the dispatch level, this view provides a robust foundation for building secure, user-specific pages in the Smarter platform.
This combination makes the view ideal for admin pages that display sensitive or frequently changing data, ensuring both strict access control and cache prevention.
Bug Fix:
Fixed a bug where Django method decorators were raising exceptions for unauthenticated users instead of redirecting them to the login page. Replaced the decorators with explicit checks in the dispatch method.
Added in version v0.13.39.
- __init__(*args, **kwargs)
Initialize the SmarterView with request and other arguments. This method initializes the SmarterRequestMixin with the request.
- Parameters:
args – Positional arguments, where the first argument is expected to be the HttpRequest.
kwargs – Keyword arguments, which may include the HttpRequest under the ‘request’ key.
- Returns:
None
- Return type:
None
- property account: Account | None
Returns the account for the current user. Handle lazy instantiation from user or user_profile.
- Returns:
The account for the current user.
- Return type:
Account or None
- property account_number: str | None
A helper function to get the account number from the account.
- Returns:
The account number for the current account.
- Return type:
str or None
- property accountmixin_ready_state: str
Returns a string representation of the AccountMixin ready state.
- Returns:
String representation of the AccountMixin ready state.
- Return type:
- property amnesty_urls: list[str]
Returns a list of URLs that are exempt from certain checks.
This is a placeholder and should be overridden in subclasses.
- property api_subdomain: str | None
Extracts the API subdomain from the URL.
- Returns:
The API subdomain or None if not found.
example:
- https://hr.3141-5926-5359.alpha.api.example.com/chatbot/ returns 'hr'
- property api_token: bytes | None
Get the API token from the request.
- Returns:
The API token as bytes if present in the Authorization header, otherwise None.
Example:
request_mixin = SmarterRequestMixin(request) token = request_mixin.api_token
- Returns:
The API token as bytes, or None if not present.
- classmethod as_view(**initkwargs)
Main entry point for a request-response process.
- property auth_header: str | None
Get the Authorization header from the request.
Example:
request_mixin = SmarterRequestMixin(request) print(request_mixin.auth_header)
This property checks for the “Authorization” header in the request headers or in the Django META dictionary.
- Returns:
The value of the “Authorization” header as a string, or None if not present.
- property cache_key: str | None
Returns a cache key for the request.
This is used to cache the chat request thread. The key is a combination of: - the class name, - authenticated username, - the chat name, - and the client UID.
Currently used by the ApiV1CliChatConfigApiView and ApiV1CliChatApiView as a means of sharing the session_key.
- Parameters:
name – A generic object or resource name.
uid – UID of the client, assumed to have been created from the machine MAC address and the hostname of the client.
- Returns:
A unique cache key string.
Example:
request_mixin = SmarterRequestMixin(request) key = request_mixin.cache_key print(key) # e.g., 'a1b2c3d4e5f6...'
- clean_http_response(request, template_path, *args, context=None, **kwargs)
Render a template and return an HttpResponse with comments removed.
- Parameters:
request (
HttpRequest) – The HTTP request object.template_path (str) – The path to the template to render.
context (dict, optional) – The context to use for rendering the template.
- Returns:
An HttpResponse with the cleaned HTML content.
- Return type:
HttpResponse
- clear_cached_properties()
Clears all cached properties in this mixin.
- property data: str | dict | list | None
Get the request body data as a dictionary, list or str.
Used for setting the session_key.
- Returns:
The request body data as a dict, list, or str, or None if not available.
Example:
request_mixin = SmarterRequestMixin(request) data = request_mixin.data print(data) # e.g., {'session_key': 'abc123', ...}
- data_to_dict(data)
Converts data to a dictionary, handling different types of input.
This method accepts either a dictionary or a string. If a string is provided, it will attempt to parse it as JSON first, and if that fails, as YAML. If parsing fails or the data type is unsupported, a SmarterValueError is raised.
- dispatch(request, *args, **kwargs)[source]
Dispatch the request, redirecting to login if the user is anonymous.
- Parameters:
request (
HttpRequest) – The HTTP request object.- Returns:
An HttpResponse object.
- Return type:
HttpResponse
- property domain: str | None
Extracts the domain from the URL.
- Returns:
The domain or None if not found.
examples:
- https://hr.3141-5926-5359.alpha.api.example.com/chatbot/ returns 'hr.3141-5926-5359.alpha.api.example.com'
- eval_chatbot_url()
If we are a chatbot, based on analysis of the URL format then we need to make a follow up check of the user and account.
Examples
- 1.) For named urls, we extract the account number from the url,
then we load the account and admin user for that account.
- 2.) For smarter api urls, we would extract the chatbot id from the url,
then we would load the chatbot, account, and admin user for that account.
- 3.) For cli api urls, we would extract the chatbot name from the url,
then we would load the chatbot, account, and admin user for that account.
- find_session_key()
Returns the unique chat session key value for this request.
The session_key is managed by the /config/ endpoint for the chatbot. The React app calls this endpoint at app initialization to get a JSON dict that includes, among other info, this session_key, which uniquely identifies the device and the individual chatbot session for the device.
For subsequent chat prompt requests, the session_key is intended to be sent in the body of the request as a key-value pair, e.g. {“session_key”: “1234567890”}.
This method will also check the request headers and cookies for the session_key. The session key can be found in one of the following:
URL parameter: http://localhost:9357/workbench/example/config/?session_key=1aeee4c1f183354247f43f80261573da921b0167c7c843b28afd3cb5ebba0d9a
Request JSON body: {‘session_key’: ‘1aeee4c1f183354247f43f80261573da921b0167c7c843b28afd3cb5ebba0d9a’}
Request header: {‘session_key’: ‘1aeee4c1f183354247f43f80261573da921b0167c7c843b28afd3cb5ebba0d9a’}
Cookie
A session_key generator
- property formatted_class_name: str
Returns the class name in a formatted string along with the name of this mixin.
- Returns:
Formatted class name string.
- property formatted_state_not_ready: str
Returns the not-ready state formatted for logging.
- Returns:
The formatted not-ready state as a string.
- Return type:
- property formatted_state_ready: str
Returns the readiness state formatted for logging.
- Returns:
The formatted readiness state as a string.
- Return type:
- generate_session_key()
Generate a session_key based on a unique string and the current datetime.
- Return type:
- Returns:
A unique session key string.
- get(request, *args, **kwargs)
Handle GET requests and return a cleaned HttpResponse.
- Parameters:
request (HttpRequest) – The HTTP request object.
- Returns:
An HttpResponse with the cleaned HTML content.
- Return type:
HttpResponse
- get_cookie_value(cookie_name)
Retrieve the value of a cookie from the request object.
- Parameters:
request – Django HttpRequest object
cookie_name – Name of the cookie to retrieve
- Returns:
Value of the cookie or None if the cookie does not exist
- http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
- http_method_not_allowed(request, *args, **kwargs)
- invalidate_cached_properties()
Invalidates all cached properties on the instance to force re-evaluation.
This method removes all attributes cached by @cached_property decorators from the instance’s __dict__. It is useful for testing or when the request object changes and you need to ensure that all dependent properties are recalculated.
Example:
from smarter.lib.django.request import SmarterRequestMixin class Foo(SmarterRequestMixin): pass foo = Foo(request) foo.invalidate_cached_properties(request)
- Raises:
None –
- property ip_address: str | None
Get the client’s IP address from the request object.
This property attempts to extract the IP address from the request’s META dictionary, using the “REMOTE_ADDR” key. If the IP address is not available, it returns None.
- Returns:
The client’s IP address as a string, or None if not found.
- Return type:
Optional[str]
Example:
request_mixin = SmarterRequestMixin(request) ip = request_mixin.ip_address print(ip) # e.g., '192.168.1.100'
- property is_accountmixin_ready: bool
Returns True if the AccountMixin is ready to be used. This is a convenience property that checks if the account and user are initialized. AccountMixin is considered ready if: - self.user is an instance of User - self.user_profile is an instance of UserProfile - self.account is an instance of Account
- Returns:
True if the AccountMixin is ready to be used.
- Return type:
- property is_chatbot: bool
Returns True if the URL resolves to a chatbot endpoint.
Conditions are checked in a lazy sequence to avoid unnecessary processing.
Examples
http://localhost:9357/workbench/chatbots/<str:hashed_id>/chat/
http://localhost:9357/workbench/chatbots/<str:hashed_id>/config/
http://localhost:9357/workbench/chatbots/<str:hashed_id>/manifest/
- Returns:
True if the URL is a chatbot endpoint, otherwise False.
- Return type:
- property is_chatbot_cli_api_url: bool
9357/api/v1/cli/chat/example/.
- The expected path parts are:
[‘api’, ‘v1’, ‘cli’, ‘chat’, ‘example’]
- Returns:
True if the URL matches the CLI chatbot API pattern, otherwise False.
- Return type:
- Type:
Returns True if the URL is of the form http
- Type:
//localhost
- property is_chatbot_named_url: bool
Returns True if the url is of the form:
- Returns:
True if the URL matches the named chatbot pattern, otherwise False.
- Return type:
- property is_chatbot_sandbox_url: bool
Example URLs for chatbot sandbox endpoints.
Examples
Web console urls: - http://localhost:9357/workbench/chatbots/<str:hashed_id>/chat/ - http://localhost:9357/workbench/chatbots/<str:hashed_id>/config/ - http://localhost:9357/workbench/chatbots/<str:hashed_id>/manifest/
Api urls: - http://localhost:9357/api/v1/prompt/1/chat/ - http://localhost:9357/api/v1/prompt/1/config/
Manifest view urls: https://alpha.platform.smarter.sh/workbench/chatbots/hashed_id/ https://<environment_domain>/workbench/chatbots/<str:hashed_id>/ path_parts: [‘workbench’, ‘chatbots’, ‘rxy123hashedx’]
- Returns:
True if the URL matches a chatbot sandbox endpoint, otherwise False.
- Return type:
- property is_chatbot_smarter_api_url: bool
- Returns True if the URL is of the form:
http://localhost:9357/api/v1/workbench/1/chat/ path_parts: [‘api’, ‘v1’, ‘workbench’, ‘<int:pk>’, ‘chat’]
http://localhost:9357/api/v1/chatbots/1556/chat/ path_parts: [‘api’, ‘v1’, ‘chatbots’, ‘<int:pk>’, ‘chat’]
- Returns:
True if the URL matches a smarter API chatbot endpoint, otherwise False.
- Return type:
- property is_config: bool
Returns True if the URL resolves to a config endpoint.
Examples
http://testserver/api/v1/cli/chat/config/testc7098865f39202d5/ http://localhost:9357/workbench/example/config/?session_key=1aeee4c1f183354247f43f80261573da921b0167c7c843b28afd3cb5ebba0d9a http://localhost:9357/api/v1/workbench/<int:chatbot_id>/chat/config/ http://example.api.localhost:9357/config
- Returns:
True if the URL is a config endpoint, otherwise False.
- Return type:
- property is_dashboard: bool
Returns True if the URL resolves to a dashboard endpoint.
- Returns:
True if the URL is a dashboard endpoint, otherwise False.
- Return type:
- property is_default_domain: bool
Returns True if the URL is the default domain for the environment.
Example
api.alpha.platform.smarter.sh
- Returns:
bool: True if the URL is the default environment domain, otherwise False.
- property is_environment_root_domain: bool
Returns True if the URL resolves to the environment root domain.
- Returns:
True if the URL is the environment root domain, otherwise False.
- Return type:
- is_internal_api_request(request)
Check if the request is an internal API request.
This method checks for a custom attribute on the request object that indicates whether the request is an internal API request. This can be used to bypass certain authentication or permission checks for internal requests.
- Parameters:
request (
HttpRequest) – The Django request object.- Returns:
True if it’s an internal API request, False otherwise.
- Return type:
- property is_requestmixin_ready: bool
Returns True if the request mixin is ready for processing. This is a convenience property to check if the request is ready.
- Returns:
True if the request mixin is ready, False otherwise.
- property is_smarter_api: bool
9357/api/v1/.
Examples
path_parts: [‘api’, ‘v1’, ‘chatbots’, ‘1’, ‘chat’]
- Returns:
True if the URL matches the smarter API pattern, otherwise False.
- Return type:
- Type:
Returns True if the URL is of the form http
- Type:
//localhost
- property is_workbench: bool
Returns True if the URL resolves to a workbench endpoint.
- Returns:
True if the URL is a workbench endpoint, otherwise False.
- Return type:
- log_account_mixin_ready_status()
Logs the ready status of the AccountMixin.
- log_request_mixin_ready_status()
Logs the ready status of the SmarterRequestMixin.
- property logger_prefix
- mask_string(string='', mask_char='*', mask_length=4, string_length=8)
Masks a string for secure logging.
This utility function masks all but the last unmasked_chars characters of the input string, replacing them with asterisks. It is useful for logging sensitive information like API keys or passwords.
- minify_html(html)
Minify an html string.
- options(request, *args, **kwargs)
Handle responding to requests for the OPTIONS HTTP verb.
- property params: QueryDict
The query string parameters from the Django request object.
This extracts the query string parameters from the request object and converts them to a dictionary. Used in child views to pass optional command-line parameters to the broker.
- Returns:
QueryDict containing the query string parameters.
Example:
request_mixin = SmarterRequestMixin(request) params = request_mixin.params print(params) # e.g., {'session_key': 'abc123', 'uid': 'xyz'}
- property parsed_url: ParseResult | None
Expose the private ParseResult URL object as a public property.
- Returns:
The parsed URL as a ParseResult object.
Example:
request_mixin = SmarterRequestMixin(request) parsed = request_mixin.parsed_url print(parsed.netloc) # e.g., 'example.com'
- property path: str | None
Extracts the path from the URL.
- Returns:
Optional[str]: The path as a string, or None if not found.
Examples
https://hr.3141-5926-5359.alpha.api.example.com/chatbot/ returns ‘/chatbot/’
- property qualified_request: bool
A cursory screening of the WSGI request object to look for any disqualifying conditions that confirm this is not a request that we are interested in.
The request is considered “qualified” if all of the following are true:
The request object (self._smarter_request) is present.
The URL path is present and non-empty.
The request does not originate from an internal AWS Kubernetes subnet (netloc starts with 192.168).
The path is not in the list of amnesty_urls.
The path does not start with /admin/.
The path does not start with /docs/.
The path does not end with a static file extension (e.g., .css, .js, .png, .jpg, .jpeg, .gif, .svg, .woff, .woff2, .ttf, .eot, .ico).
- Returns:
True if the request passes all checks and is of interest, otherwise False.
Example:
# True case: a valid chatbot request request_mixin = SmarterRequestMixin(request) if request_mixin.qualified_request: print("This is a qualified chatbot request.") # False case: a static asset or admin/docs request static_request = SmarterRequestMixin(static_asset_request) if not static_request.qualified_request: print("This request is not of interest.")
- property ready: bool
returns True if the request is ready for processing.
- Returns:
True if the request is ready, False otherwise.
- remove_comments(html)
Remove HTML comments from an html string.
- render_clean_html(request, template_path, context=None)
Render a template as a string, with comments removed and minified.
- Parameters:
request (
HttpRequest) – The HTTP request object.template_path (str) – The path to the template to render.
context (dict, optional) – The context to use for rendering the template.
- Returns:
The rendered, cleaned HTML string.
- Return type:
- property request_mixin_ready_state: str
Returns a string representation of the request mixin’s ready state.
- Returns:
A string indicating whether the request mixin is ready or not.
- property root_domain: str | None
Extracts the root domain from the URL.
- Returns:
The root domain or None if not found.
Example:
request_mixin = SmarterRequestMixin(request) print(request_mixin.root_domain) # For 'https://hr.3141-5926-5359.alpha.api.example.com/chatbot/' → 'smarter.sh' # For 'http://localhost:9357/' → 'localhost'
- property session_key: str
Getter for the session_key property.
The session_key is a unique identifier for a chat session. It is used to identify the chat session across multiple requests. If the session_key is not already set, it attempts to find it in the URL parameters. Barring that, it generates a new one.
- Returns:
The session key as a string.
Example:
request_mixin = SmarterRequestMixin(request) session_key = request_mixin.session_key print(session_key) # e.g., '38486326c21ef4bcb7e7bc305bdb062f16ee97ed8d2462dedb4565c860cd8ecc'
- set_is_internal_api_request(request, value=True)
Set the internal API request attribute on the request object.
This method allows you to mark a request as an internal API request by setting a custom attribute on the request object. This can be used in middleware or views to indicate that the request should be treated as internal.
- Parameters:
request (
HttpRequest) – The Django request object.value (
bool) – The value to set for the internal API request attribute (default is True).
- Returns:
The modified Django request object.
- Return type:
- setup(request, *args, **kwargs)[source]
Setup the view with the request and any additional arguments. This method initializes the SmarterRequestMixin with the request.
- Parameters:
request (
HttpRequest) – The HTTP request object.args – Additional positional arguments.
kwargs – Additional keyword arguments.
- Returns:
The result of the superclass setup method.
- Return type:
Any
- smarter_build_absolute_uri(request)
Attempts to get the absolute URI from a request object.
This utility function tries to retrieve the request URL from any valid child class of
django.http.HttpRequest. It is especially useful in unit tests or scenarios where the request object may not implementbuild_absolute_uri().- Parameters:
request (
HttpRequest) – The request object.- Returns:
The absolute request URL.
- Return type:
- Raises:
SmarterValueError – If the URI cannot be built from the request.
- property smarter_request: Request | HttpRequest | WSGIRequest | MagicMock | None
Returns the current request object.
This property is named to avoid potential name collisions in child classes. This property is preferred over standard Django request types in that it more elegantly resolves idiosyncratic usage like Unit tests, Sphinx docs, and other non-standard request objects.
Example:
request_mixin = SmarterRequestMixin(request) req = request_mixin.smarter_request
- Returns:
The current request object.
- property smarter_request_chatbot_id: int | None
Extract the chatbot id from the URL.
Example
http://localhost:9357/workbench/chatbots/rMTAwMDAyNwx/chat/
returns the pk id that when decoded from the hashed ID format corresponds to the chatbot id.
- Returns:
The chatbot id as an integer, or None if not found.
- property smarter_request_chatbot_name: str | None
Extract the chatbot name from the URL.
Example
http://example.3141-5926-5359.api.localhost:9357/config
returns “example”
- Returns:
The chatbot name as a string, or None if not found.
- property smarter_request_user: AnonymousUser | User | None
Returns the user associated with the request
This property is named to avoid potential name collisions in child classes. It retrieves the user from the request object if available.
Example:
request_mixin = SmarterRequestMixin(request) user = request_mixin.smarter_request_user
- Returns:
The user associated with the request, or None if not available.
- sorted_dict(data)
Returns a new dictionary with keys sorted.
- property subdomain: str | None
Extracts the subdomain from the URL.
- Returns:
The subdomain or None if not found.
Example:
request_mixin = SmarterRequestMixin(request) sub = request_mixin.subdomain print(sub) # e.g., 'hr.3141-5926-5359.alpha' for # 'https://hr.3141-5926-5359.alpha.api.example.com/chatbot/'
- property timestamp
Create a consistent timestamp based on the time that this object was instantiated.
- Returns:
The timestamp as a datetime object.
Example:
request_mixin = SmarterRequestMixin(request) ts = request_mixin.timestamp print(ts) # e.g., 2025-12-01 12:34:56.789012
- to_json()
serializes the object.
- property uid: str | None
Unique identifier for the client.
This is assumed to be a combination of the machine MAC address and the hostname.
- Returns:
The client UID as a string, or None if not available.
Example:
request_mixin = SmarterRequestMixin(request) uid = request_mixin.uid print(uid) # e.g., '00:1A:2B:3C:4D:5E-myhost'
- property unformatted_class_name: str
Returns the raw class name without formatting.
- Returns:
The unformatted class name as a string.
- Return type:
This is useful for logging or serialization where the plain class name is needed.
- property unique_client_string: str
Generate a unique string based on several request attributes.
This string is used for generating session_key and client_key.
- The unique string is composed of:
Account number
URL
User agent
IP address
Timestamp
- Returns:
A unique string representing the client and request context.
- Return type:
Example:
request_mixin = SmarterRequestMixin(request) unique_str = request_mixin.unique_client_string print(unique_str)
- property url: str | None
The string representation of the ParseResult object stored in _parsed_url.
- Returns:
The URL as a string.
Example:
request_mixin = SmarterRequestMixin(request) url_str = request_mixin.url print(url_str) # e.g., 'https://example.com/path/'
- property url_account_number: str | None
Extract the account number from the URL using the pattern defined in SmarterValidator.VALID_ACCOUNT_NUMBER_PATTERN.
Example
http://example.3141-5926-5359.api.localhost:9357/config
returns “3141-5926-5359”
- Returns:
The account number as a string, or None if not found.
- property url_path_parts: list[str]
Extract the path parts from the URL.
- Returns:
A list of strings representing each part of the URL path.
Example:
request_mixin = SmarterRequestMixin(request) parts = request_mixin.url_path_parts print(parts) # e.g., ['api', 'v1', 'workbench', '1', 'chat']
- property user: AnonymousUser | User | None
Returns the user for the current user. Handle lazy instantiation from user_profile or account.
- Returns:
The user for the current user.
- Return type:
User or None
- property user_agent: str | None
Get the client’s user agent string from the request object.
This property attempts to extract the user agent from the request’s META dictionary, using the “HTTP_USER_AGENT” key. If the user agent is not available, it returns a default value.
- Returns:
The client’s user agent string, or None if not found.
- Return type:
Optional[str]
Example:
request_mixin = SmarterRequestMixin(request) ua = request_mixin.user_agent print(ua) # e.g., 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...'
- property user_profile: UserProfile | None
Returns the user_profile for the current user. Handle lazy instantiation from user or account.
- Returns:
The user_profile for the current user.
- Return type:
UserProfile or None
- view_is_async = False