Skip to content

Commit

Permalink
Confirmation is now optional. (#270)
Browse files Browse the repository at this point in the history
* Confirmation is now optional.

AB#9779
  • Loading branch information
eccles authored Aug 20, 2024
1 parent b9290e8 commit e0fd7c7
Show file tree
Hide file tree
Showing 32 changed files with 97 additions and 135 deletions.
39 changes: 27 additions & 12 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,34 @@ You can then use the examples code to create assets (see examples directory):
# it does not start with arc_
}
#
# The first argument are the attributes of the asset
# The second argument is wait for confirmation:
# If @confirm@ is True then this function will not
# return until the asset is confirmed and ready
# to accept events (or an error occurs)
# There are 3 alternatives
#
# 1. Create the asset:
# The first argument is the attributes of the asset
return arch.assets.create(attrs=attrs)
#
# 2. alternatively one can wait for the asset to be confirmed in the
# immutable store.
# The second argument is wait for confirmation:
# If @confirm@ is True then this function will not
# return until the asset is confirmed.
#
# Confirmation guarantees that 3rd parties can retrieve and cryptographically
# verify your Assets, which can take a few seconds to propagate. It is typically
# not necessary to wait unless your workflow involves near-real-time
# communication with 3rd parties and the 3rd party needs immediate cryptographic
# verification of your new Asset.
return arch.assets.create(attrs=attrs, confirm=True)
# alternatively if some work can be done whilst the asset is confirmed then this call can be
# replaced by a two-step alternative:
#
# 3. lastly if some work can be done whilst the asset is confirmed then this call
# can be replaced by a two-step alternative:
# asset = arch.assets.create(props=props, attrs=attrs, confirm=False)
asset = arch.assets.create(props=props, attrs=attrs)
# ... do something else here
# and then wait for confirmation
# self.arch.assets.wait_for_confirmation(asset['identity']))
return arch.assets.wait_for_confirmation(asset['identity']))
def main():
Expand Down Expand Up @@ -238,7 +250,12 @@ Each step consists of control parameters (specified in the 'step' dictionary) an
the yaml representation of the request body for an asset or event.
The confirm: field is a control variable for the PythonSDK that ensures that the
asset or event is confirmed before returning.
asset or event is confirmed before returning. This is optional and is only required
3rd parties need to immediately retrieve and cryptographically
verify your Assets, which can take a few seconds to propagate. It is typically
not necessary to wait unless your workflow involves near-real-time
communication with 3rd parties and the 3rd party needs instant cryptographic
verification of your new Asset.
.. note::
Expand Down Expand Up @@ -276,7 +293,6 @@ asset or event is confirmed before returning.
radioactive: "true"
radiation_level: "0"
weight: "0"
confirm: true
# setup the radiation bags to have a varing amount of radiactive waste
# note the values to the events.create method are string representations of boolean
Expand All @@ -294,7 +310,6 @@ asset or event is confirmed before returning.
asset_attributes:
radiation_level: "3"
weight: "1"
confirm: true
Logging
========
Expand Down
12 changes: 6 additions & 6 deletions archivist/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def create(
*,
props: "dict[str, Any]|None" = None,
attrs: "dict[str, Any]|None" = None,
confirm: bool = True,
confirm: bool = False,
) -> Asset:
"""Create asset
Expand All @@ -143,7 +143,7 @@ def create(
return self.create_from_data(data, confirm=confirm)

def create_from_data(
self, data: "dict[str, Any]", *, confirm: bool = True
self, data: "dict[str, Any]", *, confirm: bool = False
) -> Asset:
"""Create asset
Expand All @@ -152,7 +152,7 @@ def create_from_data(
Args:
data (dict): request body of asset.
confirm (bool): if True wait for asset to be confirmed on DLT.
confirm (bool): if True wait for asset to be confirmed.
Returns:
:class:`Asset` instance
Expand All @@ -165,15 +165,15 @@ def create_from_data(
return self.wait_for_confirmation(asset["identity"])

def create_if_not_exists(
self, data: "dict[str, Any]", *, confirm: bool = True
self, data: "dict[str, Any]", *, confirm: bool = False
) -> "tuple[Asset, bool]":
"""
Creates an asset and associated locations and attachments if asset
does not already exist.
Args:
data (dict): request body of asset.
confirm (bool): if True wait for asset to be confirmed on DLT.
confirm (bool): if True wait for asset to be confirmed.
A YAML representation of the data argument would be:
Expand Down Expand Up @@ -272,7 +272,7 @@ def create_if_not_exists(
def wait_for_confirmation(self, identity: str) -> Asset:
"""Wait for asset to be confirmed.
Waits asset to be confirmed.
Waits for asset to be confirmed.
Args:
identity (str): identity of asset
Expand Down
6 changes: 3 additions & 3 deletions archivist/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def create(
attrs: "dict[str, Any]",
*,
asset_attrs: "dict[str, Any]|None" = None,
confirm: bool = True,
confirm: bool = False,
) -> Event:
"""Create event
Expand All @@ -308,7 +308,7 @@ def create(
props (dict): properties for this event.
attrs (dict): attributes of created event.
asset_attrs (dict): attributes of referenced asset.
confirm (bool): if True wait for event to be confirmed on DLT.
confirm (bool): if True wait for event to be confirmed.
Returns:
:class:`Event` instance
Expand All @@ -323,7 +323,7 @@ def create(
)

def create_from_data(
self, asset_id: str, data: "dict[str, Any]", *, confirm: bool = True
self, asset_id: str, data: "dict[str, Any]", *, confirm: bool = False
) -> Event:
"""Create event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@
" \"arc_display_type\": \"Vault Door\",\n",
" },\n",
" },\n",
" confirm=True,\n",
" )\n",
" print(\"DOOR:\", json_dumps(door, indent=4))\n",
" return door"
Expand Down Expand Up @@ -197,7 +196,6 @@
" \"arc_display_type\": \"Open\",\n",
" \"arc_correlation_value\": f\"{tag}\",\n",
" },\n",
" confirm=True,\n",
" )\n",
" print(\"DOOR_OPENED:\", json_dumps(door_opened, indent=4))"
]
Expand All @@ -224,7 +222,6 @@
" \"arc_display_type\": \"Close\",\n",
" \"arc_correlation_value\": f\"{tag}\",\n",
" },\n",
" confirm=True,\n",
" )\n",
" print(\"DOOR_CLOSED:\", json_dumps(door_closed, indent=4))"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@
" \"arc_description\": \"Traffic flow control light at A603 North East\",\n",
" \"arc_display_type\": \"Traffic Light\",\n",
" },\n",
" confirm=True,\n",
" )\n",
" print(\"TRAFFIC_LIGHT:\", json_dumps(traffic_light, indent=4))\n",
" return traffic_light"
Expand All @@ -191,7 +190,6 @@
" \"arc_description\": \"Maintenance performed on traffic light\",\n",
" \"arc_display_type\": f\"Maintenance Performed {tag}\",\n",
" },\n",
" confirm=True,\n",
" )\n",
" print(\"MAINTENANCE_PERFORMED:\", json_dumps(maintenance_performed, indent=4))"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
" \"artistid\": artistid,\n",
" }\n",
"\n",
" return arch.assets.create(attrs=attrs, confirm=True)"
" return arch.assets.create(attrs=attrs)"
]
},
{
Expand Down
5 changes: 2 additions & 3 deletions archivist/notebooks/Create Event with Verified Domain.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
" # alternatively if some work can be done whilst the event is confirmed then this call can be\n",
" # replaced by a two-step alternative:\n",
"\n",
" # event = arch.events.create(asset[\"identity\"], props=props, attrs=attrs, confirm=False)\n",
" # event = arch.events.create(asset[\"identity\"], props=props, attrs=attrs)\n",
"\n",
" # ... do something else here\n",
" # and then wait for confirmation\n",
Expand Down Expand Up @@ -232,8 +232,7 @@
" # The first argument is the attributes of the asset\n",
" # The second argument is wait for confirmation:\n",
" # If @confirm@ is True then this function will not\n",
" # return until the asset is confirmed and ready\n",
" # to accept events (or an error occurs)\n",
" # return until the asset is confirmed.)\n",
" return arch.assets.create(attrs=attrs, confirm=True)"
]
},
Expand Down
1 change: 0 additions & 1 deletion archivist/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,6 @@ def __call__(self, config: "dict[str, Any]"):
"radiation_level": 0,
"weight": 0,
},
"confirm": True,
}
]
```
Expand Down
2 changes: 1 addition & 1 deletion archivist/tenancies.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def __init__(self, archivist_instance: "Archivist"):
def __str__(self) -> str:
return f"TenanciesClient({self._archivist.url})"

def _identity(self, identity) -> str:
def _identity(self, identity: str) -> str:
"""Returns identity suitable for endpoint"""
prefix, uuid = identity.split("/")
if prefix == TENANCIES_PREFIX:
Expand Down
4 changes: 2 additions & 2 deletions docs/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ REST api (in any language):
* versioned package for the python 3.8,3.9,3.10,3.11,3.12 ecosystem.
* automatic confirmation of assets and events: just set **confirm=True** when
creating the asset or event and a sophisticated retry and exponential backoff
algorithm will take care of everything.
algorithm will take care of everything (optional).
* **list()** method: one can easily get an iterable of assets or events that
correspond to a particular signature. The list method is optimized for use in
loop (for a in arch.assets.list():...) but can easily be converted to a list
Expand All @@ -31,6 +31,6 @@ REST api (in any language):
* easily extensible - obeys the open-closed principle of SOLID where new endpoints
can be implemented by **extending** the package as opposed to modifying it.
* fully unittested - 100% coverage.
* code style managed and enforced using **pycodestyle**, **pylint** and **black**.
* code style managed and enforced using **ruff**, **pycodestyle**, **pylint** and **black**.

See the **examples/** directory for example code.
2 changes: 0 additions & 2 deletions docs/fixtures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ and locations.
"arc_display_name": "front door",
"colour": "red",
},
confirm=True,
)
# a green back door
Expand All @@ -49,7 +48,6 @@ and locations.
"arc_display_name": "back door",
"colour": "green",
},
confirm=True,
)
# no need to specify arc_display_type...
Expand Down
1 change: 1 addition & 0 deletions docs/runner/components/assets_create.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Usually these field values are derived from an environment variable
:code:`DATATRAILS_UNIQUE_ID` (default value is :code:`namespace`).

The optional :code:`confirm: true` entry means that the step will wait for the asset to be completely created before moving on to the next step.
This is optional.

.. code-block:: yaml
Expand Down
1 change: 1 addition & 0 deletions docs/runner/components/assets_create_if_not_exists.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Usually these field values are derived from an environment variable
:code:`DATATRAILS_UNIQUE_ID` (default value is :code:`namespace`).

:code:`confirm: true` means that the step will wait for the asset to be completely created before moving on to the next step.
This is optional.

.. code-block:: yaml
Expand Down
2 changes: 1 addition & 1 deletion docs/runner/components/events_create.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The optional :code:`sbom` setting uploads the sbom to archivist and the response
event before posting. (see second example below)

:code:`confirm: true` means that the step will wait for the event to be completely created before moving on to the next step.
This is optional.

An example when opening a door in Paris:

Expand Down Expand Up @@ -73,7 +74,6 @@ An example when releasing a software package as an sbom attachment:
print_response: true
operation: Record
behaviour: RecordEvidence
confirm: true
event_attributes:
arc_description: ACME Corporation Detector SAAS Released YYYYMMDD.1
arc_display_type: Software Package Release
Expand Down
2 changes: 2 additions & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ boolean
chmod
comparator
config
cryptographic
cryptographically
cyclonedx
dataclass
dataclasses
Expand Down
1 change: 0 additions & 1 deletion examples/applications_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def main():
"arc_display_type": "desplay_type",
"some_custom_attribute": "value",
},
confirm=True,
)
print("asset", json_dumps(asset, indent=4))

Expand Down
2 changes: 0 additions & 2 deletions examples/compliance_policies_since.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def create_traffic_light(arch):
"arc_description": "Traffic flow control light at A603 North East",
"arc_display_type": "Traffic Light",
},
confirm=True,
)
print("TRAFFIC_LIGHT:", json_dumps(traffic_light, indent=4))
return traffic_light
Expand All @@ -105,7 +104,6 @@ def perform_maintenance(arch, traffic_light, tag):
"arc_description": "Maintenance performed on traffic light",
"arc_display_type": f"Maintenance Performed {tag}",
},
confirm=True,
)
print("MAINTENANCE_PERFORMED:", json_dumps(maintenance_performed, indent=4))

Expand Down
13 changes: 9 additions & 4 deletions examples/create_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,13 @@ def create_asset(arch):
# The second argument are the attributes of the asset
# The third argument is wait for confirmation:
# If @confirm@ is True then this function will not
# return until the asset is confirmed and ready
# to accept events (or an error occurs)
# return until the asset is confirmed.
#
return arch.assets.create(props=props, attrs=attrs, confirm=True)
# alternatively if some work can be done whilst the asset is confirmed then this call can be
# replaced by a two-step alternative:

# asset = arch.assets.create(props=props, attrs=attrs, confirm=False)
# asset = arch.assets.create(props=props, attrs=attrs)

# ... do something else here
# and then wait for confirmation
Expand Down Expand Up @@ -95,8 +94,14 @@ def main():
)

# Initialize connection to Archivist. max_time is the time to wait for confirmation
# of an asset or event creation - the default is 300 seconds but one can optionally
# of an asset or event creation - the default is 30 seconds but one can optionally
# specify a different value.
# Confirmation guarantees that 3rd parties can retrieve and cryptographically
# verify your Events, which can take a few seconds to propagate. It is typically
# not necessary to wait unless your workflow involves near-real-time
# communication with 3rd parties and the 3rd party needs immediate cryptographic
# verification of your new Asset.

# The optional partner id field is allocated by Datatrails to partners - partners are then
# expected to specify this value when submitting any request to the archivist product.
# Leave blank if if you do not have a partner ID.
Expand Down
Loading

0 comments on commit e0fd7c7

Please sign in to comment.