From ab0b72a7c1a17c6d85530514caa51ce5bd77b592 Mon Sep 17 00:00:00 2001 From: Sébastien Piquemal Date: Sun, 22 Jan 2012 21:28:34 +0200 Subject: .DATA, .FILES, overloaded HTTP method, content type and content available directly on the request - see #128 --- djangorestframework/parsers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index c8a014ae..e56ea025 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -165,9 +165,10 @@ class MultiPartParser(BaseParser): `data` will be a :class:`QueryDict` containing all the form parameters. `files` will be a :class:`QueryDict` containing all the form files. """ - upload_handlers = self.view.request._get_upload_handlers() + # TODO: now self.view is in fact request, but should disappear ... + upload_handlers = self.view._get_upload_handlers() try: - django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers) + django_parser = DjangoMultiPartParser(self.view.META, stream, upload_handlers) except MultiPartParserError, exc: raise ErrorResponse(status.HTTP_400_BAD_REQUEST, {'detail': 'multipart parse error - %s' % unicode(exc)}) -- cgit v1.2.3 From 5bb6301b7f53e3815ab1a81a5fa38721dc95b113 Mon Sep 17 00:00:00 2001 From: Sébastien Piquemal Date: Thu, 2 Feb 2012 18:19:44 +0200 Subject: Response as a subclass of HttpResponse - first draft, not quite there yet. --- djangorestframework/parsers.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index e56ea025..7732a293 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -88,8 +88,9 @@ class JSONParser(BaseParser): try: return (json.load(stream), None) except ValueError, exc: - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, - {'detail': 'JSON parse error - %s' % unicode(exc)}) + raise ErrorResponse( + content={'detail': 'JSON parse error - %s' % unicode(exc)}, + status=status.HTTP_400_BAD_REQUEST) if yaml: @@ -110,8 +111,9 @@ if yaml: try: return (yaml.safe_load(stream), None) except ValueError, exc: - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, - {'detail': 'YAML parse error - %s' % unicode(exc)}) + raise ErrorResponse( + content={'detail': 'YAML parse error - %s' % unicode(exc)}, + status=status.HTTP_400_BAD_REQUEST) else: YAMLParser = None @@ -170,8 +172,9 @@ class MultiPartParser(BaseParser): try: django_parser = DjangoMultiPartParser(self.view.META, stream, upload_handlers) except MultiPartParserError, exc: - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, - {'detail': 'multipart parse error - %s' % unicode(exc)}) + raise ErrorResponse( + content={'detail': 'multipart parse error - %s' % unicode(exc)}, + status=status.HTTP_400_BAD_REQUEST) return django_parser.parse() -- cgit v1.2.3 From ca96b4523b4c09489e4bfe726a894a5c6ada78aa Mon Sep 17 00:00:00 2001 From: Sébastien Piquemal Date: Tue, 7 Feb 2012 13:15:30 +0200 Subject: cleaned a bit Response/ResponseMixin code, added some documentation + renamed ErrorResponse to ImmediateResponse --- djangorestframework/parsers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 7732a293..5fc5c71e 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -17,7 +17,7 @@ from django.http.multipartparser import MultiPartParserError from django.utils import simplejson as json from djangorestframework import status from djangorestframework.compat import yaml -from djangorestframework.response import ErrorResponse +from djangorestframework.response import ImmediateResponse from djangorestframework.utils.mediatypes import media_type_matches from xml.etree import ElementTree as ET import datetime @@ -88,7 +88,7 @@ class JSONParser(BaseParser): try: return (json.load(stream), None) except ValueError, exc: - raise ErrorResponse( + raise ImmediateResponse( content={'detail': 'JSON parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) @@ -111,7 +111,7 @@ if yaml: try: return (yaml.safe_load(stream), None) except ValueError, exc: - raise ErrorResponse( + raise ImmediateResponse( content={'detail': 'YAML parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) else: @@ -172,7 +172,7 @@ class MultiPartParser(BaseParser): try: django_parser = DjangoMultiPartParser(self.view.META, stream, upload_handlers) except MultiPartParserError, exc: - raise ErrorResponse( + raise ImmediateResponse( content={'detail': 'multipart parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) return django_parser.parse() -- cgit v1.2.3 From 21292d31e7ad5ec731c9ef3e471f90cb29054686 Mon Sep 17 00:00:00 2001 From: Sébastien Piquemal Date: Tue, 7 Feb 2012 15:38:54 +0200 Subject: cleaned Request/Response/mixins to have similar interface --- djangorestframework/parsers.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 5fc5c71e..c041d7ce 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -43,7 +43,7 @@ class BaseParser(object): media_type = None - def __init__(self, view): + def __init__(self, view=None): """ Initialize the parser with the ``View`` instance as state, in case the parser needs to access any metadata on the :obj:`View` object. @@ -167,10 +167,9 @@ class MultiPartParser(BaseParser): `data` will be a :class:`QueryDict` containing all the form parameters. `files` will be a :class:`QueryDict` containing all the form files. """ - # TODO: now self.view is in fact request, but should disappear ... - upload_handlers = self.view._get_upload_handlers() + upload_handlers = self.view.request._get_upload_handlers() try: - django_parser = DjangoMultiPartParser(self.view.META, stream, upload_handlers) + django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers) except MultiPartParserError, exc: raise ImmediateResponse( content={'detail': 'multipart parse error - %s' % unicode(exc)}, -- cgit v1.2.3 From db0b01037a95946938ccd44eae14d8779bfff1a9 Mon Sep 17 00:00:00 2001 From: Sébastien Piquemal Date: Fri, 10 Feb 2012 10:18:39 +0200 Subject: made suggested fixes --- djangorestframework/parsers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index c041d7ce..d41e07e8 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -89,7 +89,7 @@ class JSONParser(BaseParser): return (json.load(stream), None) except ValueError, exc: raise ImmediateResponse( - content={'detail': 'JSON parse error - %s' % unicode(exc)}, + {'detail': 'JSON parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) @@ -112,7 +112,7 @@ if yaml: return (yaml.safe_load(stream), None) except ValueError, exc: raise ImmediateResponse( - content={'detail': 'YAML parse error - %s' % unicode(exc)}, + {'detail': 'YAML parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) else: YAMLParser = None @@ -172,7 +172,7 @@ class MultiPartParser(BaseParser): django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers) except MultiPartParserError, exc: raise ImmediateResponse( - content={'detail': 'multipart parse error - %s' % unicode(exc)}, + {'detail': 'multipart parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) return django_parser.parse() -- cgit v1.2.3 From 1cde31c86d9423e9b7a7409c2ef2ba7c0500e47f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 25 Feb 2012 18:45:17 +0000 Subject: Massive merge --- djangorestframework/parsers.py | 77 ++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 40 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index d41e07e8..fc4450b7 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -20,6 +20,8 @@ from djangorestframework.compat import yaml from djangorestframework.response import ImmediateResponse from djangorestframework.utils.mediatypes import media_type_matches from xml.etree import ElementTree as ET +from djangorestframework.compat import ETParseError +from xml.parsers.expat import ExpatError import datetime import decimal @@ -43,13 +45,6 @@ class BaseParser(object): media_type = None - def __init__(self, view=None): - """ - Initialize the parser with the ``View`` instance as state, - in case the parser needs to access any metadata on the :obj:`View` object. - """ - self.view = view - def can_handle_request(self, content_type): """ Returns :const:`True` if this parser is able to deal with the given *content_type*. @@ -63,12 +58,12 @@ class BaseParser(object): """ return media_type_matches(self.media_type, content_type) - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Given a *stream* to read from, return the deserialized output. Should return a 2-tuple of (data, files). """ - raise NotImplementedError("BaseParser.parse() Must be overridden to be implemented.") + raise NotImplementedError(".parse() Must be overridden to be implemented.") class JSONParser(BaseParser): @@ -78,7 +73,7 @@ class JSONParser(BaseParser): media_type = 'application/json' - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Returns a 2-tuple of `(data, files)`. @@ -93,29 +88,26 @@ class JSONParser(BaseParser): status=status.HTTP_400_BAD_REQUEST) -if yaml: - class YAMLParser(BaseParser): - """ - Parses YAML-serialized data. - """ +class YAMLParser(BaseParser): + """ + Parses YAML-serialized data. + """ - media_type = 'application/yaml' + media_type = 'application/yaml' - def parse(self, stream): - """ - Returns a 2-tuple of `(data, files)`. + def parse(self, stream, meta, upload_handlers): + """ + Returns a 2-tuple of `(data, files)`. - `data` will be an object which is the parsed content of the response. - `files` will always be `None`. - """ - try: - return (yaml.safe_load(stream), None) - except ValueError, exc: - raise ImmediateResponse( - {'detail': 'YAML parse error - %s' % unicode(exc)}, - status=status.HTTP_400_BAD_REQUEST) -else: - YAMLParser = None + `data` will be an object which is the parsed content of the response. + `files` will always be `None`. + """ + try: + return (yaml.safe_load(stream), None) + except ValueError, exc: + raise ImmediateResponse( + {'detail': 'YAML parse error - %s' % unicode(exc)}, + status=status.HTTP_400_BAD_REQUEST) class PlainTextParser(BaseParser): @@ -125,7 +117,7 @@ class PlainTextParser(BaseParser): media_type = 'text/plain' - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Returns a 2-tuple of `(data, files)`. @@ -142,7 +134,7 @@ class FormParser(BaseParser): media_type = 'application/x-www-form-urlencoded' - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Returns a 2-tuple of `(data, files)`. @@ -160,21 +152,20 @@ class MultiPartParser(BaseParser): media_type = 'multipart/form-data' - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Returns a 2-tuple of `(data, files)`. `data` will be a :class:`QueryDict` containing all the form parameters. `files` will be a :class:`QueryDict` containing all the form files. """ - upload_handlers = self.view.request._get_upload_handlers() try: - django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers) + parser = DjangoMultiPartParser(meta, stream, upload_handlers) + return parser.parse() except MultiPartParserError, exc: raise ImmediateResponse( {'detail': 'multipart parse error - %s' % unicode(exc)}, status=status.HTTP_400_BAD_REQUEST) - return django_parser.parse() class XMLParser(BaseParser): @@ -184,14 +175,18 @@ class XMLParser(BaseParser): media_type = 'application/xml' - def parse(self, stream): + def parse(self, stream, meta, upload_handlers): """ Returns a 2-tuple of `(data, files)`. `data` will simply be a string representing the body of the request. `files` will always be `None`. """ - tree = ET.parse(stream) + try: + tree = ET.parse(stream) + except (ExpatError, ETParseError, ValueError), exc: + content = {'detail': 'XML parse error - %s' % unicode(exc)} + raise ImmediateResponse(content, status=status.HTTP_400_BAD_REQUEST) data = self._xml_convert(tree.getroot()) return (data, None) @@ -251,5 +246,7 @@ DEFAULT_PARSERS = ( XMLParser ) -if YAMLParser: - DEFAULT_PARSERS += (YAMLParser,) +if yaml: + DEFAULT_PARSERS += (YAMLParser, ) +else: + YAMLParser = None -- cgit v1.2.3 From 26831df88e80feb815aeb3a2b8a7c275a71732e4 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 25 Aug 2012 13:27:55 +0100 Subject: Add ParseError (Removing ImmediateResponse) --- djangorestframework/parsers.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 0eb72f38..1fff64f7 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -15,9 +15,8 @@ from django.http import QueryDict from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.http.multipartparser import MultiPartParserError from django.utils import simplejson as json -from djangorestframework import status from djangorestframework.compat import yaml -from djangorestframework.response import ImmediateResponse +from djangorestframework.exceptions import ParseError from djangorestframework.utils.mediatypes import media_type_matches from xml.etree import ElementTree as ET from djangorestframework.compat import ETParseError @@ -83,9 +82,7 @@ class JSONParser(BaseParser): try: return (json.load(stream), None) except ValueError, exc: - raise ImmediateResponse( - {'detail': 'JSON parse error - %s' % unicode(exc)}, - status=status.HTTP_400_BAD_REQUEST) + raise ParseError('JSON parse error - %s' % unicode(exc)) class YAMLParser(BaseParser): @@ -105,9 +102,7 @@ class YAMLParser(BaseParser): try: return (yaml.safe_load(stream), None) except (ValueError, yaml.parser.ParserError), exc: - raise ImmediateResponse( - {'detail': 'YAML parse error - %s' % unicode(exc)}, - status=status.HTTP_400_BAD_REQUEST) + raise ParseError('YAML parse error - %s' % unicode(exc)) class PlainTextParser(BaseParser): @@ -163,9 +158,7 @@ class MultiPartParser(BaseParser): parser = DjangoMultiPartParser(meta, stream, upload_handlers) return parser.parse() except MultiPartParserError, exc: - raise ImmediateResponse( - {'detail': 'multipart parse error - %s' % unicode(exc)}, - status=status.HTTP_400_BAD_REQUEST) + raise ParseError('Multipart form parse error - %s' % unicode(exc)) class XMLParser(BaseParser): @@ -185,8 +178,7 @@ class XMLParser(BaseParser): try: tree = ET.parse(stream) except (ExpatError, ETParseError, ValueError), exc: - content = {'detail': 'XML parse error - %s' % unicode(exc)} - raise ImmediateResponse(content, status=status.HTTP_400_BAD_REQUEST) + raise ParseError('XML parse error - %s' % unicode(exc)) data = self._xml_convert(tree.getroot()) return (data, None) -- cgit v1.2.3 From ecd3733c5e229505baca5a870963f2dd492d6dd7 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 28 Aug 2012 15:46:38 +0100 Subject: Added serializers and fields --- djangorestframework/parsers.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 1fff64f7..43ea0c4d 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -57,7 +57,7 @@ class BaseParser(object): """ return media_type_matches(self.media_type, content_type) - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Given a *stream* to read from, return the deserialized output. Should return a 2-tuple of (data, files). @@ -72,7 +72,7 @@ class JSONParser(BaseParser): media_type = 'application/json' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -92,7 +92,7 @@ class YAMLParser(BaseParser): media_type = 'application/yaml' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -112,7 +112,7 @@ class PlainTextParser(BaseParser): media_type = 'text/plain' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -129,7 +129,7 @@ class FormParser(BaseParser): media_type = 'application/x-www-form-urlencoded' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -147,13 +147,15 @@ class MultiPartParser(BaseParser): media_type = 'multipart/form-data' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. `data` will be a :class:`QueryDict` containing all the form parameters. `files` will be a :class:`QueryDict` containing all the form files. """ + meta = opts['meta'] + upload_handlers = opts['upload_handlers'] try: parser = DjangoMultiPartParser(meta, stream, upload_handlers) return parser.parse() @@ -168,7 +170,7 @@ class XMLParser(BaseParser): media_type = 'application/xml' - def parse(self, stream, meta, upload_handlers): + def parse(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. -- cgit v1.2.3 From 7abef9ac3b3fb20a6cdef5d52c640e5725c93437 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 3 Sep 2012 14:28:40 +0100 Subject: Parsers may return raw data, or a DataAndFiles object --- djangorestframework/parsers.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 43ea0c4d..fc0260fc 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -36,6 +36,12 @@ __all__ = ( ) +class DataAndFiles(object): + def __init__(self, data, files): + self.data = data + self.files = files + + class BaseParser(object): """ All parsers should extend :class:`BaseParser`, specifying a :attr:`media_type` attribute, @@ -80,7 +86,7 @@ class JSONParser(BaseParser): `files` will always be `None`. """ try: - return (json.load(stream), None) + return json.load(stream) except ValueError, exc: raise ParseError('JSON parse error - %s' % unicode(exc)) @@ -100,7 +106,7 @@ class YAMLParser(BaseParser): `files` will always be `None`. """ try: - return (yaml.safe_load(stream), None) + return yaml.safe_load(stream) except (ValueError, yaml.parser.ParserError), exc: raise ParseError('YAML parse error - %s' % unicode(exc)) @@ -119,7 +125,7 @@ class PlainTextParser(BaseParser): `data` will simply be a string representing the body of the request. `files` will always be `None`. """ - return (stream.read(), None) + return stream.read() class FormParser(BaseParser): @@ -137,7 +143,7 @@ class FormParser(BaseParser): `files` will always be :const:`None`. """ data = QueryDict(stream.read()) - return (data, None) + return data class MultiPartParser(BaseParser): @@ -149,16 +155,17 @@ class MultiPartParser(BaseParser): def parse(self, stream, **opts): """ - Returns a 2-tuple of `(data, files)`. + Returns a DataAndFiles object. - `data` will be a :class:`QueryDict` containing all the form parameters. - `files` will be a :class:`QueryDict` containing all the form files. + `.data` will be a `QueryDict` containing all the form parameters. + `.files` will be a `QueryDict` containing all the form files. """ meta = opts['meta'] upload_handlers = opts['upload_handlers'] try: parser = DjangoMultiPartParser(meta, stream, upload_handlers) - return parser.parse() + data, files = parser.parse() + return DataAndFiles(data, files) except MultiPartParserError, exc: raise ParseError('Multipart form parse error - %s' % unicode(exc)) @@ -171,19 +178,13 @@ class XMLParser(BaseParser): media_type = 'application/xml' def parse(self, stream, **opts): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will simply be a string representing the body of the request. - `files` will always be `None`. - """ try: tree = ET.parse(stream) except (ExpatError, ETParseError, ValueError), exc: raise ParseError('XML parse error - %s' % unicode(exc)) data = self._xml_convert(tree.getroot()) - return (data, None) + return data def _xml_convert(self, element): """ -- cgit v1.2.3 From 149b00a070fcbfd44feee5b37096081e18356f93 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 3 Sep 2012 15:57:43 +0100 Subject: Added the api_view decorator --- djangorestframework/parsers.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index fc0260fc..96dd81ed 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -23,6 +23,7 @@ from djangorestframework.compat import ETParseError from xml.parsers.expat import ExpatError import datetime import decimal +from io import BytesIO __all__ = ( @@ -63,12 +64,24 @@ class BaseParser(object): """ return media_type_matches(self.media_type, content_type) - def parse(self, stream, **opts): + def parse(self, string_or_stream, **opts): + """ + The main entry point to parsers. This is a light wrapper around + `parse_stream`, that instead handles both string and stream objects. + """ + if isinstance(string_or_stream, basestring): + stream = BytesIO(string_or_stream) + else: + stream = string_or_stream + return self.parse_stream(stream, **opts) + + def parse_stream(self, stream, **opts): """ Given a *stream* to read from, return the deserialized output. - Should return a 2-tuple of (data, files). + Should return parsed data, or a DataAndFiles object consisting of the + parsed data and files. """ - raise NotImplementedError(".parse() Must be overridden to be implemented.") + raise NotImplementedError(".parse_stream() Must be overridden to be implemented.") class JSONParser(BaseParser): @@ -78,7 +91,7 @@ class JSONParser(BaseParser): media_type = 'application/json' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -98,7 +111,7 @@ class YAMLParser(BaseParser): media_type = 'application/yaml' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -118,7 +131,7 @@ class PlainTextParser(BaseParser): media_type = 'text/plain' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -135,7 +148,7 @@ class FormParser(BaseParser): media_type = 'application/x-www-form-urlencoded' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): """ Returns a 2-tuple of `(data, files)`. @@ -153,7 +166,7 @@ class MultiPartParser(BaseParser): media_type = 'multipart/form-data' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): """ Returns a DataAndFiles object. @@ -177,7 +190,7 @@ class XMLParser(BaseParser): media_type = 'application/xml' - def parse(self, stream, **opts): + def parse_stream(self, stream, **opts): try: tree = ET.parse(stream) except (ExpatError, ETParseError, ValueError), exc: -- cgit v1.2.3 From c28b719333b16935e53c76fef79b096cb11322ed Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 4 Sep 2012 21:58:35 +0100 Subject: Refactored throttling --- djangorestframework/parsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 96dd81ed..fb08c5a0 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -81,7 +81,7 @@ class BaseParser(object): Should return parsed data, or a DataAndFiles object consisting of the parsed data and files. """ - raise NotImplementedError(".parse_stream() Must be overridden to be implemented.") + raise NotImplementedError(".parse_stream() must be overridden.") class JSONParser(BaseParser): -- cgit v1.2.3 From 87dae4d8549c02fa9a57adb3bb876d249dae1f79 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:19:43 +0100 Subject: Remove old 'djangorestframework directories --- djangorestframework/parsers.py | 260 ----------------------------------------- 1 file changed, 260 deletions(-) delete mode 100644 djangorestframework/parsers.py (limited to 'djangorestframework/parsers.py') diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py deleted file mode 100644 index fb08c5a0..00000000 --- a/djangorestframework/parsers.py +++ /dev/null @@ -1,260 +0,0 @@ -""" -Django supports parsing the content of an HTTP request, but only for form POST requests. -That behavior is sufficient for dealing with standard HTML forms, but it doesn't map well -to general HTTP requests. - -We need a method to be able to: - -1.) Determine the parsed content on a request for methods other than POST (eg typically also PUT) - -2.) Determine the parsed content on a request for media types other than application/x-www-form-urlencoded - and multipart/form-data. (eg also handle multipart/json) -""" - -from django.http import QueryDict -from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser -from django.http.multipartparser import MultiPartParserError -from django.utils import simplejson as json -from djangorestframework.compat import yaml -from djangorestframework.exceptions import ParseError -from djangorestframework.utils.mediatypes import media_type_matches -from xml.etree import ElementTree as ET -from djangorestframework.compat import ETParseError -from xml.parsers.expat import ExpatError -import datetime -import decimal -from io import BytesIO - - -__all__ = ( - 'BaseParser', - 'JSONParser', - 'PlainTextParser', - 'FormParser', - 'MultiPartParser', - 'YAMLParser', - 'XMLParser' -) - - -class DataAndFiles(object): - def __init__(self, data, files): - self.data = data - self.files = files - - -class BaseParser(object): - """ - All parsers should extend :class:`BaseParser`, specifying a :attr:`media_type` attribute, - and overriding the :meth:`parse` method. - """ - - media_type = None - - def can_handle_request(self, content_type): - """ - Returns :const:`True` if this parser is able to deal with the given *content_type*. - - The default implementation for this function is to check the *content_type* - argument against the :attr:`media_type` attribute set on the class to see if - they match. - - This may be overridden to provide for other behavior, but typically you'll - instead want to just set the :attr:`media_type` attribute on the class. - """ - return media_type_matches(self.media_type, content_type) - - def parse(self, string_or_stream, **opts): - """ - The main entry point to parsers. This is a light wrapper around - `parse_stream`, that instead handles both string and stream objects. - """ - if isinstance(string_or_stream, basestring): - stream = BytesIO(string_or_stream) - else: - stream = string_or_stream - return self.parse_stream(stream, **opts) - - def parse_stream(self, stream, **opts): - """ - Given a *stream* to read from, return the deserialized output. - Should return parsed data, or a DataAndFiles object consisting of the - parsed data and files. - """ - raise NotImplementedError(".parse_stream() must be overridden.") - - -class JSONParser(BaseParser): - """ - Parses JSON-serialized data. - """ - - media_type = 'application/json' - - def parse_stream(self, stream, **opts): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will be an object which is the parsed content of the response. - `files` will always be `None`. - """ - try: - return json.load(stream) - except ValueError, exc: - raise ParseError('JSON parse error - %s' % unicode(exc)) - - -class YAMLParser(BaseParser): - """ - Parses YAML-serialized data. - """ - - media_type = 'application/yaml' - - def parse_stream(self, stream, **opts): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will be an object which is the parsed content of the response. - `files` will always be `None`. - """ - try: - return yaml.safe_load(stream) - except (ValueError, yaml.parser.ParserError), exc: - raise ParseError('YAML parse error - %s' % unicode(exc)) - - -class PlainTextParser(BaseParser): - """ - Plain text parser. - """ - - media_type = 'text/plain' - - def parse_stream(self, stream, **opts): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will simply be a string representing the body of the request. - `files` will always be `None`. - """ - return stream.read() - - -class FormParser(BaseParser): - """ - Parser for form data. - """ - - media_type = 'application/x-www-form-urlencoded' - - def parse_stream(self, stream, **opts): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will be a :class:`QueryDict` containing all the form parameters. - `files` will always be :const:`None`. - """ - data = QueryDict(stream.read()) - return data - - -class MultiPartParser(BaseParser): - """ - Parser for multipart form data, which may include file data. - """ - - media_type = 'multipart/form-data' - - def parse_stream(self, stream, **opts): - """ - Returns a DataAndFiles object. - - `.data` will be a `QueryDict` containing all the form parameters. - `.files` will be a `QueryDict` containing all the form files. - """ - meta = opts['meta'] - upload_handlers = opts['upload_handlers'] - try: - parser = DjangoMultiPartParser(meta, stream, upload_handlers) - data, files = parser.parse() - return DataAndFiles(data, files) - except MultiPartParserError, exc: - raise ParseError('Multipart form parse error - %s' % unicode(exc)) - - -class XMLParser(BaseParser): - """ - XML parser. - """ - - media_type = 'application/xml' - - def parse_stream(self, stream, **opts): - try: - tree = ET.parse(stream) - except (ExpatError, ETParseError, ValueError), exc: - raise ParseError('XML parse error - %s' % unicode(exc)) - data = self._xml_convert(tree.getroot()) - - return data - - def _xml_convert(self, element): - """ - convert the xml `element` into the corresponding python object - """ - - children = element.getchildren() - - if len(children) == 0: - return self._type_convert(element.text) - else: - # if the fist child tag is list-item means all children are list-item - if children[0].tag == "list-item": - data = [] - for child in children: - data.append(self._xml_convert(child)) - else: - data = {} - for child in children: - data[child.tag] = self._xml_convert(child) - - return data - - def _type_convert(self, value): - """ - Converts the value returned by the XMl parse into the equivalent - Python type - """ - if value is None: - return value - - try: - return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') - except ValueError: - pass - - try: - return int(value) - except ValueError: - pass - - try: - return decimal.Decimal(value) - except decimal.InvalidOperation: - pass - - return value - - -DEFAULT_PARSERS = ( - JSONParser, - FormParser, - MultiPartParser, - XMLParser -) - -if yaml: - DEFAULT_PARSERS += (YAMLParser, ) -else: - YAMLParser = None -- cgit v1.2.3