Python SDK - projectSettings - nonWorkingDays

So me and the Python SDK is having a bit of a disagreement about updating projectSettings of a sheet and the SDK just gives me an error (the audacity!).

Reading the API docs (https://smartsheet-platform.github.io/api-docs/?python#projectsettings-object) my interpretation is this:

nonWorkingDays: "...The format for the timestamp array must be an array of strings that are valid ISO-8601 dates ('YYYY-MM-DD')."

workingDays: "...Valid values must be an array of strings of days of the week..."

is that both wants a list of strings when using the SDK.

So I tried with this:

updated_sheet = smartsheet_client.Sheets.update_sheet(
    SMARTSHEET_ID,
    smartsheet.models.Sheet({
        'project_settings': smartsheet.models.ProjectSettings({
            'working_days': ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY']
        })
    })
)

Works flawlessly and exactly how I would expect it. Strengthend by this I tried with this:

updated_sheet = smartsheet_client.Sheets.update_sheet(
    SMARTSHEET_ID,
    smartsheet.models.Sheet({
        'project_settings': smartsheet.models.ProjectSettings({
            'non_working_days': ['2020-10-30', '2020-12-23']
        })
    })
)

But instead of another success I get greated by this error:

{"response": {"statusCode": 400, "reason": "Bad Request", "content": {"errorCode": 1008, "message": "Unable to parse request. The following error occurred: Field \"null\" was of unexpected type.", "refId": "ozjgdl26up89"}}}
Traceback (most recent call last):
  File "smartsheet_holidays.py", line 50, in <module>
    'non_working_days': ['2020-10-30', '2020-12-23']
  File "/mnt/c/Users/sni/Documents/TempDev/PythonHolidays3.6/lib/python3.6/site-packages/smartsheet/sheets.py", line 1110, in update_sheet
    response = self._base.request(prepped_request, expected, _op)
  File "/mnt/c/Users/sni/Documents/TempDev/PythonHolidays3.6/lib/python3.6/site-packages/smartsheet/smartsheet.py", line 250, in request
    raise the_ex(native, str(native.result.code) + ': ' + native.result.message)
smartsheet.exceptions.ApiError: {"result": {"code": 1008, "errorCode": 1008, "message": "Unable to parse request. The following error occurred: Field \"null\" was of unexpected type.", "name": "ApiError", "recommendation": "Do not retry without fixing the problem. ", "refId": "ozjgdl26up89", "shouldRetry": false, "statusCode": 400}}

Either I'm too stupid too understand the API docs, too bad at Python or something else is going on. All scenarios are entirly plausible but regardless I'm stuck and very much appreciate som pointers on where I'm going wrong.

Best Answer

Answers

  • Hi @Stefan Nitsche,

     The audacity of those errors, indeed! 😉

    In looking at your code and resulting error, it looks like you've currently wrapped each statement within single apostrophes (') instead of double (") which is causing the unparseable return.

    In our documentation under the Sheet section, https://smartsheet-platform.github.io/api-docs/?python#sheets, has a great example to the left:

    {

    "accessLevel": "OWNER",

    "projectSettings": {

    "workingDays": [ ],

    "nonWorkingDays": [ ],

    "lengthOfDay": 6

    }

    I was able to update this with my PUT command to

    This provided me with a successful update in my Project Settings:

    For more information on Working Days and Non-Working Days in your project settings, check out: https://help.smartsheet.com/articles/516392-defining-working-non-working-holidays-on-a-project-sheet

    Additional resources for the Smartsheet API can be found on our Developer's Portal here: https://developers.smartsheet.com/ as well as in our discussions on https://stackoverflow.com/questions/tagged/smartsheet-api.

     Hope this helps!

    Thanks,

    ToriLynn

  • Hi @ToriLynn M , thank you for taking the time to reply.

    It would have been fantastic if it was as simple as changing it to double quotes but alas the error is in another castle...

    Just for more complete description of what's working and what's not. This works:

    updated_sheet = smartsheet_client.Sheets.update_sheet(
        SMARTSHEET_ID,
        smartsheet.models.Sheet({
            "project_settings": smartsheet.models.ProjectSettings({
                "non_working_days": []
            })
        })
    )
    

    This does not work:

    updated_sheet = smartsheet_client.Sheets.update_sheet(
        SMARTSHEET_ID,
        smartsheet.models.Sheet({
            "project_settings": smartsheet.models.ProjectSettings({
                "non_working_days": ["2020-10-30"]
            })
        })
    )
    

    My Python-fu is too low to determine what but it seems like the SDK does some kind of type setting or validation for the parameters within smartsheet.models.ProjectSettings. My guess is that is where things go wrong, either because I'm feeding it the wrong data or due a bug or something else. So while I'm certain that the raw API you tested using the PUT statement is working I was trying to avoid having to concoct my own requests, hence the use of the SDK.

    Right now my from-the-hip-probability-calculator-o-matic says that it's 40% on a bug in the SDK, 40% on bad docs for the SDK and 20% on me being an idiot. But regardless it seems like the outcome from this will be "don't use the SDK", which is a shame to be honest.

    Sidenote,  https://smartsheet-platform.github.io/api-docs/?python#sheets doesn't seem to have anything to do with Python specifially. It just seems like it is a JSON representation of the sheet object. Which is what the SDK should help me produce using Python code (which means single or double quotes shouldn't be an issue since it should be converted to valid JSON before the request is fired away).

  • Update: "Works" apparently only means that it doesn't throw an error when executing the code. Per the documentation at https://smartsheet-platform.github.io/api-docs/?python#update-sheet it says:

    If projectSettings.nonWorkingDays is specified as an empty array, all non-working days are removed from the project sheet.

    Given this I would expect this code (which throws no error when executed) to clear the list of non-working days:

    updated_sheet = smartsheet_client.Sheets.update_sheet(
        SMARTSHEET_ID,
        smartsheet.models.Sheet({
            "project_settings": smartsheet.models.ProjectSettings({
                "non_working_days": []
            })
        })
    )
    

    If I run this exactly nothing happens with sheet I'm trying to update. If toss in a name update to the sheet, like this:

    updated_sheet = smartsheet_client.Sheets.update_sheet(
        SMARTSHEET_ID,
        smartsheet.models.Sheet({
            "name": "Change me, oh yeah!",
            "project_settings": smartsheet.models.ProjectSettings({
                "non_working_days": []
            })
        })
    )
    

    It will update the name of the sheet and do nothing about the non-working days. The few manually added dates still remain.

    I would say that my from-the-hip-probability-calculator-o-matics new calculation is that it's 64% on a bug in the SDK, 32% on bad docs for the SDK and 2% on me being an idiot and 2% on something I haven't thought of.

  • Hi @Stefan Nitsche

    Sorry I missed this in your first post, however your commands are incorrectly listed causing a syntactical error - Unable to parse request.

    Right now your commands have additional _ added into them when they should be one-word commands wrapped in double quotations.

    • For example, you show "non_Working_Days": when this should be listed as "nonWorkingDays":

    However, since your additional command to update the sheet name is a single word, this went through without issue.

    Additional syntactical roadblocks are present in your code, such as additional () brackets that won't be parsed correctly, as well as the additional "updated_sheet" information listed at the top of your command which should also be removed. For any API call, I recommend always keeping it as simple as possible, while following the example syntax in our documentation.

     For example, copy and paste the following only into your PUT command body:


    {

    "projectSettings": {

    "nonWorkingDays": [],

    }

    }


    This will remove all currently listed Non Working Days from your project sheet as there are currently none defined within this request.

    For additional examples of the required syntax, please see our resources https://developers.smartsheet.com. Additionally, direct discussions pertaining to the API directly can be found here: https://stackoverflow.com/questions/tagged/smartsheet-api.

     

    Thanks,

    ToriLynn

  • Hi @ToriLynn M

    To begin with I will be upfront with the fact that I'm extremly annoyed. Also English isn't my first language so the rest of the message might be harsher than intedended (I don't have anybody available for tone check).

    Do you know what the difference between an API and an SDK is? Do you know anything about Python? The reason I ask is because your answers seems to indicate that you don't know the difference and that you don't know anything about Python. Now, there is no shame in that (nobody know everything) but it makes this very frustrating. Let me explain what I mean.

    "Right now your commands have additional _ added into them when they should be one-word commands wrapped in double quotations.

    * For example, you show "non_Working_Days": when this should be listed as "nonWorkingDays":"

    You are entirely correct in that the API is using camelCase as the naming style but as I've tried to make abundantly clear (in the title of this thread and every post I've made) I'm not talking about the raw API-commands, I'm talking about the Python SDK. If you take a look at the Python documentation that is provided for the updateSheet fuction: https://smartsheet-platform.github.io/api-docs/?python#update-sheet the example code looks like this:

    updated_sheet = smartsheet_client.Sheets.update_sheet(
      4583173393803140,       # sheet_id
      smartsheet.models.Sheet({
        'name': 'New Sheet Name',
        'user_settings': smartsheet.models.SheetUserSettings({
          'critical_path_enabled': True
        })
      })
    )
    

    Do you see it? If not let me shine a light to it. The raw API says "userSettings" but the example code provided uses "user_settings". The same with "criticalPathEnabled", in the example it is "critical_path_enabled". Even the single quotes you were talking about in your first reply is present in the example code provided by Smartsheet. Let me explain why. This is not the API, this is the SDK. The SDK is a wrapper for the API that makes it easer to work with the API when you're using Python.

    Why does the API use camelCase but the SDK use snake_case? Probably because the style guide for Python says that variables and functions should be using snake_case, you can read about it here: https://www.python.org/dev/peps/pep-0008/#function-and-variable-names

    • Why doesn't it matter if you use single or double quotes when you're using the SDK? Because you're not directly interacting with the API, the SDK will convert it to the API calls and the SDK doesn't care about single or double quotes.
    • Why doesn't it matter if you use single or double quotes when you're using the SDK? Because you're not directly interacting with the API, the SDK will convert it to the API calls and the SDK doesn't care about single or double quotes.

    Hopefully we've know established that I'm talking about the Python SDK, not the raw API. Hopefully we've know established that the SDK is not the API. What does this mean? Well that means that your answers are wrong.

    Additional syntactical roadblocks are present in your code, such as additional () brackets that won't be parsed correctly

    Not an issues since the brackets you are talking about are part of the Python code and since I'm talking about the Python SDK they need to be there. Don't belive me? Check the code example above that's taken from the offical documentation.

    ...as well as the additional "updated_sheet" information listed at the top of your command which should also be removed.

    Yeah... Not an issues since we are talking about the Python SDK. So to make use of the Python SDK you kinda have to write Python code... Also see the code example about that's taken from the official documentation.

    For any API call, I recommend always keeping it as simple as possible, while following the example syntax in our documentation.

    Well, well... Who could have known, something I actually agree with. My reasoning was that if I'm going to write a Python application and a Python SDK is provided then that is the most simple way as possible. I the wrote my code using the examples in the documentation but it gave men an error so I posted a question about it...

    Now I don't know if you're affilated with Smartsheet or just a person who likes to try and help. If you're just a helpfull person then I'm thankfull for your helping spirit but I would suggest that you focus it on areas you are knowledgeable about.

    If you're affiliated with Smartsheet (which your wording implies) then I'm severly dissappointed by your lack of reading comprehension and skill. If you don't know be upfront about it. Don't give me answers that are wrong just so that there is answer in thread. That's not helpfull to me or others who might be searching for the same answer. This is not a behaviour that is fitting a company support representative.

  • Gwyneth C
    Gwyneth C ✭✭✭✭✭✭

    Hello Stephan,

    Thanks for the caveat about tone! Yes, this was a bit strongly worded, but it's clear that you are frustrated. I have escalated your question to our next tier support team. You should be receiving a direct reply shortly. Once we've sorted out the exact issue here, one of the moderators will post back to this thread so that others can see the solution we came up with.