Giter Club home page Giter Club logo

sanic-dantic's People

Contributors

miss85246 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sanic-dantic's Issues

Add optional support for returning messages as JSON

Hey there! Thanks so much for your work on this!

Would you be willing to accept a patch that adds the ability to specify if validation/assertion errors should be returned as text vs JSON as well as specify if they want to return the first error or all present errors?

My own local testing has yielded this (very) rough draft:

def validate(request, header=None, path=None, query=None, form=None, body=None, return_json=False, send_first_error_only=True):
    """
    When there are the same parameter name in the model, the parameter in ParsedArgsObj will be overwritten,
    The priorities is: body = form > query > path \n
    :param header: Pydantic model
    :param request: Pydantic model
    :param query: Pydantic model
    :param body: Pydantic model, cannot exist at the same time as form
    :param path: Pydantic model
    :param form: Pydantic model, cannot exist at the same time as body
    :param return_json: Whether to return JSON instead of text
    :param send_first_error_only: Whether to send only the first error in the list or all errors
    :return parsed_args: ParsedArgsObj
    """
    try:
        error_message = "sanic-dantic: body model must be used together with one of ['POST','PUT','PATCH','DELETE']"
        assert request.method in ["POST", "PUT", "PATCH", "DELETE"] if body else True, error_message
        models, parsed_args = [header, path, query] + [form or body], ParsedArgsObj()
        body_storage = {k: v[0] if len(v) == 1 else v for k, v in request.form.items()} if form else request.json
        params = {k: v[0] if len(v) == 1 else v for k, v in request.args.items()}
        storages = [request.headers, request.match_info, params, body_storage]
        models = [item for item in zip(models, storages) if item[0]]
        [parsed_args.update(model(**storage).dict()) for model, storage in models]
    except ValidationError as e:
        errors = e.errors()
        if send_first_error_only:
            errors = [e.errors()[0]]

        request.ctx.sanic_dantic_validation_errors = errors

        message = '\n'.join([f'{msg.get("loc")[0]} {msg.get("msg")}' for msg in errors])

        if not return_json:
            request.ctx.sanic_dantic_validation_errors = message
            request.ctx.sanic_dantic_return_type = 'text'
        else:
            request.ctx.sanic_dantic_return_type = 'json'
        raise InvalidUsage(message)

async def catch_errors(request, exception):
  if hasattr(request.ctx, 'sanic_dantic_validation_errors'):
    logging.error(request.ctx.sanic_dantic_validation_errors)
    return getattr(sanic.response, request.ctx.sanic_dantic_return_type)(request.ctx.sanic_dantic_validation_errors, status=exception.status_code)

app.error_handler.add(InvalidUsage, catch_errors)

where validate is a reimplementation of sanic_dantic.basic_definition.validate, catch_errors is a stub for a custom error handler, and app is a predefined Sanic app.

I know it's not elegant, especially having to ask the user to register the handler themselves. Perhaps a better way would be to just attach the ValidationError to the context and let the user sort it out themselves if they want JSON?

The most important thing to me is being able to return all the errors at the same time. Implementation and everything else is secondary

Can't parse top-level lists

@parse_params is unable to parse top-level lists, like:

@parse_params(path=List[str])
@parse_params(path=List[Person])

Stacktrace:

Traceback (most recent call last):
  File "/home/gr3q/Repos/maintenance-webserver/venv/lib/python3.9/site-packages/sanic/app.py", line 914, in handle_request
    response = await response
  File "/home/gr3q/Repos/maintenance-webserver/venv/lib/python3.9/site-packages/sanic_dantic/sanic_function_dantic.py", line 35, in decorated_function
    model_obj = DanticModelObj(header=header, path=path, query=query, form=form, body=body)
  File "/home/gr3q/Repos/maintenance-webserver/venv/lib/python3.9/site-packages/sanic_dantic/basic_definition.py", line 30, in __init__
    basemodel_check = [BaseModel in [_ for _ in getmro(model)] for model in self.items.values() if model]
  File "/home/gr3q/Repos/maintenance-webserver/venv/lib/python3.9/site-packages/sanic_dantic/basic_definition.py", line 30, in <listcomp>
    basemodel_check = [BaseModel in [_ for _ in getmro(model)] for model in self.items.values() if model]
  File "/usr/lib/python3.9/inspect.py", line 490, in getmro
    return cls.__mro__
  File "/usr/lib/python3.9/typing.py", line 688, in __getattr__
    raise AttributeError(attr)
AttributeError: __mro__

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.