# Development

{% hint style="success" %}
**Have You Completed the Setup?**

Ensure you’ve followed all the steps to [set up](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/setup) your project before proceeding. This includes configuring your environment and installing dependencies.
{% endhint %}

## Project Structure

The project is organized with the following structure:

```
📂 sample_book
├── 📁 src
│   └── 📁 sample_book
│       ├── 📃 __init__.py
│       ├── 📃 __version__.py
│       └── 📃 book.py
│       └── 📁 data
│           └── 🖼️ icon.svg
├── 📁 tests
│   └── 📃 test_book.py
├── 📃 Dockerfile
├── 📃 pyproject.toml
├── 📃 poetry_scripts.py
├── 📃 poetry.lock
├── 📃 README.md
└── 📃 USAGE.md
```

#### Root Directory

The project root directory is named using the Project Slug *(default: sample\_book)*.

#### Source Code Directory

* **`📃 book.py`**: Contains the core class where your book is defined and implemented.
* **`📁 data`**: Holds images like **`🖼️ icon.svg`**, the default SVG used as a book's icon.

#### Test Directory

* **`📃 test_book.py`**: Contains unit tests to validate the Book's functionality.

#### Configuration and Dependency Files

* **`📃 Dockerfile`**: Builds the Docker image.
* **`📃 pyproject.toml`**: Manages dependencies and settings.
* **`📃 poetry_scripts.py`**: Custom automation script.
* **`📃 poetry.lock`**: Locks dependency versions.

#### Documentation

* **`📃 README.md`**: Project overview documentation, including setup and usage instructions.
* **`📃 USAGE.md`**: Reference documentation for your Book. This file is not included by default. For details on how to generate it, see [Generating Documentation](#generating-documentation).

***

## Implementation

Implement your book in **book.py**.

This class is auto-generated by the Template and serves as the starting point for your Book’s implementation. Use decorators to configure settings, define procedures, and establish API connections. Refer to the [**API Reference**](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/api-reference) and [**example books**](https://github.com/kognitos/bdk-examples) for details.

***

## Managing Dependencies

[Poetry](https://python-poetry.org/) is used for Python dependency management in custom book projects. To add an external Python dependency to your project, refer to the [**poetry add**](https://python-poetry.org/docs/cli/) command, which adds packages to your `pyproject.toml` and installs them.

***

## Development Commands

This section outlines essential commands for book development and testing.

#### Formatting

Code formatting automatically adjusts your code's structure, ensuring adherence to coding standards, readability, and maintainability. To apply the formatting, run:

```
poetry run format
```

#### Linting

[Pylint](https://pypi.org/project/pylint/) is used as the source linter for custom book projects. The linter analyzes and enforce coding standards, checks for errors in Python code, and improves code quality. To run the linter:

```
poetry run lint
```

#### Generating Documentation

This command will generate a comprehensive **USAGE.md** file by extracting and formatting the [docstrings](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/api-reference/docstrings) from your code. To generate the documentation, run:

```
poetry run doc
```

#### Testing

[Pytest](https://docs.pytest.org/en/stable/) is used to test and validate your book. To run the test suite:

```
poetry run tests
```

***

## Packaging with Docker

Build a Docker image to package your book:

```
docker build -t <project_slug>:<version> .
```

{% hint style="warning" %}
**Architecture Compatibility**

This image pulls the **Runtime** base image from Docker Hub, which is currently available only for the **linux/amd64** architecture. If you're using a machine with a different architecture, you can use the `--platform` flag to emulate linux/amd64 when building the image:

```
docker build --platform linux/amd64 -t <project_slug>:<version> .
```

{% endhint %}

***

## Running Your Book Locally

To test your Book in Kognitos before deployment, you can run your Docker image locally with [ngrok](https://ngrok.com/). Ngrok is a tool that creates a secure tunnel to your local machine and provides a public URL to make your local Docker image accessible from the platform.

**1. Install ngrok**

Follow the installation steps for [**ngrok**](https://download.ngrok.com/mac-os) based on your system. You will need to sign up for a free account.

**2. Obtain your ngrok authtoken**

Navigate to *Your Authtoken* in the ngrok portal and copy your token.

**3. Add your authtoken**

```
ngrok config add-authtoken <token>
```

**4. Configure the ngrok api key as an environment variable:**

```
export NGROK_AUTHTOKEN=<token>
```

**5. Build & run in ngrok mode**

This command will invoke a custom script that builds the Docker image and runs it in ngrok mode:

```
poetry run host
```

If you are running into issues with \`poetry run host\`, you can [package](#packaging-with-docker) and run your book manually with the following command:

```cli
docker run -e BDK_SERVER_MODE=ngrok -e NGROK_AUTHTOKEN=<auth_token> <project_slug>:<version>
```

Make sure to replace `auth_token`, `project_slug`, and `version` with your own values.

**6. Copy the URL**

You'll see the ngrok address in the following format in the logs. Copy the URL:

```
listening on https://<SOME_UUID>.ngrok-free.app
```

**7. Add the URL to your automation**

Copy the URL and paste it into your automation using this syntax:

```
learn "https://f1d7-100-34-252-18.ngrok-free.app"
```

{% hint style="warning" %}
If you implemented any custom [connections](https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/api-reference/connections), make sure you also [**connect**](https://docs.kognitos.com/legacy/legacy-experience/books/connections) to your book *after* learning.
{% endhint %}
