scolby33 / easy_config

Parse configuration values from files, the environment, and elsewhere all in one place.
MIT License
1 stars 1 forks source link

Extension for WTForms #11

Open cthoyt opened 6 years ago

cthoyt commented 6 years ago

Would be cool to automatically generate a form for use with Flask / Flask-WTF automatically from a given EasyConfig. Will submit PR later :)

cthoyt commented 6 years ago

Is there a smart way for introspecting which fields have default values?

cthoyt commented 6 years ago

Okay this isn't so complete but it's bed time. Also disregard the weird name of the variable in the test.

# -*- coding: utf-8 -*-

"""Test the Flask-WTF wrapper."""

import dataclasses
from typing import Type

import flask
from flask_wtf import FlaskForm
from wtforms import BooleanField, IntegerField, StringField
from wtforms.validators import DataRequired

from easy_config import EasyConfig

type_to_field = {
    str: StringField,
    int: IntegerField,
    bool: BooleanField,
}

def form_from_config(cls: Type[EasyConfig]):
    """Build a Flask-WTF form based on the given EasyConfig class."""
    attrs = {}

    for field in dataclasses.fields(cls):
        field_cls = type_to_field[field.type]
        attribute = field_cls(field.name, validators=[DataRequired()])
        if field.default is not dataclasses.MISSING:
            attribute.default = field.default
        attrs[field.name] = attribute

    return type(f'{cls.NAME}Form', (FlaskForm,), attrs)

def test_with_default():
    class ExampleConfig(EasyConfig):
        """Example EasyConfig subclass to test with."""

        FILES = None
        NAME = 'MyProgram'

        number: bool

    form_cls = form_from_config(ExampleConfig)
    app = flask.Flask('test_app')

    with app.app_context():
        form = form_cls(csrf_enabled=False)
        for field in form:
            print(field)

        fields = list(form)
        assert 1 == len(fields)
        field = fields[0]
        assert str(field) == '<input id="number" name="number" required type="checkbox" value="y">'
scolby33 commented 6 years ago

Same discussion as https://github.com/scolby33/easy_config/issues/4#issuecomment-424610571 applies.