flywheel-sdk 20.4.4__py2.py3-none-any.whl → 20.5.0rc0__py2.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 (34) hide show
  1. flywheel/__init__.py +2 -0
  2. flywheel/api/acquisitions_api.py +116 -0
  3. flywheel/api/sessions_api.py +3 -3
  4. flywheel/api/subjects_api.py +116 -0
  5. flywheel/api_client.py +1 -1
  6. flywheel/configuration.py +2 -2
  7. flywheel/drone_login.py +2 -1
  8. flywheel/finder.py +11 -12
  9. flywheel/flywheel.py +28 -2
  10. flywheel/gear_context.py +6 -17
  11. flywheel/models/__init__.py +3 -1
  12. flywheel/models/acquisition_container_output.py +1 -0
  13. flywheel/models/acquisition_copy_input.py +221 -0
  14. flywheel/models/acquisition_list_output.py +32 -4
  15. flywheel/models/acquisition_node.py +1 -0
  16. flywheel/models/acquisition_output.py +32 -4
  17. flywheel/models/acquisition_upsert_input.py +31 -4
  18. flywheel/models/features.py +28 -28
  19. flywheel/models/gear_invocation.py +1 -0
  20. flywheel/models/gear_mixin.py +4 -16
  21. flywheel/models/mixins.py +25 -76
  22. flywheel/models/search_parent_acquisition.py +1 -0
  23. flywheel/models/session_upsert_input.py +31 -4
  24. flywheel/models/subject.py +8 -0
  25. flywheel/models/subject_copy_input.py +221 -0
  26. flywheel/models/subject_upsert_input.py +31 -4
  27. flywheel/models/work_in_progress_features.py +30 -1
  28. flywheel/util.py +6 -8
  29. flywheel/view_builder.py +14 -40
  30. {flywheel_sdk-20.4.4.dist-info → flywheel_sdk-20.5.0rc0.dist-info}/METADATA +1 -1
  31. {flywheel_sdk-20.4.4.dist-info → flywheel_sdk-20.5.0rc0.dist-info}/RECORD +34 -32
  32. {flywheel_sdk-20.4.4.dist-info → flywheel_sdk-20.5.0rc0.dist-info}/WHEEL +0 -0
  33. {flywheel_sdk-20.4.4.dist-info → flywheel_sdk-20.5.0rc0.dist-info}/licenses/LICENSE.txt +0 -0
  34. {flywheel_sdk-20.4.4.dist-info → flywheel_sdk-20.5.0rc0.dist-info}/top_level.txt +0 -0
flywheel/models/mixins.py CHANGED
@@ -2,7 +2,8 @@ import warnings
2
2
 
3
3
  from .. import util
4
4
  from ..finder import Finder
5
- from .gear_mixin import GearMixin
5
+ from .gear_mixin import GearMixin # noqa: F401
6
+
6
7
 
7
8
  class ContextBase(object):
8
9
  def __init__(self):
@@ -35,9 +36,7 @@ class ContainerBase(object):
35
36
  fname = fmt.format(self.container_type)
36
37
  fn = getattr(self.__context, fname, None)
37
38
  if not fn:
38
- raise ValueError(
39
- f"Context {self.__context} doesn't have a function {fname}"
40
- )
39
+ raise ValueError(f"Context {self.__context} doesn't have a function {fname}")
41
40
  return fn(*args, **kwargs)
42
41
 
43
42
  def _invoke_file_api(self, fmt, *args, **kwargs):
@@ -51,9 +50,7 @@ class ContainerBase(object):
51
50
  if fn:
52
51
  return fn(*args, **kwargs)
53
52
  else:
54
- raise ValueError(
55
- f"Context {self.__context} doesn't have a function {fname}"
56
- )
53
+ raise ValueError(f"Context {self.__context} doesn't have a function {fname}")
57
54
  return None
58
55
 
59
56
  def _add_child(self, child_type, args, kwargs):
@@ -105,9 +102,7 @@ class ContainerBase(object):
105
102
  """Get the modification time in the local timezone"""
106
103
  return self._localize_date("modified")
107
104
 
108
- def _find_children(
109
- self, child_type, filters, find_first=False, find_one=False, **kwargs
110
- ):
105
+ def _find_children(self, child_type, filters, find_first=False, find_one=False, **kwargs):
111
106
  fname = "get_{}_{}".format(self.container_type, child_type)
112
107
  return self.__context._find(
113
108
  fname,
@@ -134,7 +129,6 @@ class ContainerBase(object):
134
129
 
135
130
 
136
131
  class InfoMethods(object):
137
-
138
132
  def _warn_if_keys_will_be_sanitized(self, key):
139
133
  """Log warning message for offending characters"""
140
134
  if "$" in key:
@@ -212,9 +206,7 @@ class PermissionMethods(object):
212
206
 
213
207
  def update_permission(self, user_id, permission, **kwargs):
214
208
  """Update a user's permission on container"""
215
- return self._invoke_container_api(
216
- "modify_{}_user_permission", self.id, user_id, permission, **kwargs
217
- )
209
+ return self._invoke_container_api("modify_{}_user_permission", self.id, user_id, permission, **kwargs)
218
210
 
219
211
  def delete_permission(self, user_id, **kwargs):
220
212
  """Delete a user's permission from container"""
@@ -231,12 +223,7 @@ class DownloadMethods(object):
231
223
  :return: A summary of the download
232
224
  """
233
225
  return self._invoke_container_api(
234
- "download_tar",
235
- self,
236
- dest_file,
237
- include_types=include_types,
238
- exclude_types=exclude_types,
239
- **kwargs
226
+ "download_tar", self, dest_file, include_types=include_types, exclude_types=exclude_types, **kwargs
240
227
  )
241
228
 
242
229
  def download_zip(self, dest_file, include_types=None, exclude_types=None, **kwargs):
@@ -248,16 +235,10 @@ class DownloadMethods(object):
248
235
  :return: A summary of the download
249
236
  """
250
237
  return self._invoke_container_api(
251
- "download_zip",
252
- self,
253
- dest_file,
254
- include_types=include_types,
255
- exclude_types=exclude_types,
256
- **kwargs
238
+ "download_zip", self, dest_file, include_types=include_types, exclude_types=exclude_types, **kwargs
257
239
  )
258
240
 
259
241
 
260
-
261
242
  class AnalysisMethods(object):
262
243
  def add_analysis(self, *args, **kwargs):
263
244
  """Add an analysis to this container"""
@@ -303,9 +284,7 @@ class FileMethods(object):
303
284
 
304
285
  def download_file(self, file_name, dest_file, **kwargs):
305
286
  """Download file to the given path"""
306
- return self._invoke_file_api(
307
- "download_file_from_{}", self.id, file_name, dest_file, **kwargs
308
- )
287
+ return self._invoke_file_api("download_file_from_{}", self.id, file_name, dest_file, **kwargs)
309
288
 
310
289
  def get_file_download_url(self, file_name, **kwargs):
311
290
  """Get a ticketed download url for the file"""
@@ -313,9 +292,7 @@ class FileMethods(object):
313
292
 
314
293
  def read_file(self, file_name, **kwargs):
315
294
  """Read the contents of the file"""
316
- return self._invoke_file_api(
317
- "download_file_from_{}_as_data", self.id, file_name, **kwargs
318
- )
295
+ return self._invoke_file_api("download_file_from_{}_as_data", self.id, file_name, **kwargs)
319
296
 
320
297
  def update_file(self, file_name, *args, **kwargs):
321
298
  """Update a file's type and/or modality"""
@@ -349,24 +326,18 @@ class FileMethods(object):
349
326
  def delete_file_info(self, file_name, *args, **kwargs):
350
327
  """Delete the file info fields listed in args"""
351
328
  body = util.params_to_list(args)
352
- return self._invoke_file_api(
353
- "delete_{}_file_info_fields", self.id, file_name, body, **kwargs
354
- )
329
+ return self._invoke_file_api("delete_{}_file_info_fields", self.id, file_name, body, **kwargs)
355
330
 
356
331
  def replace_file_classification(self, file_name, classification, modality=None, **kwargs):
357
332
  """Fully replace a file's modality and classification"""
358
333
  body = {"replace": classification}
359
334
  if modality is not None:
360
335
  body["modality"] = modality
361
- return self._invoke_file_api(
362
- "modify_{}_file_classification", self.id, file_name, body, **kwargs
363
- )
336
+ return self._invoke_file_api("modify_{}_file_classification", self.id, file_name, body, **kwargs)
364
337
 
365
338
  def update_file_classification(self, file_name, classification, **kwargs):
366
339
  """Update a file's classification"""
367
- return self._invoke_file_api(
368
- "set_{}_file_classification", self.id, file_name, classification, **kwargs
369
- )
340
+ return self._invoke_file_api("set_{}_file_classification", self.id, file_name, classification, **kwargs)
370
341
 
371
342
  def delete_file_classification(self, file_name, classification, **kwargs):
372
343
  """Delete a file's classification fields"""
@@ -409,9 +380,7 @@ class FileMethods(object):
409
380
 
410
381
  def read_file_zip_member(self, file_name, member_path, **kwargs):
411
382
  """Read contents of file's zip member"""
412
- return self._invoke_file_api(
413
- "download_file_from_{}_as_data", self.id, file_name, member=member_path, **kwargs
414
- )
383
+ return self._invoke_file_api("download_file_from_{}_as_data", self.id, file_name, member=member_path, **kwargs)
415
384
 
416
385
 
417
386
  class TimestampMethods(object):
@@ -445,15 +414,11 @@ class GroupMixin(ContainerBase, TagMethods, PermissionMethods):
445
414
 
446
415
  def add_permission_template(self, permission, **kwargs):
447
416
  """Add a permission template for a group"""
448
- return self._invoke_container_api(
449
- "add_group_permission_template", self.id, permission, **kwargs
450
- )
417
+ return self._invoke_container_api("add_group_permission_template", self.id, permission, **kwargs)
451
418
 
452
419
  def get_permission_template(self, user_id, **kwargs):
453
420
  """Get a user's permission template for a group"""
454
- return self._invoke_container_api(
455
- "get_group_user_permission_template", self.id, user_id, **kwargs
456
- )
421
+ return self._invoke_container_api("get_group_user_permission_template", self.id, user_id, **kwargs)
457
422
 
458
423
  def update_permission_template(self, user_id, permission, **kwargs):
459
424
  """Update a user's permission template for a group"""
@@ -467,9 +432,7 @@ class GroupMixin(ContainerBase, TagMethods, PermissionMethods):
467
432
 
468
433
  def delete_permission_template(self, user_id, **kwargs):
469
434
  """Delete a user's permission template from a group"""
470
- return self._invoke_container_api(
471
- "delete_group_user_permission_template", self.id, user_id, **kwargs
472
- )
435
+ return self._invoke_container_api("delete_group_user_permission_template", self.id, user_id, **kwargs)
473
436
 
474
437
 
475
438
  class ProjectMixin(
@@ -494,9 +457,7 @@ class ProjectMixin(
494
457
  return self._add_child("session", args, kwargs)
495
458
 
496
459
 
497
- class SubjectMixin(
498
- ContainerBase, TagMethods, NoteMethods, FileMethods, InfoMethods, AnalysisMethods
499
- ):
460
+ class SubjectMixin(ContainerBase, TagMethods, NoteMethods, FileMethods, InfoMethods, AnalysisMethods):
500
461
  container_type = "subject"
501
462
  child_types = ["sessions", "analyses", "files"]
502
463
 
@@ -573,9 +534,7 @@ class AcquisitionMixin(
573
534
  child_types = ["analyses", "files"]
574
535
 
575
536
 
576
- class AnalysisMixin(
577
- ContainerBase, NoteMethods, TagMethods, FileMethods, InfoMethods, DownloadMethods
578
- ):
537
+ class AnalysisMixin(ContainerBase, NoteMethods, TagMethods, FileMethods, InfoMethods, DownloadMethods):
579
538
  container_type = "analysis"
580
539
  child_types = ["files"]
581
540
  _file_group = "output"
@@ -587,7 +546,7 @@ class AnalysisMixin(
587
546
  def upload_output(self, file, **kwargs):
588
547
  """Upload an output file to analysis"""
589
548
  return self._invoke_container_api("upload_output_to_analysis", self.id, file, **kwargs)
590
-
549
+
591
550
  def update_file_info(self, file_name, *args, **kwargs):
592
551
  """Update the file's info with the passed in arguments"""
593
552
  body = util.params_to_dict("update_file_info", args, kwargs)
@@ -607,9 +566,7 @@ class CollectionMixin(ContainerBase, NoteMethods, TagMethods, FileMethods, InfoM
607
566
  else:
608
567
  session_ids.append(arg.id)
609
568
 
610
- return self._invoke_container_api(
611
- "add_sessions_to_{}", self.id, session_ids, **kwargs
612
- )
569
+ return self._invoke_container_api("add_sessions_to_{}", self.id, session_ids, **kwargs)
613
570
 
614
571
  def add_acquisitions(self, *args, **kwargs):
615
572
  acquisition_ids = []
@@ -619,9 +576,7 @@ class CollectionMixin(ContainerBase, NoteMethods, TagMethods, FileMethods, InfoM
619
576
  else:
620
577
  acquisition_ids.append(arg.id)
621
578
 
622
- return self._invoke_container_api(
623
- "add_acquisitions_to_{}", self.id, acquisition_ids, **kwargs
624
- )
579
+ return self._invoke_container_api("add_acquisitions_to_{}", self.id, acquisition_ids, **kwargs)
625
580
 
626
581
 
627
582
  class FileMixin(ContainerBase):
@@ -635,9 +590,7 @@ class FileMixin(ContainerBase):
635
590
  @property
636
591
  def parent(self, **kwargs):
637
592
  if self._parent is None:
638
- self._parent = self._invoke_container_api(
639
- f"get_{self._parent_ref.type}", self.parent_ref.id, **kwargs
640
- )
593
+ self._parent = self._invoke_container_api(f"get_{self._parent_ref.type}", self.parent_ref.id, **kwargs)
641
594
  return self._parent
642
595
 
643
596
  @property
@@ -675,9 +628,7 @@ class FileMixin(ContainerBase):
675
628
 
676
629
  def replace_classification(self, classification, modality=None, **kwargs):
677
630
  """Fully replace a file's modality and classification"""
678
- return self.parent.replace_file_classification(
679
- self.name, classification, modality=modality, **kwargs
680
- )
631
+ return self.parent.replace_file_classification(self.name, classification, modality=modality, **kwargs)
681
632
 
682
633
  def update_classification(self, classification, **kwargs):
683
634
  """Update a file's classification"""
@@ -723,9 +674,7 @@ class FileMixin(ContainerBase):
723
674
 
724
675
  def reload(self, **kwargs):
725
676
  """Reload the file."""
726
- return self._invoke_container_api(
727
- "get_file", self.file_id, version=self.version, **kwargs
728
- )
677
+ return self._invoke_container_api("get_file", self.file_id, version=self.version, **kwargs)
729
678
 
730
679
  def get_zip_info(self, **kwargs):
731
680
  """Get zip member information for this file"""
@@ -21,6 +21,7 @@ import six
21
21
  from flywheel.models.acquisition_output import AcquisitionOutput # noqa: F401,E501
22
22
  from flywheel.models.acquisition_parents import AcquisitionParents # noqa: F401,E501
23
23
  from flywheel.models.container_type import ContainerType # noqa: F401,E501
24
+ from flywheel.models.copy_status import CopyStatus # noqa: F401,E501
24
25
  from flywheel.models.file_output import FileOutput # noqa: F401,E501
25
26
  from flywheel.models.join_origins import JoinOrigins # noqa: F401,E501
26
27
  from flywheel.models.note import Note # noqa: F401,E501
@@ -33,7 +33,8 @@ class SessionUpsertInput(object):
33
33
  'age': 'int',
34
34
  'weight': 'float',
35
35
  'operator': 'str',
36
- 'info': 'object'
36
+ 'info': 'object',
37
+ 'tags': 'list[str]'
37
38
  }
38
39
 
39
40
  attribute_map = {
@@ -47,7 +48,8 @@ class SessionUpsertInput(object):
47
48
  'age': 'age',
48
49
  'weight': 'weight',
49
50
  'operator': 'operator',
50
- 'info': 'info'
51
+ 'info': 'info',
52
+ 'tags': 'tags'
51
53
  }
52
54
 
53
55
  rattribute_map = {
@@ -61,10 +63,11 @@ class SessionUpsertInput(object):
61
63
  'age': 'age',
62
64
  'weight': 'weight',
63
65
  'operator': 'operator',
64
- 'info': 'info'
66
+ 'info': 'info',
67
+ 'tags': 'tags'
65
68
  }
66
69
 
67
- def __init__(self, id=None, uid=None, routing_field=None, label=None, source=None, timestamp=None, timezone=None, age=None, weight=None, operator=None, info=None): # noqa: E501
70
+ def __init__(self, id=None, uid=None, routing_field=None, label=None, source=None, timestamp=None, timezone=None, age=None, weight=None, operator=None, info=None, tags=None): # noqa: E501
68
71
  """SessionUpsertInput - a model defined in Swagger"""
69
72
  super(SessionUpsertInput, self).__init__()
70
73
 
@@ -79,6 +82,7 @@ class SessionUpsertInput(object):
79
82
  self._weight = None
80
83
  self._operator = None
81
84
  self._info = None
85
+ self._tags = None
82
86
  self.discriminator = None
83
87
  self.alt_discriminator = None
84
88
 
@@ -104,6 +108,8 @@ class SessionUpsertInput(object):
104
108
  self.operator = operator
105
109
  if info is not None:
106
110
  self.info = info
111
+ if tags is not None:
112
+ self.tags = tags
107
113
 
108
114
  @property
109
115
  def id(self):
@@ -336,6 +342,27 @@ class SessionUpsertInput(object):
336
342
 
337
343
  self._info = info
338
344
 
345
+ @property
346
+ def tags(self):
347
+ """Gets the tags of this SessionUpsertInput.
348
+
349
+
350
+ :return: The tags of this SessionUpsertInput.
351
+ :rtype: list[str]
352
+ """
353
+ return self._tags
354
+
355
+ @tags.setter
356
+ def tags(self, tags):
357
+ """Sets the tags of this SessionUpsertInput.
358
+
359
+
360
+ :param tags: The tags of this SessionUpsertInput. # noqa: E501
361
+ :type: list[str]
362
+ """
363
+
364
+ self._tags = tags
365
+
339
366
 
340
367
  @staticmethod
341
368
  def positional_to_model(value):
@@ -18,6 +18,14 @@ import pprint
18
18
  import re # noqa: F401
19
19
  import six
20
20
 
21
+ from flywheel.models.cohort import Cohort # noqa: F401,E501
22
+ from flywheel.models.copy_status import CopyStatus # noqa: F401,E501
23
+ from flywheel.models.ml_type import MLType # noqa: F401,E501
24
+ from flywheel.models.note import Note # noqa: F401,E501
25
+ from flywheel.models.role_permission import RolePermission # noqa: F401,E501
26
+ from flywheel.models.subject_parents import SubjectParents # noqa: F401,E501
27
+ from flywheel.models.subject_state import SubjectState # noqa: F401,E501
28
+
21
29
 
22
30
  from flywheel.models.subject_output import SubjectOutput
23
31
 
@@ -0,0 +1,221 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Flywheel
5
+
6
+ No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501
7
+
8
+ OpenAPI spec version: 0.0.1
9
+
10
+ Generated by: https://github.com/swagger-api/swagger-codegen.git
11
+ """
12
+
13
+
14
+ ## NOTE: This file is auto generated by the swagger code generator program.
15
+ ## Do not edit the file manually.
16
+
17
+ import pprint
18
+ import re # noqa: F401
19
+ import six
20
+
21
+ from flywheel.models.copy_filter import CopyFilter # noqa: F401,E501
22
+
23
+ class SubjectCopyInput(object):
24
+
25
+ swagger_types = {
26
+ 'dst_subject_label': 'str',
27
+ 'dst_project_id': 'str',
28
+ 'filter': 'CopyFilter'
29
+ }
30
+
31
+ attribute_map = {
32
+ 'dst_subject_label': 'dst_subject_label',
33
+ 'dst_project_id': 'dst_project_id',
34
+ 'filter': 'filter'
35
+ }
36
+
37
+ rattribute_map = {
38
+ 'dst_subject_label': 'dst_subject_label',
39
+ 'dst_project_id': 'dst_project_id',
40
+ 'filter': 'filter'
41
+ }
42
+
43
+ def __init__(self, dst_subject_label=None, dst_project_id=None, filter=None): # noqa: E501
44
+ """SubjectCopyInput - a model defined in Swagger"""
45
+ super(SubjectCopyInput, self).__init__()
46
+
47
+ self._dst_subject_label = None
48
+ self._dst_project_id = None
49
+ self._filter = None
50
+ self.discriminator = None
51
+ self.alt_discriminator = None
52
+
53
+ if dst_subject_label is not None:
54
+ self.dst_subject_label = dst_subject_label
55
+ self.dst_project_id = dst_project_id
56
+ self.filter = filter
57
+
58
+ @property
59
+ def dst_subject_label(self):
60
+ """Gets the dst_subject_label of this SubjectCopyInput.
61
+
62
+ Label to apply to the copied subject
63
+
64
+ :return: The dst_subject_label of this SubjectCopyInput.
65
+ :rtype: str
66
+ """
67
+ return self._dst_subject_label
68
+
69
+ @dst_subject_label.setter
70
+ def dst_subject_label(self, dst_subject_label):
71
+ """Sets the dst_subject_label of this SubjectCopyInput.
72
+
73
+ Label to apply to the copied subject
74
+
75
+ :param dst_subject_label: The dst_subject_label of this SubjectCopyInput. # noqa: E501
76
+ :type: str
77
+ """
78
+
79
+ self._dst_subject_label = dst_subject_label
80
+
81
+ @property
82
+ def dst_project_id(self):
83
+ """Gets the dst_project_id of this SubjectCopyInput.
84
+
85
+ Project to copy to
86
+
87
+ :return: The dst_project_id of this SubjectCopyInput.
88
+ :rtype: str
89
+ """
90
+ return self._dst_project_id
91
+
92
+ @dst_project_id.setter
93
+ def dst_project_id(self, dst_project_id):
94
+ """Sets the dst_project_id of this SubjectCopyInput.
95
+
96
+ Project to copy to
97
+
98
+ :param dst_project_id: The dst_project_id of this SubjectCopyInput. # noqa: E501
99
+ :type: str
100
+ """
101
+
102
+ self._dst_project_id = dst_project_id
103
+
104
+ @property
105
+ def filter(self):
106
+ """Gets the filter of this SubjectCopyInput.
107
+
108
+
109
+ :return: The filter of this SubjectCopyInput.
110
+ :rtype: CopyFilter
111
+ """
112
+ return self._filter
113
+
114
+ @filter.setter
115
+ def filter(self, filter):
116
+ """Sets the filter of this SubjectCopyInput.
117
+
118
+
119
+ :param filter: The filter of this SubjectCopyInput. # noqa: E501
120
+ :type: CopyFilter
121
+ """
122
+
123
+ self._filter = filter
124
+
125
+
126
+ @staticmethod
127
+ def positional_to_model(value):
128
+ """Converts a positional argument to a model value"""
129
+ return value
130
+
131
+ def return_value(self):
132
+ """Unwraps return value from model"""
133
+ return self
134
+
135
+ def to_dict(self):
136
+ """Returns the model properties as a dict"""
137
+ result = {}
138
+
139
+ for attr, _ in six.iteritems(self.swagger_types):
140
+ value = getattr(self, attr)
141
+ if isinstance(value, list):
142
+ result[attr] = list(map(
143
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
144
+ value
145
+ ))
146
+ elif hasattr(value, "to_dict"):
147
+ result[attr] = value.to_dict()
148
+ elif isinstance(value, dict):
149
+ result[attr] = dict(map(
150
+ lambda item: (item[0], item[1].to_dict())
151
+ if hasattr(item[1], "to_dict") else item,
152
+ value.items()
153
+ ))
154
+ else:
155
+ result[attr] = value
156
+
157
+ return result
158
+
159
+ def to_str(self):
160
+ """Returns the string representation of the model"""
161
+ return pprint.pformat(self.to_dict())
162
+
163
+ def __repr__(self):
164
+ """For `print` and `pprint`"""
165
+ return self.to_str()
166
+
167
+ def __eq__(self, other):
168
+ """Returns true if both objects are equal"""
169
+ if not isinstance(other, SubjectCopyInput):
170
+ return False
171
+
172
+ return self.__dict__ == other.__dict__
173
+
174
+ def __ne__(self, other):
175
+ """Returns true if both objects are not equal"""
176
+ return not self == other
177
+
178
+ # Container emulation
179
+ def __getitem__(self, key):
180
+ """Returns the value of key"""
181
+ key = self._map_key(key)
182
+ return getattr(self, key)
183
+
184
+ def __setitem__(self, key, value):
185
+ """Sets the value of key"""
186
+ key = self._map_key(key)
187
+ setattr(self, key, value)
188
+
189
+ def __contains__(self, key):
190
+ """Checks if the given value is a key in this object"""
191
+ key = self._map_key(key, raise_on_error=False)
192
+ return key is not None
193
+
194
+ def keys(self):
195
+ """Returns the list of json properties in the object"""
196
+ return self.__class__.rattribute_map.keys()
197
+
198
+ def values(self):
199
+ """Returns the list of values in the object"""
200
+ for key in self.__class__.attribute_map.keys():
201
+ yield getattr(self, key)
202
+
203
+ def items(self):
204
+ """Returns the list of json property to value mapping"""
205
+ for key, prop in self.__class__.rattribute_map.items():
206
+ yield key, getattr(self, prop)
207
+
208
+ def get(self, key, default=None):
209
+ """Get the value of the provided json property, or default"""
210
+ key = self._map_key(key, raise_on_error=False)
211
+ if key:
212
+ return getattr(self, key, default)
213
+ return default
214
+
215
+ def _map_key(self, key, raise_on_error=True):
216
+ result = self.__class__.rattribute_map.get(key)
217
+ if result is None:
218
+ if raise_on_error:
219
+ raise AttributeError('Invalid attribute name: {}'.format(key))
220
+ return None
221
+ return '_' + result
@@ -38,7 +38,8 @@ class SubjectUpsertInput(object):
38
38
  'species': 'str',
39
39
  'strain': 'str',
40
40
  'info': 'object',
41
- 'state': 'SubjectState'
41
+ 'state': 'SubjectState',
42
+ 'tags': 'list[str]'
42
43
  }
43
44
 
44
45
  attribute_map = {
@@ -56,7 +57,8 @@ class SubjectUpsertInput(object):
56
57
  'species': 'species',
57
58
  'strain': 'strain',
58
59
  'info': 'info',
59
- 'state': 'state'
60
+ 'state': 'state',
61
+ 'tags': 'tags'
60
62
  }
61
63
 
62
64
  rattribute_map = {
@@ -74,10 +76,11 @@ class SubjectUpsertInput(object):
74
76
  'species': 'species',
75
77
  'strain': 'strain',
76
78
  'info': 'info',
77
- 'state': 'state'
79
+ 'state': 'state',
80
+ 'tags': 'tags'
78
81
  }
79
82
 
80
- def __init__(self, date_of_birth=None, id=None, routing_field=None, label=None, source=None, firstname=None, lastname=None, sex=None, type=None, race=None, ethnicity=None, species=None, strain=None, info=None, state=None): # noqa: E501
83
+ def __init__(self, date_of_birth=None, id=None, routing_field=None, label=None, source=None, firstname=None, lastname=None, sex=None, type=None, race=None, ethnicity=None, species=None, strain=None, info=None, state=None, tags=None): # noqa: E501
81
84
  """SubjectUpsertInput - a model defined in Swagger"""
82
85
  super(SubjectUpsertInput, self).__init__()
83
86
 
@@ -96,6 +99,7 @@ class SubjectUpsertInput(object):
96
99
  self._strain = None
97
100
  self._info = None
98
101
  self._state = None
102
+ self._tags = None
99
103
  self.discriminator = None
100
104
  self.alt_discriminator = None
101
105
 
@@ -129,6 +133,8 @@ class SubjectUpsertInput(object):
129
133
  self.info = info
130
134
  if state is not None:
131
135
  self.state = state
136
+ if tags is not None:
137
+ self.tags = tags
132
138
 
133
139
  @property
134
140
  def date_of_birth(self):
@@ -445,6 +451,27 @@ class SubjectUpsertInput(object):
445
451
 
446
452
  self._state = state
447
453
 
454
+ @property
455
+ def tags(self):
456
+ """Gets the tags of this SubjectUpsertInput.
457
+
458
+
459
+ :return: The tags of this SubjectUpsertInput.
460
+ :rtype: list[str]
461
+ """
462
+ return self._tags
463
+
464
+ @tags.setter
465
+ def tags(self, tags):
466
+ """Sets the tags of this SubjectUpsertInput.
467
+
468
+
469
+ :param tags: The tags of this SubjectUpsertInput. # noqa: E501
470
+ :type: list[str]
471
+ """
472
+
473
+ self._tags = tags
474
+
448
475
 
449
476
  @staticmethod
450
477
  def positional_to_model(value):