From 44b611919678871d544335808abe8bf2b962b606 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Oct 2016 15:45:33 +0100 Subject: [PATCH 1/2] Version 3.5.0 --- docs/api-guide/schemas.md | 47 +++++- docs/api-guide/testing.md | 4 +- docs/img/raml.png | Bin 0 -> 37216 bytes docs/index.md | 2 + docs/topics/3.5-announcement.md | 266 ++++++++++++++++++++++++++++++++ docs/topics/api-clients.md | 2 +- mkdocs.yml | 1 + 7 files changed, 315 insertions(+), 7 deletions(-) create mode 100644 docs/img/raml.png create mode 100644 docs/topics/3.5-announcement.md diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 16d2bbb011..7da6190345 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -344,12 +344,12 @@ Typically you'll instantiate `SchemaGenerator` with a single argument, like so: Arguments: -* `title` - The name of the API. **required** +* `title` **required** - The name of the API. * `url` - The root URL of the API schema. This option is not required unless the schema is included under path prefix. * `patterns` - A list of URLs to inspect when generating the schema. Defaults to the project's URL conf. * `urlconf` - A URL conf module name to use when generating the schema. Defaults to `settings.ROOT_URLCONF`. -### get_schema() +### get_schema(self, request) Returns a `coreapi.Document` instance that represents the API schema. @@ -359,9 +359,48 @@ Returns a `coreapi.Document` instance that represents the API schema. generator = schemas.SchemaGenerator(title='Bookings API') return Response(generator.get_schema()) -Arguments: +The `request` argument is optional, and may be used if you want to apply per-user +permissions to the resulting schema generation. + +### get_links(self, request) + +Return a nested dictionary containing all the links that should be included in the API schema. + +This is a good point to override if you want to modify the resulting structure of the generated schema, +as you can build a new dictionary with a different layout. + +### get_link(self, path, method, view) + +Returns a `coreapi.Link` instance corresponding to the given view. + +You can override this if you need to provide custom behaviors for particular views. + +### get_description(self, path, method, view) + +Returns a string to use as the link description. By default this is based on the +view docstring as described in the "Schemas as Documentation" section above. + +### get_encoding(self, path, method, view) + +Returns a string to indicate the encoding for any request body, when interacting +with the given view. Eg. `'application/json'`. May return a blank string for views +that do not expect a request body. + +### get_path_fields(self, path, method, view): + +Return a list of `coreapi.Link()` instances. One for each path parameter in the URL. + +### get_serializer_fields(self, path, method, view) + +Return a list of `coreapi.Link()` instances. One for each field in the serializer class used by the view. + +### get_pagination_fields(self, path, method, view + +Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fields()` method on any pagination class used by the view. + +### get_filter_fields(self, path, method, view) -* `request` - The incoming request. Optionally used if you want to apply per-user permissions to the schema-generation. +Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fields()` method of any filter classes used by the view. --- diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index fdd60b7f4c..1f8c892339 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -194,6 +194,7 @@ directly. client = RequestsClient() response = client.get('http://testserver/users/') + assert response.status_code == 200 Note that the requests client requires you to pass fully qualified URLs. @@ -251,9 +252,8 @@ The CoreAPIClient allows you to interact with your API using the Python `coreapi` client library. # Fetch the API schema - url = reverse('schema') client = CoreAPIClient() - schema = client.get(url) + schema = client.get('http://testserver/schema/') # Create a new organisation params = {'name': 'MegaCorp', 'status': 'active'} diff --git a/docs/img/raml.png b/docs/img/raml.png new file mode 100644 index 0000000000000000000000000000000000000000..87790dc484f9c6c0617189ae2766bdc1e00a3bfa GIT binary patch literal 37216 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 literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 3019467eda..9b0913f00a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -244,6 +244,7 @@ General guides to using REST framework. * [3.2 Announcement][3.2-announcement] * [3.3 Announcement][3.3-announcement] * [3.4 Announcement][3.4-announcement] +* [3.5 Announcement][3.5-announcement] * [Kickstarter Announcement][kickstarter-announcement] * [Mozilla Grant][mozilla-grant] * [Funding][funding] @@ -370,6 +371,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [3.2-announcement]: topics/3.2-announcement.md [3.3-announcement]: topics/3.3-announcement.md [3.4-announcement]: topics/3.4-announcement.md +[3.5-announcement]: topics/3.5-announcement.md [kickstarter-announcement]: topics/kickstarter-announcement.md [mozilla-grant]: topics/mozilla-grant.md [funding]: topics/funding.md diff --git a/docs/topics/3.5-announcement.md b/docs/topics/3.5-announcement.md new file mode 100644 index 0000000000..2ed8adf8e4 --- /dev/null +++ b/docs/topics/3.5-announcement.md @@ -0,0 +1,266 @@ + + +# Django REST framework 3.5 + +The 3.5 release is the second in a planned series that is addressing schema +generation, hypermedia support, API client libraries, and finally realtime support. + +--- + +## Funding + +The 3.5 release would not have been possible without our [collaborative funding model][funding]. +If you use REST framework commercially and would like to see this work continue, +we strongly encourage you to invest in its continued development by +**[signing up for a paid plan][funding]**. + + +
+ +*Many thanks to all our [sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), and [Machinalis](http://www.machinalis.com/#services).* + +--- + +## Improved schema generation + +Docstrings on views are now pulled through into schema definitions, allowing +you to [use the schema definition to document your API][schema-docs]. + +There is now also a shortcut function, `get_schema_view()`, which makes it easier to +[adding schema views][schema-view] to your API. + +For example, to include a swagger schema to your API, you would do the following: + +* Run `pip install django-rest-swagger`. + +* Add `'rest_framework_swagger'` to your `INSTALLED_APPS` setting. + +* Include the schema view in your URL conf: + +```py +from rest_framework.schemas import get_schema_view +from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer + +schema_view = get_schema_view( + title='Example API', + renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer] +) + +urlpatterns = [ + url(r'^swagger/$', schema_view), + ... +] +``` + +There have been a large number of fixes to the schema generation. These should +resolve issues for anyone using the latest version of the `django-rest-swagger` +package. + +Some of these changes do affect the resulting schema structure, +so if you're already using schema generation you should make sure to review +[the deprecation notes](#deprecations), particularly if you're currently using +a dynamic client library to interact with your API. + +Finally, we're also now exposing the schema generation as a +[publicly documented API][schema-generation-api], allowing you to more easily +override the behaviour. + +## Requests test client + +You can now test your project using the `requests` library. + +This exposes exactly the same interface as if you were using a standard +requests session instance. + + client = RequestsClient() + response = client.get('http://testserver/users/') + assert response.status_code == 200 + +Rather than sending any HTTP requests to the network, this interface will +coerce all outgoing requests into WSGI, and call into your application directly. + +## Core API client + +You can also now test your project by interacting with it using the `coreapi` +client library. + + # Fetch the API schema + client = CoreAPIClient() + schema = client.get('http://testserver/schema/') + + # Create a new organisation + params = {'name': 'MegaCorp', 'status': 'active'} + client.action(schema, ['organisations', 'create'], params) + + # Ensure that the organisation exists in the listing + data = client.action(schema, ['organisations', 'list']) + assert(len(data) == 1) + assert(data == [{'name': 'MegaCorp', 'status': 'active'}]) + +Again, this will call directly into the application using the WSGI interface, +rather than making actual network calls. + +This is a good option if you are planning for clients to mainly interact with +your API using the `coreapi` client library, or some other auto-generated client. + +## Live tests + +One interesting aspect of both the `requests` client and the `coreapi` client +is that they allow you to write tests in such a way that they can also be made +to run against a live service. + +By switching the WSGI based client instances to actual instances of `requests.Session` +or `coreapi.Client` you can have the test cases make actual network calls. + +Being able to write test cases that can exercise your staging or production +environment is a powerful tool. However in order to do this, you'll need to pay +close attention to how you handle setup and teardown to ensure a strict isolation +of test data from other live or staging data. + +## RAML support + +We now have preliminary support for [RAML documentation generation][django-rest-raml]. + +![RAML Example][raml-image] + +Further work on the encoding and documentation generation is planned, in order to +make features such as the 'Try it now' support available at a later date. + +This work also now means that you can use the Core API client libraries to interact +with APIs that expose a RAML specification. The [RAML codec][raml-codec] gives some examples of +interacting with the Spotify API in this way. + +## Validation codes + +Exceptions raised by REST framework now include short code identifiers. +When used together with our customizable error handling, this now allows you to +modify the style of API error messages. + +As an example, this allows for the following style of error responses: + + { + "message": "You do not have permission to perform this action.", + "code": "permission_denied" + } + +This is particularly useful with validation errors, which use appropriate +codes to identify differing kinds of failure... + + { + "name": {"message": "This field is required.", "code": "required"}, + "age": {"message": "A valid integer is required.", "code": "invalid"} + } + +## Client upload & download support + +The Python `coreapi` client library and the Core API command line tool both +now fully support file [uploads][uploads] and [downloads][downloads]. + +--- + +## Deprecations + +### Generating schemas from Router + +The router arguments for generating a schema view, such as `schema_title`, +are now pending deprecation. + +Instead of using `DefaultRouter(schema_title='Example API')`, you should use +the `get_schema_view()` function, and include the view in your URL conf. + +Make sure to include the view before your router urls. For example: + + from rest_framework.schemas import get_schema_view + from my_project.routers import router + + schema_view = get_schema_view(title='Example API') + + urlpatterns = [ + url('^$', schema_view), + url(r'^', include(router.urls)), + ] + +### Schema path representations + +The `'pk'` identifier in schema paths is now mapped onto the actually model field +name by default. This will typically be `'id'`. + +This gives a better external representation for schemas, with less implementation +detail being exposed. It also reflects the behaviour of using a ModelSerializer +class with `fields = '__all__'`. + +You can revert to the previous behaviour by setting `'SCHEMA_COERCE_PATH_PK': False` +in the REST framework settings. + +### Schema action name representations + +The internal `retrieve()` and `destroy()` method names are now coerced to an +external representation of `read` and `delete`. + +You can revert to the previous behaviour by setting `'SCHEMA_COERCE_METHOD_NAMES': {}` +in the REST framework settings. + +### DjangoFilterBackend + +The functionality of the built-in `DjangoFilterBackend` is now completely +included by the `django-filter` package. + +You should change your imports and REST framework filter settings as follows: + +* `rest_framework.filters.DjangoFilterBackend` becomes `django_filters.rest_framework.DjangoFilterBackend`. +* `rest_framework.filters.FilterSet` becomes `django_filters.rest_framework.FilterSet`. + +The existing imports will continue to work but are now pending deprecation. + +### CoreJSON media type + +The media type for `CoreJSON` is now `application/json+coreapi`, rather than +the previous `application/vnd.json+coreapi`. This brings it more into line with +other custom media types, such as those used by Swagger and RAML. + +The clients currently accept either media type. The old style-media type will +be deprecated at a later date. + +### ModelSerializer 'fields' and 'exclude' + +ModelSerializer and HyperlinkedModelSerializer must include either a fields +option, or an exclude option. The fields = '__all__' shortcut may be used to +explicitly include all fields. + +Failing to set either `fields` or `exclude` raised a pending deprecation warning +in version 3.3 and raised a deprecation warning in 3.4. Its usage is now mandatory. + +--- + +[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors +[funding]: funding.md +[uploads]: http://core-api.github.io/python-client/api-guide/utils/#file +[downloads]: http://core-api.github.io/python-client/api-guide/codecs/#downloadcodec +[schema-generation-api]: ../api-guide/schemas/#schemagenerator +[schema-docs]: ../api-guide/schemas/#schemas-as-documentation +[schema-view]: ../api-guide/schemas/#the-get_schema_view-shortcut +[django-rest-raml]: https://github.com/tomchristie/django-rest-raml +[raml-image]: ../img/raml.png +[raml-codec]: https://github.com/core-api/python-raml-codec diff --git a/docs/topics/api-clients.md b/docs/topics/api-clients.md index f17f5e4d42..c12551aa62 100644 --- a/docs/topics/api-clients.md +++ b/docs/topics/api-clients.md @@ -257,7 +257,7 @@ Codecs are responsible for encoding or decoding Documents. The decoding process is used by a client to take a bytestring of an API schema definition, and returning the Core API `Document` that represents that interface. -A codec should be associated with a particular media type, such as **TODO**. +A codec should be associated with a particular media type, such as `'application/coreapi+json'`. This media type is used by the server in the response `Content-Type` header, in order to indicate what kind of data is being returned in the response. diff --git a/mkdocs.yml b/mkdocs.yml index 0b89988b1c..01c59caaa3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -66,6 +66,7 @@ pages: - '3.2 Announcement': 'topics/3.2-announcement.md' - '3.3 Announcement': 'topics/3.3-announcement.md' - '3.4 Announcement': 'topics/3.4-announcement.md' + - '3.5 Announcement': 'topics/3.5-announcement.md' - 'Kickstarter Announcement': 'topics/kickstarter-announcement.md' - 'Mozilla Grant': 'topics/mozilla-grant.md' - 'Funding': 'topics/funding.md' From ea6eb07b2feb4b87ca21c2248c3bc4cd4d7c7605 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Oct 2016 15:52:45 +0100 Subject: [PATCH 2/2] Placeholder for 3.5 release notes --- docs/topics/release-notes.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 446abdd14a..30244f6d28 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -38,6 +38,14 @@ You can determine your currently installed version using `pip freeze`: --- +## 3.5.x series + +### 3.5.0 + +**Date**: [20th October 2016][3.5.0-milestone] + +--- + ## 3.4.x series ### 3.4.7 @@ -596,6 +604,7 @@ For older release notes, [please see the version 2.x documentation][old-release- [3.4.5-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.5+Release%22 [3.4.6-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.6+Release%22 [3.4.7-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.7+Release%22 +[3.5.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.0+Release%22 [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013