Hi. I originally picked up a RPI to learn a bit of Linux and python which has been generally going well but recently picked up a Pico W to learn a bit of micro python and decided to hook up some of the sensors I used with the pi and Arduino.
I happy to learn and work stuff out but need a push in the right direction to some documentation or examples I can learn from.
I have a rest endpoint which is Https. I’ve been sending POST requests to it on port 443 for some time using postman, powershell and curl. I’m sending a small json payload to the endpoint URL and then usually logging to a text file or dB some information from the 201 response or details of the error.
I’ve been successfully doing this in other ways but can’t seem to find a way to do this from micro python on the Pico W. Everything I find is geared towards http and Https doesn’t work.
Anyone had a working example of sending Https rest messages from the Pico to an endpoint? Any examples or libraries/ documentation I can look at.
Things I’ve looked at or documentation I’ve read includes:
Request & urequest. Unsuccessful
I’ve worked out the json part of this by importing json which is at least starting to get there, I’m able to built a payload and print it to console to make sure it’s correct.
I think now it’s just the HTTPS I have problems with.
im not convinced if this is a good way to do it or if its just something that works but after a rabbit hole of viewing post after post - this is what I’ve found and managed to hack together from the posts on this board, youtube and snippets from all over.
import binascii and changing the auth header is what eventually made this work along with urequests
import socket # this is new to me but i think i need to be looking at ssl
import machine
import network
import urequests # <<< this is what i thought didnt work but turns out i was just using it wrong.
import json
from time import sleep
import secrets
import utime
import time
import binascii # <<< not sure what this is. i didnt understand all the documentation
### code removed
def send_post_request(url, data):
credentials = f"{USERNAME}:{PASSWORD}"
auth_header = 'Basic ' + binascii.b2a_base64(credentials.encode()).decode().strip()
headers = {
'Content-Type': 'application/json',
'Authorization': auth_header
}
try:
print("Sending data:", json.dumps(data)) # Log the request data
response = urequests.post(url, data=json.dumps(data), headers=headers)
#print("RSP Statuscde:", response.status_code)
#print("RSP Txt:", response.text)
#print("RSP HEADS:", response.headers)
response.close()
except Exception as e:
print("Error sending POST request:", e)
# post_data = DEFINE PAYLOAD TO SEND
post_data = [ STUFF GOES IN HERE]
url = "https://APIENDPOINT"
send_post_request(url, post_data)
happy for someone to rip this apart and tell me what I’ve done wrong if there is a better and more sensible way.
Glad it works. But there are a few things remaining:
do you really need all these imports? E.g. neither socket nor network are referenced in the code you posted. But maybe this is in the “code removed” section.
socket is the low-level interface to networking. urequests is a higher level abstraction and I expect that it uses socket internally.
The binascii module allows you to base64-encode your username and password (BASIC-Auth auth_header = ...). This is an Internet standard which you actually should not use anymore (see e.g. tls - Is BASIC-Auth secure if done over HTTPS? - Information Security Stack Exchange). But depending on your API endpoint, you might not have the choice.
Otherwise, I think that is a good example, thanks for posting.
sockets isnt used - i thought i needed it when i was reading about ssl but never removed it network is used to identify the picos mac address so i know which pico is sending the data (will have a few different ones with multiple sensors all sending similar data at some point)
for the moment the basic auth is fine but the end point will allow an api key.
i havent got that far yet, as im still in the basic does this even work phase, i wanted to keep it simple and basic auth is fine for that while the end point is a windows VM but when i start trying to run this for a real endpoint i’ll want to use the api key or something more secure - (thanks for the link its saved for later and no doubt be posting again when i have more questions)