tableauserverclient 0.37__py3-none-any.whl → 0.38__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. tableauserverclient/__init__.py +4 -0
  2. tableauserverclient/bin/_version.py +3 -3
  3. tableauserverclient/helpers/strings.py +25 -1
  4. tableauserverclient/models/__init__.py +6 -1
  5. tableauserverclient/models/datasource_item.py +110 -2
  6. tableauserverclient/models/extract_item.py +82 -0
  7. tableauserverclient/models/flow_item.py +2 -2
  8. tableauserverclient/models/group_item.py +11 -0
  9. tableauserverclient/models/interval_item.py +40 -0
  10. tableauserverclient/models/location_item.py +53 -0
  11. tableauserverclient/models/project_item.py +138 -27
  12. tableauserverclient/models/schedule_item.py +57 -0
  13. tableauserverclient/models/site_item.py +28 -0
  14. tableauserverclient/models/table_item.py +7 -3
  15. tableauserverclient/models/tableau_types.py +13 -1
  16. tableauserverclient/models/user_item.py +101 -1
  17. tableauserverclient/models/view_item.py +79 -5
  18. tableauserverclient/models/workbook_item.py +151 -1
  19. tableauserverclient/server/endpoint/databases_endpoint.py +101 -18
  20. tableauserverclient/server/endpoint/datasources_endpoint.py +3 -3
  21. tableauserverclient/server/endpoint/dqw_endpoint.py +16 -6
  22. tableauserverclient/server/endpoint/endpoint.py +39 -0
  23. tableauserverclient/server/endpoint/schedules_endpoint.py +132 -2
  24. tableauserverclient/server/endpoint/sites_endpoint.py +18 -1
  25. tableauserverclient/server/endpoint/tables_endpoint.py +140 -17
  26. tableauserverclient/server/endpoint/users_endpoint.py +22 -5
  27. tableauserverclient/server/query.py +36 -0
  28. tableauserverclient/server/request_factory.py +5 -0
  29. tableauserverclient/server/request_options.py +128 -2
  30. tableauserverclient/server/server.py +42 -0
  31. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/METADATA +1 -1
  32. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/RECORD +36 -34
  33. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/WHEEL +1 -1
  34. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/licenses/LICENSE +0 -0
  35. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/licenses/LICENSE.versioneer +0 -0
  36. {tableauserverclient-0.37.dist-info → tableauserverclient-0.38.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,11 @@
1
- import logging
2
1
  import xml.etree.ElementTree as ET
3
- from typing import Optional
2
+ from typing import Optional, overload
4
3
 
5
4
  from defusedxml.ElementTree import fromstring
6
5
 
7
6
  from tableauserverclient.models.exceptions import UnpopulatedPropertyError
8
- from tableauserverclient.models.property_decorators import property_is_enum, property_not_empty
7
+ from tableauserverclient.models.property_decorators import property_is_enum
8
+ from tableauserverclient.models.user_item import UserItem
9
9
 
10
10
 
11
11
  class ProjectItem:
@@ -39,12 +39,32 @@ class ProjectItem:
39
39
 
40
40
  Attributes
41
41
  ----------
42
+ datasource_count : int
43
+ The number of data sources in the project.
44
+
42
45
  id : str
43
46
  The unique identifier for the project.
44
47
 
48
+ owner: Optional[UserItem]
49
+ The UserItem owner of the project.
50
+
45
51
  owner_id : str
46
52
  The unique identifier for the UserItem owner of the project.
47
53
 
54
+ project_count : int
55
+ The number of projects in the project.
56
+
57
+ top_level_project : bool
58
+ True if the project is a top-level project.
59
+
60
+ view_count : int
61
+ The number of views in the project.
62
+
63
+ workbook_count : int
64
+ The number of workbooks in the project.
65
+
66
+ writeable : bool
67
+ True if the project is writeable.
48
68
  """
49
69
 
50
70
  ERROR_MSG = "Project item must be populated with permissions first."
@@ -75,6 +95,8 @@ class ProjectItem:
75
95
  self.parent_id: Optional[str] = parent_id
76
96
  self._samples: Optional[bool] = samples
77
97
  self._owner_id: Optional[str] = None
98
+ self._top_level_project: Optional[bool] = None
99
+ self._writeable: Optional[bool] = None
78
100
 
79
101
  self._permissions = None
80
102
  self._default_workbook_permissions = None
@@ -87,6 +109,13 @@ class ProjectItem:
87
109
  self._default_database_permissions = None
88
110
  self._default_table_permissions = None
89
111
 
112
+ self._project_count: Optional[int] = None
113
+ self._workbook_count: Optional[int] = None
114
+ self._view_count: Optional[int] = None
115
+ self._datasource_count: Optional[int] = None
116
+
117
+ self._owner: Optional[UserItem] = None
118
+
90
119
  @property
91
120
  def content_permissions(self):
92
121
  return self._content_permissions
@@ -176,25 +205,53 @@ class ProjectItem:
176
205
  def owner_id(self, value: str) -> None:
177
206
  self._owner_id = value
178
207
 
208
+ @property
209
+ def top_level_project(self) -> Optional[bool]:
210
+ return self._top_level_project
211
+
212
+ @property
213
+ def writeable(self) -> Optional[bool]:
214
+ return self._writeable
215
+
216
+ @property
217
+ def project_count(self) -> Optional[int]:
218
+ return self._project_count
219
+
220
+ @property
221
+ def workbook_count(self) -> Optional[int]:
222
+ return self._workbook_count
223
+
224
+ @property
225
+ def view_count(self) -> Optional[int]:
226
+ return self._view_count
227
+
228
+ @property
229
+ def datasource_count(self) -> Optional[int]:
230
+ return self._datasource_count
231
+
232
+ @property
233
+ def owner(self) -> Optional[UserItem]:
234
+ return self._owner
235
+
179
236
  def is_default(self):
180
237
  return self.name.lower() == "default"
181
238
 
182
- def _parse_common_tags(self, project_xml, ns):
183
- if not isinstance(project_xml, ET.Element):
184
- project_xml = fromstring(project_xml).find(".//t:project", namespaces=ns)
185
-
186
- if project_xml is not None:
187
- (
188
- _,
189
- name,
190
- description,
191
- content_permissions,
192
- parent_id,
193
- ) = self._parse_element(project_xml)
194
- self._set_values(None, name, description, content_permissions, parent_id)
195
- return self
196
-
197
- def _set_values(self, project_id, name, description, content_permissions, parent_id, owner_id):
239
+ def _set_values(
240
+ self,
241
+ project_id,
242
+ name,
243
+ description,
244
+ content_permissions,
245
+ parent_id,
246
+ owner_id,
247
+ top_level_project,
248
+ writeable,
249
+ project_count,
250
+ workbook_count,
251
+ view_count,
252
+ datasource_count,
253
+ owner,
254
+ ):
198
255
  if project_id is not None:
199
256
  self._id = project_id
200
257
  if name:
@@ -207,6 +264,20 @@ class ProjectItem:
207
264
  self.parent_id = parent_id
208
265
  if owner_id:
209
266
  self._owner_id = owner_id
267
+ if project_count is not None:
268
+ self._project_count = project_count
269
+ if workbook_count is not None:
270
+ self._workbook_count = workbook_count
271
+ if view_count is not None:
272
+ self._view_count = view_count
273
+ if datasource_count is not None:
274
+ self._datasource_count = datasource_count
275
+ if top_level_project is not None:
276
+ self._top_level_project = top_level_project
277
+ if writeable is not None:
278
+ self._writeable = writeable
279
+ if owner is not None:
280
+ self._owner = owner
210
281
 
211
282
  def _set_permissions(self, permissions):
212
283
  self._permissions = permissions
@@ -220,31 +291,71 @@ class ProjectItem:
220
291
  )
221
292
 
222
293
  @classmethod
223
- def from_response(cls, resp, ns) -> list["ProjectItem"]:
294
+ def from_response(cls, resp: bytes, ns: Optional[dict]) -> list["ProjectItem"]:
224
295
  all_project_items = list()
225
296
  parsed_response = fromstring(resp)
226
297
  all_project_xml = parsed_response.findall(".//t:project", namespaces=ns)
227
298
 
228
299
  for project_xml in all_project_xml:
229
- project_item = cls.from_xml(project_xml)
300
+ project_item = cls.from_xml(project_xml, namespace=ns)
230
301
  all_project_items.append(project_item)
231
302
  return all_project_items
232
303
 
233
304
  @classmethod
234
- def from_xml(cls, project_xml, namespace=None) -> "ProjectItem":
305
+ def from_xml(cls, project_xml: ET.Element, namespace: Optional[dict] = None) -> "ProjectItem":
235
306
  project_item = cls()
236
- project_item._set_values(*cls._parse_element(project_xml))
307
+ project_item._set_values(*cls._parse_element(project_xml, namespace))
237
308
  return project_item
238
309
 
239
310
  @staticmethod
240
- def _parse_element(project_xml):
311
+ def _parse_element(project_xml: ET.Element, namespace: Optional[dict]) -> tuple:
241
312
  id = project_xml.get("id", None)
242
313
  name = project_xml.get("name", None)
243
314
  description = project_xml.get("description", None)
244
315
  content_permissions = project_xml.get("contentPermissions", None)
245
316
  parent_id = project_xml.get("parentProjectId", None)
317
+ top_level_project = str_to_bool(project_xml.get("topLevelProject", None))
318
+ writeable = str_to_bool(project_xml.get("writeable", None))
246
319
  owner_id = None
247
- for owner in project_xml:
248
- owner_id = owner.get("id", None)
320
+ owner = None
321
+ if (owner_elem := project_xml.find(".//t:owner", namespaces=namespace)) is not None:
322
+ owner = UserItem.from_xml(owner_elem, namespace)
323
+ owner_id = owner_elem.get("id", None)
324
+
325
+ project_count = None
326
+ workbook_count = None
327
+ view_count = None
328
+ datasource_count = None
329
+ if (count_elem := project_xml.find(".//t:contentsCounts", namespaces=namespace)) is not None:
330
+ project_count = int(count_elem.get("projectCount", 0))
331
+ workbook_count = int(count_elem.get("workbookCount", 0))
332
+ view_count = int(count_elem.get("viewCount", 0))
333
+ datasource_count = int(count_elem.get("dataSourceCount", 0))
334
+
335
+ return (
336
+ id,
337
+ name,
338
+ description,
339
+ content_permissions,
340
+ parent_id,
341
+ owner_id,
342
+ top_level_project,
343
+ writeable,
344
+ project_count,
345
+ workbook_count,
346
+ view_count,
347
+ datasource_count,
348
+ owner,
349
+ )
350
+
351
+
352
+ @overload
353
+ def str_to_bool(value: str) -> bool: ...
354
+
355
+
356
+ @overload
357
+ def str_to_bool(value: None) -> None: ...
358
+
249
359
 
250
- return id, name, description, content_permissions, parent_id, owner_id
360
+ def str_to_bool(value):
361
+ return value.lower() == "true" if value is not None else None
@@ -20,6 +20,63 @@ Interval = Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval]
20
20
 
21
21
 
22
22
  class ScheduleItem:
23
+ """
24
+ Using the TSC library, you can schedule extract refresh or subscription
25
+ tasks on Tableau Server. You can also get and update information about the
26
+ scheduled tasks, or delete scheduled tasks.
27
+
28
+ If you have the identifier of the job, you can use the TSC library to find
29
+ out the status of the asynchronous job.
30
+
31
+ The schedule properties are defined in the ScheduleItem class. The class
32
+ corresponds to the properties for schedules you can access in Tableau
33
+ Server or by using the Tableau Server REST API. The Schedule methods are
34
+ based upon the endpoints for jobs in the REST API and operate on the JobItem
35
+ class.
36
+
37
+ Parameters
38
+ ----------
39
+ name : str
40
+ The name of the schedule.
41
+
42
+ priority : int
43
+ The priority of the schedule. Lower values represent higher priority,
44
+ with 0 indicating the highest priority.
45
+
46
+ schedule_type : str
47
+ The type of task schedule. See ScheduleItem.Type for the possible values.
48
+
49
+ execution_order : str
50
+ Specifies how the scheduled tasks should run. The choices are Parallel
51
+ which uses all avaiable background processes for a scheduled task, or
52
+ Serial, which limits the schedule to one background process.
53
+
54
+ interval_item : Interval
55
+ Specifies the frequency that the scheduled task should run. The
56
+ interval_item is an instance of the IntervalItem class. The
57
+ interval_item has properties for frequency (hourly, daily, weekly,
58
+ monthly), and what time and date the scheduled item runs. You set this
59
+ value by declaring an IntervalItem object that is one of the following:
60
+ HourlyInterval, DailyInterval, WeeklyInterval, or MonthlyInterval.
61
+
62
+ Attributes
63
+ ----------
64
+ created_at : datetime
65
+ The date and time the schedule was created.
66
+
67
+ end_schedule_at : datetime
68
+ The date and time the schedule ends.
69
+
70
+ id : str
71
+ The unique identifier for the schedule.
72
+
73
+ next_run_at : datetime
74
+ The date and time the schedule is next run.
75
+
76
+ state : str
77
+ The state of the schedule. See ScheduleItem.State for the possible values.
78
+ """
79
+
23
80
  class Type:
24
81
  Extract = "Extract"
25
82
  Flow = "Flow"
@@ -1188,6 +1188,34 @@ class SiteItem:
1188
1188
  )
1189
1189
 
1190
1190
 
1191
+ class SiteAuthConfiguration:
1192
+ """
1193
+ Authentication configuration for a site.
1194
+ """
1195
+
1196
+ def __init__(self):
1197
+ self.auth_setting: Optional[str] = None
1198
+ self.enabled: Optional[bool] = None
1199
+ self.idp_configuration_id: Optional[str] = None
1200
+ self.idp_configuration_name: Optional[str] = None
1201
+ self.known_provider_alias: Optional[str] = None
1202
+
1203
+ @classmethod
1204
+ def from_response(cls, resp: bytes, ns: dict) -> list["SiteAuthConfiguration"]:
1205
+ all_auth_configs = list()
1206
+ parsed_response = fromstring(resp)
1207
+ all_auth_xml = parsed_response.findall(".//t:siteAuthConfiguration", namespaces=ns)
1208
+ for auth_xml in all_auth_xml:
1209
+ auth_config = cls()
1210
+ auth_config.auth_setting = auth_xml.get("authSetting", None)
1211
+ auth_config.enabled = string_to_bool(auth_xml.get("enabled", ""))
1212
+ auth_config.idp_configuration_id = auth_xml.get("idpConfigurationId", None)
1213
+ auth_config.idp_configuration_name = auth_xml.get("idpConfigurationName", None)
1214
+ auth_config.known_provider_alias = auth_xml.get("knownProviderAlias", None)
1215
+ all_auth_configs.append(auth_config)
1216
+ return all_auth_configs
1217
+
1218
+
1191
1219
  # Used to convert string represented boolean to a boolean type
1192
1220
  def string_to_bool(s: str) -> bool:
1193
1221
  return s.lower() == "true"
@@ -1,8 +1,12 @@
1
+ from typing import Callable, Optional, TYPE_CHECKING
1
2
  from defusedxml.ElementTree import fromstring
2
3
 
3
4
  from .exceptions import UnpopulatedPropertyError
4
5
  from .property_decorators import property_not_empty, property_is_boolean
5
6
 
7
+ if TYPE_CHECKING:
8
+ from tableauserverclient.models import DQWItem
9
+
6
10
 
7
11
  class TableItem:
8
12
  def __init__(self, name, description=None):
@@ -40,7 +44,7 @@ class TableItem:
40
44
  return self._data_quality_warnings()
41
45
 
42
46
  @property
43
- def id(self):
47
+ def id(self) -> Optional[str]:
44
48
  return self._id
45
49
 
46
50
  @property
@@ -100,8 +104,8 @@ class TableItem:
100
104
  def _set_columns(self, columns):
101
105
  self._columns = columns
102
106
 
103
- def _set_data_quality_warnings(self, dqws):
104
- self._data_quality_warnings = dqws
107
+ def _set_data_quality_warnings(self, dqw: Callable[[], list["DQWItem"]]) -> None:
108
+ self._data_quality_warnings = dqw
105
109
 
106
110
  def _set_values(self, table_values):
107
111
  if "id" in table_values:
@@ -1,8 +1,10 @@
1
1
  from typing import Union
2
2
 
3
+ from tableauserverclient.models.database_item import DatabaseItem
3
4
  from tableauserverclient.models.datasource_item import DatasourceItem
4
5
  from tableauserverclient.models.flow_item import FlowItem
5
6
  from tableauserverclient.models.project_item import ProjectItem
7
+ from tableauserverclient.models.table_item import TableItem
6
8
  from tableauserverclient.models.view_item import ViewItem
7
9
  from tableauserverclient.models.workbook_item import WorkbookItem
8
10
  from tableauserverclient.models.metric_item import MetricItem
@@ -25,7 +27,17 @@ class Resource:
25
27
 
26
28
  # resource types that have permissions, can be renamed, etc
27
29
  # todo: refactoring: should actually define TableauItem as an interface and let all these implement it
28
- TableauItem = Union[DatasourceItem, FlowItem, MetricItem, ProjectItem, ViewItem, WorkbookItem, VirtualConnectionItem]
30
+ TableauItem = Union[
31
+ DatasourceItem,
32
+ FlowItem,
33
+ MetricItem,
34
+ ProjectItem,
35
+ ViewItem,
36
+ WorkbookItem,
37
+ VirtualConnectionItem,
38
+ DatabaseItem,
39
+ TableItem,
40
+ ]
29
41
 
30
42
 
31
43
  def plural_type(content_type: Union[Resource, str]) -> str:
@@ -7,6 +7,7 @@ from typing import Optional, TYPE_CHECKING
7
7
  from defusedxml.ElementTree import fromstring
8
8
 
9
9
  from tableauserverclient.datetime_helpers import parse_datetime
10
+ from tableauserverclient.models.site_item import SiteAuthConfiguration
10
11
  from .exceptions import UnpopulatedPropertyError
11
12
  from .property_decorators import (
12
13
  property_is_enum,
@@ -37,6 +38,49 @@ class UserItem:
37
38
  auth_setting: str
38
39
  Required attribute for Tableau Cloud. How the user autenticates to the
39
40
  server.
41
+
42
+ Attributes
43
+ ----------
44
+ domain_name: Optional[str]
45
+ The name of the Active Directory domain ("local" if local authentication
46
+ is used).
47
+
48
+ email: Optional[str]
49
+ The email address of the user.
50
+
51
+ external_auth_user_id: Optional[str]
52
+ The unique identifier for the user in the external authentication system.
53
+
54
+ id: Optional[str]
55
+ The unique identifier for the user.
56
+
57
+ favorites: dict[str, list]
58
+ The favorites of the user. Must be populated with a call to
59
+ `populate_favorites()`.
60
+
61
+ fullname: Optional[str]
62
+ The full name of the user.
63
+
64
+ groups: Pager
65
+ The groups the user belongs to. Must be populated with a call to
66
+ `populate_groups()`.
67
+
68
+ last_login: Optional[datetime]
69
+ The last time the user logged in.
70
+
71
+ locale: Optional[str]
72
+ The locale of the user.
73
+
74
+ language: Optional[str]
75
+ Language setting for the user.
76
+
77
+ idp_configuration_id: Optional[str]
78
+ The ID of the identity provider configuration.
79
+
80
+ workbooks: Pager
81
+ The workbooks owned by the user. Must be populated with a call to
82
+ `populate_workbooks()`.
83
+
40
84
  """
41
85
 
42
86
  tag_name: str = "user"
@@ -94,6 +138,9 @@ class UserItem:
94
138
  self.name: Optional[str] = name
95
139
  self.site_role: Optional[str] = site_role
96
140
  self.auth_setting: Optional[str] = auth_setting
141
+ self._locale: Optional[str] = None
142
+ self._language: Optional[str] = None
143
+ self._idp_configuration_id: Optional[str] = None
97
144
 
98
145
  return None
99
146
 
@@ -184,6 +231,26 @@ class UserItem:
184
231
  raise UnpopulatedPropertyError(error)
185
232
  return self._groups()
186
233
 
234
+ @property
235
+ def locale(self) -> Optional[str]:
236
+ return self._locale
237
+
238
+ @property
239
+ def language(self) -> Optional[str]:
240
+ return self._language
241
+
242
+ @property
243
+ def idp_configuration_id(self) -> Optional[str]:
244
+ """
245
+ IDP configuration id for the user. This is only available on Tableau
246
+ Cloud, 3.24 or later
247
+ """
248
+ return self._idp_configuration_id
249
+
250
+ @idp_configuration_id.setter
251
+ def idp_configuration_id(self, value: str) -> None:
252
+ self._idp_configuration_id = value
253
+
187
254
  def _set_workbooks(self, workbooks) -> None:
188
255
  self._workbooks = workbooks
189
256
 
@@ -204,8 +271,11 @@ class UserItem:
204
271
  email,
205
272
  auth_setting,
206
273
  _,
274
+ _,
275
+ _,
276
+ _,
207
277
  ) = self._parse_element(user_xml, ns)
208
- self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None)
278
+ self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None, None, None, None)
209
279
  return self
210
280
 
211
281
  def _set_values(
@@ -219,6 +289,9 @@ class UserItem:
219
289
  email,
220
290
  auth_setting,
221
291
  domain_name,
292
+ locale,
293
+ language,
294
+ idp_configuration_id,
222
295
  ):
223
296
  if id is not None:
224
297
  self._id = id
@@ -238,6 +311,12 @@ class UserItem:
238
311
  self._auth_setting = auth_setting
239
312
  if domain_name:
240
313
  self._domain_name = domain_name
314
+ if locale:
315
+ self._locale = locale
316
+ if language:
317
+ self._language = language
318
+ if idp_configuration_id:
319
+ self._idp_configuration_id = idp_configuration_id
241
320
 
242
321
  @classmethod
243
322
  def from_response(cls, resp, ns) -> list["UserItem"]:
@@ -249,6 +328,12 @@ class UserItem:
249
328
  element_name = ".//t:owner"
250
329
  return cls._parse_xml(element_name, resp, ns)
251
330
 
331
+ @classmethod
332
+ def from_xml(cls, xml: ET.Element, ns: Optional[dict] = None) -> "UserItem":
333
+ item = cls()
334
+ item._set_values(*cls._parse_element(xml, ns))
335
+ return item
336
+
252
337
  @classmethod
253
338
  def _parse_xml(cls, element_name, resp, ns):
254
339
  all_user_items = []
@@ -265,6 +350,9 @@ class UserItem:
265
350
  email,
266
351
  auth_setting,
267
352
  domain_name,
353
+ locale,
354
+ language,
355
+ idp_configuration_id,
268
356
  ) = cls._parse_element(user_xml, ns)
269
357
  user_item = cls(name, site_role)
270
358
  user_item._set_values(
@@ -277,6 +365,9 @@ class UserItem:
277
365
  email,
278
366
  auth_setting,
279
367
  domain_name,
368
+ locale,
369
+ language,
370
+ idp_configuration_id,
280
371
  )
281
372
  all_user_items.append(user_item)
282
373
  return all_user_items
@@ -295,6 +386,9 @@ class UserItem:
295
386
  fullname = user_xml.get("fullName", None)
296
387
  email = user_xml.get("email", None)
297
388
  auth_setting = user_xml.get("authSetting", None)
389
+ locale = user_xml.get("locale", None)
390
+ language = user_xml.get("language", None)
391
+ idp_configuration_id = user_xml.get("idpConfigurationId", None)
298
392
 
299
393
  domain_name = None
300
394
  domain_elem = user_xml.find(".//t:domain", namespaces=ns)
@@ -311,6 +405,9 @@ class UserItem:
311
405
  email,
312
406
  auth_setting,
313
407
  domain_name,
408
+ locale,
409
+ language,
410
+ idp_configuration_id,
314
411
  )
315
412
 
316
413
  class CSVImport:
@@ -361,6 +458,9 @@ class UserItem:
361
458
  values[UserItem.CSVImport.ColumnType.EMAIL],
362
459
  values[UserItem.CSVImport.ColumnType.AUTH],
363
460
  None,
461
+ None,
462
+ None,
463
+ None,
364
464
  )
365
465
  return user
366
466