ChatCraft Adventures #5
Tags: ai, beginners, opensource, openai
Published: 2024-02-10 00:07:39

## This week in ChatCraft

This week in ChatCraft, Release 1.2 is complete, and is available [here](https://github.com/tarasglek/chatcraft.org/releases/tag/v1.2.0) for those interested.
The ChatCraft community has worked hard to push many changes and an awesome new feature to ChatCraft second release.

### New Feature - Image Input
One new feature I'm excited to share with you today [Image Input](https://github.com/tarasglek/chatcraft.org/pull/286), prepared by my classmate [Mingming](https://github.com/mingming-ma). Since November 2023, Mingming has been working hard to polish and push this feature into ChatCraft, and his hard work has paid off.

This feature uses [GPT-4 with Vision](https://platform.openai.com/docs/guides/vision) (model name `gpt-4-vision-preview`) to allow the model to analyze and discuss input images:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhhy6r4kz18sgll99ksw.png)

You can attach images to the prompt either by clicking on the paperclip icon or by pasting it into the prompt window using `Ctrl+V`. For a better idea, please take a look at the [conversation](https://chatcraft.org/api/share/rjwignar/sXIHj-eLoiam6NEFM2rOB) I screenshotted above.

## Sheriff Duties

In my last [blog post](https://dev.to/rjwignar/chatcraft-adventures-4-50o7), I briefly discussed Sheriff duties and my first Sheriff duty experience. This week, I have relinquished and passed on my Sheriff duties to my classmate [Rachit](https://github.com/Rachit1313). With my duties passed on, this week was more relaxing for me, although I still try to remain available on the Discord server.

## Pull Requests

For this week, I've contributed two Pull Requests to ChatCraft: a UI fix and a packaging task.

### UI Fix: [Broken Iframe Autoresize](https://github.com/tarasglek/chatcraft.org/issues/379)

You can ask ChatCraft to generate HTML files for you, and ChatCraft will render and preview those HTML files to you (conversation available [here](https://chatcraft.org/api/share/rjwignar/OhTT7enSHfxMSwb_OuEyA)):
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7yi6vtfeqa48203n4uq.png)

The HTML preview is contained in an [IframeResizer](https://github.com/davidjbradshaw/iframe-resizer-react), which we want to automatically resize to fit HTML previews content.

The issue here was the last line that could fit in a preview would be cut off:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nmu73rc3l14a53okou7.png)

#### [My solution](https://github.com/tarasglek/chatcraft.org/pull/408)
The IframeResizer [heightCalculationMethod](https://github.com/davidjbradshaw/iframe-resizer/blob/master/docs/parent_page/options.md#heightcalculationmethod) option calculates the iFrame height by converting the body margin to px then adding the top and bottom figures to the body tag's offSetHeight (bodyOffSet).

There are four main possible values for `heightCalculationMethod`:

- **(default) bodyOffset** uses `document.body.offsetHeight`
- **bodyScroll** uses `document.body.scrollHeight`
- **documentElementOffset** uses `document.documentElement.offsetHeight`
- **documentElementScroll** uses `document.documentElement.scrollHeight`

There is also a `heightCalculationMethod` value of **max**, which uses the largest value of the above 4. I found that using a `heightCalculationMethod` value of **max** fixes the issue by rendering the entire content. Rendering the entire content eliminates the need of a scrollbar in these preview renders, so I removed the scrollbar as well.

### Publishing Task: [Package and Publish github-to-sops to PyPI](https://github.com/tarasglek/chatcraft.org/issues/324)

This task isn't exactly a ChatCraft feature, but it's an important part of our secrets management. ChatCraft uses [sops](https://github.com/getsops/sops) to manage and share secrets, and the owner, [Taras](https://github.com/tarasglek) wrote [github-to-sops](https://github.com/tarasglek/github-to-sops) to make working with sops easier.

You can clone and use `github-to-sops` on your local machine, but wouldn't it be better to install it with [pip](https://pypi.org/project/pip/) instead? With my [Pull Request](https://github.com/tarasglek/github-to-sops/pull/3), I was able to package and ship `github-to-sops` to the [Python Package Index (PyPI)](https://pypi.org/). You can see its entry [here](https://pypi.org/project/github-to-sops/).

#### How I packaged a Python Package for the first time

Packaging Python packages for PyPI requires a specific kind of project directory structure that `github-to-sops` didn't have at the time. Before I could publish `github-to-sops` to PyPI I had to first modify its directory structure. I don't often write programs in Python, so this task would've been very difficult to do on my own. This would end up being the first Python Package I've published, and ironically it's not one I developed myself.

#### Publishing to PyPI with Simonw's CookieCutter Template
Luckily, [Simon Willison](https://github.com/simonw) ([django](https://www.djangoproject.com/) co-creator) created a [cookiecutter template](https://github.com/simonw/python-lib-template-repository) that creates a Python project with a suitable directory structure and all files required to publish a Python project to PyPI. The template even generates two workflow files - one for unit tests and [another one that publishes GitHub releases](https://github.com/simonw/python-lib-template-repository/blob/main/.github/workflows/publish.yml) to PyPI. Simon wrote more details on his template in [this blog post](https://simonwillison.net/2024/Jan/16/python-lib-pypi/). 

This template provided two important things:
- An appropriate package directory structure
- A publishing workflow

The publishing workflow was especially helpful, as it automatically publishes new GitHub releases. Thanks, Simon!


To package `github-to-sops`, I used Simon's [template](https://github.com/simonw/python-lib-template-repository) to generate a sample GitHub project, and then I copied appropriate files and mimicked the directory structure in `github-to-sops`. One thing `github-to-sops` doesn't require at the moment is unit tests (though it'd be nice to have!), so testing-related artifacts were not copied over. This also required removing the `test` step in the publish workflow.

#### Iterating on initial releases
Using Simon's template, I was able to successfully package and publish `github-to-sops` to PyPI, but version 1.0.0 had a major issue: it was published as a [namespace package](https://packaging.python.org/en/latest/guides/packaging-namespace-packages/) that you would import in Python code. This wasn't ideal, as `github-to-sops` is a command-line tool.

To fix this, I would have to somehow package `github-to-sops` as a command-line tool. Simon's template brought me far enough, it was time for me to research and experiment the rest of the way. Ultimately, it was a combination of [documentation](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html) and conversations with [ChatCraft](https://chatcraft.org/api/share/rjwignar/sJ0JkX4jaEgkJrSM2APns) that helped me figure it out.

After [renaming folders](https://github.com/tarasglek/github-to-sops/pull/8) and properly [setting up custom discovery](https://github.com/tarasglek/github-to-sops/pull/10/files) I was able to get `github-to-sops` packaged to PyPI as a command-line tool (**version 1.1.4**):

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sipqwivzsb0ybevx77on.png)

I must admit that this process was frustrating at times, but the sense of accomplishment I felt after pulling it off was well worth it, and I now have a better idea of packaging and publishing to PyPI, thanks to Simon and ChatCraft.

## Next week in ChatCraft
Next week, I'll be looking into extending Mingming's Image Input feature with text file inputs. Stay tuned until then.