Skip to content

Commit 3b9afb5

Browse files
authored
Version 3.5.0 (encode#4596)
1 parent 2395fb5 commit 3b9afb5

File tree

8 files changed

+324
-7
lines changed

8 files changed

+324
-7
lines changed

docs/api-guide/schemas.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,12 @@ Typically you'll instantiate `SchemaGenerator` with a single argument, like so:
344344

345345
Arguments:
346346

347-
* `title` - The name of the API. **required**
347+
* `title` **required** - The name of the API.
348348
* `url` - The root URL of the API schema. This option is not required unless the schema is included under path prefix.
349349
* `patterns` - A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.
350350
* `urlconf` - A URL conf module name to use when generating the schema. Defaults to `settings.ROOT_URLCONF`.
351351

352-
### get_schema()
352+
### get_schema(self, request)
353353

354354
Returns a `coreapi.Document` instance that represents the API schema.
355355

@@ -359,9 +359,48 @@ Returns a `coreapi.Document` instance that represents the API schema.
359359
generator = schemas.SchemaGenerator(title='Bookings API')
360360
return Response(generator.get_schema())
361361

362-
Arguments:
362+
The `request` argument is optional, and may be used if you want to apply per-user
363+
permissions to the resulting schema generation.
364+
365+
### get_links(self, request)
366+
367+
Return a nested dictionary containing all the links that should be included in the API schema.
368+
369+
This is a good point to override if you want to modify the resulting structure of the generated schema,
370+
as you can build a new dictionary with a different layout.
371+
372+
### get_link(self, path, method, view)
373+
374+
Returns a `coreapi.Link` instance corresponding to the given view.
375+
376+
You can override this if you need to provide custom behaviors for particular views.
377+
378+
### get_description(self, path, method, view)
379+
380+
Returns a string to use as the link description. By default this is based on the
381+
view docstring as described in the "Schemas as Documentation" section above.
382+
383+
### get_encoding(self, path, method, view)
384+
385+
Returns a string to indicate the encoding for any request body, when interacting
386+
with the given view. Eg. `'application/json'`. May return a blank string for views
387+
that do not expect a request body.
388+
389+
### get_path_fields(self, path, method, view):
390+
391+
Return a list of `coreapi.Link()` instances. One for each path parameter in the URL.
392+
393+
### get_serializer_fields(self, path, method, view)
394+
395+
Return a list of `coreapi.Link()` instances. One for each field in the serializer class used by the view.
396+
397+
### get_pagination_fields(self, path, method, view
398+
399+
Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fields()` method on any pagination class used by the view.
400+
401+
### get_filter_fields(self, path, method, view)
363402

364-
* `request` - The incoming request. Optionally used if you want to apply per-user permissions to the schema-generation.
403+
Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fields()` method of any filter classes used by the view.
365404

366405
---
367406

docs/api-guide/testing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ directly.
194194

195195
client = RequestsClient()
196196
response = client.get('http://testserver/users/')
197+
assert response.status_code == 200
197198

198199
Note that the requests client requires you to pass fully qualified URLs.
199200

@@ -251,9 +252,8 @@ The CoreAPIClient allows you to interact with your API using the Python
251252
`coreapi` client library.
252253

253254
# Fetch the API schema
254-
url = reverse('schema')
255255
client = CoreAPIClient()
256-
schema = client.get(url)
256+
schema = client.get('http://testserver/schema/')
257257

258258
# Create a new organisation
259259
params = {'name': 'MegaCorp', 'status': 'active'}

docs/img/raml.png

36.3 KB
Loading

docs/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ General guides to using REST framework.
244244
* [3.2 Announcement][3.2-announcement]
245245
* [3.3 Announcement][3.3-announcement]
246246
* [3.4 Announcement][3.4-announcement]
247+
* [3.5 Announcement][3.5-announcement]
247248
* [Kickstarter Announcement][kickstarter-announcement]
248249
* [Mozilla Grant][mozilla-grant]
249250
* [Funding][funding]
@@ -370,6 +371,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
370371
[3.2-announcement]: topics/3.2-announcement.md
371372
[3.3-announcement]: topics/3.3-announcement.md
372373
[3.4-announcement]: topics/3.4-announcement.md
374+
[3.5-announcement]: topics/3.5-announcement.md
373375
[kickstarter-announcement]: topics/kickstarter-announcement.md
374376
[mozilla-grant]: topics/mozilla-grant.md
375377
[funding]: topics/funding.md

docs/topics/3.5-announcement.md

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
<style>
2+
.promo li a {
3+
float: left;
4+
width: 130px;
5+
height: 20px;
6+
text-align: center;
7+
margin: 10px 30px;
8+
padding: 150px 0 0 0;
9+
background-position: 0 50%;
10+
background-size: 130px auto;
11+
background-repeat: no-repeat;
12+
font-size: 120%;
13+
color: black;
14+
}
15+
.promo li {
16+
list-style: none;
17+
}
18+
</style>
19+
20+
# Django REST framework 3.5
21+
22+
The 3.5 release is the second in a planned series that is addressing schema
23+
generation, hypermedia support, API client libraries, and finally realtime support.
24+
25+
---
26+
27+
## Funding
28+
29+
The 3.5 release would not have been possible without our [collaborative funding model][funding].
30+
If you use REST framework commercially and would like to see this work continue,
31+
we strongly encourage you to invest in its continued development by
32+
**[signing up for a paid&nbsp;plan][funding]**.
33+
34+
<ul class="premium-promo promo">
35+
<li><a href="http://jobs.rover.com/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/rover_130x130.png)">Rover.com</a></li>
36+
<li><a href="https://getsentry.com/welcome/" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/sentry130.png)">Sentry</a></li>
37+
<li><a href="https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/stream-130.png)">Stream</a></li>
38+
<li><a href="http://www.machinalis.com/#services" style="background-image: url(https://fund-rest-framework.s3.amazonaws.com/Machinalis130.png)">Machinalis</a></li>
39+
</ul>
40+
<div style="clear: both; padding-bottom: 20px;"></div>
41+
42+
*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).*
43+
44+
---
45+
46+
## Improved schema generation
47+
48+
Docstrings on views are now pulled through into schema definitions, allowing
49+
you to [use the schema definition to document your&nbsp;API][schema-docs].
50+
51+
There is now also a shortcut function, `get_schema_view()`, which makes it easier to
52+
[adding schema views][schema-view] to your API.
53+
54+
For example, to include a swagger schema to your API, you would do the following:
55+
56+
* Run `pip install django-rest-swagger`.
57+
58+
* Add `'rest_framework_swagger'` to your `INSTALLED_APPS` setting.
59+
60+
* Include the schema view in your URL conf:
61+
62+
```py
63+
from rest_framework.schemas import get_schema_view
64+
from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer
65+
66+
schema_view = get_schema_view(
67+
title='Example API',
68+
renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer]
69+
)
70+
71+
urlpatterns = [
72+
url(r'^swagger/$', schema_view),
73+
...
74+
]
75+
```
76+
77+
There have been a large number of fixes to the schema generation. These should
78+
resolve issues for anyone using the latest version of the `django-rest-swagger`
79+
package.
80+
81+
Some of these changes do affect the resulting schema structure,
82+
so if you're already using schema generation you should make sure to review
83+
[the deprecation notes](#deprecations), particularly if you're currently using
84+
a dynamic client library to interact with your API.
85+
86+
Finally, we're also now exposing the schema generation as a
87+
[publicly documented API][schema-generation-api], allowing you to more easily
88+
override the behaviour.
89+
90+
## Requests test client
91+
92+
You can now test your project using the `requests` library.
93+
94+
This exposes exactly the same interface as if you were using a standard
95+
requests session instance.
96+
97+
client = RequestsClient()
98+
response = client.get('http://testserver/users/')
99+
assert response.status_code == 200
100+
101+
Rather than sending any HTTP requests to the network, this interface will
102+
coerce all outgoing requests into WSGI, and call into your application directly.
103+
104+
## Core API client
105+
106+
You can also now test your project by interacting with it using the `coreapi`
107+
client library.
108+
109+
# Fetch the API schema
110+
client = CoreAPIClient()
111+
schema = client.get('http://testserver/schema/')
112+
113+
# Create a new organisation
114+
params = {'name': 'MegaCorp', 'status': 'active'}
115+
client.action(schema, ['organisations', 'create'], params)
116+
117+
# Ensure that the organisation exists in the listing
118+
data = client.action(schema, ['organisations', 'list'])
119+
assert(len(data) == 1)
120+
assert(data == [{'name': 'MegaCorp', 'status': 'active'}])
121+
122+
Again, this will call directly into the application using the WSGI interface,
123+
rather than making actual network calls.
124+
125+
This is a good option if you are planning for clients to mainly interact with
126+
your API using the `coreapi` client library, or some other auto-generated client.
127+
128+
## Live tests
129+
130+
One interesting aspect of both the `requests` client and the `coreapi` client
131+
is that they allow you to write tests in such a way that they can also be made
132+
to run against a live service.
133+
134+
By switching the WSGI based client instances to actual instances of `requests.Session`
135+
or `coreapi.Client` you can have the test cases make actual network calls.
136+
137+
Being able to write test cases that can exercise your staging or production
138+
environment is a powerful tool. However in order to do this, you'll need to pay
139+
close attention to how you handle setup and teardown to ensure a strict isolation
140+
of test data from other live or staging data.
141+
142+
## RAML support
143+
144+
We now have preliminary support for [RAML documentation generation][django-rest-raml].
145+
146+
![RAML Example][raml-image]
147+
148+
Further work on the encoding and documentation generation is planned, in order to
149+
make features such as the 'Try it now' support available at a later date.
150+
151+
This work also now means that you can use the Core API client libraries to interact
152+
with APIs that expose a RAML specification. The [RAML codec][raml-codec] gives some examples of
153+
interacting with the Spotify API in this way.
154+
155+
## Validation codes
156+
157+
Exceptions raised by REST framework now include short code identifiers.
158+
When used together with our customizable error handling, this now allows you to
159+
modify the style of API error messages.
160+
161+
As an example, this allows for the following style of error responses:
162+
163+
{
164+
"message": "You do not have permission to perform this action.",
165+
"code": "permission_denied"
166+
}
167+
168+
This is particularly useful with validation errors, which use appropriate
169+
codes to identify differing kinds of failure...
170+
171+
{
172+
"name": {"message": "This field is required.", "code": "required"},
173+
"age": {"message": "A valid integer is required.", "code": "invalid"}
174+
}
175+
176+
## Client upload & download support
177+
178+
The Python `coreapi` client library and the Core API command line tool both
179+
now fully support file [uploads][uploads] and [downloads][downloads].
180+
181+
---
182+
183+
## Deprecations
184+
185+
### Generating schemas from Router
186+
187+
The router arguments for generating a schema view, such as `schema_title`,
188+
are now pending deprecation.
189+
190+
Instead of using `DefaultRouter(schema_title='Example API')`, you should use
191+
the `get_schema_view()` function, and include the view in your URL conf.
192+
193+
Make sure to include the view before your router urls. For example:
194+
195+
from rest_framework.schemas import get_schema_view
196+
from my_project.routers import router
197+
198+
schema_view = get_schema_view(title='Example API')
199+
200+
urlpatterns = [
201+
url('^$', schema_view),
202+
url(r'^', include(router.urls)),
203+
]
204+
205+
### Schema path representations
206+
207+
The `'pk'` identifier in schema paths is now mapped onto the actually model field
208+
name by default. This will typically be `'id'`.
209+
210+
This gives a better external representation for schemas, with less implementation
211+
detail being exposed. It also reflects the behaviour of using a ModelSerializer
212+
class with `fields = '__all__'`.
213+
214+
You can revert to the previous behaviour by setting `'SCHEMA_COERCE_PATH_PK': False`
215+
in the REST framework settings.
216+
217+
### Schema action name representations
218+
219+
The internal `retrieve()` and `destroy()` method names are now coerced to an
220+
external representation of `read` and `delete`.
221+
222+
You can revert to the previous behaviour by setting `'SCHEMA_COERCE_METHOD_NAMES': {}`
223+
in the REST framework settings.
224+
225+
### DjangoFilterBackend
226+
227+
The functionality of the built-in `DjangoFilterBackend` is now completely
228+
included by the `django-filter` package.
229+
230+
You should change your imports and REST framework filter settings as follows:
231+
232+
* `rest_framework.filters.DjangoFilterBackend` becomes `django_filters.rest_framework.DjangoFilterBackend`.
233+
* `rest_framework.filters.FilterSet` becomes `django_filters.rest_framework.FilterSet`.
234+
235+
The existing imports will continue to work but are now pending deprecation.
236+
237+
### CoreJSON media type
238+
239+
The media type for `CoreJSON` is now `application/json+coreapi`, rather than
240+
the previous `application/vnd.json+coreapi`. This brings it more into line with
241+
other custom media types, such as those used by Swagger and RAML.
242+
243+
The clients currently accept either media type. The old style-media type will
244+
be deprecated at a later date.
245+
246+
### ModelSerializer 'fields' and 'exclude'
247+
248+
ModelSerializer and HyperlinkedModelSerializer must include either a fields
249+
option, or an exclude option. The fields = '__all__' shortcut may be used to
250+
explicitly include all fields.
251+
252+
Failing to set either `fields` or `exclude` raised a pending deprecation warning
253+
in version 3.3 and raised a deprecation warning in 3.4. Its usage is now mandatory.
254+
255+
---
256+
257+
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
258+
[funding]: funding.md
259+
[uploads]: http://core-api.github.io/python-client/api-guide/utils/#file
260+
[downloads]: http://core-api.github.io/python-client/api-guide/codecs/#downloadcodec
261+
[schema-generation-api]: ../api-guide/schemas/#schemagenerator
262+
[schema-docs]: ../api-guide/schemas/#schemas-as-documentation
263+
[schema-view]: ../api-guide/schemas/#the-get_schema_view-shortcut
264+
[django-rest-raml]: https://github.com/tomchristie/django-rest-raml
265+
[raml-image]: ../img/raml.png
266+
[raml-codec]: https://github.com/core-api/python-raml-codec

docs/topics/api-clients.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ Codecs are responsible for encoding or decoding Documents.
257257
The decoding process is used by a client to take a bytestring of an API schema
258258
definition, and returning the Core API `Document` that represents that interface.
259259

260-
A codec should be associated with a particular media type, such as **TODO**.
260+
A codec should be associated with a particular media type, such as `'application/coreapi+json'`.
261261

262262
This media type is used by the server in the response `Content-Type` header,
263263
in order to indicate what kind of data is being returned in the response.

docs/topics/release-notes.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ You can determine your currently installed version using `pip freeze`:
3838

3939
---
4040

41+
## 3.5.x series
42+
43+
### 3.5.0
44+
45+
**Date**: [20th October 2016][3.5.0-milestone]
46+
47+
---
48+
4149
## 3.4.x series
4250

4351
### 3.4.7
@@ -596,6 +604,7 @@ For older release notes, [please see the version 2.x documentation][old-release-
596604
[3.4.5-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.5+Release%22
597605
[3.4.6-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.6+Release%22
598606
[3.4.7-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.7+Release%22
607+
[3.5.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.0+Release%22
599608

600609
<!-- 3.0.1 -->
601610
[gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013

0 commit comments

Comments
 (0)