CartoDB / carto-python

CARTO Python client
https://carto.com
BSD 3-Clause "New" or "Revised" License
154 stars 62 forks source link

Imports fail for non-org users #66

Closed jgoizueta closed 6 years ago

jgoizueta commented 6 years ago

If you try to import a dataset with a non-organization user, it imports the dataset correctly, but then it raises an error:

from carto.auth import APIKeyAuthClient
from carto.datasets import DatasetManager
auth_client = APIKeyAuthClient(api_key="APIKEY", base_url="https://NONORGUSER.carto.com/")
dataset_manager = DatasetManager(auth_client)
dataset = dataset_manager.create(DATAURL)

This is the error (I've omitted non-relevant information).

.../carto-python/carto/resources.py:90: FutureWarning: This is part of a non-public CARTO API and may change in the future. Take this into account if you are using this in a production environment
  warnings.warn('This is part of a non-public CARTO API and may change in the future. Take this into account if you are using this in a production environment', FutureWarning)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../carto-python/carto/datasets.py", line 213, in create
    table = TableManager(self.client).get(import_job.table_id)
...
  File ".../carto-python/carto/users.py", line 64, in __init__
    organization-enabled APIKeyAuthClient"))
carto.exceptions.CartoException: User management requires an                                    organization-enabled APIKeyAuthClient

The problem seems to be that, after the import, the table information is requested (with Table class) which contains a permission (PermissionFieldclass) which in turn has an owner ( Userclass), But the User class only support organization users.

I've managed to avoid the problem with this patch:

diff --git a/carto/users.py b/carto/users.py
index f23f12a..b1e89e3 100644
--- a/carto/users.py
+++ b/carto/users.py
@@ -26,6 +26,7 @@ from .resources import Manager, WarnResource

 API_VERSION = "v1"
 API_ENDPOINT = "api/{api_version}/organization/{organization}/users/"
+API_NONORG_ENDPOINT = "api/{api_version}/users/"

 class User(WarnResource):
@@ -60,15 +61,16 @@ class User(WarnResource):
         :param auth_client: Auth client
         """
         if auth_client.organization is None:
-            raise CartoException(_("User management requires an \
-                                   organization-enabled APIKeyAuthClient"))
+            self._api_endpoint = API_NONORG_ENDPOINT
+        else:
+            self._api_endpoint = API_ENDPOINT

         super(User, self).__init__(auth_client)

     def get_collection_endpoint(self):
         """
         """
-        return API_ENDPOINT.format(api_version=API_VERSION,
+        return self._api_endpoint.format(api_version=API_VERSION,
                                    organization=self.client.organization)

     def get_resource_endpoint(self):
@@ -100,7 +102,7 @@ class UserManager(Manager):
     def get_collection_endpoint(self):
         """
         """
-        return API_ENDPOINT.format(api_version=API_VERSION,
+        return self._api_endpoint.format(api_version=API_VERSION,
                                    organization=self.client.organization)

     def get_resource_endpoint(self, resource_id):