resource_document#

See ResourceDocument.

aws_resource_search.documents.resource_document.get_utc_now() datetime[source]#

Get timezone aware datetime object of current time in UTC.

aws_resource_search.documents.resource_document.to_human_readable_elapsed(sec: int) str[source]#

Convert seconds to human-readable string.

Example:

>>> to_human_readable_elapsed(1)
"1 sec"
>>> to_human_readable_elapsed(320)
"5 min 20 sec"
>>> to_human_readable_elapsed(4200)
"1 hour 10 min"
>>> to_human_readable_elapsed(100000)
"1 day 3.7 hours"
aws_resource_search.documents.resource_document.to_utc_dt(dt: datetime) datetime[source]#

Convert to timezone aware datetime object in UTC.

If the input datetime object doesn’t have timezone, it will assume it’s in UTC.

aws_resource_search.documents.resource_document.to_simple_dt_fmt(dt: datetime) str[source]#

To simple datetime format string.

aws_resource_search.documents.resource_document.to_iso_dt_fmt(dt: datetime) str[source]#

To ISO datetime format string.

aws_resource_search.documents.resource_document.get_none_or_default(data: T_RESULT_DATA, path: str, default: Optional[Any] = None) Optional[Any][source]#

A helper method to get value from data. If the value doesn’t exist, it will return the default value.

Example:

>>> doc = {"a": 1, "b": {"c": 3})
>>> get_none_or_default(data, "a")
1
>>> get_none_or_default(data, "d")
None
>>> get_none_or_default(data, "d", "hello")
"hello"
>>> get_none_or_default(data, "b.c")
3
>>> get_none_or_default(data, "b.d")
None
>>> get_none_or_default(data, "b.d", "hello")
"hello"
>>> get_none_or_default(data, "c.e")
None
>>> get_none_or_default(data, "c.e", "hello")
"hello"
Parameters:
  • data – The data to get value from. It represent an AWS resource in the boto3 API response. Usually it can be a dictionary or a string.

  • path – jmespath syntax

  • default – default value if the value doesn’t exist

aws_resource_search.documents.resource_document.get_datetime(data: T_RESULT_DATA, path: str, default: Optional[datetime] = datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), as_utc: bool = True) Optional[datetime][source]#

Extract timezone aware datetime object from data using Jmespath.

Example:

>>> get_datetime({"CreateDate": datetime(2021, 1, 1)}, path="CreateDate")
datetime(2021, 1, 1)
aws_resource_search.documents.resource_document.get_datetime_simple_fmt(data: T_RESULT_DATA, path: str, default: str = 'No datetime', as_utc: bool = True) str[source]#

Extract isoformat datetime string from a dictionary using Jmespath.

Example:

>>> get_datetime_simple_fmt({"CreateDate": datetime(2021, 1, 1, microsecond=123000)}, path="CreateDate")
"2021-01-01 00:00:00"
aws_resource_search.documents.resource_document.get_datetime_iso_fmt(data: T_RESULT_DATA, path: str, default: str = 'No datetime', as_utc: bool = True) str[source]#

Extract isoformat datetime string from a dictionary using Jmespath.

Example:

>>> get_datetime_iso_fmt({"CreateDate": datetime(2021, 1, 1)}, path="CreateDate")
"2021-01-01T00:00:00"
class aws_resource_search.documents.resource_document.ResourceDocument(raw_data: T_RESULT_DATA, id: str, name: str)[source]#

This is the base class for searchable AWS resource document for all AWS resource type. Also, it provides some utility functions to help with writing the concrete document class for a specific AWS resource type.

A ‘document’ is a searchable object stored in the index, representing the detailed data of an AWS resource.

In the aws_resource_search.res.${service}.py module, we need to inherit this class to create a document class for each AWS resource type. For example, you can define a document class for S3 bucket like this:

>>> @dataclasses.dataclass
>>> class S3BucketDocument(ResourceDocument):
...    pass
Parameters:
  • raw_data – The raw data from the boto3 API call response. For example, for s3_client.list_buckets <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/list_buckets.html>, the raw data is {'Name': 'string', 'CreationDate': datetime(2015, 1, 1)}

  • id – the unique id of the aws resource, most of the time it’s the same as the resource name. For example, AWS Lambda function name, S3 bucket name. But for some resources, it’s not. For example, AWS EC2 instance id, AWS VPC id. This field is also used as a searchable IdField in aws_resource_search.base_searcher.BaseSearcher.

  • name – the human friendly name of the aws resource. For example, AWS Lambda function name, S3 bucket name. This field is also used as a searchable NgramWordsField in aws_resource_search.base_searcher.BaseSearcher.

  • name – similar to name, but this field is used as a searchable TextField in aws_resource_search.base_searcher.BaseSearcher.

In your subclass, you must implement the following methods. Please read the docstrings to understand their functionality.

Subclass FAQ

  • Q: I see there’s an attribute in the raw data from the boto3 API response,

    should I create a dataclasses.field() for it?

  • A: Depends. If you want it to be searchable, yes, declare a field for it.

    If you don’t want it to be searchable, and you just want to reference it later, declare a @property attribute instead.

  • Q: I have a derivable attribute can be calculated from the raw data,

    should I create a dataclasses.field() for it?

  • A: Depends.
    1. if you want it to be searchable, yes, declare a field for it.

    2. if the value can be calculated only using the raw data,

      declare a @property attribute instead.

    3. if the calculation needs additional information like the

      BotoSesManager object you used for the boto3 API call, then you need to create a dataclasses.field() for it. Because you can’t calculate it again when getting it back from the search index. At that time, you don’t have access to the original BotoSesManager object.

classmethod from_resource(resource: T_RESULT_DATA, bsm: BotoSesManager, boto_kwargs: dict)[source]#

Create a document object from the boto3 API response data. Since the API response data relies on both the ‘bsm’ object and ‘boto_kwargs,’ we also require this information to create the document object.

For example, s3_client.list_buckets api returns:

{
    'Name': '...',
    'CreationDate': datetime.datetime(...)
}

Then, the implementation should be:

>>> @dataclasses.dataclass
... class S3BucketDocument(ResourceDocument):
...     @classmethod
...     def from_resource(
...         cls,
...         resource: "T_RESULT_DATA",
...         bsm: "BotoSesManager",
...         boto_kwargs: dict,
...     ):
...         return cls(
...             raw_data=resource,
...             id=resource["Name"],
...             name=resource["Name"],
...         )

Note

You have to implement this method for each AWS Resource Type.

classmethod from_many_resources(resources: ResourceIterproxy, bsm: BotoSesManager, boto_kwargs: dict)[source]#

A wrapper of from_resource() to create a list of document objects.

property title: str#

The title in the zelfred UI.

For example, you want to use the S3 bucket name as the title:

>>> @dataclasses.dataclass
... class S3BucketDocument(ResourceDocument):
...     @property
...     def title(self) -> str:
...         return f"bucket name = {self.name}"

Important

You have to implement this method for each AWS Resource Type.

property subtitle: str#

The subtitle in the zelfred UI.

See also

SUBTITLE

property short_subtitle: str#

A shorter version of subtitle.

See also

SHORT_SUBTITLE

property uid: str#

The internal uid used for sorting and deduplication in the zelfred UI.

property autocomplete: str#

Autocomplete text for the zelfred UI.

property arn: str#

AWS Resource ARN, if applicable. User can tap ‘Ctrl + A’ to copy the ARN.

If the raw_data does not sufficient information to construct the ARN, you should declare a dataclasses.field() for it and initialize it in the from_resource() method. Then you can just reference it here.

Important

You have to implement this method for each AWS Resource Type.

get_console_url(console: acu.AWSConsole) str[source]#

AWS Console URL to view this AWS resource in the console. If applicable, User can tap ‘Enter’ to open in browser.

Important

You have to implement this method for each AWS Resource Type.

classmethod get_list_resources_console_url(console: acu.AWSConsole) str[source]#

AWS Console URL to view list all AWS resources of this type in the console. If applicable, User can tap ‘Enter’ to open in browser.

Important

You have to implement this method for each AWS Resource Type.

static one_line(obj, na: str = 'NA') str[source]#

Convert a python object to one line json string.

This is usually used in the ResourceDocument.get_details`() method to normalize multiline json object in the UI.

get_details(ars: ARS) List[T_ARS_ITEM][source]#

Call boto3 API to get additional details for this resource. The detailed information will be rendered in the dropdown menu. It allows user to tap ‘Ctrl + P’ to enter a sub-session to view the details. User can tap ‘F1’ to go back to the previous session.

Important

You have to implement this method for each AWS Resource Type.

Note

Here’s some tips to implement this method correctly:

  1. For immutable attributes, such as resource id, name, you can

    extract them from the raw_data. For example, the Ec2 instance id.

  2. For mutable attributes, such as tags, you have to call boto3 API,

    because the raw_data is from the index and could be outdated.

  3. Use enrich_details() context manager when you

    need to call boto3 API. Because it may fail due to permission issue, or resource not exists issue.

classmethod get_dataset_fields(id_field_boost: float = 5.0, name_minsize: int = 2, name_maxsize: int = 4, name_sortable: bool = True, name_ascending: bool = True) List[Union[StoredField, IdField, IdListField, KeywordField, TextField, NumericField, DatetimeField, BooleanField, NgramField, NgramWordsField]][source]#

A helper function to generate the arguments for Searcher.fields property.

By default, it will generate three fields:

  • raw_data (StoredField), to store the raw data from boto3 API response.

  • id (IdField), this field should have higher weight (in id_field_boost).

  • name (NgramWordsField), the default setting is that the result

    is ordered by name in ascending order (in name_sortable and name_ascending).

Also, for each dataclasses.field you declared, it will use the search field declaration stored in dataclasses.field(..., metadata={"field": sayt.SomeField(name=...)}). This method performs basic validation on the field declaration. This method helps your AWS resource document data model and search index schema in sync and avoid human-mistake.

Parameters:
  • id_field_boost – parameter for the id field.

  • name_minsize – parameter for the name fields.

  • name_maxsize – parameter for the name fields.

  • name_sortable – parameter for the name fields.

  • name_ascending – parameter for the name fields.