@@ -6,67 +6,69 @@ Upgrade notes
6
6
Upgrading to version 1.0.0
7
7
--------------------------
8
8
9
- The release ``1.0.0 `` of the DEEPaaS API implementes several backwards
9
+ The release ``1.0.0 `` of the DEEPaaS API implements several backwards
10
10
incompatible changes when compared with the previous releases in the ``0.X.X ``
11
11
series. Before upgrading your code and deploying into production, read the
12
12
following, as changes are needed in your model. Please go through the following
13
13
checklist in order.
14
14
15
- * Migrate new namespace entry point .
15
+ * ** Migrate new namespace entry point. **
16
16
17
17
Previous code relied on a top-level entry point named ``deepaas.model ``,
18
18
where we searched for the required functions or methods to be invoked for
19
19
each API action.
20
20
21
21
Now the namespace has changed to ``deepaas.v2.model ``.
22
22
23
- Therefore, assumming that your code for V1 of the API was under the
23
+ Therefore, assuming that your code for V1 of the API was under the
24
24
``my_model.api `` and you defined your the entry point as follows:
25
25
26
- .. code-block :: ini
26
+ .. code-block :: ini
27
27
28
- [entry_points]
28
+ [entry_points]
29
29
30
- deepaas.model =
31
- my_model = my_model.api
30
+ deepaas.model =
31
+ my_model = my_model.api
32
32
33
- You should migrate to the following:
33
+ You should migrate to the following:
34
34
35
- .. code-block :: ini
35
+ .. code-block :: ini
36
36
37
37
[entry_points]
38
38
39
39
deepaas.v2.model =
40
40
my_model = my_model.api
41
41
42
- .. note ::
43
- If you do not change the namespace, we will try to load the old
44
- entrypoint. However, this is deprecated and you should upgrade as soon as
45
- possible.
42
+ .. note ::
43
+ If you do not change the namespace, we will try to load the old
44
+ entrypoint. However, this is deprecated and you should upgrade as soon as
45
+ possible.
46
46
47
- * Migrate from returning dictionaries to use an argument parser to define
48
- train and predict arguments.
47
+ * ** Migrate from returning dictionaries to use an argument parser to define
48
+ train and predict arguments. **
49
49
50
- Previous code relied on returing arbitrary dictionaries that were used to
50
+ Previous code relied on returning arbitrary dictionaries that were used to
51
51
generate the arguments for each of the API endpoints. This is not anymore
52
- supported and you should return a ``webargs `` field dictioary. This is still
53
- done by defining the ``get_predict_args `` and ``fet_train_args `` functions.
52
+ supported and you should return a ``webargs `` field dictionary (check
53
+ `here <https://marshmallow.readthedocs.io/en/latest/api_reference.html#module-marshmallow.fields >`_
54
+ for a full reference of the available options). This is still
55
+ done by defining the ``get_predict_args `` and ``get_train_args `` functions.
54
56
These functions must receive no arguments and they should return a dictionary
55
57
as follows::
56
58
57
- from webargs import fields
58
-
59
- (...)
59
+ from webargs import fields
60
60
61
- def get_predict_args():
62
- return {
63
- "arg1": fields.Str(
64
- required=False,
65
- default="foo",
66
- description="Argument one"
67
- ),
68
- }
61
+ (...)
69
62
63
+ def get_predict_args():
64
+ return {
65
+ "arg1": fields.Str(
66
+ required=False, # force the user to define the value
67
+ missing="foo", # default value to use
68
+ enum=["choice1", "choice2"], # list of choices
69
+ description="Argument one" # help string
70
+ ),
71
+ }
70
72
71
73
.. note ::
72
74
If you do still follow the old way of returning the arguments we will try
@@ -75,34 +77,83 @@ checklist in order.
75
77
soon as possible. All the arguments will be converted to Strings,
76
78
therefore you will loose any type checking, etc.
77
79
78
- * Explictly define your input arguments. The previous version of the API
80
+ * **Explicitly define your input arguments. **
81
+
82
+ The previous version of the API
79
83
defined two arguments for inference: ``data `` and ``urls ``. This is not
80
- anymore true, and you must define your own input arguments as follows::
84
+ anymore true, and you must define your own input arguments.
85
+ To replicate the response of v1 you have to define::
81
86
82
87
from webargs import fields
83
88
84
89
(...)
85
90
86
91
def get_predict_args():
87
92
return {
88
- "data": fields.Field(
89
- required=True,
90
- type="file",
91
- location="form",
92
- ),
93
- }
94
-
95
- Then, you will get your input data in the ``data `` keyword argument in your
93
+ 'files': fields.Field(
94
+ required=False,
95
+ missing=None,
96
+ type="file",
97
+ data_key="data",
98
+ location="form",
99
+ description="Select the image you want to classify."),
100
+
101
+ 'urls': fields.Url(
102
+ required=False,
103
+ missing=None,
104
+ description="Select an URL of the image you want to classify.")
105
+ }
106
+
107
+ Then, you will get your input data in the ``data `` and ``urls `` keyword arguments in your
96
108
application.
97
109
98
- * Define your responses for the prediction. Now, unless you explicitly define
99
- your application response schema, whatever you return will be converted into
100
- a string and wrapped in the following response::
110
+ .. note ::
111
+ For the moment, in contrast with v1, only one url field at the same time is enabled,
112
+ although multi-url (along with multi-files) support is coming soon.
113
+
114
+ * **Define your responses for the prediction. **
115
+
116
+ Now, unless you explicitly define your application response schema,
117
+ whatever you return will be converted into a string and wrapped in the following response::
101
118
102
119
{
103
120
"status": "OK",
104
121
"predictions": "<model response as string>"
105
122
}
106
123
107
- * Arguments and now passed as unpacked keyword arguments, not anymore as a
108
- dictionary.
124
+ * **Change in the ``predict`` function name. **
125
+
126
+ The ``predict_url `` and ``predict_data `` functions have been merged into a single ``predict ``
127
+ function. In addition, arguments are now passed as unpacked keyword arguments, not anymore as a
128
+ dictionary. So if you want to upgrade to v2 with minimal code changes, you just have to add
129
+ the following function to your .py file::
130
+
131
+ def predict(**args):
132
+
133
+ if (not any([args['urls'], args['files']]) or
134
+ all([args['urls'], args['files']])):
135
+ raise Exception("You must provide either 'url' or 'data' in the payload")
136
+
137
+ if args['files']:
138
+ args['files'] = [args['files']] # patch until list is available
139
+ return predict_data(args)
140
+ elif args['urls']:
141
+ args['urls'] = [args['urls']] # patch until list is available
142
+ return predict_url(args)
143
+
144
+ * **Changes in the data response **
145
+
146
+ The return object in ``args['files'] `` is no longer a ``werkzeug.FileStorage `` but an
147
+ ``aiohttp.web_request.FileField ``.
148
+
149
+ The main difference is that now you should read the bytes using ``f.file.read() ``
150
+ instead of ``f.read() ``. Additional changes might be needed if you were also
151
+ using file information like content-type.
152
+
153
+ * **Catch error function **
154
+
155
+ The ``catch_error `` decorator around function is no longer needed.
156
+
157
+ * **API url **
158
+
159
+ Now the API functions are accessed under http://api_url/docs (eg. http://0.0.0.0:5000/docs)
0 commit comments