openbis连接和交互,为与jupyter一起使用而优化
PyBIS的Python项目详细描述
欢迎来到比比斯!
pybis是一个用于与openbis交互的python模块,设计用于jupyter。它为openbis提供了某种ide,支持tab完成和输入检查,希望能让研究人员的生活更轻松。
依赖关系和要求
- pybis依赖openbis api v3
- 需要OpenBIS版本16.05.2或更高版本
- 建议18.06.2或更高版本
- pybis使用python 3.3和pandas
安装
pip install pybis
该命令将下载install pybis及其所有依赖项。
如果尚未安装,请安装jupyter笔记本:
pip install jupyter
用法
制表符补全和其他提示
在jupyter笔记本环境中使用,pybis帮助您输入命令。在每个点.
之后,您可以按TAB
键来查看可用的命令。
如果您不确定要添加到的参数,请在方法后面添加一个问号,然后按SHIFT+ENTER
。然后,jupyter将查找该方法的签名并显示一些有用的docstring。
在处理实体的属性时,它们可能使用受控词汇表,或者属于特定的属性类型。在属性后面添加下划线_
字符,并按SHIFT+ENTER
显示有效值。当属性只访问受控词汇表时,将在格式良好的表中显示有效术语。
从openbis连接到
from pybis import Openbis
o = Openbis('https://example.com', verify_certificates=False)
import getpass
password = getpass.getpass()
o.login('username', password, save_token=True) # save the session token in ~/.pybis/example.com.token
检查会话令牌是否仍然有效并注销:
o.token
o.is_session_active()
o.logout()
浏览主数据
sample_types = o.get_sample_types() # get a list of sample types
sample_types.df # DataFrame object
st = o.get_sample_types()[3] # get 4th element of that list
st = o.get_sample_type('YEAST')
st.code
st.generatedCodePrefix
st.attrs.all() # get all attributs as a dict
st.validationPlugin # returns a plugin object
st.get_property_assignments()
st.assign_property(
prop='diff_time',
section = '',
ordinal = 5,
mandatory = True,
initialValueForExistingEntities = 'initial value'
showInEditView = True,
showRawValueInForms = True
)
o.get_material_types()
# etc. — see above
o.get_dataset_types()
# etc. — see above
o.get_experiment_types()
# etc. — see above
o.get_property_types()
pt = o.get_property_type('BARCODE_COMPLEXITY_CHECKER')
pt.attrs.all()
o.get_plugins()
pl = o.get_plugin('Diff_time')
pl.script # the Jython script that processes this property
o.get_vocabularies()
o.get_vocabulary('BACTERIAL_ANTIBIOTIC_RESISTANCE')
o.get_terms(vocabulary='STORAGE')
o.get_tags()
创建插件和属性类型
pl = o.new_plugin(
name ='my_new_entry_validation_plugin',
pluginType ='ENTITY_VALIDATION', # or 'DYNAMIC_PROPERTY' or 'MANAGED_PROPERTY',
entityKind = None, # or 'SAMPLE', 'MATERIAL', 'EXPERIMENT', 'DATA_SET'
script = 'def calculate(): pass' # a JYTHON script
)
pl.save()
pt = o.new_property_type(
code='MY_NEW_PROPERTY_TYPE',
label='yet another property type',
description='my first property',
dataType='VARCHAR'
)
# dataType can be any of ['INTEGER', 'VARCHAR', 'MULTILINE_VARCHAR', 'REAL', 'TIMESTAMP', 'BOOLEAN', 'CONTROLLEDVOCABULARY', 'MATERIAL', 'HYPERLINK', 'XML']
用户、组和角色签名
o.get_groups()
group = o.new_group(code='group_name', description='...')
group = o.get_group('group_name')
group.save()
group.assign_role(role='ADMIN', space='DEFAULT')
group.get_roles()
group.revoke_role(role='ADMIN', space='DEFAULT')
group.add_persons(['admin'])
group.get_persons()
group.del_persons(['admin'])
group.delete()
o.get_persons()
person = o.new_person(userId='username')
person.space = 'USER_SPACE'
person.save()
person.assign_role(role='ADMIN', space='MY_SPACE')
person.assign_role(role='OBSERVER')
person.get_roles()
person.revoke_role(role='ADMIN', space='MY_SPACE')
person.revoke_role(role='OBSERVER')
o.get_role_assignments()
o.get_role_assignments(space='MY_SPACE')
o.get_role_assignments(group='MY_GROUP')
ra = o.get_role_assignment(techId)
ra.delete()
空格
space = o.new_space(code='space_name', description='')
space.save()
space.delete('reason for deletion')
o.get_spaces(
start_with = 1, # start_with and count
count = 7, # enable paging
)
space = o.get_space('MY_SPACE')
space.code
space.description
space.registrator
space.registrationDate
space.modifier
space.modificationDate
space.attrs.all() # returns a dict containing all attributes
项目
project = o.new_project(
space=space,
code='project_name',
description='some project description'
)
project = space.new_project( code='project_code', description='project description')
project.save()
o.get_projects(
space = 'MY_SPACE', # show only projects in MY_SPACE
start_with = 1, # start_with and count
count = 7, # enable paging
)
o.get_projects(space='MY_SPACE')
space.get_projects()
project.get_experiments()
project.get_attachments()
p.add_attachment(fileName='testfile', description= 'another file', title= 'one more attachment')
project.download_attachments()
project.code
project.description
# ... and many more
project.attrs.all() # returns a dict containing all attributes
project.freeze = True
project.freezeForExperiments = True
project.freezeForSamples = True
样品
现在openbis中的示例称为objects。pybis还没有在所有出现“sample”的方法中完全支持这个术语。
注意:在openbis中,samples
实体最近被重命名为objects
。所有方法都有使用术语object
的同义词,例如get_object
、new_object
、get_object_types
。
sample = o.new_sample(
type = 'YEAST',
space = 'MY_SPACE',
experiment = '/MY_SPACE/MY_PROJECT/EXPERIMENT_1',
parents = [parent_sample, '/MY_SPACE/YEA66'],
children = [child_sample],
props = {"name": "some name", "description": "something interesting"}
)
sample = space.new_sample( type='YEAST' )
sample.save()
sample = o.get_sample('/MY_SPACE/MY_SAMPLE_CODE')
sample = o.get_sample('20170518112808649-52')
sample.space
sample.code
sample.permId
sample.identifier
sample.type # once the sample type is defined, you cannot modify it
sample.space
sample.space = 'MY_OTHER_SPACE'
sample.experiment # a sample can belong to one experiment only
sample.experiment = '/MY_SPACE/MY_PROJECT/MY_EXPERIMENT'
sample.project
sample.project = '/MY_SPACE/MY_PROJECT' # only works if project samples are
enabled
sample.tags
sample.tags = ['guten_tag', 'zahl_tag' ]
sample.attrs.all() # returns a dict of all attributes
sample.get_parents()
sample.set_parents(['/MY_SPACE/PARENT_SAMPLE_NAME')
sample.add_parents('/MY_SPACE/PARENT_SAMPLE_NAME')
sample.del_parents('/MY_SPACE/PARENT_SAMPLE_NAME')
sample.get_children()
sample.set_children('/MY_SPACE/CHILD_SAMPLE_NAME')
sample.add_children('/MY_SPACE/CHILD_SAMPLE_NAME')
sample.del_children('/MY_SPACE/CHILD_SAMPLE_NAME')
# A Sample may belong to another Sample, which acts as a container.
# As opposed to DataSets, a Sample may only belong to one container.
sample.container # returns a sample object
sample.container = '/MY_SPACE/CONTAINER_SAMPLE_NAME' # watch out, this will change the identifier of the sample to:
# /MY_SPACE/CONTAINER_SAMPLE_NAME:SAMPLE_NAME
sample.container = '' # this will remove the container.
# A Sample may contain other Samples, in order to act like a container (see above)
# The Sample-objects inside that Sample are called «components» or «contained Samples»
# You may also use the xxx_contained() functions, which are just aliases.
sample.get_components()
sample.set_components('/MY_SPACE/COMPONENT_NAME')
sample.add_components('/MY_SPACE/COMPONENT_NAME')
sample.del_components('/MY_SPACE/COMPONENT_NAME')
sample.get_tags()
sample.set_tags('tag1')
sample.add_tags(['tag2','tag3'])
sample.del_tags('tag1')
sample.set_props({ ... })
sample.p # same thing as .props
sample.p.my_property = "some value" # set the value of a property (value is checked)
sample.p + TAB # in IPython or Jupyter: show list of available properties
sample.p.my_property_ + TAB # in IPython or Jupyter: show datatype or controlled vocabulary
sample.p['my-weird.property-name'] # accessing properties containing a dash or a dot
sample.attrs.all() # returns all attributes as a dict
sample.props.all() # returns all properties as a dict
sample.get_attachments()
sample.download_attachments()
sample.add_attachment('testfile.xls')
samples = o.get_samples(
space ='MY_SPACE',
type ='YEAST',
tags =['*'], # only sample with existing tags
start_with = 1, # start_with and count
count = 7, # enable paging
NAME = 'some name', # properties are always uppercase
# to distinguish them from attributes
**{ "SOME.WEIRD:PROP": "value"} # property name contains a dot or a
# colon: cannot be passed as an argument
props=['NAME', 'MATING_TYPE'] # show these properties in the result
)
samples.df # returns a pandas DataFrame object
samples.get_datasets(type='ANALYZED_DATA')
sample.freeze = True
sample.freezeForComponents = True
sample.freezeForChildren = True
sample.freezeForParents = True
sample.freezeForDataSets = True
实验
注意:在openbis中,experiment
实体最近被重命名为collection
。所有方法都有使用术语collection
的同义词,例如get_collections
、new_collection
、get_collection_types
。
o.new_experiment
type='DEFAULT_EXPERIMENT',
space='MY_SPACE',
project='YEASTS'
)
o.get_experiments(
project='YEASTS',
space='MY_SPACE',
type='DEFAULT_EXPERIMENT',
tags='*',
finished_flag=False,
props=['name', 'finished_flag']
)
project.get_experiments()
exp = o.get_experiment('/MY_SPACE/MY_PROJECT/MY_EXPERIMENT')
exp.set_props({ key: value})
exp.props
exp.p # same thing as .props
exp.p.finished_flag=True
exp.p.my_property = "some value" # set the value of a property (value is checked)
exp.p + TAB # in IPython or Jupyter: show list of available properties
exp.p.my_property_ + TAB # in IPython or Jupyter: show datatype or controlled vocabulary
exp.p['my-weird.property-name'] # accessing properties containing a dash or a dot
exp.attrs.all() # returns all attributes as a dict
exp.props.all() # returns all properties as a dict
exp.attrs.tags = ['some', 'tags']
exp.tags = ['some', 'tags'] # same thing
exp.save()
exp.code
exp.description
exp.registrator
exp.registrationDate
exp.modifier
exp.modificationDate
exp.freeze = True
exp.freezeForDataSets = True
exp.freezeForSamples = True
数据集
sample.get_datasets()
ds = o.get_dataset('20160719143426517-259')
ds.get_parents()
ds.get_children()
ds.sample
ds.experiment
ds.physicalData
ds.status # AVAILABLE LOCKED ARCHIVED
# UNARCHIVE_PENDING ARCHIVE_PENDING BACKUP_PENDING
ds.archive()
ds.unarchive()
ds.attrs.all() # returns all attributes as a dict
ds.props.all() # returns all properties as a dict
ds.get_files(start_folder="/")
ds.file_list
ds.add_attachment()
ds.get_attachments()
ds.download_attachments()
ds.download(destination='/tmp', wait_until_finished=False)
ds_new = o.new_dataset(
type = 'ANALYZED_DATA',
experiment = '/SPACE/PROJECT/EXP1',
sample = '/SPACE/SAMP1',
files = ['my_analyzed_data.dat'],
props = {'name': 'some good name', 'description': '...' }
)
# DataSet CONTAINER (contains other DataSets, but no files)
ds_new = o.new_dataset(
type = 'ANALYZED_DATA',
experiment = '/SPACE/PROJECT/EXP1',
sample = '/SPACE/SAMP1',
kind = 'CONTAINER',
props = {'name': 'some good name', 'description': '...' }
)
ds_new.save()
# get, set, add and remove parent datasets
dataset.get_parents()
dataset.set_parents(['20170115220259155-412'])
dataset.add_parents(['20170115220259155-412'])
dataset.del_parents(['20170115220259155-412'])
# get, set, add and remove child datasets
dataset.get_children()
dataset.set_children(['20170115220259155-412'])
dataset.add_children(['20170115220259155-412'])
dataset.del_children(['20170115220259155-412'])
# A DataSet may belong to other DataSets, which must be of kind=CONTAINER
# As opposed to Samples, DataSets may belong (contained) to more than one DataSet-container
dataset.get_containers()
dataset.set_containers(['20170115220259155-412'])
dataset.add_containers(['20170115220259155-412'])
dataset.del_containers(['20170115220259155-412'])
# A DataSet of kind=CONTAINER may contain other DataSets, to act like a folder (see above)
# The DataSet-objects inside that DataSet are called components or contained DataSets
# You may also use the xxx_contained() functions, which are just aliases.
dataset.get_components()
dataset.set_components(['20170115220259155-412'])
dataset.add_components(['20170115220259155-412'])
dataset.del_components(['20170115220259155-412'])
ds.set_props({ key: value})
ds.props
ds.p # same thing as .props
ds.p.my_property = "some value" # set the value of a property
ds.p + TAB # show list of available properties
ds.p.my_property_ + TAB # show datatype or controlled vocabulary
ds.p['my-weird.property-name'] # accessing properties containing a dash or a dot
ds.attrs.all() # returns all attributes as a dict
ds.props.all() # returns all properties as a dict
# complex query with chaining.
# properties must be in UPPERCASE
datasets = o.get_experiments(project='YEASTS').get_samples(type='FLY').get_datasets(type='ANALYZED_DATA', props=['MY_PROPERTY'],MY_PROPERTY='some analyzed data')
# another example
datasets = o.get_experiment('/MY_NEW_SPACE/VERMEUL_PROJECT/MY_EXPERIMENT4').get_samples(type='UNKNOWN').get_parents().get_datasets(type='RAW_DATA')
datasets.df # get a pandas dataFrame object
# use it in a for-loop:
for dataset in datasets:
print(dataset.permID)
dataset.delete('give me a reason')
ds.freeze = True
ds.freezeForChildren = True
ds.freezeForParents = True
ds.freezeForComponents = True
ds.freezeForContainers = True
语义注释
# create semantic annotation for sample type 'UNKNOWN'
sa = o.new_semantic_annotation(
entityType = 'UNKNOWN',
predicateOntologyId = 'po_id',
predicateOntologyVersion = 'po_version',
predicateAccessionId = 'pa_id',
descriptorOntologyId = 'do_id',
descriptorOntologyVersion = 'do_version',
descriptorAccessionId = 'da_id'
)
sa.save()
# create semantic annotation for property type
# (predicate and descriptor values omitted for brevity)
sa = o.new_semantic_annotation(propertyType = 'DESCRIPTION', ...)
sa.save()
# create semantic annotation for sample property assignment (predicate and descriptor values omitted for brevity)
sa = o.new_semantic_annotation(entityType = 'UNKNOWN', propertyType = 'DESCRIPTION', ...)
sa.save()
# create a semantic annotation directly from a sample type
# will also create sample property assignment annotations when propertyType is given
st = o.get_sample_type("ORDER")
st.new_semantic_annotation(...)
# get all semantic annotations
o.get_semantic_annotations()
# get semantic annotation by perm id
sa = o.get_semantic_annotation("20171015135637955-30")
# update semantic annotation
sa.predicateOntologyId = 'new_po_id'
sa.descriptorOntologyId = 'new_do_id'
sa.save()
# delete semantic annotation
sa.delete('reason')
标签
new_tag = o.new_tag(
code = 'my_tag',
description = 'some descriptive text'
)
new_tag.description = 'some new description'
new_tag.save()
o.get_tags()
o.get_tag('/username/TAG_Name')
o.get_tag('TAG_Name')
tag.get_experiments()
tag.get_samples()
tag.get_owner() # returns a person object
tag.delete('why?')
词汇和词汇
例如sample(object)、experiment(collection)、material或dataset之类的实体可以是特定的实体类型:
- 样本类型
- 实验类型
- 数据集类型
- 材料类型
每个类型都定义可以定义哪些properties。属性的行为类似于attributes,但它们是特定于类型的。属性可以包含各种信息,例如自由文本、XML、超链接、布尔值以及受控词汇表。这种受控词汇表由许多vocabularyTerms组成。这些术语仅允许在属性字段中输入某些值。
例如,您希望将名为animal的属性添加到示例中,并且您希望控制在此属性字段中输入的术语。为此,您需要执行两个步骤:
- 创建一个新词汇表animalvaculary
- 在词汇表中添加术语:cat,dog,mouse
- 创建数据类型controlled词汇表的新属性类型(例如animal),并将animalvalvaculary分配给它
- 创建一个新的sample type(例如pet)和assign将创建的propertyType赋给该示例类型。
- 如果您现在创建一个类型为pet的新示例,那么您将能够向它添加一个属性animal,该属性只有接受术语cat、dog或mouse。
使用三个词汇创建新词汇
voc = o.new_vocabulary(
code = 'BBB',
description = 'description of vocabulary aaa',
urlTemplate = 'https://ethz.ch',
terms = [
{ "code": 'term_code1', "label": "term_label1", "description": "term_description1"},
{ "code": 'term_code2', "label": "term_label2", "description": "term_description2"},
{ "code": 'term_code3', "label": "term_label3", "description": "term_description3"}
]
)
voc.save()
创建其他词汇
term = o.new_term(
code='TERM_CODE_XXX',
vocabularyCode='BBB',
label='here comes a label',
description='here might appear a meaningful description'
)
term.save()
update词汇
若要更改项的序号,必须使用.move_to_top()
方法将其移到顶部,或使用.move_after_term('TERM_BEFORE')
方法将其移到另一个项之后。
voc = o.get_vocabulary('STORAGE')
term = voc.get_terms()['RT']
term.label = "Room Temperature"
term.official = True
term.move_to_top()
term.move_after_term('-40')
term.save()
term.delete()