smartsheet-platform / smartsheet-python-sdk Goto Github PK
View Code? Open in Web Editor NEWLibrary that uses Python to connect to Smartsheet services (using API 2.0).
License: Apache License 2.0
Library that uses Python to connect to Smartsheet services (using API 2.0).
License: Apache License 2.0
I'd like to be able to update a Template
Use Case:
Using the Sheet object's source attribute, a Sheet can be linked back to a Template.
If the Sheet is not flagged as an 'orphan' (that is a different functionality that prevents the update), and certain items are changed on the Sheet (for example columns added, conditional formatting updated, etc...), the Template is updated with the changes.
Alternatively, if a Sheet's source attribute could be changed to a different Template, then when a new Template is created (see issue #112), the associated Sheets would be relinked to the new version of the Template.
Use Case:
Projects are run from a set of Templates. PM's are allowed to change the structure of the sheet (columns, conditional formatting, formatting, certain formulas, etc...) and the system watches for these changes (not data changes) and puts a copy of the Sheet into a review process. When the changes are approved, the Template(s) are updated and (non-orphan) Sheets are updated with the new approved Sheets.
At the end of the process, the Templates are updated by the API.
-Craig
$ scl enable python33 python
Python 3.3.2 (default, Jul 10 2014, 18:29:37)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smartsheetclient
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/rh/python33/root/usr/lib/python3.3/site-packages/smartsheetclient/__init__.py", line 5, in <module>
from client_1_1 import (
ImportError: No module named 'client_1_1'
I want to know the modified time for a row. When I read the modified_at property for any row, it is always None.
In order to debug, I get response.request_response.text
. Here when I parse the JSON, I'm able to read valid modifiedAt property for all rows.
response = ss_client.Sheets.get_sheet(
smSheetInfo['sheetId'],
include='format,discussions')
for row in response.rows:
if row.modified_at:
print(row.modified_at) # always None, nothing is printed
The Sheet object lists TotalRowCount as an attribute.
In sheet.py, it is total_row_count
Doc lists TotalRowCount in three places.
The defaults for Sheet load do not fetch the data about attachments, discussions, formats or filters.
This is consistent with the API, but has tripped me and others up on more than one occasion.
It might be less surprising/confusing if the load Sheet methods returned all of the attributes of the Sheet by default (to the extent that they can), but allowed the user to specify that they weren't interested in certain attributes (such as attachments or discussions).
In the documentation it states that if you are a system administrator AND if IndexResult Object
is under 100 User objects
, you will include the lastLogin
attribute.
include (optional): When specified with a value of “lastLogin”, response will include the lastLogin attribute for each user if:
the request is submitted by a system administrator, and
the returned IndexResult object that contains a maximum of 100 User objects.
The python SDK does seem to support lastLogin
attribute, yet when I try with all sorts of combination the list_users
function, it always returns None
for lastLogin
attribute or does not have the lastLogin
attribute at all. All the other attributes in the User object
are returned correctly by the function.
Please point out what I am doing wrong or confirm this issue, I appreciate your help!
I'd like to be able to save existing sheets as a template.
Use Case:
Project warranty is over. Project has 50 sheets. 90% of those are historical records and need to be archived but not active. Remaining 10% will still be active.
User sets project flag to end-of-warranty and the 45 sheets are archived as Templates and then deleted.
This has several advantages over other archiving schemes as the data still resides and can be found in searches of Smartsheet, where as archiving somewhere else requires searches in two systems. In addition, most backup schemes to do account for functionality (formulas, conditional formatting, etc...) that exist on the Smartsheet platform.
-Craig
Transferring ownership is not currently supported (HTTP status code 403 / Smartsheet error code 1026)
It should be.
Use case #1
A very active user is leaving the company. Hundreds of sheets, reports, workspaces under her control.
There is no one to take over fully, so the company will divide up the control to multiple individuals.
With the API, this would take hours to accomplish. Without it ... much much longer.
It would be beneficial if this could be done with the current owner still a user, ie during the transition phase (in this case - and of course, this is not always possible)
-Craig
I turned on exceptions with Smartsheet.errors_as_exceptions(True)
I then called Sheet.delete_column() on a column that cannot be deleted. I got an exception in the error handling code within Smartsheet.request():
Traceback (most recent call last):
[ ... stack trace reduced for clarity ... ]
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/smartsheet/sheets.py", line 212, in delete_column
response = self._base.request(prepped_request, expected, _op)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/smartsheet/smartsheet.py", line 185, in request
the_ex = native.name
AttributeError: 'Error' object has no attribute 'name'
The code looks like this:
res = self.request_with_retry(prepped_request, operation)
native = res.native(expected)
if not self.raise_exceptions:
return native
if isinstance(native, self.models.Error):
==> the_ex = native.name
raise the_ex(native, native.code + ': ' + native.message)
else:
return native
The 'native' object has this value:
{"requestResponse": null, "result": {"statusCode": 400, "recommendation": "Do not retry.", "code": 1065, "message": "The column specified cannot be deleted.", "name": "ColumnCannotBeDeletedError", "shouldRetry": false}}
May be related to #36.
Debian 8.0, Python 3.4
$ cat apitest.py
#!/usr/bin/env python
import smartsheet
import smartsheet.sheets
import pprint
client = smartsheet.Smartsheet()
sobj = smartsheet.sheets.Sheets(client)
slist = sobj.list_sheets(include_all=True)
pprint.pprint(slist)
$ python3 apitest.py
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 544, in urlopen
body=body, headers=headers)
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 341, in _make_request
self._validate_conn(conn)
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 761, in _validate_conn
conn.connect()
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py", line 238, in connect
ssl_version=resolved_ssl_version)
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/ssl_.py", line 279, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/lib/python3.4/ssl.py", line 364, in wrap_socket
_context=self)
File "/usr/lib/python3.4/ssl.py", line 577, in __init__
self.do_handshake()
File "/usr/lib/python3.4/ssl.py", line 804, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 370, in send
timeout=timeout
File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 574, in urlopen
raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/smartsheet/smartsheet.py", line 208, in _request
res = self._session.send(prepped_request, stream=stream)
File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "apitest.py", line 8, in <module>
slist = sobj.list_sheets(include_all=True)
File "/usr/local/lib/python3.4/dist-packages/smartsheet/sheets.py", line 662, in list_sheets
response = self._base.request(prepped_request, expected, _op)
File "/usr/local/lib/python3.4/dist-packages/smartsheet/smartsheet.py", line 178, in request
res = self.request_with_retry(prepped_request, operation)
File "/usr/local/lib/python3.4/dist-packages/smartsheet/smartsheet.py", line 242, in request_with_retry
return self._request(prepped_request, operation)
File "/usr/local/lib/python3.4/dist-packages/smartsheet/smartsheet.py", line 210, in _request
raise UnexpectedRequestError(rex.request, rex.response)
smartsheet.exceptions.UnexpectedRequestError: (<PreparedRequest [GET]>, None)
$ pip3 list --local
autopep8 (1.2.1)
Brlapi (0.6.2)
certifi (2015.11.20.1)
chardet (2.3.0)
defer (1.0.6)
devscripts (2.15.1)
docker-compose (1.5.1)
docker-py (1.6.0)
dockerpty (0.3.4)
docopt (0.6.2)
jsonschema (2.5.1)
lazr.uri (1.0.3)
louis (2.5.3)
Magic-file-extensions (0.2)
Mako (1.0.0)
MarkupSafe (0.23)
multi-key-dict (2.0.3)
pbr (1.8.1)
pep8 (1.6.2)
pip (7.1.2)
Pygments (2.0.1)
pygobject (3.14.0)
PyMySQL (0.6.7)
python-apt (0.9.3.11)
python-dateutil (2.4.2)
python-debian (0.1.23)
python-jenkins (0.4.11)
pyxdg (0.25)
PyYAML (3.11)
requests (2.7.0)
requests-toolbelt (0.5.1)
setuptools (19.4)
six (1.10.0)
smartsheet-python-sdk (1.0.1)
texttable (0.8.4)
unattended-upgrades (0.1)
wadllib (1.3.2)
websocket-client (0.34.0)
Currently:
– sheet.get_row()
does rest api request for every call, this could be eliminated by adding a row index to Sheet
– To get a cell value by column name, a user needs to build their own index for the header. This can be part of the library and the user would be able to use provide column title to get_cell
when is used on the row
I have this functionality implemented (though without tests), and I can submit PR, but I don't see much activity in this repo, so I would like to understand if it is even worth investing my time into this (and someone will review and merge PR), or I should continue using my fork for the projects.
Hi,
I have been struggling a little bit with indenting rows. I also have a related question on stackoverflow, but now the issue i'm getting feel like I'm trying to use a deprected or non implemented method..
https://stackoverflow.com/questions/49416108/building-whole-sheet-programmatically-with-python-sdk
Now, I was trying to come up with a function to indent rows. As per answered on stack overflow, I can't update multiple rows with multiple parent ids at once. I was hoping maybe (just maybe) indent would let me do something like that. However, I'm not able to use indent at all.
I have tried something like this (I'm just testing so far, so ignore the fact that it doesn't make sense to indent every row after row 150):
def indent_rows(sheet):
i = 0
rows_to_update = []
for row in sheet.rows:
if i >= 150:
row.indent = 1
row.created_at = None # It won't accept me to update_rows without clearing this value
rows_to_update.append(row)
i += 1
return rows_to_update
I have also tried with making a new row for the update:
def indent_rows(sheet):
i = 0
rows_to_update = []
for row in sheet.rows:
if i >= 150:
new_row = ss.models.Row({'id': row.id, 'indent': 1})
rows_to_update.append(new_row)
i += 1
return rows_to_update
Reading issue #44, I tried clearing sibling ids, no luck either. All the above produced:
error 1062: "Invalid row location."
The documentation doesn't seem to mention indent at all for the row object: https://smartsheet-platform.github.io/api-docs/?python#row-object so i'm a bit confused if it's meant to work or not.
It seems like the column tag "GANTT_ALLOCATION" is missing from the list of tags there:
https://smartsheet-platform.github.io/api-docs/?python#column-object
I am trying to move all objects that are not shared from Sheets(Home) to a Workspace.
When I try to move a Sheet located in Sheets(Home)\A-Folder to A-Workspace\A-Folder, I get 'Success', but the Sheet does not move.
I build a destination object:
folder_dest = SmSh.models.ContainerDestination({
'destination_id': fldr_id,
'destination_type': 'folder'})
which is valid (no errors on the folder ID (fldr_id))
The move_sheets code is OK too (no errors)
print(folder_dest)
sht_move = SmSh.Sheets.move_sheet(sheet.id, folder_dest)
print(sht_move.message)
with the response:
{"destinationId": ****************, "destinationType": "folder"}
SUCCESS
The results returned by move_sheets does not provide any useful information.
I am using the same code to move sheets successfully from Workspace to Workspace and from Workspace\Folder to Workspace\Folder.
It is only when going from Sheets(Home)\Folder to Workspace\Folder does it not actually move the Sheet. (I did not check Sheets(Home) to Workspace as I have none matching that description.
Craig
My goal is to populate a second spreadsheet with information from the first sheet using CellLink(). I followed some example code from somewhere, but it doesn't seem to work:
def linkcell(client,source_sheetid,source_rowid,source_columnid,dest_columnid):
cell_link = client.models.CellLink()
cell_link.sheet_id = source_sheetid
cell_link.row_id = source_rowid
cell_link.column_id = source_columnid
cell = client.models.Cell()
cell.column_id = dest_columnid
cell.value=None
cell.link_in_from_cell = cell_link # cell.value not updated at this step
return cell
def update_row_wlinks(client,source_rowid,source_sheetid,dest_sheetid):
get_row(client,source_sheetid,source_rowid)
new_row = client.models.Row()
response=client.Sheets.add_rows(dest_sheetid, new_row)
dest_rowid=response.data[0].to_dict()['id']
row = client.models.Row()
row.id = dest_rowid
for i in id_dict: #id_dict is a dictionary containing mapping of column_ids in sheet A to column_ids in sheet B
cell=make_link(client,source_sheetid,source_row_id,i,id_dict[i])
row.cells.append(cell)
rows = []
rows.append(row)
client.Sheets.update_rows(dest_sheetid, rows)
at the last line i get the ApiError message:
Required object attribute(s) are missing from your request: cell.value.
I've played around with this in a variety of different way and found that cell.value is simply not updated, and I cannot update the row without updating the value. If I do put in a dummy string in cell.value even after linking, it gives me an error.
I am testing the ability to pull down a report and loop through the data, I am getting None when trying to return the column data. Is there a difference between the data returned in a report row vs a sheet row? Or am I just missing something very obvious?
gist:
https://gist.github.com/JoshNewbury/5bc95d8b7c02a8b254bd09265d5bc267
A CHECKBOX
type column will have a JSON cell representation like so in the API
{u'columnId': 3...4, u'value': True}
This value
of True never gets set in the Cell model due to
@value.setter
def value(self, value):
if isinstance(value, six.string_types):
self._value = value
So it is impossible to determine the value of a CHECKBOX
, or am I missing something? :) Thank you!
import smartsheet
smartsheet = smartsheet.Smartsheet('ACCESS_TOKEN')
sheetId = SHEET_ID
smartsheet.Sheets.delete_rows(sheetId,[ROW_ID_1,ROW_ID_2,ROW_ID_3])
This should delete all three rows, but only the first row is deleted.
Passing a comma separated string of the row ids does delete all of the rows.
import smartsheet
smartsheet = smartsheet.Smartsheet('ACCESS_TOKEN')
sheetId = SHEET_ID
smartsheet.Sheets.delete_rows(sheetId,"ROW_ID_1,ROW_ID_2,ROW_ID_3")
When I try to update a row where any one cell is indented, the update call returns the error message invalidRowLocationError
as show at the bottom of this report. I did a little bit of testing, and it appears that if a group of rows is indented, I can update the first one but not the subsequent ones. Because the update_rows method updates the entire row, it really doesn't matter which cell in the row I want to update; I still get the error.
If the following text represents a few rows of a Smartsheet, I've marked which rows I can successfully update and which ones fail.
Parent 1 <-- success
Parent 2 <-- success
Child 1 <-- success
Child 2 <-- fail
Child 3 <-- fail
Child 4 <-- fail
Parent 3 <-- success
Here is the error message.
{
"requestResponse": null,
"result": {
"code": 1062,
"name": "InvalidRowLocationError",
"recommendation": "Do not retry without fixing the problem.",
"shouldRetry": false,
"message": "Invalid row location.",
"statusCode": 400
}
}
The INFO level logging for the package produces WAY too much output. A log entry is recorded for every cell of every row that gets created. This level of logging may be more appropriately represented as DEBUG logging.
The fundamental challenge is that useful INFO logging messages are getting buried and lost in all of these row and cell messages.
Hi , first try of the sdk ,
import smartsheet
ss = smartsheet.Smartsheet(access_token)
sheet = ss.Sheets.get_sheet(smartsheet_id)
*after making call with proper access_token and smartsheet_id assigned ,it threw error !
Traceback (most recent call last):
File "", line 1, in
File "/Users/admin/odoo-env/lib/python2.7/site-packages/smartsheet/sheets.py", line 516, in get_sheet
response = self._base.request(prepped_request, expected, _op)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 242, in request
res = self.request_with_retry(prepped_request, operation)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 333, in request_with_retry
result = self._request(prepped_request, operation)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 304, in _request
res = self._session.send(prepped_request, stream=stream)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/sessions.py", line 596, in send
r = adapter.send(request, **kwargs)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/adapters.py", line 423, in send
timeout=timeout
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 583, in urlopen
conn = self._get_conn(timeout=pool_timeout)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 257, in _get_conn
return conn or self._new_conn()
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 819, in _new_conn
strict=self.strict, **self.conn_kw)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/packages/urllib3/connection.py", line 210, in init
timeout=timeout, **kw)
File "/Users/admin/odoo-env/lib/python2.7/site-packages/requests/packages/urllib3/connection.py", line 126, in init
_HTTPConnection.init(self, *args, **kw)
TypeError: init() got an unexpected keyword argument 'ssl_context'
init() got an unexpected keyword argument 'ssl_context'
and will appreciate if any one can give me some advice on this ?
import smartsheet
smartsheet = smartsheet.Smartsheet('ACCESS_TOKEN')
row = smartsheet.models.Row()
row.to_top = True
row.cells.append({
'column_id': COLUMN_ID,
'value': 1234
})
action = smartsheet.Sheets.add_rows(SHEET_ID, [row])
Above code should insert a new row to the top of the sheet with the number 1234 in the cell. Instead no value is entered, a blank row is created, and there is no error reported. Making 1234 a string will allow the value to be inserted, but it comes in as text. There looks to be no way to insert a number using the Python SDK.
Version 2.0 of the Smartsheet API was announced on July 11, 2015.
The Python SDK only supports version 1.1 of the API.
The Discussion object is incomplete.
It has no mechanism to fetch any of its Attachments or Comments.
The Discussion objects returned when fetching a Sheet with discussions=True
is something of scaffold, it doesn't contain any of the Comments. It also doesn't contain any of the Attachments to the Discussion unless the Sheet was also fetched with attachments=True
.
There should be a mechanism to fetch the full Discussion object given a partial Discussion object (such as is returned when fetching the Sheet or a a Row).
I'd like to access the Email Object.
I asked the question on Stack Overflow here:
https://stackoverflow.com/questions/51732734/possible-to-access-sheet-report-email-object-smartsheet/51733230#51733230
I am referring to the Email Object that is created when Send As Attachment is setup with Delivery settings that are recurring.
Use Case (retrieval):
Provide means to see all recurring emails being sent out of the system.
Use Case (modification):
Provide means to increase or decrease frequency of emails when certain criteria are met (identified risks, approaching deadlines, missed deadlines, etc...)
Craig
I think the column numbers start after the i on the sheets. Am I right? If that is the case it should be noted somewhere in the documentation. Unless I somehow missed the note.
Most of the row attributes have a corresponding attribute to get information, but there is no created_by. Had to write my own to call the API directly.
Unable to retrieve sight object with the Sights.get_sight() method. It seems that the it's not able to parse the 'id' field in the response:
Traceback (most recent call last):
File "D:/Users/dduransseau/Developpement/trunk/test_script/smartsheet/test1.py", line 59, in
program_sight = ss.Sights.get_sight(program_sight_id)
File "C:\Python35\lib\site-packages\smartsheet\sights.py", line 78, in get_sight
response = self._base.request(prepped_request, expected, op)
File "C:\Python35\lib\site-packages\smartsheet\smartsheet.py", line 211, in request
native = res.native(expected)
File "C:\Python35\lib\site-packages\smartsheet\smartsheet.py", line 448, in native
obj = class(data, self._base)
File "C:\Python35\lib\site-packages\smartsheet\models\sight.py", line 72, in init
self.widgets = props['widgets']
File "C:\Python35\lib\site-packages\smartsheet\models\sight.py", line 138, in widgets
if not isinstance(x, Widget) else x) for x in value
File "C:\Python35\lib\site-packages\smartsheet\models\sight.py", line 138, in
if not isinstance(x, Widget) else x) for x in value
File "C:\Python35\lib\site-packages\smartsheet\models\widget.py", line 98, in init
self.contents = props['contents']
File "C:\Python35\lib\site-packages\smartsheet\models\widget.py", line 220, in contents
self._contents = WidgetContent(value, self._base)
File "C:\Python35\lib\site-packages\smartsheet\models\widget_content.py", line 66, in init
self.hyperlink = props['id']
KeyError: 'id'
Hello,
I'm writing an ETL script for our company's smartsheets that frequently uses get_row() and get_column(). My script works for a while, but then starts receiving 404 errors when the queried sheet_id and row_id exist.
Response: {
status: 404 Not Found
content: {
{
"errorCode": 1006,
"message": "Not Found",
"refId": "s8uwcraf9rsv"
}
}
In my jupyter notebook, I can call get_row() with the same values that it is erroring out on, and it's working. It only seems to be an issue when it is running in the script. I thought there might be a rate limit error, but I believe that should have a different error code. Do you know what's happening?
Using python 2.7 and the smartsheet-python-sdk in PyPi on 9/17/2016, all Checkbox types columns returned displayValues and values of None, regardless of the actual value of the cell, in multiple sheets.
Any write operation on a Row invalidates the entire Row cache for the Sheet.
After that, all further Row accesses result in a fetch of the specific Row.
Whether I use a valid access token, a revoked token, or "bob", I get the same error:
In [24]: sIn [24]: ss = smartsheet.Smartsheet(new_at)
In [25]: ss.Server.server_info()
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:120: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
UnexpectedRequestError Traceback (most recent call last)
in ()
----> 1 ss.Server.server_info()
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/server.pyc in server_info(self)
45 expected = 'ServerInfo'
46 prepped_request = self._base.prepare_request(_op)
---> 47 response = self._base.request(prepped_request, expected, _op)
48
49 return response
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in request(self, prepped_request, expected, operation)
176 The API operation result object.
177 """
--> 178 res = self.request_with_retry(prepped_request, operation)
179 native = res.native(expected)
180
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in request_with_retry(self, prepped_request, operation)
240 self._log.info('Request to %s', prepped_request.url)
241 try:
--> 242 return self._request(prepped_request, operation)
243 except (ApiError, HttpError) as err:
244 if isinstance(err, (
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in _request(self, prepped_request, operation)
208 res = self._session.send(prepped_request, stream=stream)
209 except (requests.exceptions.RequestException) as rex:
--> 210 raise UnexpectedRequestError(rex.request, rex.response)
211
212 # req_headers = dump_message_headers(res.request)
UnexpectedRequestError: (<PreparedRequest [GET]>, None)
s = smartsheet.Smartsheet(new_at)
In [25]: ss.Server.server_info()
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:120: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
UnexpectedRequestError Traceback (most recent call last)
in ()
----> 1 ss.Server.server_info()
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/server.pyc in server_info(self)
45 expected = 'ServerInfo'
46 prepped_request = self._base.prepare_request(_op)
---> 47 response = self._base.request(prepped_request, expected, _op)
48
49 return response
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in request(self, prepped_request, expected, operation)
176 The API operation result object.
177 """
--> 178 res = self.request_with_retry(prepped_request, operation)
179 native = res.native(expected)
180
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in request_with_retry(self, prepped_request, operation)
240 self._log.info('Request to %s', prepped_request.url)
241 try:
--> 242 return self._request(prepped_request, operation)
243 except (ApiError, HttpError) as err:
244 if isinstance(err, (
/home/scottw/code/new-python-sdk/py27/local/lib/python2.7/site-packages/smartsheet/smartsheet.pyc in _request(self, prepped_request, operation)
208 res = self._session.send(prepped_request, stream=stream)
209 except (requests.exceptions.RequestException) as rex:
--> 210 raise UnexpectedRequestError(rex.request, rex.response)
211
212 # req_headers = dump_message_headers(res.request)
UnexpectedRequestError: (<PreparedRequest [GET]>, None)
From the API documentation it looks like there should be a way to update a subset of cells in a row. However, the current sdk doesn't seem to support this - update_rows only accepts an list of rows and sheetID. Can this functionality be added?
def update_rows(self, sheet_id, list_of_rows):
"""Update properties of the specified Row.
Updates cell values in the specified row(s),
expands/collapses the specified row(s), and/or modifies the
position of the specified rows (including indenting/outdenting).
If a row's position is updated, all child rows are moved with the
row.
In a parent row, values of the following fields are auto-calculated
based upon values in the child rows (and therefore cannot be
updated using the API): Start Date, End Date, Duration, % Complete.
Args:
sheet_id (int): Sheet ID
list_of_rows (list[Row]): Array containing one
or more Row objects.
Returns:
Result
"""
_op = fresh_operation('update_rows')
_op['method'] = 'PUT'
_op['path'] = '/sheets/' + str(sheet_id) + '/rows'
_op['json'] = list_of_rows
# filter before we go
for item in _op['json']:
item.pre_request_filter = 'update_rows'
expected = ['Result', 'Row']
prepped_request = self._base.prepare_request(_op)
response = self._base.request(prepped_request, expected, _op)
return response
This is an issue because I am unable to update entire rows in my sheet because some cells contain hyperlinks.
response = smartsheet.Sheets.update_rows(devOnGoingID, [row_2update])
{"requestResponse": null, "result": {"code": 1046, "name": "NotEditableViaApiError", "recommendation": "Do not retry.", "shouldRetry": false, "message": "Cells containing formulas, links to other cells, system values, or Gantt values cannot be inserted or updated through the API, columnId : 6220532535322500", "statusCode": 400}}
(that 'column id' is actually the sheet id.)
I am writing ETL to wipe and rewrite a smartsheet each day based on the content of another smartsheet. As part of that I delete each column with ss.Sheets.delete_column()
, and then I want to add columns to the sheet and fill out rows.
I found examples of how to write rows in the test_mock_api_rows.py
file, but I'm having trouble figuring out how to add columns. Here's what I'm trying:
test_sheet_id = '1234'
sheet = ss.Sheets.get_sheet(test_sheet_id)
for c in sheet.columns:
if not c.primary:
ss.Sheets.delete_column(out_sheet_id, c.id)
ss.Sheets.add_columns(out_sheet_id, [
{'title':'a', 'type': "TEXT_NUMBER", 'index':1},
{'title':'b', 'type': "TEXT_NUMBER", 'index':2}
])
This code is able to wipe the columns, but I'm getting this API response when adding the new columns:
Response: {
status: 400 Bad Request
content: {
{
"detail": {
"columnTitle": null
},
"errorCode": 1012,
"message": "Required object attribute(s) are missing from your request: column.title, column.type, column.index.",
"refId": "qsuvqbntaixm"
}
}
I've tried passing in column jsons using column.title, columnTitle, and title (for each of title, type, index), and nothing has worked. Can you give me a quick example of how I can add columns to a smartsheet?
I just wrote a program to delete all empty columns from all sheets in a workspace.
The way this works is to iterate all rows and count non-empty cells for each column.
Not having all of the rows could result in accidental deletion of a column that appears empty because I'm only seeing the first 100 rows.
I guess I understand that the default matches the API, but it would be really nice to have a way to pass the includeAll=true parameter to fetch all rows in a single call.
Even better would be to have the SDK hide the paging from me and simply allow me to iterate all of the rows without worrying about using includeAll or handling the paging myself.
Thanks.
smartsheet-python-sdk/smartsheet/models/sent_update_request.py
Lines 40 to 43 in 81882ed
CANCELED
is missing from valid values for update_request_status. This breaks the method.
ValueError: `CANCELED` is an invalid value for SentUpdateRequest`update_request_status`, must be one of ['PENDING', 'COMPLETE']
The Python SDK doesn't support Unicode characters. Running a Get Sheet results in this error:
>>> sheet = smartsheet.Sheets.get_sheet(sheetId)
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/site-packages/smartsheet/sheets.py", line 460, in get_sheet response = self._base.request(prepped_request, expected, _op) File "/usr/local/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 179, in request native = res.native(expected) File "/usr/local/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 408, in native obj = class_(data, self._base) File "/usr/local/lib/python2.7/site-packages/smartsheet/models/sheet.py", line 90, in __init__ self.columns = props['columns'] File "/usr/local/lib/python2.7/site-packages/smartsheet/models/sheet.py", line 220, in columns if not isinstance(x, Column) else x) for x in value File "/usr/local/lib/python2.7/site-packages/smartsheet/models/column.py", line 134, in __init__ self.options = props['options'] File "/usr/local/lib/python2.7/site-packages/smartsheet/models/column.py", line 257, in options if not isinstance(x, str) else x) for x in value UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 4: ordinal not in range(128)
Error updating rows: {'result': {'errorCode': 1008, 'statusCode': 400, 'code': 1008, 'recommendation': 'Do not retry without fixing the problem. ', 'name': 'ApiError', 'shouldRetry': False, 'refId': 'ldmd8op6jknr', 'message': 'Unable to parse request. The following error occurred: Field "createdAt" was of unexpected type.'}}
Does this suggest that smartsheet-python-sdk 1.3.3 should stop sending the created_at attribute to Smartsheet API 2.0?
smartsheet-python-sdk 1.3.3
python 3.5
In the API Documentation for List Workspaces the response for a request via python looks like below:
{
"pageNumber": 1,
"pageSize": 100,
"totalPages": 1,
"totalCount": 2,
"data": [
{
"accessLevel": "OWNER",
"id": 3457273486960516,
"name": "workspace 1",
"permalink": "https://app.smartsheet.com/b/home?lx=JNL0bgXtXc0pzni9tzAc4g"
},
{
"accessLevel": "OWNER",
"id": 7960873114331012,
"name": "workspace 2",
"permalink": "https://app.smartsheet.com/b/home?lx=JLiJbgXtXc0pzni9tzAKiR"
}
]
}
The list_workspaces method in the python sdk includes additional arrays for folders, templates, sheets and reports in each workspace object that are always empty regardless of the contents of the workspace:
Request:
action = smartsheet.Workspaces.list_workspaces()
workspaces = action.data
print(workspaces[0])
Response:
{"folders": [], "templates": [], "permalink": "{{PERMALINK}}", "name": "{{WORKSPACE_NAME}}", "sheets": [], "accessLevel": "{{ACCESS_LEVEL}}", "favorite": null, "id": {{WORKSPACE_ID}}, "reports": []}
The site is generally unusable because it just hangs.
Just wanted to get this on our radar.
requests==2.17.3
smartsheet-python-sdk==1.2.0
urllib3==1.21.1
Traceback (most recent call last):
File "/var/bdb/tasks/test_smartsheet_api/__init__.py", line 17, in task
print(ss.Sheets.list_sheets())
File "/venv/python2713-1/lib/python2.7/site-packages/smartsheet/sheets.py", line 732, in list_sheets
response = self._base.request(prepped_request, expected, _op)
File "/venv/python2713-1/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 210, in request
res = self.request_with_retry(prepped_request, operation)
File "/venv/python2713-1/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 278, in request_with_retry
result = self._request(prepped_request, operation)
File "/venv/python2713-1/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 240, in _request
res = self._session.send(prepped_request, stream=stream)
File "/venv/python2713-1/lib/python2.7/site-packages/requests/sessions.py", line 623, in send
r = adapter.send(request, **kwargs)
File "/venv/python2713-1/lib/python2.7/site-packages/requests/adapters.py", line 440, in send
timeout=timeout
File "/venv/python2713-1/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 587, in urlopen
timeout_obj = self._get_timeout(timeout)
File "/venv/python2713-1/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 302, in _get_timeout
return Timeout.from_float(timeout)
File "/venv/python2713-1/lib/python2.7/site-packages/requests/packages/urllib3/util/timeout.py", line 154, in from_float
return Timeout(read=timeout, connect=timeout)
File "/venv/python2713-1/lib/python2.7/site-packages/requests/packages/urllib3/util/timeout.py", line 94, in __init__
self._connect = self._validate_timeout(connect, 'connect')
File "/venv/python2713-1/lib/python2.7/site-packages/requests/packages/urllib3/util/timeout.py", line 127, in _validate_timeout
"int, float or None." % (name, value))
ValueError: Timeout value connect was Timeout(connect=None, read=None, total=None), but it must be an int, float or None.
Hi,
Using the SDK in python 2.7, I noticed most of the errors do not actually format properly.
I was wondering why the error messages I was getting were not giving useful information:
ValueError:
[0]
invalid type for [1] value
Looking at the code, it seems like it's not using the right syntax:
For example, looking at types.py, line 75:
raise ValueError("Can't convert %s to %s in TypedList", item, self.item_type)
would need to be:
raise ValueError("Can't convert %s to %s in TypedList" % (item, self.item_type))
or line 135:
raise ValueError("
[0] invalid type for [1] value".format(value, self.object_type))
would need to be:
raise ValueError("
{0} invalid type for {1} value".format(value, self.object_type))
Hello,
Our software is attempting to insert 366 new rows into the target Smartsheet.
Upon invoking the SDK (smartsheet-python-sdk 1.3.3) add_rows() method, the error response below is returned from Smartsheet.
How should we interpret the following error response?
Does the detail.index suggest that it was the 5th row (record) that was missing a value for one of the cells? Which cell? The first one?
Is there a way to turn up the verbosity so that the error response will indicate which of the 366 inbound rows contain missing values and which cells specifically?
Thank you in advance.
Response: { status: 400 Bad Request content: { { "detail": { "index": 5 }, "errorCode": 1012, "message": "Required object attribute(s) are missing from your request: cell.value.", "refId": "1ayar3kc6daio" } }
Thank you for your efforts on this library. I am having troubles getting up and running. Here's my environment:
A basic request of smartsheet.Users.get_current_user()
results in this cryptic message:
Traceback (most recent call last):
File "ss.py", line 4, in <module>
print ss.Users.get_current_user()
File "/usr/lib/python2.7/site-packages/smartsheet/users.py", line 151, in get_current_user
response = self._base.request(prepped_request, expected, _op)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 178, in request
res = self.request_with_retry(prepped_request, operation)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 242, in request_with_retry
return self._request(prepped_request, operation)
File "/usr/lib/python2.7/site-packages/smartsheet/smartsheet.py", line 210, in _request
raise UnexpectedRequestError(rex.request, rex.response)
smartsheet.exceptions.UnexpectedRequestError: (<PreparedRequest [GET]>, None)
It turns out that the requests library can't make a simple request to the server:
>>> import requests
>>> import certifi
>>> requests.get('https://api.smartsheet.com')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/requests/api.py", line 68, in get
return request('get', url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 464, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:765)
>>> requests.get('https://api.smartsheet.com', cert=certifi.where())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/requests/api.py", line 68, in get
return request('get', url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 464, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL] PEM lib (_ssl.c:2757)
I am also attempting to figure out how to work around this and am puzzled as it does not seem that certifi
even provides the Symantec certs used by the API server necessary to make this work? I am missing something obvious about this? Is there a minimum version requirement on requests? I fully expect I am doing something wrong, so thank you kindly for the help. Thank you!
The method in sheets.py is defined as
def list_org_sheets(self):
without parameters like list_sheets
def list_sheets(self, include=None, page_size=100, page=1,
include_all=False):
This results in the return being limited to page_size 100 without a way to change it.
Perhaps the only difference in the two methods should be the path?
Limited tested of a new version of sheets.py with this update seems positive.
Craig
row = smartsheet.Sheets.get_row(SHEET_ID,ROW_ID)
print(row)
In response the createdAt and modifiedAt values are null instead of containing date/time values.
sheet = smartsheet.Sheets.get_sheet(SHEET_ID, include='attachments,discussions,format,ownerInfo')
This request will only return the the attachments info and ignore the other items listed in include.
sheet = smartsheet.Sheets.get_sheet(SHEET_ID, include='attachments')
This request will return the attachments data or other include parameters.
Hi.
This one is most likely an user error (using python 2.7).
I can't seem to add_rows() if a cell in PICKLIST column contains any value other than the pre-defined ones, though in the smartsheet UI the column is set to not "restrict to dropdown values only".
smartsheet.exceptions.ApiError: {"result": {"shouldRetry": false, "code": 1042, "name": "ApiError", "errorCode": 1042, "recommendation": "Do not retry without fixing the problem. ", "message": "The value for cell in column 2529062913632132, Final, did not conform to the strict requirements for type PICKLIST.", "refId": "vnoknjvk4g05", "statusCode": 400}}
When printing the column, I get:
{"index": 1, "title": "Status", "options": ["Not Started", "In Progress", "On Track", "At Risk", "Complete"], "width": 181, "validation": false, "type": "PICKLIST", "id": 2529062913632132}
Hi,
I am trying to list all the sheets that I have in a folder, however I have the following issue:
`C:\Python27\python.exe "C:/Python27/Labs/Cisco Smartsheet/SS_LIST_Sheet.py"
You are Working on folder : Dev Leer Smart-Sheet
Traceback (most recent call last):
File "C:/Python27/Labs/Cisco Smartsheet/SS_LIST_Sheet.py", line 17, in
print response._sheets
File "C:\Python27\lib\site-packages\smartsheet\types.py", line 82, in str
return json.dumps(self._store)
File "C:\Python27\lib\site-packages\openpyxl-2.4.0a1-py2.7.egg\json_init.py", line 244, in dumps
return _default_encoder.encode(obj)
File "C:\Python27\lib\site-packages\openpyxl-2.4.0a1-py2.7.egg\json\encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Python27\lib\site-packages\openpyxl-2.4.0a1-py2.7.egg\json\encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "C:\Python27\lib\site-packages\openpyxl-2.4.0a1-py2.7.egg\json\encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <smartsheet.models.sheet.Sheet object at 0x02AEB610> is not JSON serializable
Process finished with exit code 1
`
My code is this:
`# -- coding: utf-8 --
import pprint
import json
import smartsheet
access_token = 'MyToken'
ss_client = smartsheet.Smartsheet(access_token)
#response = ss_client.Sheets.list_sheets(include_all=True)
response = ss_client.Folders.get_folder(
7197610382518148)
print "You are Working on folder : " + response._name
print response._sheets`
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.