11
11
UdtDictionaryDescriptor , ExternalidListDescriptor , EntityDescriptor , BooleanDescriptor , EntityListDescriptor , \
12
12
StringAttributeDescriptor , StringListDescriptor , DimensionDescriptor , IntegerDescriptor , \
13
13
PlacementDictionaryDescriptor , InputOutputMapList , LocationDescriptor , ReagentLabelList , NestedEntityListDescriptor , \
14
- NestedStringListDescriptor , NestedAttributeListDescriptor , IntegerAttributeDescriptor
14
+ NestedStringListDescriptor , NestedAttributeListDescriptor , IntegerAttributeDescriptor , NestedStringDescriptor , \
15
+ NestedBooleanDescriptor
15
16
16
17
try :
17
18
from urllib .parse import urlsplit , urlparse , parse_qs , urlunparse
@@ -317,13 +318,26 @@ def _create(cls, lims, creation_tag=None, **kwargs):
317
318
@classmethod
318
319
def create (cls , lims , creation_tag = None , ** kwargs ):
319
320
"""Create an instance from attributes then post it to the LIMS"""
320
- instance = cls ._create (lims , creation_tag = None , ** kwargs )
321
+ instance = cls ._create (lims , creation_tag = creation_tag , ** kwargs )
321
322
data = lims .tostring (ElementTree .ElementTree (instance .root ))
322
323
instance .root = lims .post (uri = lims .get_uri (cls ._URI ), data = data )
323
324
instance ._uri = instance .root .attrib ['uri' ]
324
325
return instance
325
326
326
327
328
+ class Instrument (Entity ):
329
+ """Lab Instrument
330
+ """
331
+ _URI = "instruments"
332
+ _tag = "instrument"
333
+ _PREFIX = "inst"
334
+
335
+ name = StringDescriptor ('name' )
336
+ type = StringDescriptor ('type' )
337
+ serial_number = StringDescriptor ('serial-number' )
338
+ expiry_date = StringDescriptor ('expiry-date' )
339
+ archived = BooleanDescriptor ('archived' )
340
+
327
341
class Lab (Entity ):
328
342
"Lab; container of researchers."
329
343
@@ -338,7 +352,6 @@ class Lab(Entity):
338
352
externalids = ExternalidListDescriptor ()
339
353
website = StringDescriptor ('website' )
340
354
341
-
342
355
class Researcher (Entity ):
343
356
"Person; client scientist or lab personnel. Associated with a lab."
344
357
@@ -357,11 +370,26 @@ class Researcher(Entity):
357
370
externalids = ExternalidListDescriptor ()
358
371
359
372
# credentials XXX
373
+ username = NestedStringDescriptor ('username' , 'credentials' )
374
+ account_locked = NestedBooleanDescriptor ('account-locked' , 'credentials' )
360
375
361
376
@property
362
377
def name (self ):
363
378
return "%s %s" % (self .first_name , self .last_name )
364
379
380
+ class Permission (Entity ):
381
+ """A Clarity permission. Only supports GET"""
382
+ name = StringDescriptor ('name' )
383
+ action = StringDescriptor ('action' )
384
+ description = StringDescriptor ('description' )
385
+
386
+
387
+ class Role (Entity ):
388
+ """Clarity Role, hosting permissions"""
389
+ name = StringDescriptor ('name' )
390
+ researchers = NestedEntityListDescriptor ('researcher' , Researcher , 'researchers' )
391
+ permissions = NestedEntityListDescriptor ('permission' , Permission , 'permissions' )
392
+
365
393
366
394
class Reagent_label (Entity ):
367
395
"""Reagent label element"""
@@ -473,6 +501,9 @@ def get_placements(self):
473
501
self .lims .get_batch (list (result .values ()))
474
502
return result
475
503
504
+ def delete (self ):
505
+ self .lims .delete (self .uri )
506
+
476
507
477
508
class Processtype (Entity ):
478
509
_TAG = 'process-type'
@@ -517,8 +548,8 @@ class Process(Entity):
517
548
udt = UdtDictionaryDescriptor ()
518
549
files = EntityListDescriptor (nsmap ('file:file' ), File )
519
550
process_parameter = StringDescriptor ('process-parameter' )
551
+ instrument = EntityDescriptor ('instrument' , Instrument )
520
552
521
- # instrument XXX
522
553
# process_parameters XXX
523
554
524
555
def outputs_per_input (self , inart , ResultFile = False , SharedResultFile = False , Analyte = False ):
@@ -704,13 +735,14 @@ class StepPools(Entity):
704
735
def _remove_available_inputs (self , input_art ):
705
736
""" removes an input from the available inputs, one replicate at a time
706
737
"""
738
+ self .get_available_inputs ()
707
739
rep = self ._available_inputs .get (input_art , {'replicates' : 0 }).get ('replicates' , 1 )
708
740
if rep > 1 :
709
741
self ._available_inputs [input_art ]['replicates' ] = rep - 1
710
742
elif rep == 1 :
711
743
del (self ._available_inputs [input_art ])
712
744
else :
713
- raise Exception ( "No more replicates left for artifact {0}" .format (input_art ))
745
+ logger . info ( "using more inputs than replicates for input {0}" .format (input_art . uri ))
714
746
self .available_inputs = self ._available_inputs
715
747
716
748
def set_available_inputs (self , available_inputs ):
@@ -719,7 +751,7 @@ def set_available_inputs(self, available_inputs):
719
751
for input_art in available_inputs :
720
752
current_elem = ElementTree .SubElement (available_inputs_root , "input" )
721
753
current_elem .attrib ['uri' ] = input_art .uri
722
- current_elem .attrib ['replicates' ] = available_inputs [input_art ]['replicates' ]
754
+ current_elem .attrib ['replicates' ] = str ( available_inputs [input_art ]['replicates' ])
723
755
self ._available_inputs = available_inputs
724
756
725
757
def get_available_inputs (self ):
@@ -784,7 +816,7 @@ def get_placement_list(self):
784
816
for node in self .root .find ('output-placements' ).findall ('output-placement' ):
785
817
input = Artifact (self .lims , uri = node .attrib ['uri' ])
786
818
location = (None , None )
787
- if node .find ('location' ):
819
+ if node .find ('location' ) is not None :
788
820
location = (
789
821
Container (self .lims , uri = node .find ('location' ).find ('container' ).attrib ['uri' ]),
790
822
node .find ('location' ).find ('value' ).text
@@ -963,6 +995,7 @@ class Step(Entity):
963
995
program_status = EntityDescriptor ('program-status' , StepProgramStatus )
964
996
965
997
def advance (self ):
998
+ self .get ()
966
999
self .root = self .lims .post (
967
1000
uri = "{}/advance" .format (self .uri ),
968
1001
data = self .lims .tostring (ElementTree .ElementTree (self .root ))
@@ -1035,6 +1068,7 @@ def __init__(self, lims, uri=None, id=None):
1035
1068
if child .attrib .get ("name" ) == "Sequence" :
1036
1069
self .sequence = child .attrib .get ("value" )
1037
1070
1071
+
1038
1072
class Queue (Entity ):
1039
1073
"""Queue of a given step"""
1040
1074
_URI = "queues"
@@ -1049,4 +1083,5 @@ class Queue(Entity):
1049
1083
Artifact .workflow_stages = NestedEntityListDescriptor ('workflow-stage' , Stage , 'workflow-stages' )
1050
1084
Step .configuration = EntityDescriptor ('configuration' , ProtocolStep )
1051
1085
StepProgramStatus .configuration = EntityDescriptor ('configuration' , ProtocolStep )
1086
+ Researcher .roles = NestedEntityListDescriptor ('role' , Role , 'credentials' )
1052
1087
0 commit comments