strawberry icon indicating copy to clipboard operation
strawberry copied to clipboard

Support StrEnum

Open PaleNeutron opened this issue 5 months ago • 7 comments

Feature Request Type

  • [ ] Core functionality
  • [x] Alteration (enhancement/optimization) of existing feature(s)
  • [ ] New behavior

Description

Since python 3.11 , enum module provide StrEnum which use value instead of key:


class Direction(StrEnum):
    NORTH = 'north'
    SOUTH = 'south'

print(Direction.NORTH)
>>> north

And is supported by pydantic.

This allow user use value not suitable for variable name as enum, for example, "01ab".

PaleNeutron avatar Jul 17 '25 06:07 PaleNeutron

Hi @PaleNeutron!

This should already work, just tried in the playground:

import strawberry
from enum import StrEnum


@strawberry.enum
class Direction(StrEnum):
    NORTH = 'north'
    SOUTH = 'south'



@strawberry.type
class Query:
    @strawberry.field
    def hello(self, info: strawberry.Info) -> Direction:
        return "north"


schema = strawberry.Schema(Query)

patrick91 avatar Jul 17 '25 07:07 patrick91

Thanks, I'll check what's wrong in my local project.

PaleNeutron avatar Jul 17 '25 08:07 PaleNeutron

@patrick91 See this playground https://play.strawberry.rocks/?gist=1d37e7d0f002dcbb1fb9ff456b3556e7

the result is upper case

{
  "data": {
    "hello": "NORTH"
  }
}

not

{
  "data": {
    "hello": "north"
  }
}

Here is a pydantic example

Image

PaleNeutron avatar Jul 18 '25 02:07 PaleNeutron

@PaleNeutron that's the expected behaviour at the moment 😊

We wanted to make it configurable but never got around doing so

patrick91 avatar Jul 18 '25 09:07 patrick91

It's also the recommended behavior in the GraphQL spec 😊 https://spec.graphql.org/October2021/#sec-Enum-Value

erikwrede avatar Jul 19 '25 13:07 erikwrede

@erikwrede I understand... It is a limitation from graphql. But this design is inconvenient for CJK languages users, we have to use CJK characters as enum for end users. Otherwise, we have to translate all enum from key to value at frontend, which make enum useless, why not just string here?

In most cases, the class should be.

class Direction(StrEnum):
    NORTH = '北边'
    SOUTH = '南边'

Where can I submit a ticket to graphql.org?

PaleNeutron avatar Jul 20 '25 01:07 PaleNeutron

@PaleNeutron Makes sense. I'd advise against providing human-readable values using enums. Their big strong suit is the machine-readability of a static value, otherwise you could just use a string. Seeing that you chose NORTH and SOUTH as the enum keys in your code, over directly using the CJK chars, I'd recommend putting them into the schema using these keys as well. Frontend translation can be annoying - you could help users by adding the following resolver to your type:

@strawberry.type
class Compass:
  direction: Direction

  @strawberry.field
  def direction_label(self, # optionally add a locale input here
            ) -> str: 
     return self.direction.value

This might seem like extra effort, but I'd question the necessity of the enum in your API if all you want to do is output the value. Below is another option where you don't output the enum type at all.

@strawberry.type
class Compass:
  direction_enum: strawberry.Private[Direction]

  @strawberry.field
  def direction(self, # optionally add a locale input here
            ) -> str: 
     return self.direction_enum.value

erikwrede avatar Jul 21 '25 09:07 erikwrede