Skip to content

Commit

Permalink
Add Jupyter support for the example contract
Browse files Browse the repository at this point in the history
Adds the basic factory/template model for the example contract. This
should allow for, more or less, a cut and paste for creating a new
contract that preserved the counter. That is, the factory & template
are for the specific contract type and would have to be replaced
completely for a new contract.

Signed-off-by: Mic Bowman <[email protected]>
  • Loading branch information
cmickeyb committed Oct 2, 2024
1 parent 1b7004d commit 768421c
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 1 deletion.
2 changes: 2 additions & 0 deletions example-contract/MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ context/counter.toml
etc/example.toml
pdo/__init__.py
pdo/example/__init__.py
pdo/example/jupyter/__init__.py
pdo/example/jupyter/context.py
pdo/example/plugins/__init__.py
pdo/example/plugins/counter.py
pdo/example/resources/__init__.py
Expand Down
1 change: 1 addition & 0 deletions example-contract/docs/notebooks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.ipynb
49 changes: 49 additions & 0 deletions example-contract/docs/notebooks/factories/counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ---
# jupyter:
# jupytext:
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.16.1
# kernelspec:
# display_name: Python 3 (ipykernel)
# language: python
# name: python3
# ---

# %% [markdown]
# # Counter Factory
#
# This notebook simplifies the creation of counter.

# %%
import os
import pdo.contracts.jupyter as pc_jupyter
import IPython.display as ip_display

pc_jupyter.load_contract_families(example='example')
pc_jupyter.load_ipython_extension(get_ipython())

try : state
except NameError:
(state, bindings) = pc_jupyter.initialize_environment('unknown')

# %% [markdown]
# ## Configure Counter Information
#

# %% tags=["parameters"]
counter_name = input('Name of the counter: ')
identity = input('Identity to use to create the counter [user1]: ') or "user1"
service_group = input('Service group [default]: ') or "default"

# %%
instance_parameters = {
'counter_owner' : identity,
'counter_name' : counter_name,
'service_group' : service_group,
}

instance_file = pc_jupyter.instantiate_notebook_from_template(counter_name, 'counter', instance_parameters)
ip_display.display(ip_display.Markdown('[Newly created counter]({})'.format(instance_file)))
112 changes: 112 additions & 0 deletions example-contract/docs/notebooks/templates/counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# ---
# jupyter:
# jupytext:
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.16.1
# kernelspec:
# display_name: Python 3 (ipykernel)
# language: python
# name: python3
# ---

# %% [markdown]
# # Notebook to Invoke Counter Operations

# %% [markdown]
# ## Configure Counter Information
#
# %% tags=["parameters"]
counter_owner = 'user1'
counter_name = 'counter_1'
service_group = 'default'
instance_identifier = ''

# %% [markdown]
# <hr style="border:2px solid gray">
#
# ## Initialize

# %%
import os
import pdo.contracts.jupyter as pc_jupyter

pc_jupyter.load_contract_families(example='example')
pc_jupyter.load_ipython_extension(get_ipython())

# %% [markdown]
# ### Initialize the PDO Environment
#
# Initialize the PDO environment. This assumes that a functional PDO configuration is in place and
# that the PDO virtual environment has been activated.
#
# For the most part, no modifications should be required below.
# %%
common_bindings = {
'counter_owner' : counter_owner,
'counter_name' : counter_name,
'instance' : instance_identifier,
}

try : state
except NameError :
(state, bindings) = pc_jupyter.initialize_environment(counter_owner, **common_bindings)

print('environment initialized')

# %% [markdown]
# ### Initialize the Contract Context
#
# The contract context defines the configuration for a collection of contract objects that interact
# with one another. In the case of the counter contract, there are no interactions and the context
# is very simple.

# %%
context_file = bindings.expand('${etc}/context/${counter_name}_${instance}.toml')
print("using context file {}".format(context_file))

context_bindings = {
'identity' : counter_owner,
'service_group' : service_group,
}

counter_path = 'counter.' + counter_name
context = pc_jupyter.example_jupyter.initialize_counter_context(
state, bindings, context_file, counter_path, **context_bindings)
print('context initialized')

counter_context = pc_jupyter.pbuilder.Context(state, counter_path + '.counter')
counter_save_file = pc_jupyter.pcommand.invoke_contract_cmd(
pc_jupyter.example_counter.cmd_create_counter, state, counter_context)
pc_jupyter.pbuilder.Context.SaveContextFile(state, context_file, prefix=counter_path)
print('saved counter contract in {}'.format(counter_save_file))

# %% [markdown]
# <hr style="border:2px solid gray">
# ## Operate on the Counter
#

# %% [markdown]
# ### Get Counter Value
#
# %%
def get_counter_value() :
return pc_jupyter.pcommand.invoke_contract_cmd(
pc_jupyter.example_counter.cmd_get_value, state, counter_context)
# %%
# %%skip True
print("The current value of the counter is {}".format(get_counter_value()))

# %% [markdown]
# ### Increment the Counter Value
#
# %%
def inc_counter_value() :
return pc_jupyter.pcommand.invoke_contract_cmd(
pc_jupyter.example_counter.cmd_inc_value, state, counter_context)
# %%
# %%skip True
inc_counter_value()
print("The current value of the counter is {}".format(get_counter_value()))
2 changes: 1 addition & 1 deletion example-contract/pdo/example/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.

__all__ = [ 'plugins', 'resources', 'scripts' ]
__all__ = [ 'jupyter', 'plugins', 'resources', 'scripts' ]
18 changes: 18 additions & 0 deletions example-contract/pdo/example/jupyter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

# Copyright 2024 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__all__ = [ 'context' ]

from .context import *
56 changes: 56 additions & 0 deletions example-contract/pdo/example/jupyter/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2024 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

import pdo.contracts.common as jp_common

_logger = logging.getLogger(__name__)

__all__ = [
'counter_context',
'initialize_counter_context',
]

# -----------------------------------------------------------------
# set up the context
# -----------------------------------------------------------------
counter_context = jp_common.ContextTemplate('counter', {
'module' : 'pdo.example.plugins.counter',
'identity' : '${..identity}',
'source' : '${ContractFamily.Example.counter.source}',
'eservice_group' : '${..eservice_group}',
'pservice_group' : '${..pservice_group}',
'sservice_group' : '${..sservice_group}',
})

# -----------------------------------------------------------------
# -----------------------------------------------------------------
def initialize_counter_context(state, bindings, context_file : str, prefix : str, **kwargs) :
"""Initialize a context for counters
@type state: pdo.client.builder.state.State
@param state: client state
@type bindings: pdo.client.builder.bindings.Bindings
@param bindings: current interpreter bindings
@param context_file: name of the context file
@param prefix: prefix for paths in the context
@keyword kwargs: dictionary of string (paths) to values that override context
@rtype: pdo.client.builder.context.Context
@return: the initialized context
"""
contexts = [
counter_context,
]
return jp_common.initialize_context(state, bindings, context_file, prefix, contexts, **kwargs)

0 comments on commit 768421c

Please sign in to comment.