I'm interested in using the ArcGIS API for Python to connect to an ArcGIS Online for Organizations account via a token, and not a username/password. All the examples I have found look like this:
from arcgis.gis import GIS gis = GIS("portal url", "username", "password")
How would I pass a token into this API, instead of username/password?
In case it matters, I want to connect to ArcGIS Online for Organizations, so my user name is <user>_<org_suffix>. My organization does not use an Enterprise Login, so I just log in directly at the Esri site.
Bonus question: I know how to generate the token with Python and the REST API (using JSON). Any idea how to do so with the ArcGIS API for Python?
thanks, David
Solved! Go to Solution.
Actually David and all, this has already been resolved starting with ArcGIS for Python version 1.4. Make sure you have updated to this or latest 1.5 version.
The GIS class has been extended to take a token as part of the kwargs optional keyword arguments.
arcgis.gis module — arcgis 1.5.0 documentation
Code below assumes connecting to arcgis.com and uses a token (it will also connect to your organizational account in agol).
AGOLConnection = GIS(token=agolToken)
if you wanted to connect to your own portal then provide the url parameter.
This is resolve now.
from arcgis.gis import GIS
gis = GIS()
dir(gis)
Out[137]: ['__class__', .... snip ....
'_server_list', '_tools', '_url', '_username', '_verify_cert', 'content', 'groups', 'map', 'properties', 'update_properties', 'users']
help(gis)
help on GIS in module arcgis.gis object:
class GIS(builtins.object)
| .. _gis:
|
| A GIS is representative of ArcGIS Online or ArcGIS Enterprise. The GIS object provides helper objects to manage
| (search, create, retrieve) GIS resources such as content, users, and groups.
|
| Additionally, the GIS object has properties to query it's state, which is accessible using the properties attribute.
|
| The GIS provides a mapping widget that can be used in the Jupyter Notebook environment for visualizing GIS content
| as well as the results of your analysis. To create a new map, call the map() method.
|
provides anonymous login apparent... give it whirl
Hi Dan, I noodled around with this a bit. Not sure how this would work. I did note that if I put in bogus credentials, I get back an error that it cannot generate a token (which makes sense). I guess my question is still how would I skip the user/pass checking if I already have a token that was supplied?
>>> from arcgis.gis import GIS
>>> gis = GIS('https://xxx.maps.arcgis.com/', username='xxx', password='xxx')
Unable to generate token.
Invalid username or password.
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\arcgis\gis\__init__.py", line 257, in __init__
client_id=self._client_id)
File "C:\Python36\lib\site-packages\arcgis\_impl\portalpy.py", line 163, in __init__
client_id=client_id)
File "C:\Python36\lib\site-packages\arcgis\_impl\connection.py", line 284, in __init__
self.login(username, password, expiration, client_id)
File "C:\Python36\lib\site-packages\arcgis\_impl\connection.py", line 532, in login
newtoken = self.generate_token(username, password, expiration, client_id)
File "C:\Python36\lib\site-packages\arcgis\_impl\connection.py", line 397, in generate_token
ssl=True, add_token=False)
File "C:\Python36\lib\site-packages\arcgis\_impl\connection.py", line 1129, in post
self._handle_json_error(resp_json['error'], errorcode)
File "C:\Python36\lib\site-packages\arcgis\_impl\connection.py", line 1149, in _handle_json_error
raise RuntimeError(errormessage)
RuntimeError: Unable to generate token.
Invalid username or password.
(Error Code: 400)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Python36\lib\site-packages\arcgis\gis\__init__.py", line 264, in __init__
raise RuntimeError(e.args)
RuntimeError: ('Unable to generate token.\nInvalid username or password.\n(Error Code: 400)',)
I not sure about a token, but from a admin (for moving items to new user, etc) sample and some messing around, this is what I use to connect:
(edit: btw, I'm also hoping to figure out a better way with a token or at least a hidden encrypted pasword...just havent' messed with that yet)
# standard modules to load
from arcgis.gis import GIS
from IPython.display import display
from getpass import getpass
# the organizational admin account to use. This is a generic one to be used for administration tasks only
adminuser = "an_adminuser"
# the URL to our organizational account
ourAGOLOrg = "https://ourorg.maps.arcgis.com"
# Set password variable..enter the password for the admin user specified above. e.g. alaskafishandgame
# will prompt for password, will display *** as you type and ... after
password = getpass()
#Create a connection to the portal. In this case, we will exercise the verify_cert option to not validate the SSL certificate (True by default).
# make sure the correct admin user and password are set above
# If it works, will not return anything and will skip to next box.
# If credentials are bad, will return an error message.
gis = GIS(ourAGOLOrg, adminuser, password, verify_cert=False)
Thanks, Rebecca. I didn't specify, but I'd like this to run headless without a user prompt.
I king of suspected that (my edit about not getting it any further), but thought that might help you or others in future. I also would like a headless option. Trying to set things up for not admin users.
btw...you can hard code the password variable instead of using getpass....but I wouldn't think that would be desirable.
Indeed, hard-coding the password was what I was trying to avoid... I was thinking of generating a token (they seem to have a 2-week max length for AGOL) on some interval and putting it somewhere my code can access it, but no such luck. Generating a profile will at least get the storage out of my code and my Git repo, but it's still in clear text on the hard drive...
>>> from arcgis.gis import GIS
>>> gis = GIS('https://xxx.maps.arcgis.com/', username='xxx', password='xxx', profile='my_profile')
I'm honestly thinking it is just easier to send JSON to the REST endpoint than to use the ArcGIS API for Python.
I had a similar question posted in 2017. I had a JS app that did SAML user login into AGOL and received a token. I wanted to pass that token to a Python module (using ArcGIS API for Python).
At the time the only suggestion I was given was to hack it:
from arcgis.gis import GIS
my_gis = GIS()
con = my_gis._con
con._token = mytoken
my_gis._url = 'https://myorg.maps.arcgis.com'
con._url = 'https://myorg.maps.arcgis.com'
Frankly I never got this to work.
Only recently, my questions was answered and I was referred to the latest API which now includes a kwargs section in the GIS object that lets you specify a token if user/pass is empty.
arcgis.gis module — arcgis 1.4.0 documentation
There seem to be no samples provided so I just tried:
my_gis = GIS(url='https://myorg.maps.arcgis.com', token='mytokenvalue')
No luck still.
Hi,
The authentication is handled when you call gis class in the ArcGIS Python API. Using the python API, tokens and authentication are provided by the api so you don't need to manually create and append tokens to each request. YOu can still use tokens and send direct rest calls using the rest api if desired:
Generate Token—ArcGIS REST API: Users, groups, and content | ArcGIS for Developers
Example Script:
http://www.arcgis.com/home/item.html?id=f448101c080d4edb8991fb79da818915
As a rule of thumb, never embed a token or username and password in a script that users have access to. With any of these components a potentially malicious user could access your content and resources as your username. If you are looking to authenticate on behalf of users in a public application, check out the app login workflow:
Implementing App Login | ArcGIS for Developers
-Kelly
Hi,
Did you get any solution for this? Please share your workout with code sample that will great.
Arun