Using typing.Literal for choosing from a set of strings

I have defined the following class:

from typing import List, Optional, Literal, Union
from pydantic import BaseModel, EmailStr

class Rating(BaseModel):
    type: Literal["rating"]
    name: str
    class Options(TypedDict):
        color: Literal["yellowBright", "orangeBright", "redBright", "pinkBright",
                       "purpleBright", "blueBright", "cyanBright", "tealBright",
                       "greenBright", "grayBright"]
        max: int
    options: Options

I assumed that this code indicated to OpenAI API that color was required. However, in the generated output, color is absent. What is wrong here please?

Thanks

On Python 3.11, this won’t run without:

from typing_extensions import TypedDict # Required on Python < 3.12 version which openai likes

(That TypedDict comes from a different module than openai itself may be using may be the source of that library’s beta.parse problems on 3.12)

The AI gets the options name, which could be made more useful, so some humor to drive that home…

class TotallyNotOptional(TypedDict):
    color: Literal["yellowBright", "orangeBright", "redBright", "pinkBright",
                   "purpleBright", "blueBright", "cyanBright", "tealBright",
                   "greenBright", "grayBright"]
    max: int
    
class Rating(BaseModel):
    type: Literal["rating"]
    name: str
    mandatory_options: TotallyNotOptional

I don’t know what the schema is for, but it rated “Happy Gilmore” yellowBright

From what I understand, if I name it “NotOptional”, the AI will make it required. Is that correct? That’s superb.

I have a related issue with the Literal definition. In the following, AI returns the type as longText even though the type is required to be multilineText. In other words, it picks up the value for type from the class name rather than the specified value. Can you explain how this works?

class LongText(BaseModel):
    type: Literal["multilineText"]
    name: str

Thanks.

Naming it NotOptional did not work. Here is the new definition

class Rating(BaseModel):
    type: Literal["rating"]
    name: str
    class NotOptional(TypedDict):
        color: Literal["yellowBright", "orangeBright", "redBright", "pinkBright",
                       "purpleBright", "blueBright", "cyanBright", "tealBright",
                       "greenBright", "grayBright"]
        max: int
    options: NotOptional

and the result I received: Note that color is still missing.

        {
          "type": "rating",
          "name": "Quality Rating",
          "options": {
            "max": 5
          }
        }

What can I try next?

Thanks

I tried this one (using Union) and it is working. I will leave it like that till I understand why Literal did not work here.

class Rating(BaseModel):
    type: Literal["rating"]
    name: str
    class NotOptional(TypedDict):
        color: Union["yellowBright", "orangeBright", "redBright", "pinkBright",
                     "purpleBright", "blueBright", "cyanBright", "tealBright",
                     "greenBright", "grayBright"]
        max: int
    options: NotOptional

The name of the subclass can be whatever, in CamelCase for clarity.

The key used is a title given to the AI, so has value for determining the purpose of the object. The AI cannot deviate from a strict structured output, so the name doesn’t matter for getting a complete structured response - only for understanding of how to fill it in.

I can run it: my python 3.11 good
U can’t run: ur python bad

Here’s upgrading and downgrading all libraries on an install or venv to that which is in OpenAI requirements. If you do a manual install or upgrade after openai of a module like Pydantic, or your distro has newer versions, you could introduce problems.

pip install --upgrade --upgrade-strategy eager regex "charset-normalizer<4" "idna" "urllib3<3" "certifi" "requests" "anyio<5" "distro<2" "sniffio" "h11<0.15" "httpcore==1.*" "httpx<1" "annotated-types" "typing-extensions<5" "pydantic-core==2.20.1" "pydantic<3" "jiter<1" "tqdm" "colorama" "openai" "tiktoken"