Skip to content

Commit 7421966

Browse files
authored
Improve request payload docs (#1566)
1 parent bc43f7a commit 7421966

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
@@ -492,58 +492,206 @@ If your application requires additional dependencies, you can install additional
492492

493493
## API requests
494494

495-
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:
495+
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):
496496

497497
1. For `Content-Type: application/json`, `payload` will be the parsed JSON body.
498-
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)).
498+
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)).
499499
1. For all other `Content-Type` values, `payload` will be the raw `bytes` of the request body.
500500

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

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

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

511517
```bash
512-
$ curl http://***.amazonaws.com/my-api \
513-
-X POST -H "Content-Type: application/octet-stream" \
514-
--data-binary @file.bin
518+
$ curl https://***.amazonaws.com/my-api \
519+
-X POST -H "Content-Type: application/json" \
520+
-d @file.json
515521
```
516522

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

519-
```bash
520-
$ curl http://***.amazonaws.com/my-api \
521-
-X POST -H "Content-Type:" \
522-
-d @sample.txt
525+
```python
526+
import requests
527+
528+
url = "https://***.amazonaws.com/my-api"
529+
requests.post(url, json={"key": "value"})
523530
```
524531

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

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

533-
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:
595+
Here's an example if the binary data is an image:
596+
597+
```python
598+
from PIL import Image
599+
import io
600+
601+
class PythonPredictor:
602+
def __init__(self, config):
603+
pass
604+
605+
def predict(self, payload, headers):
606+
img = Image.open(io.BytesIO(payload)) # read the payload bytes as an image
607+
print(img.size)
608+
```
609+
610+
### Form data (files)
611+
612+
#### Making the request
613+
614+
##### Curl
534615

535616
```bash
536-
$ curl http://***.amazonaws.com/my-api \
537-
-X POST -H "Content-Type: application/x-www-form-urlencoded" \
538-
-d @file.txt
617+
$ curl https://***.amazonaws.com/my-api \
618+
-X POST \
619+
-F "text=@text.txt" \
620+
-F "object=@object.pkl" \
621+
-F "image=@image.png"
622+
```
623+
624+
##### Python
625+
626+
```python
627+
import requests
628+
import pickle
629+
630+
url = "https://***.amazonaws.com/my-api"
631+
files = {
632+
"text": open("text.txt", "rb"),
633+
"object": open("object.pkl", "rb"),
634+
"image": open("image.png", "rb"),
635+
}
636+
637+
requests.post(url, files=files)
638+
```
639+
640+
#### Reading the payload
641+
642+
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).
643+
644+
```python
645+
from PIL import Image
646+
import pickle
647+
648+
class PythonPredictor:
649+
def __init__(self, config):
650+
pass
651+
652+
def predict(self, payload):
653+
text = payload["text"].file.read()
654+
print(text.decode("utf-8")) # prints the contents of text.txt
655+
656+
obj = pickle.load(payload["object"].file)
657+
print(obj["key"]) # prints "value" assuming `object.pkl` is a pickled dictionary {"key": "value"}
658+
659+
img = Image.open(payload["image"].file)
660+
print(img.size) # prints the dimensions of image.png
539661
```
540662

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

543669
```bash
544-
$ curl http://***.amazonaws.com/my-api \
670+
$ curl https://***.amazonaws.com/my-api \
545671
-X POST \
546-
-d @file.txt
672+
-d "key=value"
673+
```
674+
675+
##### Python
676+
677+
```python
678+
import requests
679+
680+
url = "https://***.amazonaws.com/my-api"
681+
requests.post(url, data={"key": "value"})
682+
```
683+
684+
#### Reading the payload
685+
686+
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).
687+
688+
```python
689+
class PythonPredictor:
690+
def __init__(self, config):
691+
pass
692+
693+
def predict(self, payload):
694+
print(payload["key"]) # will print "value"
547695
```
548696

549697
## API responses

0 commit comments

Comments
 (0)