Hướng dẫn python requests post json authentication - python yêu cầu đăng xác thực json

Tôi đang gặp sự cố khi sử dụng các yêu cầu

API mà tôi đang kiểm tra cho biết tham số device_info sẽ được đăng trong thân thông báo. Nó cũng nói rằng Device_info dưới dạng trường biểu mẫu. Trong tất cả các tài liệu cho các yêu cầu, tôi không thể tìm cách thêm "tên" vào tham số khác ngoài việc tát tên với giá trị của nó trong JSON. Đây là những gì tôi đã thử.

import requests
import json

loginPayload = {'device_info':{'app-id':'fc','os-type':'ios'}}
loginHeaders = {'content-type': 'application/json','Authorization':'Basic base64here'}
loginUrl = "http://subdomain.test.com/endpoint/method"
loginPost = requests.post(loginUrl, params=json.dumps(loginPayload), headers=loginHeaders)

print loginPost.text

Tôi đã thử thay đổi params= thành data= nhưng tôi không gặp may mắn.

Câu trả lời mà tôi nhận được là:

{
"response": {
"message": "Parameter 'device_info' has invalid value ()", 
"code": 400, 
"id": "8c4c51e4-9db6-4128-ad1c-31f870654374"
  }
}

EDITED:

Nhận được một nơi mới! Tôi không có mã được sửa đổi để xem như sau:

import requests

login = 'test'
password = 'testtest'
url = "http://subdomain.domain.com/endpoint/method"

authentication = (login,password)
payload = {'device_info': {'device_id': 'id01'}}
request = requests.post(url, data=payload, auth=authentication)

print request.text

Sản xuất:

{
  "response": {
    "message": "Parameter 'device_info' has invalid value (device_id)", 
    "code": 400, 
    "id": "e2f3c679-5fca-4126-8584-0a0eb64f0db7"
  }
}

Điều gì dường như là vấn đề? Tôi không gửi nó ở định dạng cần thiết?

Đã chỉnh sửa: Giải pháp đã thay đổi các tham số của tôi thành:

{
    "device_info": "{\"app-id\":\"fc\",\"os-type\":\"ios\",\"device_id\":\"myDeviceID1\"}"
}


Khi tôi hiện đang làm việc trên một kịch bản mới sử dụng Python, tôi đã phải tìm một cách đơn giản nhưng hiệu quả để nói chuyện với API HTTP với các phản hồi của JSON. Hóa ra có một vài khả năng khác nhau, nhưng mô -đun "yêu cầu" dường như là một trong những cách phổ biến nhất và cũng dễ hiểu nhất để gửi các yêu cầu HTTP.

Đơn giản nhận yêu cầu

Với Curl, đây là yêu cầu cơ bản nhất mà bạn có thể làm:curl this is the most basic request you can do:

$ Curl https://www.claudiokuenzler.comcurl https://www.claudiokuenzler.com

Sử dụng Python:

$ Python >>> Nhập yêu cầu >>> r = requests.get ('https://www.claudiokuenzler.com')python
>>> import requests
>>> r=requests.get('https://www.claudiokuenzler.com')

Biến "R" hiện giữ tất cả dữ liệu liên quan đến URL được yêu cầu. Bao gồm mã phản hồi HTTP:

>>> in (R.Status_code) 200print(r.status_code)
200

Bằng cách này, bạn có thể dễ dàng kiểm tra xem yêu cầu có thành công hay không. Hãy kiểm tra một trang không tìm thấy lỗi.

Với Curl, bạn sẽ kiểm tra các tiêu đề của URL (Phương pháp nhanh nhất):curl you would check the headers of an URL (quickest method):

$ Curl https://www.claudiokuenzler.com/nothinghere -ihttp/2 404 Máy chủ: nginxdate: Tue, 15 tháng 2 năm 2022 08:10:49 gmtcontent -type: text/html; Charset = ISO-8859-1Vary: Chấp nhận mã hóacurl https://www.claudiokuenzler.com/nothinghere -I
HTTP/2 404
server: nginx
date: Tue, 15 Feb 2022 08:10:49 GMT
content-type: text/html; charset=iso-8859-1
vary: Accept-Encoding

Sử dụng Python:

$ Python >>> Nhập yêu cầu >>> r = requests.get ('https://www.claudiokuenzler.com')r=requests.get('https://www.claudiokuenzler.com/nothinghere')
>>> if (r.status_code != 200):
...   print("Sorry, something went wrong")
...
Sorry, something went wrong

Biến "R" hiện giữ tất cả dữ liệu liên quan đến URL được yêu cầu. Bao gồm mã phản hồi HTTP:

>>> in (R.Status_code) 200

Bằng cách này, bạn có thể dễ dàng kiểm tra xem yêu cầu có thành công hay không. Hãy kiểm tra một trang không tìm thấy lỗi.curl you would put the data payload into a parameter -d:

Với Curl, bạn sẽ kiểm tra các tiêu đề của URL (Phương pháp nhanh nhất):curl -X POST -d '{"id": 1, "method": "Switch.GetStatus", "params": {"id": 0}}' http://api.example.com/rpc

$ Curl https://www.claudiokuenzler.com/nothinghere -ihttp/2 404 Máy chủ: nginxdate: Tue, 15 tháng 2 năm 2022 08:10:49 gmtcontent -type: text/html; Charset = ISO-8859-1Vary: Chấp nhận mã hóa

>>> r = requests.get ('https://www.claudiokuenzler.com/nothinghere') >>> if (r.status_code! = 200): ... & nbsp; & nbsp; in ("Xin lỗi, có gì đó không ổn") ... xin lỗi, có gì đó không ổnr=requests.post('http://api.example.com/rpc',  data=somedata)

Gửi yêu cầu bài đăng với tải trọng JSON

Gửi một bài đăng sử dụng "Bài đăng" thay vì lớp "Nhận".r=requests.post('http://api.example.com/rpc', json={'key':'value','key2':'value2'})

Với Curl, bạn sẽ đặt tải trọng dữ liệu vào một tham số -D:

$ curl -x post -d '{"id": 1, "phương thức": "switch.getstatus", "params": {"id": 0}}' http://api.example.com/rpcpostdata = { "id": 1, "method": "Switch.GetStatus", "params": {"id": 0} }
>>> r = requests.post('http://api.example.com/rpc', json=postdata)

Trong các yêu cầu của Python, tải trọng dữ liệu có thể được xác định theo nhiều cách khác nhau. Mặc định là chỉ cần xác định tải trọng trong tham số dữ liệu:

>>> r = requests.post ('http://api.example.com/rpc'.  data = somedata)methodchoice="Switch.GetStatus"
>>> postdata = { "id": 1, "method": methodchoice, "params": {"id": 0} }
>>> print(postdata)
{'id': 1, 'method': 'Switch.GetStatus', 'params': {'id': 0}}
>>> r = requests.post('http://api.example.com/rpc', json=postdata)

Nhưng khi chúng tôi đang gửi tải trọng JSON, có một tham số đặc biệt cho JSON:

>>> r = requests.post ('http://api.example.com/rpc', json = {'key': 'value', 'key2': 'value2'})

Tất nhiên các trọng tải JSON có thể trở nên khá lớn, vì vậy thật hợp lý khi đặt tải trọng vào một biến riêng biệt trước khi thực sự gửi yêu cầu bài đăng:curl request looks like this:

>>> postdata = {"id": 1, "phương thức": "switch.getstatus", "params": {"id": 0}} >>> r = requests.post ('http: // api. Ví dụ.com/rpc ', json = postdata)curl https://www.example.com/hidden.txt -u "myuser:secret" -I
HTTP/2 200
server: nginx
date: Tue, 15 Feb 2022 08:36:16 GMT
content-type: text/plain
content-length: 187
[...]

Và để làm cho nó trở nên năng động hơn, bạn cũng có thể sử dụng các biến trong tải trọng postdata:

>>> r = requests.get ('https://www.example.com/hidden.txt', auth = ('myuser', 'secret')) >>> in (r.status_code) 200r=requests.get('https://www.example.com/hidden.txt', auth=('myuser', 'secret'))
>>> print(r.status_code)
200

Để xử lý một phương thức xác thực khác, ví dụ Digest Auth, một lớp khác cần được tải với tham số Auth:

>>> Phương thứcChoice = "Switch.getStatus" >>> postdata = {"id": 1, "Phương thức": MethodChoice, "params": {"id": 0}} >>> r = request.post (' http://api.example.com/rpc ', json = postdata, auth = httpdigestauth (' admin ',' secret ')) Traceback (cuộc gọi gần đây nhất cuối cùng): & nbsp; Tệp "", dòng 1, trong NameError: name 'httpdigestauth' không được xác địnhmethodchoice="Switch.GetStatus"
>>> postdata = { "id": 1, "method": methodchoice, "params": {"id": 0} }
>>> r = requests.post('http://api.example.com/rpc', json=postdata, auth=HTTPDigestAuth('admin', 'secret'))
Traceback (most recent call last):
  File "", line 1, in
NameError: name 'HTTPDigestAuth' is not defined

WHOA, một lỗi cho thấy, xác thực HTTPDigestAuth không được tìm thấy/xác định. Để cho phép các phương thức xác thực bổ sung, chúng phải được tải (nhập) cụ thể:

>>> Từ các yêu cầu >> r = requests.post ('http://api.example.com/rpc', json = postdata, auth = httpdigestauth ('admin', 'secret')) >>> in (r.status_code) 200from requests.auth import HTTPDigestAuth
>>> methodchoice="Switch.GetStatus"
>>> postdata = { "id": 1, "method": methodchoice, "params": {"id": 0} }
>>> r = requests.post('http://api.example.com/rpc', json=postdata, auth=HTTPDigestAuth('admin', 'secret'))
>>> print(r.status_code)
200

Mật khẩu sai sẽ dẫn đến 401 hoặc, tùy thuộc vào API, mã phản hồi 403:

>>> Từ các yêu cầu >> r = requests.post ('http://api.example.com/rpc', json = postdata, auth = httpdigestauth ('admin', 'sraidpass')) >>> in (r.status_code) 401from requests.auth import HTTPDigestAuth
>>> methodchoice="Switch.GetStatus"
>>> postdata = { "id": 1, "method": methodchoice, "params": {"id": 0} }
>>> r = requests.post('http://api.example.com/rpc', json=postdata, auth=HTTPDigestAuth('admin', 'wrongpass'))
>>> print(r.status_code)
401

Đọc và xử lý phản hồi JSON

Như bạn có thể đoán từ bài viết, mục tiêu của tôi là nói chuyện với API nhận đầu vào dữ liệu JSON và trả về đầu ra JSON.

Trong Curl, bạn sẽ kết hợp đầu ra với trình phân tích cú pháp JSON, chẳng hạn như JQ, để có "chế độ xem đẹp" cho mắt người:curl you would combine the output with a json parser, such as jq, to have a "pretty view" for the human eye:

 

$ curl -x post -d '{"id": 1, "phương thức": "switch.getstatus", "params": {"id": 0}}' http://api.example.com/rpc - -anyAuth -u admin: Secret {"id": 1, "src": "shellypro4pm -xxx", "result": {"id": 0, "nguồn": "init", "in": true, " Apower ": 445.1," Điện áp ": 235,6," hiện tại ": 2.164," PF ":-0.27," AENERGY ": {" Tổng số ": 5297.006," BY_MINUTE ": [1139.782,7497.179.7637 : 1644915308}, "Nhiệt độ": {"TC": 49.8, "TF": 121.6}}}}curl -X POST -d '{"id": 1, "method": "Switch.GetStatus", "params": {"id": 0}}' http://api.example.com/rpc --anyauth -u admin:secret
{"id":1,"src":"shellypro4pm-xxx","result":{"id":0, "source":"init", "output":true, "apower":445.1, "voltage":235.6, "current":2.164, "pf":-0.27, "aenergy":{"total":5297.006,"by_minute":[1139.782,7497.179,7637.339],"minute_ts":1644915308},"temperature":{"tC":49.8, "tF":121.6}}}

$ curl -s -x post -d '{"id": 1, "phương thức": "switch.getstatus", "params": {"id": 0}}' http://api.example.com/ RPC --anyAuth -u Quản trị viên: Bí mật | jq {& nbsp; "ID": 1, & nbsp; "SRC": "ShellyPro4pm-xxx", & nbsp; "Kết quả": {& nbsp; & nbsp; & nbsp; "id": 0, & nbsp; & nbsp; & nbsp; "Nguồn": "init", & nbsp; & nbsp; & nbsp; "đầu ra": Đúng, & nbsp; & nbsp; & nbsp; "Apower": 460.7, & nbsp; & nbsp; & nbsp; "Điện áp": 235, & nbsp; & nbsp; & nbsp; "hiện tại": 2.237, & nbsp; & nbsp; & nbsp; "PF": -0,26, & nbsp; & nbsp; & nbsp; "AENERGY": {& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; "Tổng số": 5300.551, & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; "by_minute": [& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; 4683.653, & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; 7497.179, & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; 7637.339 & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; ], & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; "phút_ts": 1644915336 & nbsp; & nbsp; & nbsp; }, & nbsp; & nbsp; & nbsp; "Nhiệt độ": {& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; "TC": 49,9, & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; "TF": 121.9 & nbsp; & nbsp; & nbsp; } & nbsp; }}curl -s -X POST -d '{"id": 1, "method": "Switch.GetStatus", "params": {"id": 0}}' http://api.example.com/rpc --anyauth -u admin:secret | jq
{
  "id": 1,
  "src": "shellypro4pm-xxx",
  "result": {
    "id": 0,
    "source": "init",
    "output": true,
    "apower": 460.7,
    "voltage": 235,
    "current": 2.237,
    "pf": -0.26,
    "aenergy": {
      "total": 5300.551,
      "by_minute": [
        4683.653,
        7497.179,
        7637.339
      ],
      "minute_ts": 1644915336
    },
    "temperature": {
      "tC": 49.9,
      "tF": 121.9
    }
  }
}

Để xử lý điều này trong Python, mô -đun JSON có thể được sử dụng. Như chúng ta đã biết, phản hồi HTTP được lưu trong biến "R". Bằng cách chạy "R" thông qua hàm JSON và lưu nó trong một biến khác Jsondata, khóa và giá trị khác nhau sau đó có thể được sử dụng. Để xem các khóa và giá trị nào đã được phân tích cú pháp, hãy sử dụng hàm json.dumps trên biến jsondata:

>>> Nhập JSON >>> Nhập yêu cầu >>> từ các yêu cầu. hay >> jsondata = r.json () >>> in (json.dumps (jsondata)) {"id": 1, "src": "shellypro4pm-xxx", "result": {"id": 0, " Nguồn ":" init "," đầu ra ": true," apower ": 454.5," điện áp ": 235.2," hiện tại ": 2.218," pf ": -0,27," aEngergy ": {" tổng số ": 5326.812," BY_MINUTE ": [385.795, 7667.42, 7639.309]," phút_ts ": 1644915542}," Nhiệt độ ": {" TC ": 49.6," TF ": 121.4}}}}}}}import json
>>> import requests
>>> from requests.auth import HTTPDigestAuth
>>> methodchoice="Switch.GetStatus"
>>> postdata = { "id": 1, "method": methodchoice, "params": {"id": 0} }
>>> r = requests.post('http://api.example.com/rpc', json=postdata, auth=HTTPDigestAuth('admin', 'secret'))
>>> jsondata=r.json()
>>> print(json.dumps(jsondata))
{"id": 1, "src": "shellypro4pm-xxx", "result": {"id": 0, "source": "init", "output": true, "apower": 454.5, "voltage": 235.2, "current": 2.218, "pf": -0.27, "aenergy": {"total": 5326.812, "by_minute": [385.795, 7667.42, 7639.309], "minute_ts": 1644915542}, "temperature": {"tC": 49.6, "tF": 121.4}}}

Để lấy một giá trị từ một khóa cụ thể, mảng jsondata hiện có thể được sử dụng:

>>> in (jsondata ['src']) shellypro4pm-xxxprint(jsondata['src'])
shellypro4pm-xxx

Để đi sâu hơn vào một đối tượng JSON lồng nhau, chỉ cần nối các mảng với tên đối tượng lồng nhau:

>>> in (jsondata ['result'] ['AENERGY'] ['TOTAL']) 5326.812print(jsondata['result']['aenergy']['total'])
5326.812

>>> in (jsondata ['result'] ['nhiệt độ'] ['tc']) 49.6print(jsondata['result']['temperature']['tC'])
49.6

Tất cả cái này là gì?

Bạn có thể tự hỏi tại sao tôi đã vượt qua tất cả những điều này? Trên thực tế, tôi hiện đang làm việc trên một plugin giám sát mới để giám sát Shelly Power Switch và các thiết bị đo điện. Khi tôi quyết định sử dụng Python cho ngôn ngữ tập lệnh của plugin, tôi cần đào sâu hơn vào các yêu cầu HTTP (có và không có xác thực) và JSON xử lý trong Python. Trình giám sát plugin Check_shelly sẽ được xuất bản trên blog này khi sẵn sàng. Kho lưu trữ công cộng có thể được tìm thấy trên GitHub.



Thêm một bình luận

Hiển thị biểu mẫu để lại nhận xét

Nhận xét (mới nhất đầu tiên)

Chưa có nhận xét nào.