Skip to content

Commit

Permalink
bring back change made to lims/entitites lost when merging with master
Browse files Browse the repository at this point in the history
  • Loading branch information
tcezard committed Jun 14, 2017
1 parent 9a1a58c commit 1377c20
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 29 deletions.
86 changes: 61 additions & 25 deletions pyclarity_lims/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
InputOutputMapList, LocationDescriptor, IntegerAttributeDescriptor, \
StringAttributeDescriptor, EntityListDescriptor, StringListDescriptor, PlacementDictionaryDescriptor, \
ReagentLabelList, AttributeListDescriptor, StringDictionaryDescriptor, OutputPlacementListDescriptor

try:
from urllib.parse import urlsplit, urlparse, parse_qs, urlunparse
except ImportError:
Expand Down Expand Up @@ -235,6 +234,8 @@ class Entity(object):
_TAG = None
_URI = None
_PREFIX = None
_CREATION_PREFIX = None
_CREATION_TAG = None

def __new__(cls, lims, uri=None, id=None, _create_new=False):
if not uri:
Expand Down Expand Up @@ -297,15 +298,18 @@ def post(self):
self.lims.post(self.uri, data)

@classmethod
def _create(cls, lims, creation_tag=None, **kwargs):
def _create(cls, lims, **kwargs):
"""Create an instance from attributes and return it"""
instance = cls(lims, _create_new=True)
if creation_tag:
instance.root = ElementTree.Element(nsmap(cls._PREFIX + ':' + creation_tag))
elif cls._TAG:
instance.root = ElementTree.Element(nsmap(cls._PREFIX + ':' + cls._TAG))
else:
instance.root = ElementTree.Element(nsmap(cls._PREFIX + ':' + cls.__name__.lower()))
prefix = cls._CREATION_PREFIX
if prefix is None:
prefix = cls._PREFIX
tag = cls._CREATION_TAG
if tag is None:
tag = cls._TAG
if tag is None:
tag = cls.__name__.lower()
instance.root = ElementTree.Element(nsmap(prefix + ':' + tag))
for attribute in kwargs:
if hasattr(instance, attribute):
setattr(instance, attribute, kwargs.get(attribute))
Expand All @@ -315,9 +319,9 @@ def _create(cls, lims, creation_tag=None, **kwargs):
return instance

@classmethod
def create(cls, lims, creation_tag=None, **kwargs):
def create(cls, lims, **kwargs):
"""Create an instance from attributes then post it to the LIMS"""
instance = cls._create(lims, creation_tag=None, **kwargs)
instance = cls._create(lims, **kwargs)
data = lims.tostring(ElementTree.ElementTree(instance.root))
instance.root = lims.post(uri=lims.get_uri(cls._URI), data=data)
instance._uri = instance.root.attrib['uri']
Expand Down Expand Up @@ -406,6 +410,7 @@ class Sample(Entity):

_URI = 'samples'
_PREFIX = 'smp'
_CREATION_TAG = 'samplecreation'

name = StringDescriptor('name')
date_received = StringDescriptor('date-received')
Expand All @@ -426,7 +431,7 @@ def create(cls, lims, container, position, **kwargs):
"""Create an instance of Sample from attributes then post it to the LIMS"""
if not isinstance(container, Container):
raise TypeError('%s is not of type Container'%container)
instance = super(Sample, cls)._create(lims, creation_tag='samplecreation', **kwargs)
instance = super(Sample, cls)._create(lims, **kwargs)

location = ElementTree.SubElement(instance.root, 'location')
ElementTree.SubElement(location, 'container', dict(uri=container.uri))
Expand Down Expand Up @@ -495,9 +500,9 @@ class Udfconfig(Entity):
first_preset_is_default_value = BooleanDescriptor('first-preset-is-default-value')
show_in_tables = BooleanDescriptor('show-in-tables')
is_editable = BooleanDescriptor('is-editable')
is_deviation = BooleanDescriptor('is-deviation')
is_deviation = BooleanDescriptor('is-deviation')
is_controlled_vocabulary = BooleanDescriptor('is-controlled-vocabulary')
presets = StringListDescriptor('preset')
presets = StringListDescriptor('preset')



Expand All @@ -506,6 +511,7 @@ class Process(Entity):

_URI = 'processes'
_PREFIX = 'prc'
_CREATION_PREFIX = 'prx'

type = EntityDescriptor('type', Processtype)
date_run = StringDescriptor('date-run')
Expand Down Expand Up @@ -584,8 +590,8 @@ def result_files(self):
return [a for a in artifacts if a.output_type == 'ResultFile']

def analytes(self):
"""Retreving the output Analytes of the process, if existing.
If the process is not producing any output analytes, the input
"""Retreving the output Analytes of the process, if existing.
If the process is not producing any output analytes, the input
analytes are returned. Input/Output is returned as a information string.
Makes aggregate processes and normal processes look the same."""
info = 'Output'
Expand All @@ -611,7 +617,7 @@ def output_containers(self):

@property
def step(self):
"""Retrive the Step coresponding to this process. They share the same id"""
"""Retrieve the Step corresponding to this process. They share the same id"""
return Step(self.lims, id=self.id)


Expand Down Expand Up @@ -804,19 +810,26 @@ class StepDetails(Entity):
udt = UdtDictionaryDescriptor(nesting=['fields'])


class StepProgramStatus(Entity):
"""Status display in the step"""

status = StringDescriptor('status')
message = StringDescriptor('message')


class Step(Entity):
"Step, as defined by the pyclarity_lims API."
"Step, as defined by the genologics API."

_URI = 'steps'
_PREFIX = 'stp'
_CREATION_TAG = 'step-creation'

current_state = StringAttributeDescriptor('current-state')
_reagent_lots = EntityDescriptor('reagent-lots', StepReagentLots)
actions = EntityDescriptor('actions', StepActions)
placements = EntityDescriptor('placements', StepPlacements)
details = EntityDescriptor('details', StepDetails)

#program_status = EntityDescriptor('program-status',StepProgramStatus)
current_state = StringAttributeDescriptor('current-state')
_reagent_lots = EntityDescriptor('reagent-lots', StepReagentLots)
actions = EntityDescriptor('actions', StepActions)
placements = EntityDescriptor('placements', StepPlacements)
details = EntityDescriptor('details', StepDetails)
program_status = EntityDescriptor('program-status', StepProgramStatus)

def advance(self):
self.root = self.lims.post(
Expand All @@ -828,6 +841,30 @@ def advance(self):
def reagent_lots(self):
return self._reagent_lots.reagent_lots

def process(self):
"""Retrieve the Process corresponding to this Step. They share the same id"""
return Process(self.lims, id=self.id)

@classmethod
def create(cls, lims, inputs, container_type_name=None, reagent_category=None, **kwargs):
instance = super(Step, cls)._create(lims, **kwargs)
if container_type_name:
container_type_node = ElementTree.SubElement(instance.root, 'container-type')
container_type_node.text = container_type_name
if reagent_category:
reagent_category_node = ElementTree.SubElement(instance.root, 'reagent_category')
reagent_category_node.text = reagent_category
inputs_node = ElementTree.SubElement(instance.root, 'inputs')
for artifact in inputs:
if not isinstance(artifact, Artifact):
raise TypeError('Input must be of type Artifact not %s.' % type(artifact))
input_node = ElementTree.SubElement(inputs_node, 'input')
input_node.attrib['uri'] = artifact.uri
data = lims.tostring(ElementTree.ElementTree(instance.root))
instance.root = lims.post(uri=lims.get_uri(cls._URI), data=data)
instance._uri = instance.root.attrib['uri']
return instance


class ProtocolStep(Entity):
"""Steps key in the Protocol object"""
Expand Down Expand Up @@ -904,4 +941,3 @@ class Queue(Entity):
Stage.workflow = EntityDescriptor('workflow', Workflow)
Artifact.workflow_stages = EntityListDescriptor(tag='workflow-stage', klass=Stage, nesting=['workflow-stages'])
Step.configuration = EntityDescriptor('configuration', ProtocolStep)

8 changes: 4 additions & 4 deletions pyclarity_lims/lims.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ class Lims(object):
def __init__(self, baseuri, username, password, version=VERSION):
"""baseuri: Base URI for the GenoLogics server, excluding
the 'api' or version parts!
For example: https://pyclarity_lims.scilifelab.se:8443/
For example: https://genologics.scilifelab.se:8443/
username: The account name of the user to login as.
password: The password for the user account to login as.
version: The optional LIMS API version, by default 'v2'
version: The optional LIMS API version, by default 'v2'
"""
self.baseuri = baseuri.rstrip('/') + '/'
self.username = username
Expand Down Expand Up @@ -200,7 +200,7 @@ def parse_response(self, response, accept_status_codes=[200]):
def get_udfs(self, name=None, attach_to_name=None, attach_to_category=None, start_index=None, add_info=False):
"""Get a list of udfs, filtered by keyword arguments.
name: name of udf
attach_to_name: item in the system, to wich the udf is attached, such as
attach_to_name: item in the system, to wich the udf is attached, such as
Sample, Project, Container, or the name of a process.
attach_to_category: If 'attach_to_name' is the name of a process, such as 'CaliperGX QC (DNA)',
then you need to set attach_to_category='ProcessType'. Must not be provided otherwise.
Expand Down Expand Up @@ -483,7 +483,7 @@ def _get_instances(self, klass, add_info=None, params=dict()):
results.append(klass(self, uri=node.attrib['uri']))
info_dict = {}
for attrib_key in node.attrib:
info_dict[attrib_key] = node.attrib['uri']
info_dict[attrib_key] = node.attrib[attrib_key]
for subnode in node:
info_dict[subnode.tag] = subnode.text
additionnal_info_dicts.append(info_dict)
Expand Down

0 comments on commit 1377c20

Please sign in to comment.