Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New (Python) example: simple drawings (rectangle, ellipse, arrow) #238

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bb9e32f
Install python-dotenv and tabulate
gvanrossum Apr 17, 2024
6737581
Small working demo that can draw boxes on a canvas
gvanrossum Apr 17, 2024
de03aa9
Add chat history to drawing demo
gvanrossum Apr 17, 2024
2edaedd
[WIP] Hack on translation a bit
gvanrossum Apr 17, 2024
09ea859
New API for chat history
gvanrossum Apr 18, 2024
c52aa53
Improved the schema with ChatGPT's help. Added Arrow and Ellipse.
gvanrossum Apr 19, 2024
5d07a2a
rendering program using Tkinter
gvanrossum Apr 19, 2024
f46a836
Add a simple rendering function (most of it written by ChatGPT)
gvanrossum Apr 19, 2024
131ad4f
Added dashed and dotted arrows (some help from ChatGPT)
gvanrossum Apr 19, 2024
3f44129
Merge commit '66fd7bb' into drawing
gvanrossum Apr 20, 2024
b90faa7
Rip oput history, for now
gvanrossum Apr 22, 2024
02e28e4
Make pyright happy
gvanrossum Apr 22, 2024
3e1f3e6
Merge branch 'main' into drawing
gvanrossum Apr 22, 2024
e9ac5cf
Keep pydantic also happy
gvanrossum Apr 22, 2024
9e14f42
Add (flawed) history based on prompt_preamble
gvanrossum Apr 22, 2024
75c2efe
Prune history
gvanrossum Apr 22, 2024
970d50b
Add temporary logging
gvanrossum Apr 22, 2024
7560273
Alternate prompting scheme from #241
gvanrossum Apr 22, 2024
439f521
Revert changes to translator.py
gvanrossum May 2, 2024
b0fdd8d
Merge branch 'main' into drawing
gvanrossum May 2, 2024
d385e40
Use Anders' suggestion for history
gvanrossum May 2, 2024
42ce16a
Switch schema to dataclasses
gvanrossum May 2, 2024
c6da914
Black formatting
gvanrossum May 2, 2024
390558e
Remove unused imports
gvanrossum May 2, 2024
e42b2dd
Clarify Failure output
gvanrossum May 2, 2024
11edfb7
Revert verbose logging
gvanrossum May 2, 2024
3f099dc
Reuse drawing window
gvanrossum May 2, 2024
5c6e15f
Don't crash if we cannot import readline (e.g. on Windows)
gvanrossum May 8, 2024
0894ef6
Add crude progress messages
gvanrossum May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Small working demo that can draw boxes on a canvas
The idea is that you can write a small amount of JavaScript that reads the
JSON and renders in an HTML5 canvas, or some Python that renders it in Tkinter,
or anything else that strikes your fancy.

I would like to use this to draw diagrams representing the stack and
memory layout for an interpreter, to be used in internal docs.
gvanrossum committed Apr 18, 2024
commit 673758122bc3b93241e8b92297b678c0c845a55f
2 changes: 2 additions & 0 deletions python/examples/drawing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Let's draw some diagrams

37 changes: 37 additions & 0 deletions python/examples/drawing/demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import asyncio
import json
import sys
from typing import Any

import schema as drawing
from dotenv import dotenv_values

from typechat import Success, Failure, TypeChatJsonTranslator, TypeChatValidator, create_language_model, process_requests


async def main(file_path: str | None):
env_vals = dotenv_values()
model = create_language_model(env_vals)
validator = TypeChatValidator(drawing.Drawing)
translator = TypeChatJsonTranslator(model, validator, drawing.Drawing)
print(translator._schema_str)

async def request_handler(message: str):
result: Success[drawing.Drawing] | Failure = await translator.translate(message)
if isinstance(result, Failure):
print(result.message)
else:
value = result.value
print(json.dumps(value, indent=2))
if any(item["type"] == "Unknown" for item in value["items"]):
print("I did not understand the following")
for item in value["items"]:
if item["type"] == "Unknown":
print(item["text"])

await process_requests("~> ", file_path, request_handler)


if __name__ == "__main__":
file_path = sys.argv[1] if len(sys.argv) == 2 else None
asyncio.run(main(file_path))
44 changes: 44 additions & 0 deletions python/examples/drawing/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""TypeChat schema for simple line drawings."""


from typing_extensions import Literal, NotRequired, TypedDict, Annotated, Doc


class Style(TypedDict):
type: Literal["Style"]
corners: Literal["rounded", "sharp"]
# We'll add things like line thickness, color, fill, etc. later


class Box(TypedDict):
"""A rectangular box.

The coordinate system has origin top left, x points right, y points down.
Measurements are in pixels.

There can also be text in the box. There are optional style properties.

"""
type: Literal["Box"]
x: Annotated[int, Doc("Top left corner coordinates")]
y: int
width: Annotated[int, Doc("Size of the box")]
height: int
text: Annotated[str, Doc("Text centered in the box")]
style: Annotated[Style | None, Doc("Box drawing style (optional)")]


class UnknownText(TypedDict):
"""
Use this type for input that match nothing else
"""

type: Literal["Unknown"]
text: Annotated[str, Doc("The text that wasn't understood")]


class Drawing(TypedDict):
"""
A drawing is a list of boxes. (We'll add other elements later, like arrows.)
"""
items: list[Box | UnknownText]