From ad1763720801a8b1171cae615d64e9df7cc778b1 Mon Sep 17 00:00:00 2001 From: benzguo Date: Sun, 18 Aug 2024 14:13:13 -0400 Subject: [PATCH] reorganize examples --- examples/background-removal.py | 27 - examples/basic.py | 35 - examples/basic_embedding.py | 50 - examples/basic_rag.py | 60 -- examples/basics/README.md | 1 + examples/explicit_edges.py | 34 - examples/intro.py | 28 - examples/media_pipe.py | 27 - examples/notebooks/IBMPlexSans-Medium.ttf | Bin 177104 -> 0 bytes examples/notebooks/Makefile | 21 - examples/notebooks/background-removal.py | 125 --- examples/notebooks/basic.py | 57 -- examples/notebooks/blog-images.py | 208 ---- examples/notebooks/edit-poster.py | 143 --- examples/notebooks/film-showings.py | 193 ---- examples/notebooks/first-graph.py | 68 -- examples/notebooks/image-game.py | 236 ----- examples/notebooks/inpaint-poster.py | 127 --- examples/notebooks/interior-design.py | 167 ---- examples/notebooks/interpolate.py | 112 --- examples/notebooks/logo-controlnet.py | 72 -- examples/notebooks/logo-inpaint.py | 103 -- examples/notebooks/poetry.lock | 937 ------------------ examples/notebooks/prompt-enhance.py | 147 --- examples/notebooks/pyproject.toml | 18 - examples/notebooks/svd.py | 74 -- examples/remove_bg_objects.py | 46 - examples/streaming.py | 38 - examples/streaming/fastapi-example/main.py | 30 - examples/techniques/README.md | 1 + examples/workshop/README.md | 1 + examples/{ => workshop}/descript/__init__.py | 0 examples/{ => workshop}/descript/generate.py | 0 .../descript/generate_chapters.py | 0 examples/{ => workshop}/descript/index.html | 0 examples/{ => workshop}/descript/util.py | 0 .../{ => workshop}/mixture-of-agents/ask.py | 0 .../mixture-of-agents/index.html | 0 .../{ => workshop}/mixture-of-agents/util.py | 0 39 files changed, 3 insertions(+), 3183 deletions(-) delete mode 100755 examples/background-removal.py delete mode 100755 examples/basic.py delete mode 100755 examples/basic_embedding.py delete mode 100644 examples/basic_rag.py create mode 100644 examples/basics/README.md delete mode 100755 examples/explicit_edges.py delete mode 100755 examples/intro.py delete mode 100755 examples/media_pipe.py delete mode 100644 examples/notebooks/IBMPlexSans-Medium.ttf delete mode 100644 examples/notebooks/Makefile delete mode 100644 examples/notebooks/background-removal.py delete mode 100644 examples/notebooks/basic.py delete mode 100644 examples/notebooks/blog-images.py delete mode 100644 examples/notebooks/edit-poster.py delete mode 100644 examples/notebooks/film-showings.py delete mode 100644 examples/notebooks/first-graph.py delete mode 100644 examples/notebooks/image-game.py delete mode 100644 examples/notebooks/inpaint-poster.py delete mode 100644 examples/notebooks/interior-design.py delete mode 100644 examples/notebooks/interpolate.py delete mode 100644 examples/notebooks/logo-controlnet.py delete mode 100644 examples/notebooks/logo-inpaint.py delete mode 100644 examples/notebooks/poetry.lock delete mode 100644 examples/notebooks/prompt-enhance.py delete mode 100644 examples/notebooks/pyproject.toml delete mode 100644 examples/notebooks/svd.py delete mode 100755 examples/remove_bg_objects.py delete mode 100755 examples/streaming.py delete mode 100644 examples/streaming/fastapi-example/main.py create mode 100644 examples/techniques/README.md create mode 100644 examples/workshop/README.md rename examples/{ => workshop}/descript/__init__.py (100%) rename examples/{ => workshop}/descript/generate.py (100%) rename examples/{ => workshop}/descript/generate_chapters.py (100%) rename examples/{ => workshop}/descript/index.html (100%) rename examples/{ => workshop}/descript/util.py (100%) rename examples/{ => workshop}/mixture-of-agents/ask.py (100%) rename examples/{ => workshop}/mixture-of-agents/index.html (100%) rename examples/{ => workshop}/mixture-of-agents/util.py (100%) diff --git a/examples/background-removal.py b/examples/background-removal.py deleted file mode 100755 index be66681..0000000 --- a/examples/background-removal.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -import json - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import ( - Substrate, - EraseImage, - InpaintImage, - GenerateImage, - RemoveBackground, -) - -substrate = Substrate(api_key=api_key, timeout=60 * 5) -prompt = "by edward hopper, a red leather wing chair in an open room, pillars, amazing painting composition" -image = GenerateImage(prompt=prompt, store="hosted") -mask = RemoveBackground(image_uri=image.future.image_uri, return_mask=True, store="hosted") -bg = EraseImage(image_uri=image.future.image_uri, mask_image_uri=mask.future.image_uri, store="hosted") -bg_prompt = "by edward hopper, an empty room with pillars, amazing painting composition" -inpaint = InpaintImage(image_uri=bg.future.image_uri, prompt=bg_prompt, store="hosted") -result = substrate.run(inpaint) -viz = Substrate.visualize(inpaint) -os.system(f"open {viz}") - -print(json.dumps(result.json, indent=2)) diff --git a/examples/basic.py b/examples/basic.py deleted file mode 100755 index 1090c1f..0000000 --- a/examples/basic.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import sys -from pathlib import Path - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import Secrets, Substrate, ComputeText, sb - -substrate = Substrate( - api_key=api_key, - secrets=Secrets(openai="YOUR_OPENAI_KEY", anthropic="YOUR_ANTHROPIC_KEY"), -) - -story = ComputeText(prompt="tell me a story") -summary = ComputeText(prompt=sb.format(f"Summarize this story: {story}", story=story.future.text)) - -response = substrate.run(story, summary) -print(response) - -print("=== story") -story_out = response.get(story) -print(story_out.text) - -print("=== summary") -summary_out = response.get(summary) -print(summary_out.text) - -# viz = Substrate.visualize(ry) -# print(viz) diff --git a/examples/basic_embedding.py b/examples/basic_embedding.py deleted file mode 100755 index 69e189f..0000000 --- a/examples/basic_embedding.py +++ /dev/null @@ -1,50 +0,0 @@ -import os -import sys -import json -from pathlib import Path - -import requests - -response = requests.get("https://www.substrate.run/openapi.json") -openapi_spec = response.json() -openapi_version = openapi_spec["openapi"] -api_components = openapi_spec["components"]["schemas"] -api_nodes = openapi_spec["paths"] -cleaned_nodes = {key.replace("/", ""): value for key, value in api_nodes.items()} - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import Substrate, MultiEmbedText, DeleteVectorStore, FindOrCreateVectorStore - -substrate = Substrate(api_key=api_key, timeout=60 * 5) - -old_collection = DeleteVectorStore(collection_name="substrate_api_v2", model="jina-v2") - -collection = FindOrCreateVectorStore( - collection_name=old_collection.future.collection_name, - model=old_collection.future.model, -) - -components_embeddings = MultiEmbedText( - collection_name=collection.future.collection_name, - items=[ - {"doc_id": name, "text": json.dumps(component), "metadata": {"type": "component"}} - for name, component in api_components.items() - ], -) - -nodes_embeddings = MultiEmbedText( - collection_name=collection.future.collection_name, - items=[ - {"doc_id": node_name, "text": json.dumps(node), "metadata": {"type": "node"}} - for node_name, node in cleaned_nodes.items() - ], -) - -res = substrate.run(collection, components_embeddings, nodes_embeddings) diff --git a/examples/basic_rag.py b/examples/basic_rag.py deleted file mode 100644 index 4bb777c..0000000 --- a/examples/basic_rag.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import sys -from pathlib import Path - -from substrate.nodes import ComputeText - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import Substrate, QueryVectorStore, FindOrCreateVectorStore, sb - -substrate = Substrate(api_key=api_key, timeout=60 * 5) - -prompt_text = input("Enter a prompt: ") - -collection = FindOrCreateVectorStore(collection_name="substrate_api_v2", model="jina-v2") - -relevant_node = QueryVectorStore( - collection_name=collection.future.collection_name, - model=collection.future.model, - query_strings=[prompt_text], - top_k=1, - include_metadata=True, - include_values=True, - filters={"type": {"$eq": "node"}}, -) - -relevant_components = QueryVectorStore( - collection_name=collection.future.collection_name, - model=collection.future.model, - top_k=5, - query_vectors=[sb.jq(relevant_node.future.results, ".[0].[0].vector")], - include_metadata=True, - filters={"type": {"$eq": "component"}}, -) - -generated_text = ComputeText( - prompt=sb.concat( - """ -You are a helpful AI assistant. A user is going to ask you a question about -an AI platform called Substrate. Please use the following information to summarize -the key points about Substrate. The user is looking for a high-level overview of the -following resource: - """, - sb.concat(sb.jq(relevant_node.future.results, ".[0].[0].metadata.doc")), - "The user's question is:", - prompt_text, - ) -) - -res = substrate.stream(generated_text) -with open(sys.stdout.fileno(), "w") as stdout: - for item in res.iter(): - if item.data["object"] == "node.delta": - stdout.write(item.data.get("data", {}).get("text", "")) diff --git a/examples/basics/README.md b/examples/basics/README.md new file mode 100644 index 0000000..0f8e929 --- /dev/null +++ b/examples/basics/README.md @@ -0,0 +1 @@ +# Basic examples diff --git a/examples/explicit_edges.py b/examples/explicit_edges.py deleted file mode 100755 index d948a95..0000000 --- a/examples/explicit_edges.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -import sys -from pathlib import Path - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import RunPython, Substrate - -substrate = Substrate(api_key=api_key, timeout=60 * 5) - - -def print_time(): - import time - - return time.time() - - -a = RunPython(function=print_time) -a.id = "a" - -b = RunPython(function=print_time, _depends=[a]) -b.id = "b" - -c = RunPython(function=print_time, _depends=[a, b]) -c.id = "c" - -res = substrate.run(a, b, c) -print(res.json) diff --git a/examples/intro.py b/examples/intro.py deleted file mode 100755 index 345e809..0000000 --- a/examples/intro.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import sys -import json -from pathlib import Path - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import Substrate, ComputeText, GenerateImage, sb - -substrate = Substrate(api_key=api_key, timeout=60 * 5) - -scene = ComputeText(prompt="description of a mythical forest creature: ") - -styles = ["woodblock printed", "art nouveau poster"] -images = [GenerateImage(store="hosted", prompt=sb.concat(style, ": ", scene.future.text)) for style in styles] - -result = substrate.run(*images) - -print(json.dumps(result.json, indent=2)) - -viz = Substrate.visualize(*images) -os.system(f"open {viz}") diff --git a/examples/media_pipe.py b/examples/media_pipe.py deleted file mode 100755 index 9a17d62..0000000 --- a/examples/media_pipe.py +++ /dev/null @@ -1,27 +0,0 @@ -import os -import json - -from substrate import Substrate, Firellava13B, GenerateImage, sb - -api_key = os.environ.get("SUBSTRATE_API_KEY") -substrate = Substrate(api_key=api_key, timeout=60 * 5) -schema = { - "type": "object", - "properties": { - "main_object": {"type": "string"}, - "replacement": {"type": "string"}, - }, - "required": ["main_object"], -} -image_uri = "https://media.substrate.run/desk.jpeg" - -replacement = Firellava13B( - prompt="Identify the main object in the image. Then think of something funny to replace it with. Respond with the replacement. Your answer should be only one or two words.", - image_uris=[image_uri], -) -image = GenerateImage(prompt=sb.concat("a picture of a ", replacement.future.text), image_uri=image_uri, store="hosted") -result = substrate.run(image) -viz = Substrate.visualize(image) -os.system(f"open {viz}") - -print(json.dumps(result.json, indent=2)) diff --git a/examples/notebooks/IBMPlexSans-Medium.ttf b/examples/notebooks/IBMPlexSans-Medium.ttf deleted file mode 100644 index 9395402b0ae00fa731c4ad63958a41dff26d9344..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177104 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 diff --git a/examples/notebooks/Makefile b/examples/notebooks/Makefile deleted file mode 100644 index bb36a7d..0000000 --- a/examples/notebooks/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.DEFAULT_GOAL := help -SHELL := /bin/bash - -default: help; - -.PHONY: help -help: - @echo "Substrate notebooks" - @echo "" - @echo " ensure Install dependencies" - @echo " update Update substrate-python to the latest version" - -poetry.lock: pyproject.toml - poetry lock - -ensure: poetry.lock - poetry install --no-root - -.PHONY: update -update: - poetry cache clear pypi --all && poetry update substrate diff --git a/examples/notebooks/background-removal.py b/examples/notebooks/background-removal.py deleted file mode 100644 index 2a88eaf..0000000 --- a/examples/notebooks/background-removal.py +++ /dev/null @@ -1,125 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(): - import os - import json - import base64 - import marimo as mo - from substrate import ( - Substrate, - GenerateImage, - RemoveBackground, - InpaintImage, - EraseImage, - UpscaleImage, - sb, - ) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - substrate = Substrate( - api_key=api_key, - ) - return ( - EraseImage, - GenerateImage, - InpaintImage, - RemoveBackground, - Substrate, - UpscaleImage, - api_key, - base64, - json, - mo, - os, - sb, - substrate, - ) - - -@app.cell -def __(mo): - prompt = mo.ui.text( - placeholder="prompt", - value="a dark red chesterfield leather wing chair in a dark majestic room, pillars, celestial galaxy wallpaper", - full_width=True, - ).form() - prompt - return prompt, - - -@app.cell -def __(EraseImage, GenerateImage, InpaintImage, RemoveBackground, prompt): - image = GenerateImage( - prompt=prompt.value, - ) - fg = RemoveBackground(image_uri=image.future.image_uri) - mask = RemoveBackground( - image_uri=image.future.image_uri, - return_mask=True, - ) - bg = EraseImage( - image_uri=image.future.image_uri, - mask_image_uri=mask.future.image_uri, - ) - bg_prompt = "empty dark majestic room, celestial galaxy wallpaper, high resolution AD" - inpaint = InpaintImage(image_uri=bg.future.image_uri, prompt=bg_prompt) - return bg, bg_prompt, fg, image, inpaint, mask - - -@app.cell -def __(bg, fg, image, inpaint, mask, mo, substrate, upscale): - viz = substrate.visualize(image, fg, mask, bg, inpaint, upscale) - mo.md(f"[viz]({viz})") - return viz, - - -@app.cell -def __(bg, fg, image, inpaint, mask, mo, substrate, upscale): - res = substrate.run(image, fg, mask, bg, inpaint, upscale) - print(res) - mo.tree(res.json) - return res, - - -@app.cell -def __(bg, fg, image, inpaint, mask, mo, res): - mo.carousel( - items=[ - mo.vstack( - [ - mo.image(src=res.get(image).image_uri), - ] - ), - mo.vstack( - [ - mo.image(src=res.get(fg).image_uri), - ] - ), - mo.vstack( - [ - mo.image(src=res.get(mask).image_uri), - ] - ), - mo.vstack( - [ - mo.image(src=res.get(bg).image_uri), - ] - ), - mo.vstack( - [ - mo.image(src=res.get(inpaint).image_uri), - ] - ), - ] - ) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/basic.py b/examples/notebooks/basic.py deleted file mode 100644 index e52b347..0000000 --- a/examples/notebooks/basic.py +++ /dev/null @@ -1,57 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App() - - -@app.cell -def __(): - import os - import json - import base64 - - import marimo as mo - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - api_key - return api_key, base64, json, mo, os - - -@app.cell -def __(api_key): - from substrate import Substrate, ComputeText, Box, If, sb - - substrate = Substrate(api_key=api_key) - return Box, ComputeText, If, Substrate, sb, substrate - - -@app.cell -def __(Box, ComputeText): - story = ComputeText(prompt="tell me a story") - box = Box(value={ - "story": story.future.text - }) - return box, story - - -@app.cell -def __(box, story, substrate): - res = substrate.run(story, box) - return res, - - -@app.cell -def __(box, mo, res): - mo.tree(res.get(box).value) - return - - -@app.cell -def __(mo, res, story): - mo.md(res.get(story).text) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/blog-images.py b/examples/notebooks/blog-images.py deleted file mode 100644 index d453b44..0000000 --- a/examples/notebooks/blog-images.py +++ /dev/null @@ -1,208 +0,0 @@ -import marimo - -__generated_with = "0.6.23" -app = marimo.App(width="medium") - - -@app.cell -def __(): - import marimo as mo - return mo, - - -@app.cell -def __(mo): - from PIL import Image, ImageDraw, ImageFont - from io import BytesIO - import os - import base64 - from textwrap import dedent - - text = """tasteful AI - marketing image""" - width = 1944 - height = 1024 - image = Image.new("RGB", (width, height), color="white") - draw = ImageDraw.Draw(image) - try: - font = ImageFont.truetype("examples/notebooks/IBMPlexSans-Medium.ttf", 200) - except IOError: - print("couldn't load font") - font = ImageFont.load_default(200) - - bbox = draw.textbbox((0, 0), text, font=font) - text_width = bbox[2] - bbox[0] - text_height = bbox[3] - bbox[1] - - x = (width - text_width) / 2 - y = (height - text_height) / 2 - draw.text((x, y), text, font=font, fill="black") - buffered = BytesIO() - image.save(buffered, format="PNG") - - img_str = base64.b64encode(buffered.getvalue()) - base_img_data = f"data:image/png;base64,{img_str.decode('ascii')}" - mo.image(base_img_data) - return ( - BytesIO, - Image, - ImageDraw, - ImageFont, - base64, - base_img_data, - bbox, - buffered, - dedent, - draw, - font, - height, - image, - img_str, - os, - text, - text_height, - text_width, - width, - x, - y, - ) - - -@app.cell -def __(os): - from substrate import ( - Substrate, - GenerateImage, - StableDiffusionXLControlNet, - RemoveBackground, - UpscaleImage, - ) - api_key = os.environ.get("SUBSTRATE_API_KEY") - substrate = Substrate(api_key=api_key) - return ( - GenerateImage, - RemoveBackground, - StableDiffusionXLControlNet, - Substrate, - UpscaleImage, - api_key, - substrate, - ) - - -@app.cell -def __( - RemoveBackground, - StableDiffusionXLControlNet, - UpscaleImage, - base_img_data, - substrate, -): - mask = RemoveBackground( - image_uri=base_img_data, - return_mask=True, - ) - prompt = "birds eye aerial view of clouds and ocean waves at sunset" - controlnet = StableDiffusionXLControlNet( - image_uri=mask.future.image_uri, - prompt=prompt, - control_method="illusion", - conditioning_scale=0.9, - strength=0.6, - num_images=1, - ) - upscale = UpscaleImage( - image_uri=controlnet.future.outputs[0].image_uri, - prompt=f"hokusai highly detailed woodblock print, bright colors {prompt}", - output_resolution=2048, - ) - res = substrate.run(upscale) - return controlnet, mask, prompt, res, upscale - - -@app.cell -def __(controlnet, mask, mo, res, upscale): - mo.vstack( - [ - mo.hstack( - [ - mo.image(res.get(mask).image_uri), - mo.image(res.get(controlnet).outputs[0].image_uri), - ] - ), - mo.image(res.get(upscale).image_uri), - ] - ) - return - - -@app.cell -def __(BytesIO, Image, ImageDraw, base64, font, height, text, width, x, y): - import re - import numpy as np - from PIL import ImageChops - - - def dilate(image, iterations=1): - image_array = np.array(image) - kernel = np.ones((3, 3), np.uint8) - for _ in range(iterations): - image_array = np.pad(image_array, 1, mode="constant") - dilated = np.zeros_like(image_array) - for i in range(1, image_array.shape[0] - 1): - for j in range(1, image_array.shape[1] - 1): - dilated[i, j] = np.max(image_array[i - 1 : i + 2, j - 1 : j + 2] * kernel) - image_array = dilated[1:-1, 1:-1] - return Image.fromarray(image_array) - - - def draw_text(img, x, y, text, font, outline_color, outline_width=2): - text_img = Image.new("L", img.size, 0) - text_draw = ImageDraw.Draw(text_img) - text_draw.text((x, y), text, font=font, fill=255) - outline_img = dilate(text_img, iterations=outline_width) - hollow_outline = ImageChops.subtract(outline_img, text_img) - outline_rgba = Image.new("RGBA", img.size, (0, 0, 0, 0)) - outline_rgba.putalpha(hollow_outline) - colored_outline = Image.new("RGBA", img.size, outline_color) - colored_outline.putalpha(hollow_outline) - result = Image.alpha_composite(img, colored_outline) - return result - - - def final_image(image_uri): - base64_string = re.sub(r"^data:image/.+;base64,", "", image_uri) - image_data = base64.b64decode(base64_string) - original_image = Image.open(BytesIO(image_data)).convert("RGBA") - resized_image = original_image.resize((width, height), Image.LANCZOS) - finalimg = Image.new("RGBA", resized_image.size, (255, 255, 255, 0)) - finalimg.paste(resized_image, (0, 0), resized_image) - - outline_color = (255, 255, 255, 255) - outline_width = 3 - - finalimg = draw_text(finalimg, x, y, text, font, outline_color, outline_width) - - finalbuff = BytesIO() - finalimg.save(finalbuff, format="PNG") - finalimg_str = base64.b64encode(finalbuff.getvalue()).decode("ascii") - return f"data:image/png;base64,{finalimg_str}" - return ImageChops, dilate, draw_text, final_image, np, re - - -@app.cell -def __(): - # controlnet_final = final_image(res.get(controlnet).outputs[0].image_uri) - # mo.image(controlnet_final) - return - - -@app.cell -def __(): - # upscale_final = final_image(res.get(upscale).image_uri) - # mo.image(upscale_final) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/edit-poster.py b/examples/notebooks/edit-poster.py deleted file mode 100644 index d936fcf..0000000 --- a/examples/notebooks/edit-poster.py +++ /dev/null @@ -1,143 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - return Path, api_key, mo, os, parent_dir, sys, typing_extensions - - -@app.cell -def __(): - from substrate import ( - Substrate, - StableDiffusionXLControlNet, - GenerativeEditImage, - MultiGenerativeEditImage, - UpscaleImage, - RemoveBackground, - RunPython, - ) - return ( - GenerativeEditImage, - MultiGenerativeEditImage, - RemoveBackground, - RunPython, - StableDiffusionXLControlNet, - Substrate, - UpscaleImage, - ) - - -@app.cell -def __(Substrate, api_key): - substrate = Substrate(api_key=api_key) - return substrate, - - -@app.cell -def __( - MultiGenerativeEditImage, - RemoveBackground, - RunPython, - StableDiffusionXLControlNet, - substrate, -): - # original = "https://blog.substrate.run/launch-image.png" - original = "https://media.substrate.run/spc-tw.png" - controlnet = StableDiffusionXLControlNet( - image_uri=original, - control_method="edge", - prompt="neon lights, retro futuristic 80s club", - conditioning_scale=1.0, - num_images=1, - ) - mask = RemoveBackground( - image_uri=original, - return_mask=True, - store="hosted", - ) - crop = RunPython( - input={ - "image": mask.future.image_uri, - }, - pip_install=["requests", "pillow"], - code="""# get the bottom left portion of the mask - from PIL import Image - from io import BytesIO - import base64, requests - response = requests.get(SB_IN["image"]) - img = Image.open(BytesIO(response.content)) - full = 800 - section = 550 - bg = Image.new('RGB', (full, full), (0, 0, 0)) - cropped = img.crop((0, full - section, section, full)) - bg.paste(cropped, (0, full - section)) - buffer = BytesIO() - bg.save(buffer, format="jpeg") - b64 = base64.b64encode(buffer.getvalue()).decode("utf-8") - SB_OUT["image"] = f"data:image/jpeg;base64,{b64}" - """, - ) - num_images = 3 - edit = MultiGenerativeEditImage( - image_uri=controlnet.future.outputs[0].image_uri, - mask_image_uri=crop.future.output["image"], - prompt="bright white mirrored metallic water surface high resolution CG render", - num_images=num_images, - ) - res = substrate.run(controlnet, mask, crop, edit) - return controlnet, crop, edit, mask, num_images, original, res - - -@app.cell -def __(crop, mo, res): - mo.download(res.get(crop).output["image"]) - return - - -@app.cell -def __(mo, res): - mo.tree(res.json) - return - - -@app.cell -def __(edit, mo, num_images, res): - mo.hstack( - [ - mo.image(res.get(edit).outputs[i].image_uri) - for i in list(range(num_images)) - ] - ) - return - - -@app.cell -def __(edit, mo, num_images, res): - mo.hstack( - [ - mo.download(res.get(edit).outputs[i].image_uri) - for i in list(range(num_images)) - ] - ) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/film-showings.py b/examples/notebooks/film-showings.py deleted file mode 100644 index c4d3621..0000000 --- a/examples/notebooks/film-showings.py +++ /dev/null @@ -1,193 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="full") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - from substrate import ( - Substrate, - GenerateJSON, - GenerateText, - RunPython, - sb, - ) - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - - substrate = Substrate(api_key=api_key) - return ( - GenerateJSON, - GenerateText, - Path, - RunPython, - Substrate, - api_key, - mo, - os, - parent_dir, - sb, - substrate, - sys, - typing_extensions, - ) - - -@app.cell -def __(): - return - - -@app.cell -def __(): - import requests, re - from bs4 import BeautifulSoup - from datetime import datetime, timedelta - - today = datetime.today() - tomorrow = today + timedelta(days=1) - today_str = today.strftime("%Y-%m-%d") - tomorrow_str = tomorrow.strftime("%Y-%m-%d") - - response = requests.get(f"https://metrograph.com/calendar") - soup = BeautifulSoup(response.text, "html.parser") - pattern = r"^/film/\?vista_film_id=" - pattern_re = re.compile(pattern) - urls = [] - today_el = soup.find(id=f"calendar-list-day-{today_str}") - tomorrow_el = soup.find(id=f"calendar-list-day-{tomorrow_str}") - for anchor in today_el.find_all("a", href=True): - if pattern_re.match(anchor["href"]): - urls.append(f"https://metrograph.com{anchor['href']}") - for anchor in tomorrow_el.find_all("a", href=True): - if pattern_re.match(anchor["href"]): - urls.append(f"https://metrograph.com{anchor['href']}") - urls = list(set(urls)) - return ( - BeautifulSoup, - anchor, - datetime, - pattern, - pattern_re, - re, - requests, - response, - soup, - timedelta, - today, - today_el, - today_str, - tomorrow, - tomorrow_el, - tomorrow_str, - urls, - ) - - -@app.cell -def __(mo, urls): - mo.tree(urls) - return - - -@app.cell -def __(): - from pydantic import BaseModel, Field - return BaseModel, Field - - -@app.cell -def __( - BaseModel, - Field, - GenerateJSON, - GenerateText, - RunPython, - sb, - substrate, - urls, -): - summaries = [] - mds = [] - import json - - - class Film(BaseModel): - title: str = Field(..., description="The film's title") - url: str = Field(..., description="The film's url from the top of the text") - description: str = Field(..., description="A short summary of the film including genre, director, and year.") - showtimes: list[str] = Field(..., description="List of showtimes for the film.") - - - for url in urls[:1]: - md = RunPython( - input={ - "url": url, - }, - code="""import requests - from bs4 import BeautifulSoup - from markdownify import markdownify - url = SB_IN['url'] - print(url) - res = requests.get(url) - soup = BeautifulSoup(res.content, 'html.parser') - SB_OUT['markdown'] = markdownify(str(soup)) - """, - pip_install=["requests", "beautifulsoup4", "markdownify"], - ) - - mds.append(md) - - summary = GenerateJSON( - prompt=sb.concat( - "Summarize the following markdown about a film playing at local theater, generating JSON following the schema below\n ", - md.future.output["markdown"], - ), - json_schema=Film.model_json_schema(), - node="Llama3Instruct8B", - ) - summaries.append(summary) - - markdown = GenerateText( - prompt=sb.concat( - "Generate markdown summarizing the following movies. Include title in brackets followed by the url of the film in parentheses, e.g. [title](url). Do not mix up urls. Include a very concise one sentence description. Do not include the theater where the film is playing. Include showtimes. Today is the earliest date that appears, replace the appropriate dates with TODAY and TOMORROW. Do not include preamble before the markdown. Categorize the movies into a few genres.\n", - *[sb.jq(s.future.json_object, "@json") for s in summaries], - ), - node="Llama3Instruct70B", - ) - res = substrate.run(*summaries, *mds, markdown) - return Film, json, markdown, md, mds, res, summaries, summary, url - - -@app.cell -def __(mo, res): - mo.tree(res.json) - return - - -@app.cell -def __(markdown, mo, res): - mo.md(res.get(markdown).text) - return - - -@app.cell -def __(markdown, res): - print(res.get(markdown).text) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/first-graph.py b/examples/notebooks/first-graph.py deleted file mode 100644 index a3000c2..0000000 --- a/examples/notebooks/first-graph.py +++ /dev/null @@ -1,68 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App() - - -@app.cell -def __(): - import os - import json - import base64 - - import marimo as mo - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - api_key - return api_key, base64, json, mo, os - - -@app.cell -def __(api_key): - from substrate import Substrate, GenerateImage, GenerateText, sb - - substrate = Substrate(api_key=api_key) - return GenerateImage, GenerateText, Substrate, sb, substrate - - -@app.cell -def __(GenerateImage, GenerateText, sb, substrate): - scene = GenerateText( - prompt="a short detailed descriptions of a mythical forest creature: ", - ) - styles = ["woodblock printed", "art nouveau poster"] - images = [ - GenerateImage(prompt=sb.concat("render in a ", style, " style: ", scene.future.text)) - for style in styles - ] - - result = substrate.run(scene, *images) - return images, result, scene, styles - - -@app.cell -def __(mo, result): - mo.tree(result.api_response.json) - return - - -@app.cell -def __(): - return - - -@app.cell -def __(images, mo, result): - mo.download(result.get(images[0]).image_uri) - return - - -@app.cell -def __(images, mo, result): - mo.download(result.get(images[1]).image_uri) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/image-game.py b/examples/notebooks/image-game.py deleted file mode 100644 index d859bf0..0000000 --- a/examples/notebooks/image-game.py +++ /dev/null @@ -1,236 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(): - # enter your API key (or store it in the SUBSTRATE_API_KEY env var) - import os - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - return api_key, os - - -@app.cell(hide_code=True) -def __(api_key): - # import modules + initialize substrate - import time - import datetime - import json - import string - import random - import base64 - import marimo as mo - import substrate as sb - - substrate = sb.Substrate(api_key=api_key) - return base64, datetime, json, mo, random, sb, string, substrate, time - - -@app.cell -def __(datetime, mo, sb, substrate): - # create a vector store - now = datetime.datetime.now() - start_of_day = now.replace(hour=0, minute=0, second=0, microsecond=0) - start_of_day_ts = int(start_of_day.timestamp()) - collection_name = f"image_test_{start_of_day_ts}" - mo.md(f"collection name: {collection_name}") - create_vstore = sb.CreateVectorStore(model="clip", collection_name=collection_name) - create_res = substrate.run(create_vstore) - mo.accordion({"response": mo.tree(create_res.json)}) - return ( - collection_name, - create_res, - create_vstore, - now, - start_of_day, - start_of_day_ts, - ) - - -@app.cell(hide_code=True) -def __(mo): - prompt = mo.ui.text( - placeholder="prompt", - label="Enter a secret image prompt", - value="A bowl of fruit", - kind="password", - full_width=True, - ).form() - prompt - return (prompt,) - - -@app.cell -def __(collection_name, mo, prompt, sb, substrate): - # generate an image and embed it - image = sb.GenerateImage( - prompt=prompt.value, - ) - embed = sb.EmbedImage( - image_uri=image.future.image_uri, - collection_name=collection_name, - ) - res = substrate.run(image, embed) - mo.accordion({"response": mo.tree(res.json)}) - return embed, image, res - - -@app.cell(hide_code=True) -def __(embed, image, mo, res): - mo.vstack( - [ - mo.image(src=res.get(image).image_uri, width=400), - mo.md(f"embedding id: `{res.get(embed).embedding.doc_id}`"), - ] - ) - return - - -@app.cell -def __(mo): - guesses = ( - mo.md( - """ - ### Let two other people try to generate a similar image: - - Guess prompt 1 {guess1} - - Guess prompt 2 {guess2} - """ - ) - .batch(guess1=mo.ui.text(full_width=True), guess2=mo.ui.text(full_width=True)) - .form() - ) - guesses - return (guesses,) - - -@app.cell -def __(collection_name, guesses, sb): - # Generate and embed the images - guess1image = sb.GenerateImage( - prompt=guesses.value["guess1"], - ) - guess2image = sb.GenerateImage( - prompt=guesses.value["guess2"], - ) - embed1 = sb.EmbedImage( - image_uri=guess1image.future.image_uri, - collection_name=collection_name, - ) - embed2 = sb.EmbedImage( - image_uri=guess2image.future.image_uri, - collection_name=collection_name, - ) - return embed1, embed2, guess1image, guess2image - - -@app.cell -def __(embed1, embed2, guess1image, guess2image, mo, substrate): - guess_res = substrate.run(guess1image, guess2image, embed1, embed2) - mo.accordion({"response": mo.tree(guess_res.json)}) - return (guess_res,) - - -@app.cell -def __(embed1, embed2, guess_res, mo): - image1_embed_id = guess_res.get(embed1).embedding.doc_id - image2_embed_id = guess_res.get(embed2).embedding.doc_id - mo.accordion({"ids": mo.tree({"image1": image1_embed_id, "image2": image2_embed_id})}) - return image1_embed_id, image2_embed_id - - -@app.cell -def __(collection_name, guess1image, guess2image, guess_res, sb): - # query with the embeddings of the two image guesses - query = sb.QueryVectorStore( - model="clip", - collection_name=collection_name, - query_image_uris=[ - guess_res.get(guess1image).image_uri, - guess_res.get(guess2image).image_uri, - ], - top_k=100, - ef_search=64, - ) - return (query,) - - -@app.cell -def __(mo, query, substrate): - query_res = substrate.run(query) - query_items = query_res.get(query).results - mo.accordion({"items": mo.tree(query_items)}) - return query_items, query_res - - -@app.cell -def __(embed, mo, query_items, res): - # get the similarity of the two guesses to the original image - orig_embed_id = res.get(embed).embedding.doc_id - match1 = next((i for i in query_items[0] if i.id == orig_embed_id), None) - match2 = next((i for i in query_items[1] if i.id == orig_embed_id), None) - match1_wins = match1.distance < match2.distance - - mo.accordion( - { - "result": mo.tree( - { - "orig_embed_id": orig_embed_id, - "image1_distance": match1.distance, - "image2_distance": match2.distance, - "match1_wins": match1_wins, - } - ) - } - ) - return match1, match1_wins, match2, orig_embed_id - - -@app.cell -def __( - guess1image, - guess2image, - guess_res, - guesses, - image, - match1, - match1_wins, - match2, - mo, - prompt, - res, -): - mo.hstack( - [ - mo.vstack( - [ - mo.image(src=res.get(image).image_uri), - mo.md(f"Original prompt: {prompt.value}"), - ] - ), - mo.vstack( - [ - mo.image(src=guess_res.get(guess1image).image_uri), - mo.md(f"Guess 1: {guesses.value['guess1']}"), - mo.md(f"Distance: {match1.distance}"), - mo.md(f"**{'WINNER' if match1_wins else 'LOSER'}**"), - ] - ), - mo.vstack( - [ - mo.image(src=guess_res.get(guess2image).image_uri), - mo.md(f"Guess 2: {guesses.value['guess2']}"), - mo.md(f"Distance: {match2.distance}"), - mo.md(f"**{'LOSER' if match1_wins else 'WINNER'}**"), - ] - ), - ] - ) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/inpaint-poster.py b/examples/notebooks/inpaint-poster.py deleted file mode 100644 index 93547bc..0000000 --- a/examples/notebooks/inpaint-poster.py +++ /dev/null @@ -1,127 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - return Path, api_key, mo, os, parent_dir, sys, typing_extensions - - -@app.cell -def __(api_key): - from substrate import ( - Substrate, - RemoveBackground, - MultiGenerativeEditImage, - StableDiffusionXLInpaint, - UpscaleImage, - RunPython, - ) - - substrate = Substrate(api_key=api_key) - return ( - MultiGenerativeEditImage, - RemoveBackground, - RunPython, - StableDiffusionXLInpaint, - Substrate, - UpscaleImage, - substrate, - ) - - -@app.cell -def __(RemoveBackground, RunPython, StableDiffusionXLInpaint, substrate): - original_image = "https://media.substrate.run/spc-tw.png" - mask = RemoveBackground( - image_uri=original_image, - return_mask=True, - store="hosted", - ) - crop = RunPython( - input={ - "image": mask.future.image_uri, - }, - pip_install=["requests", "pillow"], - code="""# get the bottom left portion of the mask - from PIL import Image - from io import BytesIO - import base64, requests - response = requests.get(SB_IN["image"]) - img = Image.open(BytesIO(response.content)) - full = 800 - section = 550 - bg = Image.new('RGB', (full, full), (0, 0, 0)) - cropped = img.crop((0, full - section, section, full)) - bg.paste(cropped, (0, full - section)) - buffer = BytesIO() - bg.save(buffer, format="jpeg") - b64 = base64.b64encode(buffer.getvalue()).decode("utf-8") - SB_OUT["image"] = f"data:image/jpeg;base64,{b64}" - """, - ) - edit = StableDiffusionXLInpaint( - image_uri="https://media.substrate.run/spc-tw.png", - mask_image_uri=crop.future.output["image"], - strength=0.92, - prompt="retro computer with black and red smoke and flames billowing out of the screen, high resolution poster", - negative_prompt="rainbow, paint", - store="hosted", - num_images=5, - ) - res = substrate.run(mask, crop, edit) - return crop, edit, mask, original_image, res - - -@app.cell -def __(crop, mask, mo, original_image, res): - mo.hstack( - [ - mo.image(original_image), - mo.image(res.get(mask).image_uri), - mo.image(res.get(crop).output["image"]), - ] - ) - return - - -@app.cell -def __(edit, mo, res): - mo.hstack([ - mo.image(res.get(edit).outputs[0].image_uri), - mo.image(res.get(edit).outputs[1].image_uri), - mo.image(res.get(edit).outputs[2].image_uri), - mo.image(res.get(edit).outputs[3].image_uri), - mo.image(res.get(edit).outputs[4].image_uri), - ]) - return - - -@app.cell -def __(edit, mo, res): - mo.hstack([ - res.get(edit).outputs[0].seed, - res.get(edit).outputs[1].seed, - res.get(edit).outputs[2].seed, - res.get(edit).outputs[3].seed, - ]) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/interior-design.py b/examples/notebooks/interior-design.py deleted file mode 100644 index 73d1227..0000000 --- a/examples/notebooks/interior-design.py +++ /dev/null @@ -1,167 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - return Path, api_key, mo, os, parent_dir, sys, typing_extensions - - -@app.cell -def __(api_key): - from substrate import ( - Substrate, - StableDiffusionXLControlNet, - StableDiffusionXLInpaint, - GenerativeEditImage, - GenerateTextVision, - GenerateText, - sb, - ) - - substrate = Substrate(api_key=api_key) - return ( - GenerateText, - GenerateTextVision, - GenerativeEditImage, - StableDiffusionXLControlNet, - StableDiffusionXLInpaint, - Substrate, - sb, - substrate, - ) - - -@app.cell -def __( - GenerateText, - GenerateTextVision, - StableDiffusionXLInpaint, - sb, - substrate, -): - styles = ["sunlit onsen style tokyo office", "80s disco style berlin office at night"] - images = [ - StableDiffusionXLInpaint( - image_uri="https://media.substrate.run/office.jpg", - # control_method="depth", - strength=0.75, - prompt=s, - num_images=1, - ) - for s in styles - ] - descriptions = [ - GenerateTextVision( - prompt="Describe the interesting interior decor touches in this image", - # image_uris=[i.future.image_uri], - image_uris=[i.future.outputs[0].image_uri], - ) - for i in images - ] - summaries = [ - GenerateText( - prompt=sb.concat( - "Summarize the 2 most interesting details in one sentence, be concise: ", - d.future.text, - ), - ) - for d in descriptions - ] - res = substrate.run(*images, *descriptions, *summaries) - return descriptions, images, res, styles, summaries - - -@app.cell -def __(mo, res): - mo.tree(res.json) - return - - -@app.cell -def __(mo, original_image): - mo.image(original_image) - return - - -@app.cell -def __(images, mo, res, summaries): - mo.vstack( - [ - mo.vstack( - [ - mo.image(res.get(images[0]).image_uri), - mo.md(res.get(summaries[0]).text), - ] - ), - mo.vstack( - [ - mo.image(res.get(images[1]).image_uri), - mo.md(res.get(summaries[1]).text), - ] - ), - ] - ) - return - - -@app.cell -def __(images, mo, res, summaries): - mo.vstack( - [ - mo.vstack( - [ - mo.image(res.get(images[0]).outputs[0].image_uri), - mo.md(res.get(summaries[0]).text), - ] - ), - mo.vstack( - [ - mo.image(res.get(images[1]).outputs[0].image_uri), - mo.md(res.get(summaries[1]).text), - ] - ), - ] - ) - return - - -@app.cell -def __(images, mo, res): - mo.hstack( - [ - mo.download(res.get(images[0]).image_uri), - mo.download(res.get(images[1]).image_uri), - ] - ) - return - - -@app.cell -def __(images, mo, res): - mo.hstack( - [ - mo.download(res.get(images[0]).outputs[0].image_uri), - mo.download(res.get(images[1]).outputs[0].image_uri), - ] - ) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/interpolate.py b/examples/notebooks/interpolate.py deleted file mode 100644 index e34fb55..0000000 --- a/examples/notebooks/interpolate.py +++ /dev/null @@ -1,112 +0,0 @@ -import marimo - -__generated_with = "0.6.23" -app = marimo.App() - - -@app.cell -def __(): - import os - import json - - import marimo as mo - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - print(api_key) - return api_key, json, mo, os - - -@app.cell -def __(api_key): - from substrate import Substrate - - substrate = Substrate(api_key=api_key, base_url="https://api.substrate.run") - return Substrate, substrate - - -@app.cell -def __(substrate): - from substrate import GenerateImage, InterpolateFrames, StableDiffusionXLInpaint - - # Generate a base image - base_image = GenerateImage(prompt="aerial view of ocean waves") - - # Generate variations - times = [ - "6am sunrise", - "1pm afternoon bright sun", - "8pm after sunset", - ] - images = [] - for t in times: - image = StableDiffusionXLInpaint( - image_uri=base_image.future.image_uri, - prompt=f"aerial view of rainforest, {t}", - num_images=1, - strength=0.9, - ) - images.append(image) - - # Interpolate from base through variations - interpolate = InterpolateFrames( - frame_uris=[ - base_image.future.image_uri, - images[0].future.outputs[0].image_uri, - images[1].future.outputs[0].image_uri, - images[2].future.outputs[0].image_uri, - base_image.future.image_uri, - ], - num_steps=2, - store="hosted", - output_format="mp4", - ) - res = substrate.run(interpolate) - return ( - GenerateImage, - InterpolateFrames, - StableDiffusionXLInpaint, - base_image, - image, - images, - interpolate, - res, - t, - times, - ) - - -@app.cell -def __(res): - print(res.request_id) - print(res) - return - - -@app.cell -def __(interpolate, res): - print(res.get(interpolate).video_uri) - return - - -@app.cell -def __(interpolate, mo, res): - mo.image(res.get(interpolate).video_uri) - return - - -@app.cell -def __(images, mo, res): - mo.vstack( - [ - mo.image(res.get(images[0]).outputs[0].image_uri), - mo.image(res.get(images[1]).outputs[0].image_uri), - mo.image(res.get(images[2]).outputs[0].image_uri), - mo.image(res.get(images[3]).outputs[0].image_uri), - ] - ) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/logo-controlnet.py b/examples/notebooks/logo-controlnet.py deleted file mode 100644 index f351757..0000000 --- a/examples/notebooks/logo-controlnet.py +++ /dev/null @@ -1,72 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - return Path, api_key, mo, os, parent_dir, sys, typing_extensions - - -@app.cell -def __(api_key): - from substrate import ( - Substrate, - RemoveBackground, - StableDiffusionXLControlNet, - UpscaleImage, - ) - - s = Substrate(api_key=api_key) - return ( - RemoveBackground, - StableDiffusionXLControlNet, - Substrate, - UpscaleImage, - s, - ) - - -@app.cell -def __(RemoveBackground, StableDiffusionXLControlNet, s): - num_images = 2 - mask = RemoveBackground(image_uri="https://media.substrate.run/logo-sq.png", return_mask=True) - controlnet = StableDiffusionXLControlNet( - image_uri=mask.future.image_uri, - control_method="illusion", - conditioning_scale=1.0, - prompt="street view futuristic solarpunk city of atlantis", - num_images=num_images, - ) - res = s.run(mask, controlnet) - return controlnet, mask, num_images, res - - -@app.cell -def __(controlnet, mo, num_images, res): - mo.hstack([mo.image(res.get(controlnet).outputs[i].image_uri) for i in list(range(num_images))]) - return - - -@app.cell -def __(controlnet, mo, num_images, res): - mo.hstack([mo.download(res.get(controlnet).outputs[i].image_uri) for i in list(range(num_images))]) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/logo-inpaint.py b/examples/notebooks/logo-inpaint.py deleted file mode 100644 index 79c2ce6..0000000 --- a/examples/notebooks/logo-inpaint.py +++ /dev/null @@ -1,103 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - return Path, api_key, mo, os, parent_dir, sys, typing_extensions - - -@app.cell -def __(api_key): - from substrate import ( - Substrate, - RemoveBackground, - StableDiffusionXLControlNet, - StableDiffusionXLInpaint, - GenerativeEditImage, - ) - - s = Substrate(api_key=api_key) - return ( - GenerativeEditImage, - RemoveBackground, - StableDiffusionXLControlNet, - StableDiffusionXLInpaint, - Substrate, - s, - ) - - -@app.cell -def __( - RemoveBackground, - StableDiffusionXLControlNet, - StableDiffusionXLInpaint, - mo, - s, -): - original = "https://media.substrate.run/logo-sq.png" - mask = RemoveBackground(image_uri=original, return_mask=True) - controlnet = StableDiffusionXLControlNet( - image_uri=original, - control_method="edge", - prompt="bright silver disco high contrast", - conditioning_scale=0.8, - num_images=1, - ) - inpaint = StableDiffusionXLInpaint( - image_uri=controlnet.future.outputs[0].image_uri, - mask_image_uri=mask.future.image_uri, - prompt="towers in the futuristic ancient solarpunk city of atlantis", - num_images=2, - ) - res = s.run(mask, controlnet, inpaint) - mo.tree(res.json) - return controlnet, inpaint, mask, original, res - - -@app.cell -def __(controlnet, mo, res): - mo.image(res.get(controlnet).outputs[0].image_uri) - return - - -@app.cell -def __(inpaint, mo, res): - mo.image(res.get(inpaint).outputs[0].image_uri) - return - - -@app.cell -def __(inpaint, mo, res): - mo.image(res.get(inpaint).outputs[1].image_uri) - return - - -@app.cell -def __(controlnet, inpaint, mo, res): - mo.hstack([ - mo.download(res.get(controlnet).outputs[0].image_uri), - mo.download(res.get(inpaint).outputs[0].image_uri), - mo.download(res.get(inpaint).outputs[1].image_uri), - ]) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/poetry.lock b/examples/notebooks/poetry.lock deleted file mode 100644 index 77ab2ff..0000000 --- a/examples/notebooks/poetry.lock +++ /dev/null @@ -1,937 +0,0 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.6.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, -] - -[[package]] -name = "anyio" -version = "4.3.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -files = [ - {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, - {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "black" -version = "24.4.2" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, - {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, - {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, - {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, - {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, - {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, - {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, - {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, - {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, - {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, - {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, - {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, - {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, - {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, - {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, - {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, - {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, - {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, - {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, - {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, - {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, - {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "certifi" -version = "2024.2.2" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "cloudpickle" -version = "3.0.0" -description = "Pickler class to extend the standard pickle.Pickler functionality" -optional = false -python-versions = ">=3.8" -files = [ - {file = "cloudpickle-3.0.0-py3-none-any.whl", hash = "sha256:246ee7d0c295602a036e86369c77fecda4ab17b506496730f2f576d9016fd9c7"}, - {file = "cloudpickle-3.0.0.tar.gz", hash = "sha256:996d9a482c6fb4f33c1a35335cf8afd065d2a56e973270364840712d9131a882"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "distro" -version = "1.9.0" -description = "Distro - an OS platform information API" -optional = false -python-versions = ">=3.6" -files = [ - {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, - {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, -] - -[[package]] -name = "docutils" -version = "0.21.2" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=3.9" -files = [ - {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, - {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.1" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.5" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] - -[[package]] -name = "httpx" -version = "0.27.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "httpx-sse" -version = "0.4.0" -description = "Consume Server-Sent Event (SSE) messages with HTTPX." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721"}, - {file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"}, -] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "jedi" -version = "0.19.1" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, -] - -[package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "marimo" -version = "0.3.12" -description = "A library for making reactive notebooks and apps" -optional = false -python-versions = ">=3.8" -files = [ - {file = "marimo-0.3.12-py3-none-any.whl", hash = "sha256:769720a49d9512372f7260bbb48390828eb42e253175d0b04b9b245a70f835ef"}, - {file = "marimo-0.3.12.tar.gz", hash = "sha256:e0ec1363838591341c42a1e7b6371fc0f4f1e30fb618f114072fd7816fe70135"}, -] - -[package.dependencies] -black = "*" -click = ">=8.0,<9" -docutils = ">=0.17.0" -jedi = ">=0.18.0" -markdown = ">=3.4,<4" -pygments = ">=2.13,<3" -pymdown-extensions = ">=9.0,<11" -starlette = ">=0.26.1,<0.36.0 || >0.36.0" -tomlkit = ">=0.12.0" -typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.11\""} -uvicorn = ">=0.22.0" -websockets = ">=10.0.0,<13.0.0" - -[package.extras] -dev = ["autoclasstoc (>=1.6.0,<1.7.0)", "black (>=23.3.0,<23.4.0)", "build (>=0.10.0,<0.11.0)", "click (<8.1.4)", "furo (==2023.5.20)", "httpx (>=0.26.0,<0.27.0)", "mypy (>=1.7.0,<1.8.0)", "myst-parser (>=2.0.0,<2.1.0)", "pandas (>=1.3.0)", "pandas-stubs (>=1.3.0)", "pillow (>=10.2.0,<10.3.0)", "polars (==0.19.12)", "pyarrow (>=15.0.2,<16)", "pyarrow-stubs (>=10)", "pypandoc (>=1.11,<2.0)", "pytest (>=7.4.0,<7.5.0)", "pytest-asyncio (>=0.23.4,<0.24.0)", "pytest-codecov (>=0.5.1,<0.6.0)", "ruff (>=0.0.275,<0.1.0)", "sphinx (==7.0.1)", "sphinx-copybutton (>=0.5.2,<0.6.0)", "sphinx-design (>=0.5.0,<0.6.0)", "sphinx-new-tab-link (>=0.1.1,<0.2.0)", "sphinx-sitemap (>=2.5.1,<2.6.0)", "types-Pillow (>=10.2.0.20240311,<10.3.0.0)", "typos (>=1.17.1,<1.18.0)"] -testcore = ["click (<8.1.4)", "httpx (>=0.26.0,<0.27.0)", "pytest (>=7.4.0,<7.5.0)", "pytest-asyncio (>=0.23.4,<0.24.0)", "pytest-codecov (>=0.5.1,<0.6.0)"] -testoptional = ["altair (>=5.0.0)", "anywidget (>=0.9.3,<0.10.0)", "ipython (>=8.12.3,<8.13.0)", "openai (>=1.12.0,<1.13.0)", "pandas (>=1.3.0)", "pandas-stubs (>=1.3.0)", "pillow (>=10.2.0,<10.3.0)", "polars (==0.19.12)", "pyarrow (>=15.0.2,<16)", "pyarrow-stubs (>=10)", "types-Pillow (>=10.2.0.20240311,<10.3.0.0)"] - -[[package]] -name = "markdown" -version = "3.6" -description = "Python implementation of John Gruber's Markdown." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, -] - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] -testing = ["coverage", "pyyaml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "networkx" -version = "3.3" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.10" -files = [ - {file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"}, - {file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9"}, -] - -[package.extras] -default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - -[[package]] -name = "openai" -version = "1.25.0" -description = "The official Python library for the openai API" -optional = false -python-versions = ">=3.7.1" -files = [ - {file = "openai-1.25.0-py3-none-any.whl", hash = "sha256:d0cfdf6afb31a5dabf3b95966cb31f3c757a0edaf3228715409cb404b9933de0"}, - {file = "openai-1.25.0.tar.gz", hash = "sha256:22c35b26b8281cd2759b1a4c05ac99e2f2b26a9df71f90a0b4ddb75aa27adc81"}, -] - -[package.dependencies] -anyio = ">=3.5.0,<5" -distro = ">=1.7.0,<2" -httpx = ">=0.23.0,<1" -pydantic = ">=1.9.0,<3" -sniffio = "*" -tqdm = ">4" -typing-extensions = ">=4.7,<5" - -[package.extras] -datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] - -[[package]] -name = "packaging" -version = "24.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, -] - -[[package]] -name = "parso" -version = "0.8.4" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, - {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, -] - -[package.extras] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["docopt", "pytest"] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pillow" -version = "10.3.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - -[[package]] -name = "platformdirs" -version = "4.2.1" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, - {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "pydantic" -version = "2.7.1" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"}, - {file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.18.2" -typing-extensions = ">=4.6.1" - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.18.2" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"}, - {file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"}, - {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"}, - {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"}, - {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"}, - {file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"}, - {file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"}, - {file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"}, - {file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"}, - {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"}, - {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"}, - {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"}, - {file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"}, - {file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"}, - {file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"}, - {file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"}, - {file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"}, - {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"}, - {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"}, - {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"}, - {file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"}, - {file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"}, - {file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"}, - {file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"}, - {file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"}, - {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"}, - {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"}, - {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"}, - {file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"}, - {file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"}, - {file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"}, - {file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"}, - {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"}, - {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"}, - {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"}, - {file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"}, - {file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"}, - {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"}, - {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"}, - {file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pygments" -version = "2.17.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, -] - -[package.extras] -plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pymdown-extensions" -version = "10.8.1" -description = "Extension pack for Python Markdown." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, - {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, -] - -[package.dependencies] -markdown = ">=3.6" -pyyaml = "*" - -[package.extras] -extra = ["pygments (>=2.12)"] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "soupsieve" -version = "2.5" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, -] - -[[package]] -name = "starlette" -version = "0.37.2" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.8" -files = [ - {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, - {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, -] - -[package.dependencies] -anyio = ">=3.4.0,<5" - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] - -[[package]] -name = "substrate" -version = "220240617.0.1" -description = "Substrate Python SDK" -optional = false -python-versions = ">=3.9" -files = [ - {file = "substrate-220240617.0.1-py3-none-any.whl", hash = "sha256:f3920487e282b37219de42f56aa99bfc96d51be7e1dbf6ef27662e195e4328c6"}, - {file = "substrate-220240617.0.1.tar.gz", hash = "sha256:8ab5faeaeb66443a6d87c00dcf49a4af3ce06864f22f162840685b790d925545"}, -] - -[package.dependencies] -cloudpickle = "3.0.0" -distro = ">=1.8.0" -httpx = ">=0.26.0" -httpx-sse = ">=0.4.0,<0.5.0" -networkx = ">=3.2.1" -pydantic = ">=1.0.0" -typing-extensions = ">=4.10.0,<5.0.0" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "tomlkit" -version = "0.12.4" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, - {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, -] - -[[package]] -name = "tqdm" -version = "4.66.2" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, - {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.11.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, -] - -[[package]] -name = "uvicorn" -version = "0.29.0" -description = "The lightning-fast ASGI server." -optional = false -python-versions = ">=3.8" -files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, -] - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" -typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "websockets" -version = "12.0" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, - {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, - {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, - {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, - {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, - {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, - {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, - {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, - {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, - {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, - {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, - {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, - {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, - {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, - {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, - {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, - {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, - {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, - {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, - {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, - {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, - {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, - {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, - {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, - {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, - {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, - {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, - {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, - {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, - {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, - {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, - {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, - {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, - {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, - {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, - {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, - {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, - {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, - {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, - {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, - {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, - {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, - {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, - {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, - {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, - {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.10" -content-hash = "c4b3891e09fa5019b1ec31afb6871810361acf155f60a5ca604ac389963fbaa7" diff --git a/examples/notebooks/prompt-enhance.py b/examples/notebooks/prompt-enhance.py deleted file mode 100644 index b5571ac..0000000 --- a/examples/notebooks/prompt-enhance.py +++ /dev/null @@ -1,147 +0,0 @@ -import marimo - -__generated_with = "0.3.12" -app = marimo.App(width="medium") - - -@app.cell -def __(): - import time - - print(f"time {int(time.time())}") - return (time,) - - -@app.cell -def __(__file__): - import os - import sys - import typing_extensions - from pathlib import Path - import marimo as mo - import substrate as ss - - # add parent dir to sys.path to make 'substrate' importable - parent_dir = Path(__file__).resolve().parent.parent - sys.path.insert(0, str(parent_dir)) - - api_key = os.environ.get("SUBSTRATE_API_KEY") - if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - - substrate = ss.Substrate(api_key=api_key) - return ( - Path, - api_key, - mo, - os, - parent_dir, - ss, - substrate, - sys, - typing_extensions, - ) - - -@app.cell -def __(): - # create = ss.CreateVectorStore( - # collection_name="image_prompt_enhancements", - # model="jina-v2", - # ); - # create_res = substrate.run(create) - - # mo.tree(create_res.json) - return - - -@app.cell -def __(ss): - enhancements = [ - "highly detailed", - "digital painting", - "ultrafine detailed painting", - "cell shaded cartoon", - "concept art", - "matte", - "octane render", - "volumetric lighting", - "exquisite detail", - "8k postprocessing", - "cinematic", - "sharp focus", - "wide shot", - "wide angle", - ] - nodes = [] - for e in enhancements: - embed = ss.EmbedText( - text=e, - collection_name="image_prompt_enhancements", - model="jina-v2", - ) - nodes.append(embed) - # embed_res = substrate.run(*nodes) - # mo.tree(embed_res.json) - return e, embed, enhancements, nodes - - -@app.cell -def __(mo, ss, substrate): - prompt = "a towering spiral seashell in a city the size of a city skyscraper" - query = ss.QueryVectorStore( - query_strings=[prompt], - collection_name="image_prompt_enhancements", - model="jina-v2", - include_metadata=True, - top_k=3, - ) - image1 = ss.GenerateImage( - prompt=ss.sb.concat( - prompt, - "octane render, volumetric lighting, cinematic, highly detailed, ", - query.future.results[0][0].metadata["doc"], - ) - ) - image2 = ss.GenerateImage( - prompt=ss.sb.concat( - prompt, - "cell shaded cartoon, volumetric lighting, cinematic, highly detailed, ", - query.future.results[0][1].metadata["doc"], - ) - ) - query_res = substrate.run(query, image1, image2) - # query_out = query_res.get(query); - mo.tree(query_res.json) - return image1, image2, prompt, query, query_res - - -@app.cell -def __(image1, image2, mo, query_res): - mo.hstack( - [ - mo.vstack( - [ - mo.image(query_res.get(image1).image_uri), - mo.download(query_res.get(image1).image_uri), - ] - ), - mo.vstack( - [ - mo.image(query_res.get(image2).image_uri), - mo.download(query_res.get(image2).image_uri), - ] - ), - ] - ) - return - - -@app.cell -def __(): - # mo.tree(response.json) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/notebooks/pyproject.toml b/examples/notebooks/pyproject.toml deleted file mode 100644 index 821003b..0000000 --- a/examples/notebooks/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[tool.poetry] -name = "substrate-notebooks" -version = "0.0.0" -description = "" -authors = ["substrate "] -readme = "README.md" - -[tool.poetry.dependencies] -python = "^3.10" -marimo = "^0.3.4" -substrate = "*" -openai = "^1.25.0" -pillow = "^10.3.0" -beautifulsoup4 = "^4.12.3" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/examples/notebooks/svd.py b/examples/notebooks/svd.py deleted file mode 100644 index c214644..0000000 --- a/examples/notebooks/svd.py +++ /dev/null @@ -1,74 +0,0 @@ -import marimo - -__generated_with = "0.6.23" -app = marimo.App() - - -@app.cell -def __(): - import os - import json - - import marimo as mo - - api_key = os.environ.get("SUBSTRATE_API_KEY") - api_key = api_key or "YOUR_API_KEY" - print(api_key) - return api_key, json, mo, os - - -@app.cell -def __(api_key): - from substrate import Substrate - - substrate = Substrate(api_key=api_key, base_url="https://api.substrate.run") - return Substrate, substrate - - -@app.cell -def __(substrate): - from substrate import GenerateImage, UpscaleImage, StableVideoDiffusion - - prompt = "aerial shot of desert at sunset under clouds" - image_node = GenerateImage( - prompt=prompt, - seed=888, - ) - video_node = StableVideoDiffusion( - image_uri=image_node.future.image_uri, store="hosted", motion_bucket_id=20, fps=10 - ) - - res = substrate.run(video_node) - return ( - GenerateImage, - StableVideoDiffusion, - UpscaleImage, - image_node, - prompt, - res, - video_node, - ) - - -@app.cell -def __(res): - print(res.request_id) - print(res) - return - - -@app.cell -def __(res, video_node): - video = res.get(video_node).video_uri - print(video) - return video, - - -@app.cell -def __(mo, video): - mo.image(video) - return - - -if __name__ == "__main__": - app.run() diff --git a/examples/remove_bg_objects.py b/examples/remove_bg_objects.py deleted file mode 100755 index 91911b9..0000000 --- a/examples/remove_bg_objects.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import json - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import ( - Box, - Substrate, - EraseImage, - ComputeText, - InpaintImage, - GenerateImage, - RemoveBackground, - sb, -) - -substrate = Substrate(api_key=api_key, timeout=60 * 5) -num_images = 2 -object_name = "a red leather wing chair" -artists = [ - ComputeText( - prompt="respond with just the name of a 20th century painter (moma, whitney): ", max_tokens=10, temperature=1 - ) - for _ in range(num_images) -] -prompt_for = lambda x: sb.concat("by ", x, object_name, " in an open room, pillars, amazing painting composition") -bg_prompt_for = lambda x: sb.concat("by ", x, "an empty room with pillars, amazing painting composition") -images = [GenerateImage(prompt=prompt_for(artist.future.text), _cache_age=1000) for artist in artists] -removals = [RemoveBackground(image_uri=image.future.image_uri) for image in images] -masks = [RemoveBackground(image_uri=image.future.image_uri, return_mask=True) for image in images] -bg_images = [ - EraseImage(image_uri=image.future.image_uri, mask_image_uri=mask.future.image_uri) - for image, mask in zip(images, masks, strict=False) -] -inpainted_images = [ - InpaintImage(image_uri=bg_image.future.image_uri, prompt=bg_prompt_for(artist.future.text), store="hosted") - for bg_image, artist in zip(bg_images, artists, strict=False) -] -final = Box(value=[inpainted_image.future.image_uri for inpainted_image in inpainted_images]) -result = substrate.run(final) -viz = Substrate.visualize(final) -os.system(f"open {viz}") - -print(json.dumps(result.json, indent=2)) diff --git a/examples/streaming.py b/examples/streaming.py deleted file mode 100755 index 3b45ada..0000000 --- a/examples/streaming.py +++ /dev/null @@ -1,38 +0,0 @@ -import os -import sys -import asyncio -from pathlib import Path - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from substrate import Substrate, ComputeText, sb - -substrate = Substrate(api_key=api_key, timeout=60 * 5) - - -a = ComputeText(prompt="tell me about windmills", max_tokens=10) -b = ComputeText(prompt=sb.concat("is this true? ", a.future.text), max_tokens=10) - - -async def amain(): - response = await substrate.async_stream(a, b) - async for event in response.async_iter(): - print(event) - - -asyncio.run(amain()) - - -def main(): - response = substrate.stream(a, b) - for message in response.iter(): - print(message) - - -main() diff --git a/examples/streaming/fastapi-example/main.py b/examples/streaming/fastapi-example/main.py deleted file mode 100644 index 1cb519b..0000000 --- a/examples/streaming/fastapi-example/main.py +++ /dev/null @@ -1,30 +0,0 @@ -import os -import sys -from pathlib import Path - -from substrate.nodes import Llama3Instruct8B - -# add parent dir to sys.path to make 'substrate' importable -parent_dir = Path(__file__).resolve().parent.parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -api_key = os.environ.get("SUBSTRATE_API_KEY") -if api_key is None: - raise EnvironmentError("No SUBSTRATE_API_KEY set") - -from fastapi import FastAPI -from fastapi.responses import StreamingResponse - -from substrate import Substrate, Llama3Instruct8B - -app = FastAPI() -substrate = Substrate(api_key=api_key, timeout=60 * 5) - - -@app.get("/qotd") -def quote_of_the_day(): - quote = Llama3Instruct8B(prompt="What's an inspirational quote of the day?") - - response = substrate.stream(quote) - - return StreamingResponse(response.iter_events(), media_type="text/event-stream") diff --git a/examples/techniques/README.md b/examples/techniques/README.md new file mode 100644 index 0000000..fbbcf9e --- /dev/null +++ b/examples/techniques/README.md @@ -0,0 +1 @@ +# Technique examples diff --git a/examples/workshop/README.md b/examples/workshop/README.md new file mode 100644 index 0000000..607e84c --- /dev/null +++ b/examples/workshop/README.md @@ -0,0 +1 @@ +# Workshop examples diff --git a/examples/descript/__init__.py b/examples/workshop/descript/__init__.py similarity index 100% rename from examples/descript/__init__.py rename to examples/workshop/descript/__init__.py diff --git a/examples/descript/generate.py b/examples/workshop/descript/generate.py similarity index 100% rename from examples/descript/generate.py rename to examples/workshop/descript/generate.py diff --git a/examples/descript/generate_chapters.py b/examples/workshop/descript/generate_chapters.py similarity index 100% rename from examples/descript/generate_chapters.py rename to examples/workshop/descript/generate_chapters.py diff --git a/examples/descript/index.html b/examples/workshop/descript/index.html similarity index 100% rename from examples/descript/index.html rename to examples/workshop/descript/index.html diff --git a/examples/descript/util.py b/examples/workshop/descript/util.py similarity index 100% rename from examples/descript/util.py rename to examples/workshop/descript/util.py diff --git a/examples/mixture-of-agents/ask.py b/examples/workshop/mixture-of-agents/ask.py similarity index 100% rename from examples/mixture-of-agents/ask.py rename to examples/workshop/mixture-of-agents/ask.py diff --git a/examples/mixture-of-agents/index.html b/examples/workshop/mixture-of-agents/index.html similarity index 100% rename from examples/mixture-of-agents/index.html rename to examples/workshop/mixture-of-agents/index.html diff --git a/examples/mixture-of-agents/util.py b/examples/workshop/mixture-of-agents/util.py similarity index 100% rename from examples/mixture-of-agents/util.py rename to examples/workshop/mixture-of-agents/util.py