Getting started with API's

15 comments started 2023-10-16 last 2023-10-18
APIsHome Automation
S
#1 Stephen_Coombs

Hi,
I'm new to writing code for API's and for starters I've copied the bash code into a script file to get my account details having created an API token ie
curl --request GET \
--get "https://api.givenergy.cloud/v1/account" \
--header "Authorization: Bearer {YOUR_API_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
The response I get is
bash: ./Givenergy_API.sh: cannot execute: required file not found
I presume the missing file is my account.
Please can somebody point me in the right direction.
Thanks
Stephen

D
#2 DD

A shell script should start with a #! line containing the path to the interpreter which will execute it. eg #!/bin/bash
You could get that error message if you've got the path to the interpreter wrong. Though I think it defaults to /bin/sh if that line is missing. You can use file to ask it what it thinks the script is.

Alternatively, you can explicitly invoke the shell, as
$ bash ./Givenergy_API.sh
in which case it doesn't need that line.

You can use bash -x script.sh to have it echo commands as they are executed, though since this is a single line, probably not helpful. (Unless you explicitly need bash extensions, it's usual for scripts to use /bin/sh rather than /bin/bash )

I assume this works if you issue the curl command directly at the prompt, rather than putting it in a script.

D
#4 DD

Stephen_Coombs I asume you realise that {YOUR_API_KEY} is a placeholder for your own key. In a shell-script, it would be natural to access it either an environment variable, eg $API_KEY, or pass it to the script as a parameter,where you can access it as $1

Or you could put the key in a file, and access it from the script using $(cat apikey.txt)

S
#5 Stephen_Coombs

Thanks for your responses.
The first line of the shell script is #!/bin/bash I just didn't include it here.
For the API_KEY I included the whole text but again didn't show it here.
I should say I am using a Linux machine Mageia 9 not Windows
It doesn't work using curl directly from the prompt. This is what I get with the key from a file:-

[stephen@localhost ~]$ curl --request GET --get "https://api.givenergy.cloud/v1/account" -- header "Authorization: Bearer $(cat Givenergy_token)" --header "Content-Type: application/json" --header "Accept: application/json"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0;url='https://api.givenergy.cloud/login'" />

    <title>Redirecting to https://api.givenergy.cloud/login</title>
</head>
<body>
    Redirecting to <a href="https://api.givenergy.cloud/login">https://api.givenergy.cloud/login</a>.
</body>

</html>curl: (6) Could not resolve host: header
curl: (3) URL using bad/illegal format or missing URL
curl: (6) Could not resolve host: --header
curl: (3) URL using bad/illegal format or missing URL
curl: (6) Could not resolve host: --header
curl: (3) URL using bad/illegal format or missing URL

S
#6 stevelewis

Stephen_Coombs you may find it easier to use python than curl as your scripts become more complex. Plenty of worked examples out there, including my own at www.github.com/salewis38/palm. The code is open source so you can take it and edit to your heart's content!

S
#7 Stephen_Coombs

Using bash -x I get this error
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

S
#8 Stephen_Coombs

stevelewis
Thank you I'll take a look at that

#9 Wonder Watt

Stephen_Coombs I think this is a simple case of an accidental space in front of your Authorization header arg switch (between the -- and the header arg), resulting in the HTML login redirect.

Use: curl --request GET --get "https://api.givenergy.cloud/v1/account" --header "Authorization: Bearer $(cat Givenergy_token)" --header "Content-Type: application/json" --header "Accept: application/json"

S
#10 Stephen_Coombs

Wonder Watt
Thanks for spotting accidental space. However I still get
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

#11 Wonder Watt

Stephen_Coombs Works perfectly fine here.

Could be some SSL lib version issue or such.

My curl --version output is:

curl 8.1.2 (x86_64-apple-darwin23.0) libcurl/8.1.2 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.55.1
Release-Date: 2023-05-30
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL threadsafe UnixSockets

Additionally, you could add the -v arg for some more verbose output to see what's going on.

S
#12 Stephen_Coombs

Wonder Watt My version of curl is different
curl 7.88.1 (x86_64-mageia-linux-gnu) libcurl/7.88.1 OpenSSL/3.0.10 zlib/1.2.13 brotli/1.0.9 libidn2/2.3.4 libpsl/0.21.2 (+libidn2/2.3.4) libssh/0.10.5/gnutls/zlib nghttp2/1.54.0
Release-Date: 2023-02-20
It has all the Protcols and Features plus a few more.
It's the lastest update in the Mageia repository but I'll see if I can download your version

#13 Wonder Watt

Stephen_Coombs Any useful output running with the verbose -v flag?

S
#14 Stephen_Coombs

Wonder Watt Curl error 93 is Stream error in HTTP/2 framing layer. This is usually an unrecoverable error, but trying to force curl to speak HTTP/1 instead might circumvent it.
I added --http1.1 -v args and found the problem (I think)
It connects to the server passes all the handshakes and authorisations then
< HTTP/1.1 400 Bad Request
< Date: Wed, 18 Oct 2023 10:38:22 GMT
< Content-Type: text/html
< Content-Length: 150
< Connection: close
< Server: nginx
Any clues?

#15 Wonder Watt

Stephen_Coombs I had done the same thing before, forcing HTTP 1.1 and also worked fine for me.

What is the response content body? Is it just empty?