Skip to content

Entities

Entities are the main building blocks of the Everysk SDK. They are the objects that you will interact with to create, read, update, and delete data in the Everysk platform. The SDK provides a set of classes that represent the main entities in the platform, such as Portfolio, Security, Datastore, File, Report, CustomIndex, and PrivateSecurity.


Base Entity

The BaseEntity class is the foundation that all Everysk entities build upon. Every entity — Custom Index, Datastore, File, Portfolio, Private Security, Report, Secrets, Worker Execution, Workflow Execution, and Workspace — inherits from it, gaining a shared set of methods for creation, retrieval, modification, deletion, cloning, and querying.

Lets take a look a them below.


Create

Use create() to persist a new entity. Pass a dictionary with the entity's attributes and get back the created instance:

from everysk.sdk.entities import Portfolio

portfolio = Portfolio.create({
    'name': 'My Portfolio',
    'workspace': 'main',
    'date': '20210622',
    'securities': [
        {'id': 'id1', 'symbol': 'AAPL', 'quantity': 1000.0},
        {'id': 'id2', 'symbol': 'MSFT', 'quantity': 500.0},
    ],
})

portfolio.id
# 'port_V7xU8dwCMnJIuyUPHJPx2ynuz'


Retrieve

Use retrieve() to fetch an existing entity by its ID. Returns the entity instance, or None if not found:

portfolio = Portfolio.retrieve('port_V7xU8dwCMnJIuyUPHJPx2ynuz')

portfolio.name
# 'My Portfolio'

portfolio.date
# '20210622'


Modify

Use modify() to update an existing entity. Pass the entity ID and a dictionary of fields to overwrite. Returns the updated instance, or None if not found:

portfolio = Portfolio.modify(
    'port_V7xU8dwCMnJIuyUPHJPx2ynuz',
    {
        'name': 'My Updated Portfolio',
        'securities': [
            {'id': 'id3', 'symbol': 'GOOGL', 'quantity': 300.0},
        ],
    },
)

portfolio.name
# 'My Updated Portfolio'


Remove

Use remove() to permanently delete an entity by its ID. Returns the deleted instance, or None if not found:

deleted = Portfolio.remove('port_V7xU8dwCMnJIuyUPHJPx2ynuz')

deleted.id
# 'port_V7xU8dwCMnJIuyUPHJPx2ynuz'


Delete

Use delete() to permanently delete an entity instance directly, without needing its ID separately:

portfolio = Portfolio.retrieve('port_V7xU8dwCMnJIuyUPHJPx2ynuz')
portfolio.delete()


Remove Many

Use remove_many() to permanently delete multiple entities in bulk by passing a list of IDs:

Portfolio.remove_many([
    'port_abc123',
    'port_def456',
    'port_ghi789',
])


Script API

The script interface provides lower-level methods used to fetch and persist entities within worker contexts. Each entity class exposes a script attribute with the following methods:

fetch

Fetches a single entity by query, variant, and workspace. Returns the entity instance or None if not found:

datastore = Datastore.script.fetch('dats_abc123', 'id', 'main')

# fetch by tag (latest)
datastore = Datastore.script.fetch('my-tag', 'tagLatest', 'main')

# fetch by link_uid (latest)
portfolio = Portfolio.script.fetch('my-link', 'linkLatest', 'main')

fetch_list

Fetches a list of entities by query, variant, and workspace:

datastores = Datastore.script.fetch_list(['dats_abc123', 'dats_def456'], 'id', 'main')

fetch_multi

Fetches multiple entities at once using separate lists of queries, variants, and workspaces. Useful when each entity may come from a different workspace or use a different lookup variant:

datastores = Datastore.script.fetch_multi(
    ['dats_abc123', 'dats_def456'],
    ['id', 'id'],
    ['workspace_a', 'workspace_b'],
)

storage

Persists an entity according to the provided storage_settings. This is the standard way to save an entity inside a worker after building or modifying it:

storage_settings = BaseMapping(mode='create')  # or 'update', 'transient'
datastore = Datastore.script.storage(datastore, storage_settings)



Now that we've seen the shared CRUD interface, let's take a closer look at each entity individually — their specific attributes, behaviors, and usage patterns.


Custom Index

A custom index is a proprietary vector of date-value tuples. It can represent a proprietary benchmark, a risk factor, a proxy or any other measure. Even when persisted to your account, it is only available to the account. Custom Indexes are not bind to a workspace, meaning that they can be used globally, no matter the workspace.

We can start using the Custom Index entity by running the following import statement:

from everysk.sdk.entities import CustomIndex
  • symbol: Refers to the symbol of the custom index. Unique to the user account, starts with the prefix CUSTOM:.

  • name: The name of the custom index.

  • description: The description of the custom index.

  • tags: The tags of the custom index.

  • periodicity: The periodicity of the custom index.

  • currency: The currency of the custom index.

  • base_price: The base price of the custom index.

  • data_type: The data type of the custom index.

Instantiating a Custom Index Entity

Below let's instantiate a Custom Index entity and set the most common attributes used:

custom_index = CustomIndex()
custom_index.symbol = 'CUSTOM:INDEX'
custom_index.name = 'Custom Index'
custom_index.description = 'Description'
custom_index.tags = ['tag1', 'tag2']
custom_index.version = '1.0'
custom_index.periodicity = 'M'
custom_index.currency = 'USD'
custom_index.base_price = 1000
custom_index.data_type = 'PRICE'
custom_index.data = [[1, 2, 3], [4, 5, 6]]

Convert Custom Index to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

custom_index = CustomIndex()
type(custom_index)
everysk.sdk.entities.custom_index.base.CustomIndex

to_dict = custom_index.to_dict()
type(to_dict)
dict

Validating a Custom Index Entity

For validating a Custom Index entity, we can make use of the validate() method, which will either return a boolean value or raise an exception in the case of an invalid entity, let's use our previous instantiated entity:

custom_index.validate()
True

If somehow the entity were to be invalid, the validate() method would raise an exception along with the error message indicating the issue.

custom_index = CustomIndex()
custom_index.id = 'invalid id'
FieldValueError: The value 'invalid id' for field 'symbol' must match with this regex: ^CUSTOM:[A-Z0-9_]*$.


Datastore

Datastores are fully integrated repositories to manage and persist data. They can record data calculated by Everysk’s servers, proprietary data from the client or both. The most common usage is the storage of securities as rows and related properties as columns, but there are no constraints on the usage. They enable powerful data explorations and trend analysis to be performed.

The Datastore entity is kept under the following import statement:

from everysk.sdk.entities import Datastore

Below we have the most common attributes used in the Datastore entity:

  • name: The name of the Datastore entity.

  • tags: The tags of the datastore.

  • description: The current description of the datastore.

  • workspace: Which workspace will the Datastore entity reside.

  • date: The date of the datastore.

  • data: The data associated with the current datastore.

  • level: The level of the datastore.

Instantiating a Datastore Entity and Passing Attributes

To instantiate a Datastore entity, we can use the following code snippet:

datastore = Datastore()
type(datastore)
everysk.sdk.entities.datastore.base.Datastore

Now we can manually set the class attributes in order to properly configure our Datastore entity.

datastore.name = 'SampleDatastore'
datastore.tags = ['tag1', 'tag2']
datastore.description = 'Description'
datastore.workspace = 'SampleWorkspace'
datastore.date = DateTime(2023, 9, 9, 9, 9, 9, 9)
datastore.data = 'data'
datastore.level = 1

Convert Datastore to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

datastore = Datastore()
type(datastore)
everysk.sdk.entities.datastore.base.Datastore

to_dict = datastore.to_dict()
type(to_dict)
dict

Validating a Datastore Entity

The validate() method from the Datastore entity is used as a lazy validation method in order to check if the entity is valid or not by returning a boolean value:

datastore = Datastore()
datastore.validate()
True

In the case of an invalid entity, meaning that some field is missing or has an invalid value, the validate() method will raise a FieldValueError:

datastore = Datastore()
datastore.id = 'invalid_id'
FieldValueError: The value 'invalid_id' for field 'id' must match with this regex: ^dats_[a-zA-Z0-9].


File

A file is a collection of data stored in one unit, identified by a filename. It can be a document, picture, data library, binary data, or any other collection of data.

In order to work with the File entity we will be using the following import throughout the examples:

from everysk.sdk.entities import File

Below we have all the required attributes associated with the File Entity

  • name: The name of the File entity

  • tags: The tags of the file.

  • description: The current description of the file.

  • workspace: Which workspace will the File entity reside.

  • date: The date of the file.

  • data: The data of the file in base64 format.

  • content_type: Refers to the media type of the file.

  • url: The URL which the file will reside.

Creating a File Entity

For creating a brand new File entity we can simply instantiate the class and passing our desired arguments:

file = File()
file.name = 'SampleFile'
file.tags = ['tag1', 'tag2']
file.description = 'Description'
file.workspace = 'SampleWorkspace'
file.date = '20230909'
file.data = 'data'
file.content_type = 'text/plain'
file.url = '/filehttps://example.com'

Convert File Entity to Dictionary

For converting a File entity to a python dictionary, we can make use of the to_dict() method, let's see that in practice by using our previously created File entity:

file = File()
type(file)
everysk.sdk.entities.file.base.File

to_dict = file.to_dict(file)
type(to_dict)
dict

Validate the File Entity

The validate() method from the File entity is used as a lazy validation method in order to check if the entity is valid or not by returning a boolean value:

file = File()
file.validate()
True

In the case of an invalid entity, the validate() method will raise a FieldValueError in the case of an invalid entity or a RequiredFieldError in the case of a missing required field.

file = File()
file.url = 123
FieldValueError: Key url must be <class 'str'>.


Portfolio

A portfolio is a collection of financial investments like stocks, bonds, derivatives, commodities, cash, and cash equivalents. Each security can be traded in a specific local currency. The portfolio has a base currency that is required to reflect each FX risk.

We can start using the Portfolio entity by running the following import statement:

from everysk.sdk.entities import Portfolio

Below we have the attributes used in the Portfolio entity

  • workspace: Refers to the workspace which the Portfolio entity will reside.

  • name: The name of the portfolio.

  • tags: The tags of the portfolio. Used for filtering and searching

  • nlv: The NLV for the portfolio.

  • base_currency: Which currency will be used as the standard.

  • date: The current date of the portfolio.

  • securities: The securities of the portfolio. Generally comes in a list format filled with dictionaries inside of type Securities.

Convert Portfolio to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

port = Portfolio()
type(port)
everysk.sdk.entities.portfolio.base.Portfolio

to_dict = port.to_dict()
type(to_dict)
dict

Convert Portfolio to a CSV

Another useful conversion for our Portfolio entity, is the ability to convert it to a CSV type using the to_csv() method:

For demonstration purposes let's grab some sample data for instantiating our Portfolio entity:

portfolio_data = {
    'id': 'port_1234567891011211234567890',
    'workspace': 'SampleWorkspace',
    'name': 'SamplePortfolio',
    'tags': ['tag1', 'tag2'],
    'link_uid': 'ABC',
    'description': 'Description',
    'nlv': 1000.0,
    'base_currency': 'USD',
    'date': DateTime(2023, 9, 9, 9, 9, 9, 9),
    'securities': Securities([{'symbol': 'AAPL'}]),
    'version': '1.0',
    'created_on': DateTime(2023, 9, 9, 9, 9, 9, 9),
    'updated_on': DateTime(2023, 9, 9, 9, 9, 9, 9),
    'level': 'v1',
    'outstanding_shares': 1000,
    'source_hash': 'XYZ',
    'status': 'OK',
    'portfolio_uid': 'UID123',
    'check_securities': False
}

Now let's use the data above in our Portfolio:

port = Portfolio(**portfolio_data)
to_csv = port.to_csv()
type(to_csv)

to_csv
'SamplePortfolio,20230909 09:09:09,USD,1000.0,Description,tag1 tag2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\r\nstatus,id,symbol,quantity,instrument_class,ticker,label,name,isin '

As seen above we have our portfolio entity converted to a CSV format, ready to be used.

Validate the entity

Before actually using the entity we may want to validate its arguments using the validate() method, otherwise we might get unwanted behavior when using:

port = Portfolio()
port.validate()
True

In the case of something going wrong, the method will point out the invalid field. Let's see how that works in practice by setting an invalid value for the securities attribute:

port = Portfolio()
port.securities = 'Invalid'
FieldValueError: Key securities mus be <class 'everysk.sdk.entities.portfolio.securities.Securities'>.


Private Security

The "Private Security" entity allows for the customized registration of fixed income instruments, covering data such as issue date, maturity, issue price, and the calculation method (SELIC, IPCA, Private). This enables the creation or simulation of private assets, adjusting various specific characteristics.

To start using the Private Security entity, run the following import statement:

from everysk.sdk.entities import PrivateSecurity

Below we have the most common attributes used in the Private Security entity:

  • symbol: The symbol of the private security. The symbol attribute is prefixed with the string PRIVATE:.

  • name: The name of the private security.

  • tags: The tags of the private security. Used for filtering and searching.

  • description: The description of the private security.

  • currency: The currency of the private security.

  • data: The data contained inside the private security.

  • instrument_type: The type of instrument of the private security.

Creating a Private Security Entity

To create a new Private Security entity, we can use the following code snippet, where we manually set the attributes:

private_security = PrivateSecurity()
private_security.symbol = 'PRIVATE:ABC'
private_security.name = 'ABC Private Security'
private_security.tags = ['tag1', 'tag2']
private_security.description = 'This is a private security'
private_security.currency = 'USD'
private_security.data = {'key1': 'value1', 'key2': 'value2'}
private_security.instrument_type = 'EQUITY'

Validate Private Security Entity

To validate the Private Security entity, we can use the validate() method, in the case of getting an invalid entity, the method will raise either a FieldValueError or a RequiredFieldError depending on the case.

private_security = PrivateSecurity()
private_security.validate()
True

Below we have an example of a FieldValueError exception:

private_security = PrivateSecurity()
private_security.symbol = '123'
The value "123" for field "symbol" must match this regex: ^PRIVATE:[A-Z0-9_]*$.

Convert Private Security to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

private_security = PrivateSecurity()
type(private_security)
everysk.sdk.entities.private_security.base.PrivateSecurity

to_dict = private_security.to_dict()
type(to_dict)
dict


Query

The Query class allows you to build and execute queries to retrieve entities from the data source based on specific conditions. A query can return a single entity, a list of entities, or a paginated set.

from everysk.sdk.entities.query import Query

Every entity also exposes a .query shortcut that returns a pre-configured Query instance for that entity type:

Portfolio.query


Attributes

Below are the attributes available on a Query instance:

  • filters: The list of filter conditions added via where().

  • order: The list of properties by which to sort the results.

  • projection: The list of properties to include or exclude in the result.

  • distinct_on: The list of properties for which the resulting entities should be distinct.

  • limit: The maximum number of entities to retrieve.

  • offset: The number of initial entities to skip before starting retrieval.

  • page_size: The number of entities to retrieve per page.

  • page_token: The token representing the desired page of results.


Building a Query

Instantiate a Query by passing the entity class you want to query:

query = Query(Portfolio)

All builder methods return self, so they can be chained:

query = (
    Query(Portfolio)
    .where('name', 'My Portfolio')
    .sort_by('date')
    .set_limit(10)
)


where

The where() method adds a filter condition to the query. It accepts either two arguments (property, value) — in which case = is assumed as the operator — or three arguments (property, operator, value):

query = Query(Portfolio)
query.where('name', 'My Portfolio')
# equivalent to:
query.where('name', '=', 'My Portfolio')

Supported operators are =, <, <=, >, >=, and IN.

Filtering by date — when the operator is =, a full-day range is created automatically:

query = Query(Portfolio)
query.where('date', '=', '2023-08-10')
# expands to: date >= 2023-08-10 00:00:00 AND date <= 2023-08-10 23:59:59

Filtering by tags — pass a single string or a list of strings:

query = Query(Portfolio)
query.where('tags', ['risk', 'equity'])

Filtering by a list — use the IN operator with a list of values:

from everysk.sdk.entities import File

query = Query(File)
query.where('content_type', 'IN', ['text/csv', 'application/pdf'])

Filtering by link_uid — filter by a single value or multiple values using IN:

query = Query(Portfolio)
query.where('link_uid', 'my-link-uid')

# match any of several link UIDs
query = Query(Portfolio)
query.where('link_uid', 'IN', ['link-a', 'link-b'])

Passing an unsupported operator raises an SDKValueError:

query.where('name', '<>', 'value')
# SDKValueError: Invalid operator: <> for property name


sort_by

The sort_by() method adds a property to the sort order. Prefix the property name with - for descending order:

query = Query(Portfolio)
query.sort_by('date')
query.sort_by('-name')

Adding a property that is not sortable or that has already been added raises a ValueError:

query.sort_by('invalid_property')
# ValueError: invalid_property is not sortable

query.sort_by('date')
# ValueError: Duplicated order property: date in ['date']


set_projection

The set_projection() method specifies which properties to include or exclude from the result. Pass a string or a list of strings. Prefix a property name with - to exclude it (inverse projection):

# Include only name and date
query = Query(Portfolio)
query.set_projection(['name', 'date'])

# Exclude date
query.set_projection(['-date'])

Mixing inclusion and exclusion in the same call raises a ValueError:

query.set_projection(['name', '-date'])
# ValueError: Projection and Inverse Projection should not be set in the same query


set_distinct_on

The set_distinct_on() method specifies the properties for which the resulting entities should be distinct. Pass a string or a list of strings:

query = Query(Portfolio)
query.set_distinct_on('date')
query.set_distinct_on(['date', 'workspace'])


set_limit

Sets the maximum number of entities the query should return:

query = Query(Portfolio)
query.set_limit(50)

The value must be an integer greater than or equal to 0, otherwise an SDKValueError is raised.


set_offset

Sets the number of initial entities to skip before retrieval begins:

query = Query(Portfolio)
query.set_offset(10)

The value must be an integer greater than or equal to 0, otherwise an SDKValueError is raised.


set_page_size

Sets the number of entities to retrieve per page in a paginated query:

query = Query(Portfolio)
query.set_page_size(20)

The value must be an integer greater than or equal to 0, otherwise an SDKValueError is raised.


set_page_token

Sets the page token to resume from a specific page:

query = Query(Portfolio)
query.set_page_token('eyJvZmZzZXQiOiAyMH0=')


set_find_or_fail

When set to True, the query raises an error if no entity is found instead of returning None:

query = Query(Portfolio)
query.set_find_or_fail(True)


load

Fetches a single entity matching the query. Returns the entity instance or None if nothing is found. An optional offset can be passed to skip results:

portfolio = Query(Portfolio).where('name', 'My Portfolio').load()
portfolio.name
# 'My Portfolio'

# Skip the first result and return the second match
portfolio = Query(Portfolio).where('name', 'My Portfolio').load(offset=1)


loads

Fetches a list of entities matching the query. Returns an empty list if nothing is found. Optional limit and offset parameters control the result set:

portfolios = Query(Portfolio).where('tags', 'equity').loads()
# [<Portfolio ...>, <Portfolio ...>, ...]

# Fetch up to 2 results, skipping the first
portfolios = Query(Portfolio).where('tags', 'equity').loads(limit=2, offset=1)


page

Fetches a single page of entities. Returns a QueryPage dictionary with entities and next_page_token keys:

result = Query(Portfolio).page(page_size=10)
len(result['entities'])
# up to 10 — depends on available data

result['next_page_token']
# 'eyJvZmZzZXQiOiAxMH0='  (None if this is the last page)

Pass the token from the previous response to retrieve the next page:

result = Query(Portfolio).page(page_size=10, page_token=result['next_page_token'])


pages

A generator that iterates over all pages automatically. Yields one list of entities per page until no more pages are available:

for page in Query(Portfolio).where('tags', 'equity').pages(page_size=10):
    for portfolio in page:
        print(portfolio.name)


fetch_ids

Fetches only the IDs of matching entities instead of full entity objects. Optional limit and offset parameters are supported:

ids = Query(Portfolio).where('tags', 'equity').fetch_ids()
# ['port_abc123', 'port_def456', ...]

ids = Query(Portfolio).fetch_ids(limit=5, offset=10)


fetch_id

Fetches the ID of a single matching entity. Returns the ID string or None if nothing is found. An optional offset can be provided:

entity_id = Query(Portfolio).where('name', 'My Portfolio').fetch_id()
# 'port_abc123'

entity_id = Query(Portfolio).where('name', 'My Portfolio').fetch_id(offset=1)


Report

Interactive dashboards that present portfolio analytics information in an intuitive and explorable way. Reports represent a specific portfolio and date so that they can be referenced in the future.

We can start using the Report entity by running the following import statement:

from everysk.sdk.entities import Report

Below we have the most common class attributes used in the Report entity:

  • script: The script used to generate the report.

  • name: The name of the report.

  • description: The description of the report.

  • tags: The tags associated with the report.

  • workspace: The workspace where the report is stored.

  • date: The date the report was created.

  • widgets: The widgets associated with the report.

  • url: The URL of the report.

  • authorization: The type of authorization in the report.

  • config_cascaded: The different configurations in the report.

  • layout_content: How the layout of the content will be structured.

Instantiating a Report Entity

Below we have a code segment demonstrating how to instantiate a Report entity and set its class attributes:

report = Report()
report.script = 'my_script'
report.name = 'My Report'
report.description = 'This is a report'
report.tags = ['tag1', 'tag2']
report.workspace = 'my_workspace'
report.date = '20210101'
report.widgets = [{'type': 'chart', 'data': {...}}, {'type': 'table', 'data': {...}}]
report.url = '/my_report_url'
report.authorization = 'private'
report.config_cascaded = {'config1': 'value1', 'config2': 'value2'}
report.layout_content = {'section1': {...}, 'section2': {...}}

Converting Report to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

report = Report()
type(report)
everysk.sdk.entities.report.base.Report

to_dict = report.to_dict()
type(to_dict)
dict


Tags

You can start using the Tags entity by running the following import statement:

from everysk.sdk.entities.tags import Tags

Below we have the most common attributes used in the Tags entity:

min_size: The minimum size of each individual tag. Default is 1.

max_size: The maximum size of each individual tag. Default is 252.

Creating a Tag instance

For creating a new Tag instance and starting using, we can use the following piece of code:

tags = Tags()
tags
[]

Min Size

The min_size attribute is used to set the minimum size of each individual tag. By default, the minimum size is 1. If we want to change it, we can do it as follows:

tags.min_size = 2
tags.min_size
2

Let's try to add a tag with less than 2 characters:

tags.append('a')
FieldValueError: Tags: "a" size it's not between 2 and 252

Max Size

The max_size attribute is used to set the maximum size of each individual tag. By default, the maximum size is 252. If we want to change it, we can do it as follows:

tags.max_size = 5
tags.max_size
5

Let's try to add a tag with more than 5 characters:

tags.append('abcdef')
FieldValueError: Tags: "abcdef" size it's not between 2 and 5

Now, let's understand below the append() method along with a few other methods that can be used to manipulate the tags.

Adding new tags

The append() method is used in order to add new tags to our tag instance:

tags = Tags()
tags.append('tag1')
tags
['tag1']

tags.append('tag2')
tags
['tag1', 'tag2']

Keep in mind that the append() method only accepts a single tag as an argument, which can be a string, integer, or float. If you want to add multiple tags at once, you can use the extend() method.

Extending tags

There is also the possibility of adding multiple tags at once on a list format by using the extend method:

tags = Tags()
tags.extend(['tag1', 'tag2', 'tag3'])
tags
['tag1', 'tag2', 'tag3']

Inserting a tag at some index

To add a specific tag at a certain index, we can make use of the insert method:

Lets continue with our previous tag instance, now let's say that we want to add a new tag at the beginning of our tags list:

tags.insert(0, 'tag0')
tags
['tag0', 'tag1', 'tag2', 'tag3']

Unifying Tags

The unify() static method merges two tag sources — typically an overwrite value and an existing entity's tags — into a single Tags instance. If the overwrite is provided it takes precedence; otherwise the existing tags are kept:

existing_tags = Tags(['equity', 'risk'])
overwrite_tags = Tags(['bond'])

Tags.unify(overwrite_tags, existing_tags)
# Tags(['bond'])

# When overwrite is empty, existing tags are preserved
Tags.unify(Tags(), existing_tags)
# Tags(['equity', 'risk'])

This is the standard pattern used by modifier workers when applying partial updates to an entity's tags.


Secrets Entity

The Secrets entity is kept under the following import statement:

from everysk.sdk.entities import Secrets


Attributes

Below we have the most common attributes used in the Secrets entity:

  • id: The unique identifier of the Secrets entity. Follows the format sec_<value>.

  • name: The name of the secrets entity.

  • description: The current description of the secrets entity.

  • data: A dictionary containing the secret values. This field is required and must be a non-empty dictionary.


Instantiating a Secrets Entity and Passing Attributes

To instantiate a Secrets entity, we can use the following code snippet:

secrets = Secrets()
type(secrets)
everysk.sdk.entities.secrets.base.Secrets

Now we can manually set the class attributes in order to properly configure our Secrets entity.

secrets.name = 'api-keys'
secrets.description = 'Third-party API credentials'
secrets.data = {'v1': {'openai': 'sk-abc123', 'stripe': 'sk-live-xyz'}}


Retrieving a Value by Path

The Secrets entity provides a class method value_from_path() that allows retrieving a specific value using a dot-notation path. The path must start with a valid secret id, followed by one or more keys separated by dots.

value = Secrets.value_from_path('sec_abc123.v1.openai')

If the path format is invalid or the secret ID does not match the expected format, a ValueError is raised:

Secrets.value_from_path('invalid-path')
ValueError: Invalid path format. Expected format: "<secret_id>.<key1>.<key2>..."


Convert Secrets to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

secrets = Secrets()
type(secrets)
everysk.sdk.entities.secrets.base.Secrets

to_dict = secrets.to_dict()
type(to_dict)
dict


Validating a Secrets Entity

The validate() method from the Secrets entity is used as a lazy validation method in order to check if the entity is valid or not by returning a boolean value:

secrets = Secrets(name='api-keys', data={'v1': {'key': 'value'}})
secrets.validate()
True

In the case of an invalid entity, meaning that some field is missing or has an invalid value, the validate() method will raise a FieldValueError:

secrets = Secrets(name='api-keys')
secrets.validate()
FieldValueError: data is required.


Securities Entity

The Securities entity is a typed list of Security objects. It is the standard container used to hold a portfolio's positions and provides methods for validation, transformation, and comparison.

from everysk.sdk.entities.portfolio.securities import Securities


Creating a Securities Collection

Pass a list of dictionaries or Security objects:

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0},
    {'symbol': 'GOOGL', 'quantity': 50.0},
])

len(securities)
# 2

type(securities[0])
# <class 'everysk.sdk.entities.portfolio.security.Security'>


Validate

The validate() method checks that the collection is not empty and that every Security inside it has all required fields. It auto-generates the id field for any security that is missing one:

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0},
    {'symbol': 'GOOGL', 'quantity': 50.0},
])
securities.validate()
# True

Calling validate() on an empty collection raises a FieldValueError:

Securities().validate()
# FieldValueError: The quantity of securities cannot be zero.


Remove Errors

The remove_errors() method returns a new Securities collection containing only positions whose status is not 'ERROR':

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0, 'status': 'OK'},
    {'symbol': 'GOOGL', 'quantity': 50.0, 'status': 'ERROR'},
    {'symbol': 'MSFT', 'quantity': 75.0, 'status': 'OK'},
])

clean = securities.remove_errors()
len(clean)
# 2


Create from Lists

The from_lists() static method builds a Securities collection from a list-of-lists where the first row is the header:

data = [
    ['symbol', 'quantity', 'market_price'],
    ['AAPL', 100.0, 150.0],
    ['GOOGL', 50.0, 2800.0],
]

securities = Securities.from_lists(data)
len(securities)
# 2

securities[0].symbol
# 'AAPL'


Convert to Lists

The to_lists() method is the inverse of from_lists(). It returns a list-of-lists with the header as the first row:

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0},
    {'symbol': 'GOOGL', 'quantity': 50.0},
])

rows = securities.to_lists()
len(rows)
# 3  (header + 2 securities)

rows[0]
# ['symbol', 'quantity', ...]  (header row, ordered by sort_header)

A custom header can be passed to control the column order:

rows = securities.to_lists(header=['symbol', 'quantity'])
rows[0]
# ['symbol', 'quantity']

rows[1]
# ['AAPL', 100.0]


Convert to a List of Dicts

The to_list() method converts each Security to a plain dictionary and returns them as a list:

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0},
    {'symbol': 'GOOGL', 'quantity': 50.0},
])

dicts = securities.to_list()
len(dicts)
# 2

dicts[0]['symbol']
# 'AAPL'


Diff

The diff() static method compares two securities lists and returns a breakdown of the changes. By default it uses the comparable field as the comparison key:

securities_a = [{'symbol': 'AAPL', 'quantity': 100.0, 'comparable': 'AAPL'}]
securities_b = [{'symbol': 'AAPL', 'quantity': 120.0, 'comparable': 'AAPL'},
                {'symbol': 'MSFT', 'quantity': 50.0, 'comparable': 'MSFT'}]

result = Securities.diff(securities_a, securities_b)
# {
#     'added_positions': [...],
#     'removed_positions': [...],
#     'partial_positions': [...],
#     'equal_positions': [...],
# }

A custom accessor field can be specified:

result = Securities.diff(securities_a, securities_b, accessor='symbol')


Consolidate

The consolidate() method merges positions that share the same values for the given keys, summing their quantities:

securities = Securities([
    {'symbol': 'AAPL', 'quantity': 100.0, 'exchange': 'NASDAQ'},
    {'symbol': 'AAPL', 'quantity': 50.0, 'exchange': 'NASDAQ'},
    {'symbol': 'GOOGL', 'quantity': 75.0, 'exchange': 'NASDAQ'},
])

consolidated = securities.consolidate(['symbol', 'exchange'])
# Returns a new Securities with AAPL consolidated into one position


Security Entity

The Security entity represents a single financial instrument inside a portfolio. It behaves both as a dictionary and as an SDK entity, meaning you can access its fields by attribute name or by key.

from everysk.sdk.entities.portfolio.security import Security


Attributes

Below are the main attributes of the Security entity:

  • status: The status of the security (e.g. 'OK', 'DELISTED', 'ERROR').
  • id: The unique identifier of the security. Auto-generated if not provided.
  • symbol: The symbol of the security (e.g. 'AAPL').
  • quantity: The quantity held.
  • instrument_class: The class of the instrument (e.g. 'Equity').
  • ticker: The ticker symbol.
  • label: A short label for display purposes.
  • name: The full name of the security (e.g. 'Apple Inc.').
  • isin: The ISIN (International Securities Identification Number).
  • exchange: The exchange where the security is traded.
  • currency: The currency of the security (e.g. 'USD').
  • fx_rate: The foreign exchange rate.
  • market_price: The current market price.
  • market_value: The market value (quantity × market_price).
  • market_value_in_base: The market value in the portfolio base currency.
  • instrument_type / instrument_subtype: Type and subtype of the instrument.
  • asset_class / asset_subclass: Asset classification.
  • maturity_date: The maturity date (stored as 'YYYYMMDD' string).
  • issue_date: The issue date (stored as 'YYYYMMDD' string).
  • return_date: The return date (stored as 'YYYYMMDD' string).
  • settlement: The settlement date (stored as 'YYYYMMDD' string).
  • cost_price: The cost price.
  • unrealized_pl / unrealized_pl_in_base: Unrealized profit or loss.
  • extra_data: A dictionary for any additional fields that do not map to standard attributes.

Unknown keyword arguments passed at construction time are automatically stored in extra_data.


Creating a Security

security = Security(
    symbol='AAPL',
    quantity=100.0,
    market_price=150.0,
    currency='USD',
    name='Apple Inc.',
    status='OK',
)

security.symbol
# 'AAPL'

security.quantity
# 100.0


Extra Data

Any attribute that does not correspond to a known field is automatically moved to extra_data:

security = Security(symbol='AAPL', quantity=50.0, industry='Technology')

security.extra_data
# {'industry': 'Technology'}

You can also provide extra data explicitly:

security = Security(
    symbol='AAPL',
    quantity=50.0,
    extra_data={'industry': 'Technology', 'country': 'USA'},
)

security.extra_data
# {'industry': 'Technology', 'country': 'USA'}


Generate a Security ID

The generate_security_id() static method creates a unique security ID with a standard prefix:

Security.generate_security_id()
# 'sec_p06No4'

Security.generate_security_id()
# 'sec_OxvW5r'

Each call returns a different value. If a Security object is validated without an id, one is auto-generated.


Validate Required Fields

The validate_required_fields() method checks that all mandatory fields (symbol, quantity, id) are present. If id is missing it is auto-generated:

security = Security(symbol='AAPL', quantity=100.0)
security.validate_required_fields()
# True

security.id
# 'sec_p06No4'  (auto-generated)


Get Attribute

The _get_attr() static method retrieves a value from a security dictionary, also looking inside extra_data when the key is not a top-level field. An optional fallback callable is called if the key is not found anywhere:

security = Security(symbol='AAPL', quantity=100.0, industry='Technology')

Security._get_attr(security, 'symbol')
# 'AAPL'

Security._get_attr(security, 'industry')
# 'Technology'

Security._get_attr(security, 'missing_key')
# None

Security._get_attr(security, 'missing_key', lambda: 'default_val')
# 'default_val'


Generate Consolidation Key

The generate_consolidation_key() method builds a single string key from one or more attribute values, used to group or deduplicate securities:

security = Security(symbol='AAPL', quantity=100.0, instrument_class='Equity')
security.generate_consolidation_key(['symbol', 'instrument_class'])
# 'AAPL_Equity'

If a specified attribute is missing, a new security ID is generated as a fallback to ensure uniqueness.


Sort Header

The sort_header() static method reorders a list of attribute names according to the platform's canonical column order. Unrecognised keys are appended alphabetically at the end:

Security.sort_header(['symbol', 'name', 'quantity', 'instrument_class'])
# ['symbol', 'quantity', 'instrument_class', 'name']


Create from a List

The from_list() static method constructs a Security from a flat list of values and a matching list of header names:

security = Security.from_list(
    ['AAPL', 100.0, 150.0],
    ['symbol', 'quantity', 'market_price'],
)

security.symbol
# 'AAPL'

security.market_price
# 150.0


Convert to a List

The to_list() method serializes the security back to a flat list of values. The column order follows sort_header() by default, or a custom header can be provided:

security = Security(symbol='AAPL', quantity=100.0, market_price=150.0)
security.to_list(header=['symbol', 'quantity', 'market_price'])
# ['AAPL', 100.0, 150.0]


Worker Execution Entity

The Worker Execution entity is kept under the following import statement:

from everysk.sdk.entities import WorkerExecution


Attributes

Below we have the most common attributes used in the Worker Execution entity:

  • id: The unique identifier of the Worker Execution entity. Follows the format wkex_<value>.

  • status: The current execution status of the worker. Possible values are defined by the platform (e.g. PREPARING, RUNNING, OK, ERROR).

  • execution_type: How the worker was triggered (e.g. scheduled, manual).

  • result: An object containing the outcome of the execution, with the following fields:

  • status: Result status — OK, ERROR, or UNKNOW.
  • data: The output data returned by the worker.
  • log: A list of log entries produced during execution.

  • input_params: An object containing the input parameters passed to the worker, including:

  • worker_id: The ID of the worker.
  • workflow_id: The ID of the parent workflow.
  • workspace: The workspace in which the worker runs.
  • script_inputs: A dictionary of script-level inputs.
  • parallel_info: Parallel execution metadata (index and length).

  • parallel_info: Metadata about parallel execution, with index (current shard) and length (total shards).

  • start_time: When the worker execution started.

  • end_time: When the worker execution ended.

  • duration: Total wall-clock duration of the execution in seconds.

  • cpu_time: CPU time consumed during execution.

  • process_cpu_time: Process-level CPU time consumed.

  • workflow_execution_id: The ID of the parent Workflow Execution.

  • workflow_id: The ID of the workflow this worker belongs to.

  • workflow_name: The name of the workflow.

  • worker_id: The ID of the worker definition.

  • worker_name: The name of the worker.

  • worker_type: The template type of the worker.


Instantiating a Worker Execution Entity

To instantiate a Worker Execution entity, we can use the following code snippet:

worker_execution = WorkerExecution()
type(worker_execution)
everysk.sdk.entities.worker_execution.base.WorkerExecution


Retrieving a Worker Execution

To retrieve an existing Worker Execution by its ID:

worker_execution = WorkerExecution.retrieve('wkex_abc123')
print(worker_execution.status)
print(worker_execution.duration)


Retrieving Input Params

The Worker Execution entity provides a class method get_input_params() that retrieves the InputParams object of a worker execution by its ID.

params = WorkerExecution.get_input_params('wkex_abc123')
print(params.worker_id)
print(params.workflow_id)

If the ID is invalid or the entity is not found, a ValueError is raised:

WorkerExecution.get_input_params('invalid_id')
ValueError: Invalid Entity ID: invalid_id


Querying Worker Executions

Worker executions can be queried by their parent workflow execution:

worker_execution = WorkerExecution(workflow_execution_id='wfex_abc123')
results = worker_execution.query()

for execution in results:
    print(execution.id, execution.status, execution.duration)


Convert Worker Execution to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

worker_execution = WorkerExecution()
type(worker_execution)
everysk.sdk.entities.worker_execution.base.WorkerExecution

to_dict = worker_execution.to_dict()
type(to_dict)
dict


Workflow Execution Entity

The Workflow Execution entity is kept under the following import statement:

from everysk.sdk.entities import WorkflowExecution


Attributes

Below we have the most common attributes used in the Workflow Execution entity:

  • id: The unique identifier of the Workflow Execution entity. Follows the format wfex_<value>.

  • status: The overall status of the workflow execution. Possible values are defined by the platform (e.g. OK, ERROR).

  • run_status: The current running status of the execution (e.g. PREPARING, RUNNING, OK, ERROR).

  • execution_type: How the workflow was triggered (e.g. scheduled, manual).

  • start_time: When the workflow execution started.

  • end_time: When the workflow execution ended.

  • duration: Total wall-clock duration of the execution in seconds.

  • real_execution_time: The actual computation time of the execution.

  • total_execution_time: The sum of all worker execution times within this workflow execution.

  • workflow_id: The ID of the workflow definition being executed.

  • workflow_name: The name of the workflow.

  • workspace: The workspace in which the workflow runs.

  • started_worker_id: The ID of the worker that started the execution.

  • ender_worker_id: The ID of the worker that ended the execution.

  • ender_worker_execution_id: The execution ID of the worker that ended the execution.

  • worker_ids: A list of all worker IDs involved in this workflow execution.

  • resume: A list of checkpoint data used to resume the workflow execution.


Instantiating a Workflow Execution Entity

To instantiate a Workflow Execution entity, we can use the following code snippet:

workflow_execution = WorkflowExecution()
type(workflow_execution)
everysk.sdk.entities.workflow_execution.base.WorkflowExecution


Retrieving a Workflow Execution

To retrieve an existing Workflow Execution by its ID:

workflow_execution = WorkflowExecution.retrieve('wfex_abc123')
print(workflow_execution.run_status)
print(workflow_execution.duration)


Querying Workflow Executions

Workflow executions can be queried by their parent workflow:

workflow_execution = WorkflowExecution(workflow_id='wf_abc123')
results = workflow_execution.query()

for execution in results:
    print(execution.id, execution.run_status, execution.duration)


Convert Workflow Execution to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

workflow_execution = WorkflowExecution()
type(workflow_execution)
everysk.sdk.entities.workflow_execution.base.WorkflowExecution

to_dict = workflow_execution.to_dict()
type(to_dict)
dict

Workspace Entity

The Workspace entity is kept under the following import statement:

from everysk.sdk.entities import Workspace


Attributes

Below we have the most common attributes used in the Workspace entity:

  • name: The name of the Workspace entity. Also serves as the unique identifier (id is an alias for name).

  • description: The current description of the workspace.

  • group: An optional group label used to organize workspaces together.


Instantiating a Workspace Entity and Passing Attributes

To instantiate a Workspace entity, we can use the following code snippet:

workspace = Workspace()
type(workspace)
everysk.sdk.entities.workspace.base.Workspace

Now we can manually set the class attributes in order to properly configure our Workspace entity.

workspace.name = 'my-workspace'
workspace.description = 'Production workspace'
workspace.group = 'production'


Convert Workspace to a Dictionary

Most times when working with entities, there might be a point where we need to convert the entity to a dictionary, and to achieve this we simply use the to_dict() method:

workspace = Workspace()
type(workspace)
everysk.sdk.entities.workspace.base.Workspace

to_dict = workspace.to_dict()
type(to_dict)
dict


Validating a Workspace Entity

The validate() method from the Workspace entity is used as a lazy validation method in order to check if the entity is valid or not by returning a boolean value:

workspace = Workspace(name='my-workspace')
workspace.validate()
True

In the case of an invalid entity, meaning that some field is missing or has an invalid value, the validate() method will raise a FieldValueError:

workspace = Workspace()
workspace.validate()
RequiredFieldError: The field 'name' is required.