Generate additional Type Hints for the Dictionary Form of Messages & Enums
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 30/100
Línea de trabajo
Empieza rastreando los mensajes de dataclass generados y los puntos de entrada existentes from_dict() y to_dict(); el issue no menciona archivos ni tests del repositorio. Compara los ejemplos solicitados de DocumentTypeStringified y DocumentDict, resuelve los casos límite de bytes y de nombres, y verifica que las sugerencias generadas admitan casos de uso de conversión de diccionarios y validación.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
I frequently use the dictionary form of betterproto messages (from_dict(), to_dict()) with stringified enums as arguments for web endpoints and database ODMs. Having an exact type hint for the dictionary form would allow for automatic data validation and more.
What is the feature request for?
The core library
The Problem
I frequently use the dictionary form of betterproto messages (from_dict(), to_dict()) as arguments for web endpoints (Quart, Quart Schema) and database ODMs (such as Beanie for MongoDB).
These frameworks often use pydantic for their validation mechanism, as well as documentation generation (such as Swagger). Having an exact type hint for the dictionary form would allow for automatic data validation and more.
Using the original Message type hints directly (i.e. using the @dataclass annotated message classes) is an option. Yet in some of my cases I need to use the stringified form of the protobuf enums, rather than the integer based one. Generating a dynamic type hint in runtime is cumbersome and not a solution.
The Ideal Solution
It would be great to have the dictionary types of messages to be generated side by side with the current dataclasses:
They dictionary types could be later used inside validation frameworks.
See the following example:
enum DocumentType {
UNKNOWN = 0;
CONTRACT = 1;
INVOICE = 2;
}
message Document {
DocumentType type = 1;
string content = 2;
}
This would generate to
# Currently generated
class DocumentType(betterproto.Enum):
UNKNOWN = 0
CONTRACT = 1
INVOICE = 2
@dataclass(eq=False, repr=False)
class Document(betterproto.Message):
type: "DocumentType" = betterproto.enum_field(1)
content: str = betterproto.string_field(2, group="_data")
# Additionally generated
class DocumentTypeStringified(str, Enum):
UNKNOWN = "UNKNOWN"
CONTRACT = "CONTRACT"
INVOICE = "INVOICE"
class DocumentDict(TypedDict):
type: DocumentTypeStringified
content: str
Now we could use this inside Quart-Schema for parameter validation and documentation:
app = Quart(__name__)
QuartSchema(app)
@app.post(
"/documents/<document_name>",
)
@validate_request(
DocumentDict,
)
async def create_document(document_name: str, data: DocumentDict):
document = Document().from_dict(data)
await db.save_document(document)
return jsonify(success=True), 200
Of course, there might be some corner-cases, e.g. what to do in case of bytes? Should this be done by manually extending the DocumentDict class and override it? How should dataclass names be extended without interfering with other messages? Maybe put them into their own python file?
All in all it seems to be a most valuable and maybe even an easy to develop solution for many good use cases.
What do you think?
Best regards
Markus
The Current Solution
Generating a dynamic type hint from proto enums in runtime is cumbersome and not very maintainable.
DocumentTypeEnumStringified= Enum("DocumentTypeEnumStringified", [item.name for item in DocumentTypeEnum])
class MyDbDocument(Document):
type: Annotated[str, DocumentTypeEnumStringified]
- Lenguaje dominante
- Python
- Estrellas
- 1.8k
- Forks
- 235
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de danielgtaylor/python-betterproto
-
Dificultad 3/5 1-2 días Aptitud para principiantes 55/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 15/100
-
bug investigation needed
Dificultad 3/5 1-2 días Aptitud para principiantes 42/100
-
bug investigation needed
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
-
bug investigation needed
Dificultad 4/5 3-5 días Aptitud para principiantes 38/100
danielgtaylor/python-betterproto#676 · 3 comentarios ·
Todos los issues de danielgtaylor/python-betterproto
Issues similares
-
Validate non-divisible effective batch sizes in the Unsloth LoRA backendPosiblemente ocupada @debesh-biswas la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
reflex-dev/reflex#7634 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
documentation
Dificultad 1/5 1-3 horas Aptitud para principiantes 82/100
topoteretes/cognee#6239 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
ranaroussi/yfinance#3009 ·
Los mantenedores suelen responder en 1 día
-
Test discovery aborts on GPU builds without cuStateVec: check_cuStateVec expects a failed result but set_config() now raises RuntimeErrorPosiblemente ocupada @dmeliksetian la tomó hoy. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Qiskit/qiskit-aer#2495 ·
Los mantenedores suelen responder en 1 día