Skip to main content

Python SDK for automating Draw Things image generation over gRPC.

Project description

drawthings-py

drawthings-py is a Python SDK for automating image generation with Draw Things. It provides an async client for the Draw Things gRPC service, helpers for building generation requests, reusable model/config presets, image result handling, seed utilities, and filename helpers for scripting repeatable image workflows.

The package is published as drawthings-py and imported as drawthings_py.

Installation

Install the package with pip:

pip install drawthings-py

drawthings-py requires Python 3.11 or newer. To generate images, you will also need a running Draw Things service that accepts gRPC requests.

Basic Usage

To generate an image with the Draw Things service, you'll need to:

  1. Connect to the service using the gRPC client
  2. Load a config (either from a preset or custom)
  3. Build your request with a RequestBuilder
  4. Generate the image and save the result
import asyncio
from drawthings_py import DrawThings, Configs, RequestBuilder

async def main():
    async with DrawThings.grpc() as service:
        # Load a community preset (guaranteed to work with bridge mode/DT+)
        config = Configs.from_preset("ernie_image_turbo")

        # Build your image request with prompt and negative prompt
        req = RequestBuilder(config, "some random thing", "normal")

        # Generate the image
        (result,) = await service.generate_image(req)

        # Save the result to a file
        result.to_file("astro-rider.png")

asyncio.run(main())

RequestBuilder

Regardless of whether you are using the gRPC service or the CLI, you will use a RequestBuilder to construct your image generation request. At a minimum, a RequestBuilder needs a config.

from drawthings_py import RequestBuilder, Configs

config = Configs.from_preset("flux_2_klein_9b")
req = RequestBuilder(config)

You can assign prompts when creating the RequestBuilder, or set/change them later with the prompt() and negative_prompt() methods.

req = RequestBuilder(config, "A firebreathing dragon", "Ugly, boring, unimpressive")
req.prompt("An icebreathing dragon")
req.negative_prompt("Ugly, boring, unimpressive, fire")

RequestBuilder instances are reusable across requests. You don't need to call a build method; the service will build the appropriate request when you call generate_image().

(result_a,) = await grpc_service.generate_image(req)
(result_b,) = await cli_service.generate_image(req)

(Note: the CLI service is coming soon.)

You can update properties on the config through the request's config property. See the Configs section for more examples

req.config["steps"] = 8

If you want to change to a different config, for example to alternate between different models, it's easier to use another RequestBuilder.

req_alt = RequestBuilder(Configs.from_preset("anima_preview_3"))

You can add reference images, control images, or an init image for Img2Img using either a file path or an ImageBuffer returned from generate_image().

req.add_moodboard_image("my_character.png")
req.add_moodboard_image("awesome_outfit.png")
req.control_image("something.png", "pose")
req.init_image(gen_result)

Images will remain on the RequestBuilder until cleared.

req.clear_moodboard()
req.clear_init_image()
req.clear_control_image("pose")

ImageBuffer

Generated images are returned as a list of ImageBuffers. An ImageBuffer contains the image's pixel data, dimensions, channel count, and any generation metadata returned by Draw Things.

You can save a generated image directly with to_file():

(image,) = await service.generate_image(req)
image.to_file("output.png")

Note: Images saved with the .png format will have metadata importable by Draw Things.

ImageBuffer can also load images from disk for use as reference, control, or init images in a RequestBuilder.

Configs

There are a number of ways to get a config.

from drawthings_py import Configs

# Load a Community Configuration preset
config = Configs.from_preset("flux_2_klein_4b")

# From JSON, as copied from the Draw Things app
config = Configs.from_json("""{"model":"z_image_turbo_1.0_q6p.ckpt","strength":1,"height":1024,"width":1024, ...}""")

# Create from scratch
config = Configs.create(width=1024, height=1024, ...)
config = Configs.create({
  "width": 768,
  "height": 768,
  ...
})

Change individual properties using ["item"] notation. Update many at once using .set().

config["steps"] = 8
config.set({
    "width": 1024,
    "height": 1024,
})
config.set(height=1024, width=1024)

Loras and controlnets are exposed as lists and can be accessed and updatd through their respective items. Typed helper methods are provided to add new items.

config.add_lora("dmd2.ckpt", 0.5)
config["loras"][0].weight = 0.25
config["loras"].clear()

Seeds

Draw Things supports any seed value from 1 to 4,294,967,295, in addition to -1, which will use a random seed for each generation. This package also adds features to help manage seeds in your scripts.

Reusable seeds - For scripts that make multiple requests, it can sometimes be useful to use the same random seed more than once. If you use a negative value other than -1, a random seed will be used and saved for reuse. Any time you use the same negative value, you will get the same seed.

req.config["seed"] = -2
(result_a,) = await service.generate_image(req) # a random seed will be chosen and assigned to -2
req.config["seed"] = -1
(result_b,) = await service.generate_image(req) # another random seed
req.config["seed"] = -2
(result_c,) = await service.generate_image(req) # this gen will have the same seed as result_a

(This is currently specific to an individual RequestBuilder)

Determinate seeds - You can initialize a RequestBuilder's RNG by calling req.seed_seed(value), allowing you to get the same sequence of random seeds across multiple runs.

req.seed_seed("example seed") # you can also use any int, float, or bytes
req.config["seed"] = -1
(result,) = await service.generate(req) # the seed is 3137907891
(result2,) = await service.generate(req) # this seed is 604582375

Every time you run, you will get the same sequence of seeds.

(This is also currently specific to an individual RequestBuilder)

Checking a gen's seed - If you need to see what seed was used for a gen, you can check result.metadata["seed"]. It will also be in the PNG metadata when the result is saved to a file.

Filenames

You can use a FilenamePattern to generate filenames for your images. A FilenamePattern is a filename with a placeholder for a numeric counter, for example image_####.png. Any time the returned function is called, the specified directory will be scanned for files matching the pattern, and the highest matching filename + 1 will be returned.

next_filename = FilenamePattern("image_####.png", "~/Documents/Draw Things images/")
(result,) = await service.generate_image(req)
result.to_file(next_filename()) # creates image_0001.png
(result,) = await service.generate_image(req)
result.to_file(next_filename()) # creates image_0002.png

This makes it easy to generate a number of images without having to worry about overwriting anything.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drawthings_py-0.1.0.tar.gz (75.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drawthings_py-0.1.0-py3-none-any.whl (93.7 kB view details)

Uploaded Python 3

File details

Details for the file drawthings_py-0.1.0.tar.gz.

File metadata

  • Download URL: drawthings_py-0.1.0.tar.gz
  • Upload date:
  • Size: 75.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for drawthings_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b66e10387b8195b0b147b09b860df36422ef46f84146b293f034a64127d226b0
MD5 13653e406c7d0680de5bd209539f4fec
BLAKE2b-256 bf4ca8fd3ee48e66005f6e0281f8adfa86aed38a3d41cac78ec2d12d740daac5

See more details on using hashes here.

Provenance

The following attestation bundles were made for drawthings_py-0.1.0.tar.gz:

Publisher: python-package.yaml on kcjerrell/drawthings-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file drawthings_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: drawthings_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 93.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for drawthings_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 24a522a409914a9061c6b7a0fa93392d1eaac413d3bfb9dcd58719429749a5ff
MD5 93517d021d9a379daf4bc4d968854d65
BLAKE2b-256 f5794e1875fbf3c6a1628478c4c0fdc6131a820dc213a6d200ce671b90e4963e

See more details on using hashes here.

Provenance

The following attestation bundles were made for drawthings_py-0.1.0-py3-none-any.whl:

Publisher: python-package.yaml on kcjerrell/drawthings-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page