# Coding Reference

Sample custom block script provided in AugeLab:

{% code title="Example_Block code" %}
```python
## Bootstrap phase
from studio.custom_block import *
# Importing of community modules 
import cv2
import numpy as np

## Class Definition 
class Example_Block(Block):
	op_code = 'Example_Block' # DO NOT CHANGE !!!, must be same as class name

	def init(self):
		self.width = 200
		self.height = 120
		self.tooltip = 'Increment image values by one.'

		self.input_sockets = [SocketTypes.ImageAny('in1')]
		self.output_sockets = [SocketTypes.ImageAny('out1')]

		self.param['text1'] = TextInput(text= '5')

	def run(self):
		in1 = self.input['in1'].data
		self.output['out1'].data = in1 + 1


add_block(Example_Block.op_code, Example_Block)

```
{% endcode %}

<figure><img src="https://63608322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbH8gla5D8g5pQAK8IzR8%2Fuploads%2Fgit-blob-7652bc170f0fe2590b3f71bd0811585657c26e51%2Fimage.png?alt=media" alt=""><figcaption><p>Example Custom Block</p></figcaption></figure>

## Bootstrap Phase <a href="#bootstrap-phase" id="bootstrap-phase"></a>

### Mandatory Imports <a href="#mandatory-imports" id="mandatory-imports"></a>

Sample script always starts with imports of certain modules. from `studio.custom_block import *`imports necessary super classes, widgets and methods for you to utilize in your block. This line is mandatory for all class definitions.

### Importing Community Modules <a href="#importing-community-modules" id="importing-community-modules"></a>

Here, most used two libraries are already set to be imported for you. You can use OpenCV and numpy libraries in your custom blocks.

You can also import custom libraries by installing them with Import Package Window and set-read custom static variables.

{% hint style="warning" %}
All blocks provided in AugeLab Studio is cross platform compatible. However, using community modules may compromise that.
{% endhint %}

## Class Definition <a href="#class-definition" id="class-definition"></a>

Name of your class is determined by whatever [title](#block-name) you've provided in Block Name text edit. You can introduce attributes or methods however you like in this section.

### Class Attributes-Methods <a href="#class-attributes-methods" id="class-attributes-methods"></a>

### \`Block.op\_code: str\` <a href="#blockop_code-str" id="blockop_code-str"></a>

`op_code` defines a unique identifier string for your custom block. To upload your custom block, you must choose a unique block name for your custom block.

### \`Block.tooltip: str\` <a href="#blocktooltip-str" id="blocktooltip-str"></a>

`tooltip` allows you to show tooltips on your custom blocks when users hover over your custom block.

<figure><img src="https://63608322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbH8gla5D8g5pQAK8IzR8%2Fuploads%2Fgit-blob-6cfa4d6c790153b8ff9d12e09957c575f25d4694%2Fimage.png?alt=media" alt=""><figcaption><p>Tooltip shown on custom block</p></figcaption></figure>

### \`Block.input\_sockets: list\[SocketType]\` <a href="#blockinput_sockets-listsockettype" id="blockinput_sockets-listsockettype"></a>

`input_sockets` attribute stores socket types. Each socket type is automatically generated for you in [Input Socket](#input-socket-list) or [Output Socket](#output-socket-list) section.

`SocketType` takes two arguments:

```python
...
SomeSocketClass(SocketTypes.BaseSocketClass):
    def __init__(self, name: str = '', multiple: bool = False):
        ''' 
            name: Text shown beside socket graphics
            multiple: Draw a horizontal line to indicate a list of type.
        '''
        ...
```

List of `SocketType`s can be seen below:

* \[`ImageAny`]`: ImageRGB | ImageGray`
* \[`ImageRGB`]`: npt.NDArray[np.uint8] # [N, N, 3]`
* \[`ImageGray`]`: npt.NDArray[np.uint8] # [N, N]`
* \[`Integer`]`: int`
* \[`Float`]`: int`
* \[`Number`]`: float | int`
* \[`Boolean`]`: bool`
* \[`String`]`: str`
* \[`Generic`]`: object`
* \[`Shape`]`: list[list[int, int], ...]`
* \[`Pixel`]`: tuple[int] | tuple[int, int, int]`
* \[`Point`]`: tuple[int, int]`

### \`Block.output\_sockets: list\[SocketType]\` <a href="#blockoutput_sockets-listsockettype" id="blockoutput_sockets-listsockettype"></a>

Same rules on [Input\_sockets](#block.input/_sockets-list-sockettype) applies to this section as well.

### \`Block.param: dict\[str, Component]\` <a href="#blockparam-dictstr-component" id="blockparam-dictstr-component"></a>

This property holds your block components, and interactable widgets by their unique names. There are several components you can utilize:

* [Text Input](#text-input)
* [Drop Down List](#drop-down-list)
* [Label Text](#label)
* [Slider](#slider)
* [Slider Labeled](#slider-labeled)
* [Check Box](#checkbox)
* [Button](#button)
* [Image](#image)
* [Table](#table)

### \`Block.input: dict\[str, object]\` <a href="#blockinput-dictstr-object" id="blockinput-dictstr-object"></a>

`input` property is a dynamic `dict` that transfer data into your custom block. You can retrieve data from your input sockets by their unique **socket** names.

```python
...
class Example_Block(Block):
    ...
    def init(self):
        ...
        self.input_sockets = [SocketTypes.ImageAny('Image'),
                              SocketTypes.Number('Constant')]
        ...
        
    def run(self):
        image = self.input['Image'].data
        constant = self.input['Image']
        ...
```

### \`Block.output: dict\[str, object]\` <a href="#blockoutput-dictstr-object" id="blockoutput-dictstr-object"></a>

`output` property is a dynamic `dict` that transfer data out of your custom block. You can place data into your output sockets by their unique **socket** names.

```python
...
class Example_Block(Block):
    ...
    def init(self):
        ...
        self.output_sockets = [SocketTypes.ImageAny('Result'),
                              SocketTypes.Number('Detections')]
        ...
        
    def run(self):
        ...
        self.output['Result'].data = img_detections_drawn
        self.output['Detections'].data = n_detections
        
```

### \`Block.register\_resource(name: str = '', path: str = '') -> str\` <a href="#blockregister_resourcename-str-path-str-str" id="blockregister_resourcename-str-path-str-str"></a>

Registers paths and automatically saves them in the scenario file.

Normally, using raw paths may create problems during transferring scenario files across different computers. However, using automatic resource management allows you to use generic or relative paths. Simply storing a resource in a path lower than the scenario file will allow your script to receive the correct path no matter the where the root path is.

<mark style="color:blue;">**Arguments:**</mark>

`name: str` **:** Unique name provided to distinguish a path.

`path: str`**:** Path to be registered.

<mark style="color:blue;">**Returns:**</mark>

`path: str`**:** Registered path.

To receive the path provided, use [`get_resource`](#block.get/_resource-name-str-greater-than-str) method.

### \`Block.get\_resource(name: str = '') -> str\` <a href="#blockget_resourcename-str-str" id="blockget_resourcename-str-str"></a>

Allows you the receive the resource you have provided into resource manager of a custom block.

<mark style="color:blue;">**Arguments:**</mark>

`name: str` : Unique name provided to distinguish a path.

<mark style="color:blue;">**Returns:**</mark>

`path: str`: Registered path.

To register a path, use [`register_resource`](#block.register/_resource-name-str-path-str-greater-than-str) method.

### \`Block.init(self)\` <a href="#blockinitself" id="blockinitself"></a>

This part is executed every time when a custom block is dragged-dropped, copy-pasted, or loaded in a new scenario. It's mostly advised to use this section to:

* Load resources for your custom block
* Define components to be used (text inputs, buttons etc.)
* Inner block states that change with runtime.

### \`Block.run(self)\` <a href="#blockrunself" id="blockrunself"></a>

Run method is executed at every step of an execution of a scenario in AugeLab Studio. You can utilize your custom blocks inner states, custom modules, constants etc.

You can receive inputs by utilizing dynamic attributes provided by super `Block` class and send outputs as well, change configurations of your components and read component state to choose the right execution logic.

### \`QAFileDialog\` <a href="#qafiledialog" id="qafiledialog"></a>

QAFileDialog is a static class that offers file path choosing dialog for users:

#### \`QAFileDialog.getOpenFileName(\*\*kwargs)\` <a href="#qafiledialoggetopenfilenamekwargs" id="qafiledialoggetopenfilenamekwargs"></a>

<mark style="color:blue;">Arguments</mark>

`caption: str = ''`: Title of file dialog header

`directory: str = ''`: Starting directory of the dialog

`filter: str = ''`: Filenames to be filtered, for example -> `'Image Files (*.png *.jpg *.bmp)'`

<mark style="color:blue;">Returns</mark>

`path:str`: Chosen path by user.

#### \`QAFileDialog.getExistingDirectory\` <a href="#qafiledialoggetexistingdirectory" id="qafiledialoggetexistingdirectory"></a>

<mark style="color:blue;">Arguments</mark>

`caption: str = ''`: Title of file dialog header

`directory: str = ''`: Starting directory of the dialog

<mark style="color:blue;">Returns</mark>

`path:str`: Chosen path by user.

### \`add\_block(My\_Block.op\_code, My\_Block)\` <a href="#add_blockmy_blockop_code-my_block" id="add_blockmy_blockop_code-my_block"></a>

This part is automatically generated by the Designer Window and should not be modified. If to be modified, make sure the block name is the same as class name and `op_code.`
