Resources & fields¶
Resources are the configurable, persistable components (connections, configs, destinations); fields declare how their values are collected.
Resource
¶
Bases: pydantic_settings.main.BaseSettings, interloper.component.base.Component
Base for injectable dependencies resolved and injected into asset functions.
Extends BaseSettings, so resource values can be loaded from
environment variables, .env files, or passed directly. Subclass to
define a custom resource:
class MyCache(Resource):
model_config = SettingsConfigDict(env_prefix="my_cache_")
host: str = "localhost"
port: int = 6379
def get(self, key: str) -> Any: ...
def set(self, key: str, value: Any) -> None: ...
Resources are declared on assets via decorator kwargs or type annotations and resolved through a cascade: asset → source → auto-instantiate.
Built-in resource types:
- Config: env-loaded settings
- Connection: credentials and client factories
key
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
kind
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
model_config
¶
model_config = {'extra': 'forbid', 'arbitrary_types_allowed': True, 'validate_default': True, 'case_sensitive': False, 'env_prefix': '', 'env_prefix_target': 'variable', 'nested_model_default_partial_update': False, 'env_file': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_none_str': None, 'env_parse_enums': None, 'cli_prog_name': None, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_hide_none_type': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_use_class_docs_for_groups': False, 'cli_show_env_vars': False, 'cli_exit_on_error': True, 'cli_prefix': '', 'cli_flag_prefix_char': '-', 'cli_implicit_flags': False, 'cli_ignore_unknown_args': False, 'cli_kebab_case': False, 'cli_shortcuts': None, 'json_file': None, 'json_file_encoding': None, 'yaml_file': None, 'yaml_file_encoding': None, 'yaml_config_section': None, 'toml_file': None, 'secrets_dir': None, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'enable_decoding': True, 'ignored_types': (<class 'interloper.serializable.base.IgnoredDescriptor'>, <class 'interloper.component.relation.Relation'>)}
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
relations
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
sensitive
¶
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
definition
¶
definition() -> ResourceDefinition
Produce a structured definition of this resource class.
The config schema is inlined as it belongs to the resource itself.
Returns:
| Type | Description |
|---|---|
ResourceDefinition
|
A ResourceDefinition with metadata and JSON Schema. |
model_post_init
¶
Default id to a generated UUID if not provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Any
|
The pydantic validation context, unused here. |
required |
ResourceDefinition
¶
Bases: interloper.component.base.ComponentDefinition
Definition of a resource with its config schema inlined.
The config schema is the JSON Schema of the resource's own fields: this is same-entity data so it's always inlined, never a key reference.
model_config
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
config
¶
Create a Config subclass from a decorated class.
Can be used bare or with arguments:
@config
class MyConfig:
api_key: str
base_url: str = "https://api.example.com"
@config(key="custom", name="Custom Config")
class OtherConfig(Config):
timeout: int = 30
The decorated class's annotations and attributes become the Config subclass
body. Since Config extends BaseSettings, fields can still be loaded from
environment variables.
relations maps a relation name to a Relation, a component class, or a list
of component classes narrowing the relation the decorated class declares under
that name. Every other keyword is one of the public ClassVars and field defaults
the decorated class declares, or Config itself for a plain class (key,
name, icon, tags). An unknown name is a TypeError at decoration.
Config
¶
Bases: interloper.resource.base.Resource
A resource for arbitrary configuration values.
Like every Resource, config values can be loaded from environment
variables, .env files, or passed directly:
class MyConfig(Config):
api_key: str
base_url: str = "https://api.example.com"
# Loads API_KEY from environment if not passed explicitly
config = MyConfig()
key
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
kind
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
model_config
¶
model_config = {'extra': 'forbid', 'arbitrary_types_allowed': True, 'validate_default': True, 'case_sensitive': False, 'env_prefix': '', 'env_prefix_target': 'variable', 'nested_model_default_partial_update': False, 'env_file': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_none_str': None, 'env_parse_enums': None, 'cli_prog_name': None, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_hide_none_type': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_use_class_docs_for_groups': False, 'cli_show_env_vars': False, 'cli_exit_on_error': True, 'cli_prefix': '', 'cli_flag_prefix_char': '-', 'cli_implicit_flags': False, 'cli_ignore_unknown_args': False, 'cli_kebab_case': False, 'cli_shortcuts': None, 'json_file': None, 'json_file_encoding': None, 'yaml_file': None, 'yaml_file_encoding': None, 'yaml_config_section': None, 'toml_file': None, 'secrets_dir': None, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'enable_decoding': True, 'ignored_types': (<class 'interloper.serializable.base.IgnoredDescriptor'>, <class 'interloper.component.relation.Relation'>)}
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
relations
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
tags
¶
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
model_post_init
¶
Default id to a generated UUID if not provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Any
|
The pydantic validation context, unused here. |
required |
InputField
¶
String field rendered as a standard text input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
TextField
¶
String field rendered as a multi-line textarea.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
SecretField
¶
String field rendered as a password input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
SelectField
¶
SelectField(
default: Any = Ellipsis,
*,
options: list[dict[str, str]] | None = None,
options_from: str | None = None,
**kwargs: Any,
) -> Any
String field rendered as a dropdown select.
Options can be provided statically via options, or resolved
dynamically at render time via options_from.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
options
|
list[dict[str, str]] | None
|
Static list of |
None
|
options_from
|
str | None
|
Entity whose configured instances provide the options
(e.g. |
None
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
JsonField
¶
Dict/object field rendered as a JSON code editor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
CronField
¶
Cron-expression field rendered with presets and a human-readable schedule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
TimezoneField
¶
IANA timezone field rendered as a searchable timezone picker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Example:
FetchField
¶
FetchField(
default: Any = Ellipsis,
*,
provider: str,
label_key: str = "name",
value_key: str = "id",
**kwargs: Any,
) -> Any
Field whose options are fetched from a resource's provider method.
The backend instantiates the resource bound to the relation <name>
(from the credentials the form already holds) and calls the
fetch_field_provider method <method> on it. The lookup logic lives next to the credentials
it uses; there is no per-provider API route to hand-write.
The dependency is the provider's own relation (the <name> part): the
frontend waits for that resource to be selected, then resolves via
/components/resolve. It is implicit in provider, so there is no
separate depends_on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Default value ( |
Ellipsis
|
provider
|
str
|
|
required |
label_key
|
str
|
Key in each response item used as the display label. |
'name'
|
value_key
|
str
|
Key in each response item used as the stored value. |
'id'
|
**kwargs
|
Any
|
Forwarded to |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A Pydantic Field descriptor. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example:
fetch_field_provider
¶
Mark a resource method as a FetchField data source.
A FetchField(provider="<name>.<method>") resolves its options by
instantiating the resource bound to the relation <name> (from the credentials the
form already holds) and calling the method named <method>. Only
methods marked with this decorator may be invoked that way; it is the
allowlist that stops the browser from calling arbitrary attributes.
The method runs inside the API process, which installs the connection
classes but not their heavy provider SDK extras, so a provider must
use lightweight HTTP (httpx2), never self.api (the SDK client).
It returns a list[dict]; the FetchField picks label_key /
value_key out of each item:
class FacebookAdsConnection(il.Connection):
@il.fetch_field_provider
async def accounts(self) -> list[dict]:
...
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
F
|
The resource method to mark as an options provider. |
required |
Returns:
| Type | Description |
|---|---|
F
|
The same callable, stamped as a fetch provider. |
is_fetch_field_provider
¶
Return whether candidate (a function or bound method) is a fetch provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
candidate
|
Any
|
The attribute to test; anything without the provider stamp is not one. |
required |