Validation Error on Tuning

#1

Great site - nice, accurate forecasts! Congratulations!

Now I’m trying to add tuning but I keep getting status 400 (Validation Error). Using python request library I say

 post(url, data)

with

 url = https://api.solcast.com.au/rooftop_sites/{my_resource_id}/measurements
 data = {'measurements': [
            { 'period_end': '2021-01-23T08:00:00.0000000Z', 
              'period': 'PT5M', 
              'total_power': 0.02425}, 
            { 'period_end': '2021-01-23T08:05:00.0000000Z', 
              'period': 'PT5M', 
              'total_power': 0.019776}
          ]
        }

What am I missing?

Thx. for help!

#2

Your data is not valid JSON use double quotes when sending data. The 400 error you are receiving is this if you look into the body content details

{
    "response_status": {
        "error_code": "NotNull",
        "message": "'measurement' or 'measurements' must have a valid value.",
        "errors": [
            {
                "error_code": "NotNull",
                "field_name": "Measurement",
                "message": "'measurement' or 'measurements' must have a valid value.",
                "meta": {
                    "PropertyName": "Measurement"
                }
            },
            {
                "error_code": "NotEmpty",
                "field_name": "Measurements",
                "message": "'measurement' or 'measurements' must have a valid value.",
                "meta": {
                    "PropertyName": "Measurements"
                }
            }
        ]
    }
}

Send this instead

{
  "measurements": [
    {
      "period_end": "2021-01-23T08:00:00.0000000Z",
      "period": "PT5M",
      "total_power": 0.02425
    },
    {
      "period_end": "2021-01-23T08:05:00.0000000Z",
      "period": "PT5M",
      "total_power": 0.019776
    }
  ]
}
#3

Thx., siliconrob - but no success so far.

I used the dictionary interface yesterday (should have made that explicit); now trying JSON. Down to this code now:

from requests import post
import json

m    = []
m.append( { "period_end" : "2021-01-23T08:00:00.0000000Z", "period" : "PT5M", "total_power" : 0.02425 } )
m.append( { "period_end" : "2021-01-23T08:05:00.0000000Z", "period" : "PT5M", "total_power" : 0.01977 } )
data = { "measurements" : m }
url  = "https://api.solcast.com.au/rooftop_sites/{my_resource_id}/measurements"
str  = json.dumps(data)
#req  = post(url, data=data)
req = post(url, json=str)
pass

but still Response [400]

req.content reads

{
    "response_status": {
	"error_code": "SerializationException",
	"message": "Type definitions should start with a \'{\', expecting serialized type \'CreateRooftopSiteMeasurement\', got string starting with: \\"{\\\\\\"measurements\\\\\\": [{\\\\\\"period_end\\\\\\": \\\\\\"2021-01-23"}}
    }
}
#4

This works for me, but if your stuff isn’t working after making the minor change to let requests do the serialization but setup the request with the headers Content-Type

If it doesn’t work go ahead and post something to a public repo and can work it out i.e. GitHub, GitLab etc

import requests
import json

if __name__ == '__main__':

    api_key = "<YOUR_API_KEY>"
    resource_id = "<ROOFTOP_RESOURCE_ID>"

    m = []
    m.append({"period_end": "2021-01-23T08:00:00.0000000Z", "period": "PT5M", "total_power": 0.02425})
    m.append({"period_end": "2021-01-23T08:05:00.0000000Z", "period": "PT5M", "total_power": 0.01977})
    data = {"measurements": m}

    url  = f"https://api.solcast.com.au/rooftop_sites/{resource_id}/measurements?api_key={api_key}"
    print(url)

    post_data = json.dumps(data)

    headers = {
        'Content-Type': 'application/json'
    }
    
    response = requests.post(url, post_data, headers=headers)

    if response:
        print('Success')
    else:
        print('An error occurred')
1 Like
#5

Hi Siliconrob,

… this worked wonders - thx. a lot! :grinning:

I was starting from pysolcast of mcaulifn, which worked fine for ‘get’ requests and is a tad easier … - I’ll post an issue against that library.

To summarize:

  • headers={ ‘Content-Type’:‘application/json’ } was the essential bit

  • the URL needs authentication (which makes sense, but was missing in my example code above; it would create a 401 after working around the 400 - which might sound a bit upside down)

Thx. again, Stefan

1 Like
#6

Cool it worked :+1:, I saw that library before, but I’m not a python expert (getting there though) so definitely send them issues. Would not mind doing any work you need to fix up the PR for submission

Content type is important because you could post up formats like xml, csv and the solcast api should be able to ingest them no big deal.

I know json is the most popular, but csv is probably the most efficient and easiest to read (for human debugging) in my opinion.

XML well that’s for your grandparents :older_man::older_woman::older_adult:

#7

Issue posted - I’ll make a code proposal later this week vs. pysolcast.

1 Like
#8

I corrected the both issues. v1.0.7 has been released to PyPI. Thanks again for finding it!

1 Like
#9

:snake: :100: Awesome :100: :snake:

#10

Perfect - works like a charm. Thanks a lot to both of you :ok_hand:

Was not having a lot of time this week, so apologies for the slow reply

1 Like