Metadata-Version: 2.1
Name: stablehordeapi-py
Version: 0.1.0
Summary: Library for using Stable Horde API in Python
Home-page: https://github.com/timius100/StableHordeAPI.py
License: MIT
Keywords: stablehorde,async,asyncio
Author: Timur Bogdanov
Author-email: timurbogdanov2008@gmail.com
Requires-Python: >=3.8,<4.0
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: aiofiles (>=22.1.0,<23.0.0)
Requires-Dist: aiohttp (>=3.8.3,<4.0.0)
Requires-Dist: loguru (>=0.6.0,<0.7.0)
Requires-Dist: msgspec (>=0.10.1,<0.11.0)
Project-URL: Repository, https://github.com/timius100/StableHordeAPI.py
Description-Content-Type: text/markdown

<h1 align="center">
StableHordeAPI.py
</h1>
<h2 align="center">Simple wrapper around Stable Horde API</h2>

# Content
- [Installation](#installation)
- [Usage](#usage)
- [Examples](#examples)
- [License](#license)

# Installation
```
pip install stablehordeapi.py
```

# Usage
```python
import asyncio

from stablehorde_api import StableHordeAPI

async def main():
    client = StableHordeAPI("Your Stable Horde token here")
    await client.generate_from_txt(
        "Futuristic cyberpunk landscape, 8k, hyper realistic, cinematic"
    )

asyncio.run(main())
```
This code will generate an image based on your prompt and save it as "{unix timestamp}\_0.webp" in your current directory.

Additionally, you can specify file name:
```python
await client.generate_from_txt(
    "Your prompt...",
    filename="my_image"
)
```
In that case, your file will be saved as "my\_image.webp"

However, you'll probably want more control over how image is generated. So, for example, you can do this:
```python
import asyncio
from stablehorde_api import GenerationInput, ModelGenerationInputStable

async def main():
    client = StableHordeAPI("Your Stable Horde token here")
    payload = GenerationInput(
        "masterpiece, best quality, ((Hu Tao)), brown hair, long hair, flower-shaped pupils",
	params=ModelGenerationInputStable(
	    height=512,
	    width=768,
	    steps=50,
	    post_processing=['RealESRGAN_x4plus']
	),
	nsfw=True,
	censor_nsfw=False,
	models=['Anything Diffusion'],
	n=5
    )
    # payload can also be a dict, which is useful, if something new added
    txt2img_rsp = await client.txt2img_request(payload)
    img_uuid = txt2img_rsp.id

    done = False
    while not done:
        # Checking every second if image is generated
        await asyncio.sleep(1)
        generate_check = await client.generate_check(img_uuid)
	if generate_check.done == 1:
	    done = True

    # Generating a status which has all generations (in our case,
    # there should be 5 generations, because n is set to 5)
    generate_status = await client.generate_status(img_uuid)
    generations = generate_status.generations
```
After that, all generations will be in `generations` variable. To access first image, use `generations[0].img`

# Examples
This example will generate 3 Hu Tao images using Anything Diffusion model.
```python
import asyncio
import base64

import aiofiles
from stablehorde_api import GenerationInput, ModelGenerationInputStable

async def main():
    client = StableHordeAPI("Your Stable Horde token here")
    payload = GenerationInput(
        "masterpiece, best quality, ((Hu Tao)), brown hair, long hair, flower-shaped pupils",
	models=['Anything Diffusion'],
	n=3
    )
    txt2img_rsp = await client.txt2img_request(payload)
    img_uuid = txt2img_rsp.id

    done = False
    while not done:
        await asyncio.sleep(1)
        generate_check = await client.generate_check(img_uuid)
	if generate_check.done == 1:
	    done = True

    generate_status = await client.generate_status(img_uuid)
    generations = generate_status.generations
    for num, generation in enumerate(generations):
        new_filename = f'{filename}_{num}.webp'
        async with aiofiles.open(new_filename, 'wb') as file:
            b64_bytes = generation.img.encode('utf-8')
            img_bytes = base64.b64decode(b64_bytes)
            awat file.write(img_bytes)
```
If you set `r2` to true, then you will need to request content from the link in generations. You can do that by using aiohttp:
```python
import aiohttp
...

aiohttp_client = aiohttp.ClientSession()
...

img_rsp = (await aiohttp_client.request(url=generation.img)).content
img_bytes = await img_rsp.read()
```

# License
[MIT License](./LICENSE)


