Skip to content

Commit 59f797d

Browse files
committed
Improve request payload docs (#1566)
(cherry picked from commit 7421966)
1 parent f6267f3 commit 59f797d

File tree

1 file changed

+172
-24
lines changed

1 file changed

+172
-24
lines changed

docs/deployments/realtime-api/predictors.md

Lines changed: 172 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -490,58 +490,206 @@ If your application requires additional dependencies, you can install additional
490490

491491
## API requests
492492

493-
The type of the `payload` parameter in `predict(self, payload)` can vary based on the content type of the request. The `payload` parameter is parsed according to the `Content-Type` header in the request:
493+
The type of the `payload` parameter in `predict(self, payload)` can vary based on the content type of the request. The `payload` parameter is parsed according to the `Content-Type` header in the request. Here are the parsing rules (see below for examples):
494494

495495
1. For `Content-Type: application/json`, `payload` will be the parsed JSON body.
496-
1. For `Content-Type: multipart/form-data` / `Content-Type: application/x-www-form-urlencoded`, `payload` will be `starlette.datastructures.FormData` (key-value pairs where the value is a `string` for form data, or `starlette.datastructures.UploadFile` for file uploads, see [Starlette's documentation](https://www.starlette.io/requests/#request-files)).
496+
1. For `Content-Type: multipart/form-data` / `Content-Type: application/x-www-form-urlencoded`, `payload` will be `starlette.datastructures.FormData` (key-value pairs where the values are strings for text data, or `starlette.datastructures.UploadFile` for file uploads; see [Starlette's documentation](https://www.starlette.io/requests/#request-files)).
497497
1. For all other `Content-Type` values, `payload` will be the raw `bytes` of the request body.
498498

499-
The `payload` parameter type will be a Python object (*lists*, *dicts*, *numbers*) if a request with a JSON payload is made:
499+
Here are some examples:
500+
501+
### JSON data
502+
503+
#### Making the request
504+
505+
##### Curl
500506

501507
```bash
502-
$ curl http://***.amazonaws.com/my-api \
508+
$ curl https://***.amazonaws.com/my-api \
503509
-X POST -H "Content-Type: application/json" \
504510
-d '{"key": "value"}'
505511
```
506512

507-
The `payload` parameter type will be a `bytes` object if a request with a `Content-Type: application/octet-stream` is made:
513+
Or if you have a json file:
508514

509515
```bash
510-
$ curl http://***.amazonaws.com/my-api \
511-
-X POST -H "Content-Type: application/octet-stream" \
512-
--data-binary @file.bin
516+
$ curl https://***.amazonaws.com/my-api \
517+
-X POST -H "Content-Type: application/json" \
518+
-d @file.json
513519
```
514520

515-
The `payload` parameter type will be a `bytes` object if a request doesn't have the `Content-Type` set:
521+
##### Python
516522

517-
```bash
518-
$ curl http://***.amazonaws.com/my-api \
519-
-X POST -H "Content-Type:" \
520-
-d @sample.txt
523+
```python
524+
import requests
525+
526+
url = "https://***.amazonaws.com/my-api"
527+
requests.post(url, json={"key": "value"})
521528
```
522529

523-
The `payload` parameter type will be a `starlette.datastructures.FormData` object if a request with a `Content-Type: multipart/form-data` is made:
530+
Or if you have a json string:
531+
532+
```python
533+
import requests
534+
import json
535+
536+
url = "https://***.amazonaws.com/my-api"
537+
jsonStr = json.dumps({"key": "value"})
538+
requests.post(url, data=jsonStr, headers={"Content-Type": "application/json"})
539+
```
540+
541+
#### Reading the payload
542+
543+
When sending a JSON payload, the `payload` parameter will be a Python object:
544+
545+
```python
546+
class PythonPredictor:
547+
def __init__(self, config):
548+
pass
549+
550+
def predict(self, payload):
551+
print(payload["key"]) # prints "value"
552+
```
553+
554+
### Binary data
555+
556+
#### Making the request
557+
558+
##### Curl
524559

525560
```bash
526-
$ curl http://***.amazonaws.com/my-api \
527-
-X POST -H "Content-Type: multipart/form-data" \
528-
-F "fieldName=@file.txt"
561+
$ curl https://***.amazonaws.com/my-api \
562+
-X POST -H "Content-Type: application/octet-stream" \
563+
--data-binary @object.pkl
564+
```
565+
566+
##### Python
567+
568+
```python
569+
import requests
570+
import pickle
571+
572+
url = "https://***.amazonaws.com/my-api"
573+
pklBytes = pickle.dumps({"key": "value"})
574+
requests.post(url, data=pklBytes, headers={"Content-Type": "application/octet-stream"})
575+
```
576+
577+
#### Reading the payload
578+
579+
Since the `Content-Type: application/octet-stream` header is used, the `payload` parameter will be a `bytes` object:
580+
581+
```python
582+
import pickle
583+
584+
class PythonPredictor:
585+
def __init__(self, config):
586+
pass
587+
588+
def predict(self, payload):
589+
obj = pickle.loads(payload)
590+
print(obj["key"]) # prints "value"
529591
```
530592

531-
The `payload` parameter type will be a `starlette.datastructures.FormData` object if a request with a `Content-Type: application/x-www-form-urlencoded` is made:
593+
Here's an example if the binary data is an image:
594+
595+
```python
596+
from PIL import Image
597+
import io
598+
599+
class PythonPredictor:
600+
def __init__(self, config):
601+
pass
602+
603+
def predict(self, payload, headers):
604+
img = Image.open(io.BytesIO(payload)) # read the payload bytes as an image
605+
print(img.size)
606+
```
607+
608+
### Form data (files)
609+
610+
#### Making the request
611+
612+
##### Curl
532613

533614
```bash
534-
$ curl http://***.amazonaws.com/my-api \
535-
-X POST -H "Content-Type: application/x-www-form-urlencoded" \
536-
-d @file.txt
615+
$ curl https://***.amazonaws.com/my-api \
616+
-X POST \
617+
-F "text=@text.txt" \
618+
-F "object=@object.pkl" \
619+
-F "image=@image.png"
620+
```
621+
622+
##### Python
623+
624+
```python
625+
import requests
626+
import pickle
627+
628+
url = "https://***.amazonaws.com/my-api"
629+
files = {
630+
"text": open("text.txt", "rb"),
631+
"object": open("object.pkl", "rb"),
632+
"image": open("image.png", "rb"),
633+
}
634+
635+
requests.post(url, files=files)
636+
```
637+
638+
#### Reading the payload
639+
640+
When sending files via form data, the `payload` parameter will be `starlette.datastructures.FormData` (key-value pairs where the values are `starlette.datastructures.UploadFile`, see [Starlette's documentation](https://www.starlette.io/requests/#request-files)). Either `Content-Type: multipart/form-data` or `Content-Type: application/x-www-form-urlencoded` can be used (typically `Content-Type: multipart/form-data` is used for files, and is the default in the examples above).
641+
642+
```python
643+
from PIL import Image
644+
import pickle
645+
646+
class PythonPredictor:
647+
def __init__(self, config):
648+
pass
649+
650+
def predict(self, payload):
651+
text = payload["text"].file.read()
652+
print(text.decode("utf-8")) # prints the contents of text.txt
653+
654+
obj = pickle.load(payload["object"].file)
655+
print(obj["key"]) # prints "value" assuming `object.pkl` is a pickled dictionary {"key": "value"}
656+
657+
img = Image.open(payload["image"].file)
658+
print(img.size) # prints the dimensions of image.png
537659
```
538660

539-
The `payload` parameter type will be a `starlette.datastructures.FormData` object if no headers are added to the request:
661+
### Form data (text)
662+
663+
#### Making the request
664+
665+
##### Curl
540666

541667
```bash
542-
$ curl http://***.amazonaws.com/my-api \
668+
$ curl https://***.amazonaws.com/my-api \
543669
-X POST \
544-
-d @file.txt
670+
-d "key=value"
671+
```
672+
673+
##### Python
674+
675+
```python
676+
import requests
677+
678+
url = "https://***.amazonaws.com/my-api"
679+
requests.post(url, data={"key": "value"})
680+
```
681+
682+
#### Reading the payload
683+
684+
When sending text via form data, the `payload` parameter will be `starlette.datastructures.FormData` (key-value pairs where the values are strings, see [Starlette's documentation](https://www.starlette.io/requests/#request-files)). Either `Content-Type: multipart/form-data` or `Content-Type: application/x-www-form-urlencoded` can be used (typically `Content-Type: application/x-www-form-urlencoded` is used for text, and is the default in the examples above).
685+
686+
```python
687+
class PythonPredictor:
688+
def __init__(self, config):
689+
pass
690+
691+
def predict(self, payload):
692+
print(payload["key"]) # will print "value"
545693
```
546694

547695
## API responses

0 commit comments

Comments
 (0)