# Development

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

Ensure you’ve followed all the steps to [set up](/legacy/legacy-experience/books/custom-books/setup.md) 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**](/legacy/legacy-experience/books/custom-books/api-reference.md) 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](/legacy/legacy-experience/books/custom-books/api-reference/docstrings.md) 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](/legacy/legacy-experience/books/custom-books/api-reference/connections.md), make sure you also [**connect**](/legacy/legacy-experience/books/connections.md) to your book *after* learning.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kognitos.com/legacy/legacy-experience/books/custom-books/development.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
