semvec/pypi-packages huggingface dataset:
sgf-image-loader 1.0.1
A small package to manage loading and saving SGF files
Requires Python: >=3.8

# SGF Image Loader
A small package for loading and saving files in the SGF format. SGF stands for <ins>S</ins>imple <ins>G</ins>raphic <ins>F</ins>ormat, and it's a custom file format I designed to help me learn various different topics.
## Limitations
SGF is primarily geared towards simpler pixel art images. Additionally, due to SGF's simple implementation, images are limited by two factors:

 1. SGF has a max palette size of 256 colors
 2. SGF has a max image size of 65,535 x 65,535 pixels

## Usage
The SGF Image Loader requires a Pillow Image object for loading and saving files in the SGF format.

To store a Pillow Image:
```python
from PIL import Image
from sgf_image_loader.sgf import SGF

# load image using Pillow
image = Image.open("file_name.png")

# save image in the SGF format
SGF.save_sgf("file_name.sgf", image, find_best=True)
```
Note: The `find_best` parameter causes the image loader to try every parameter combination to find the best possible parameters (more information below). This causes slower save times, but a generally smaller file.

In order to load an SGF image:
```python
image = SGF.load_sgf("file_name.sgf")
```

assuming all previously imported packages were also imported.

## Parameters
**Vertical Stacking** (bool):
The SGF format combines similar pixels into one "chunk" that is made up of a repetition value, and a color index. By default, this chunk is created by scanning the pixels horizontally, combining any continuous pixels with the same color. Enabling `vertical_stacking` causes the chunk to be created by scanning pixels vertically.

**Disable Repetition** (bool):
By default, the SGF format attempts to compress groups of similar pixels into a smaller chunk. However, sometimes this may end up making the file size larger. Enabling `disable_repetition` causes each pixel to be stores as just a color index, with no repetition value.
pymultirun 0.1.0
A multi-process runtime library with health checks
Requires Python: >=3.9

## multirun
A multi-process runtime library with health checks, Excerpted from uvicorn.

If the script needs to use multiple processes and run for a long time, use it.

---

### Installation
```shell
pip install pymultirun
```

---

### Usage
Create a script that you want to run in multiple processes, in `example.py`:
```python
import socket

from multirun import run_multiprocess
import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')

    print(f"Received {message!r} from {addr!r}")

    print(f"Send: {message!r}")
    writer.write(data)
    await writer.drain()

    print("Close the connection")
    writer.close()
    await writer.wait_closed()

async def main(sock: socket.socket):
    server = await asyncio.start_server(
        handle_echo, sock=sock)

    addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
    print(f'Serving on {addrs}')

    async with server:
        await server.serve_forever()

def worker(sock: socket.socket) -> None:
    loop: asyncio.AbstractEventLoop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    try:
        loop.run_until_complete(main(sock))
    finally:
        loop.close()


if __name__ == '__main__':
    with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
        sock.bind(("::", 8888))
        run_multiprocess(worker, workers=2, args=(sock, ))
```
You can also use the command line, in `example.py`:
```python
import os
import time

def worker_function(name: str, age:int, sleep_time=1, **kwargs):
    pid = os.getpid()
    count = 0
    print(f"Name {name}, Age {age}, Kwargs {kwargs}.")

    try:
        while True:
            time.sleep(sleep_time)
            count += 1
            print(f"Worker {name} (PID: {pid}) - count: {count}")
    except KeyboardInterrupt:
        print(f"Worker {name} (PID: {pid}) shutting down")
```
Run it:
```shell
multirun example:worker_function --workers 2 --timeout 3  --args vvanglro --args 23  --kwargs a 1 
```

---

### Signal

You can use signals to stop the workers:

```shell
kill -SIGINT <pid>
```

Restart the workers:
```shell
kill -SIGHUP <pid>
```

Add workers:
```shell
kill -SIGTTIN <pid>
```

Reduce workers:
```shell
kill -SIGTTOU <pid>
```