Labstep / labstepPy

Python wrapper around the Labstep API
MIT License
3 stars 0 forks source link

Can't seem to add text,files or tables to my experiment. #90

Open HenrivdGeest opened 2 months ago

HenrivdGeest commented 2 months ago

Im new to using the api. Logon and creating a new experiment worked from the start. However, adding text to my experiment seems harder. I tried:


import labstep

def authenticate_user():
    user = labstep.authenticate('someone', '123245')
    return user

if __name__ == "__main__":
    user=authenticate_user()
    entity = user.getWorkspace(12345)
    user.setWorkspace(entity.id)
    #my_experiment=user.newExperiment(name='The Synthesis of Aspirin') #worked!
    #expriment with id 268135 is created is previous run of this script, not doing it again.
    experiment = user.getExperiment(268135)
    #print(experiment)
    #experiment.addFile(filepath='/tmp/pycharm_project_1234/test.xlsx') # no error, but in the webbrowser nothing shows up.
    experiment.update() # maybe this helps?
   data = {
        "rowCount": 2,
        "columnCount": 2,
        "colHeaderData": {},
        "data": {
            "dataTable_2": {
                0: {
                    0: {
                        "value": 'Cell_ A1'
                    },
                    1: {
                        "value": 'Cell_ B1'
                    }
                }
            }
        }
    }
    experiment.addTable(name='Calibration', data=data)

    #print(experiment.getFiles())
    experiment.update()
    print(experiment.getTables())# previously added data tables are also shown here.
    #experiment.addComment(body='I am commenting!') # yes, these comments show up in the 'Notes' section in the browser.

I ran the script multiple times while changing the dataTable, and it seems that getTables() does retrieve all my tries, but Online I can see some text+image which I also added via the web browser.

[{'created_at': '2024-07-02T13:45:39+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 12,
          'data': {'dataTable': [[{'value': 'Cell A1'}, {'value': 'Cell B1'}]]},
          'rowCount': 12},
 'deleted_at': None,
 'guid': '8af8c399-69cb-45c6-9d9a-7377a5dcdc28',
 'id': 262937,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T13:45:39+00:00'}, {'created_at': '2024-07-02T13:50:24+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 12,
          'data': {'dataTable': [[{'value': 'Cell A1'}, {'value': 'Cell B1'}]]},
          'rowCount': 12},
 'deleted_at': None,
 'guid': 'c35f44fd-3313-46b7-8275-2eafee058bdd',
 'id': 262941,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T13:50:24+00:00'}, {'created_at': '2024-07-02T13:52:30+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 12,
          'data': {'dataTable': [[{'value': 'Cell A1'}, {'value': 'Cell B1'}]]},
          'rowCount': 12},
 'deleted_at': None,
 'guid': 'e5859d15-bc28-4c30-a4a4-52a59dc49356',
 'id': 262942,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T13:52:30+00:00'}, {'created_at': '2024-07-02T13:53:34+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 12,
          'data': {'dataTable': [[{'value': 'Cell A1'}, {'value': 'Cell B1'}]]},
          'rowCount': 12},
 'deleted_at': None,
 'guid': '469c3ec3-1a35-4808-9343-2bf0d6f8ebba',
 'id': 262943,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T13:53:34+00:00'}, {'created_at': '2024-07-02T13:56:50+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 12,
          'data': {'dataTable': [[{'value': 'Cell A1'}, {'value': 'Cell B1'}]]},
          'rowCount': 12},
 'deleted_at': None,
 'guid': '058433d8-892a-445b-a973-ab6d4a26a1c9',
 'id': 262948,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T13:56:50+00:00'}, {'created_at': '2024-07-02T14:01:49+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 2,
          'data': {'dataTable_2': [[{'value': 'Cell A1'},
                                    {'value': 'Cell B1'}]]},
          'rowCount': 2},
 'deleted_at': None,
 'guid': '0f346a17-200c-4a4b-affd-c7ffac3f1a85',
 'id': 262949,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T14:01:49+00:00'}, {'created_at': '2024-07-02T14:02:12+00:00',
 'data': {'colHeaderData': [],
          'columnCount': 2,
          'data': {'dataTable_2': [[{'value': 'Cell_ A1'},
                                    {'value': 'Cell_ B1'}]]},
          'rowCount': 2},
 'deleted_at': None,
 'guid': '728f894e-8711-4feb-94bb-2efb73459a54',
 'id': 262950,
 'is_experiment_child': True,
 'lock_entity_info': {'entityName': 'experiment', 'id': 501424},
 'locked_at': None,
 'name': 'Calibration',
 'permission_entity_info': {'entityName': 'experiment_workflow',
                            'guid': 'ad59f312-bd02-4e91-99ea-1aeeb042987b',
                            'id': 268135},
 'updated_at': '2024-07-02T14:02:12+00:00'}]

I also tried addFile(), but that did not work either. Only comments are ending up in the notes section, so that does work. Any ideas ?

BarneyLabstep commented 1 month ago

Hi Henri,

The entry itself is stored as a JSON document so it requires a bit of extra knowledge about the format to edit it. Here are some examples of how to add some different types of elements. For other elements or formatting options you can use the web app to produce the desired result and the inspect the network request sent to see the shape of the JSON document object (look for the state field that is sent).

import labstep
import os

user = labstep.authenticate(apikey='YOUR_API_KEY')

initialEntry = {
  "type": "doc",
  "content": []
}

experiment = user.newExperiment('API Experiment',entry=initialEntry)

# Adding text to the entry

entry = experiment.getEntry()

newContent = {
    "type": "paragraph",
    "attrs": {"align": None},
    "content": [
        {
            "type": "text", ## NOTE: this type of node MUST be embdedded in a paragraph node
            "text": "This is a new paragraph"
        }
    ]
}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding a file / image to the entry (images rendered automatically)

entry = experiment.getEntry()

file = experiment.addFile(os.path.abspath(__file__)) ## Replace with path to file

newContent = {
    "type": "paragraph",
    "attrs": {"align": None},
    "content": [
       {
        "type": "file", ## NOTE: this type of node MUST be embdedded in a paragraph node
        "attrs": {
            "id": file["id"],
            "fullWidth": False
            }
        }
    ]
}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding a data field to the entry

dataField = experiment.addDataField('My Data Field',fieldType='file')

file = user.newFile(os.path.abspath(__file__)) ## Replace with path to file

dataField.setValue(file)

newContent = {"type": "metadata", "attrs": {"id": dataField["id"]}}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding an inventory field to the entry

inventoryField = experiment.addInventoryField('Sample')

newContent = {
    "type": "paragraph",
    "attrs": {"align": None},
    "content": [
        {
           "type": "protocol_value", ## NOTE: this type of node MUST be embdedded in a paragraph node
           "attrs": {"id": inventoryField["id"]}
        }
    ]
}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding an inline spreadsheet to the entry

data = {
    "rowCount": 12,
    "columnCount": 12,
    "colHeaderData": {},
    "data": {
        "dataTable": {
            0: {
                0: {
                    "value": 'Column 1'
                },
                1: {
                    "value": 'Column 2'
                }
            },
            1: {
                0: {
                    "value": "A2"
                },
                1: {
                    "value": "B2"
                }
            }
        }
    }
}

table = experiment.addTable('Spreadsheet 1',data=data)

newContent = {"type": "protocol_table", "attrs": {"id": table["id"]}}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding a protocol to the entry

protocol = user.newProtocol('My Protocol')

experiment_protocol = experiment.addProtocol(protocol)

newContent = {
    "type": "paragraph",
    "attrs": {"align": None},
    "content": [
        {
           "type": "experiment", ## NOTE: this type of node MUST be embdedded in a paragraph node
           "attrs": {"id": experiment_protocol["id"]}
        }
    ]
}

entry['content'].append(newContent)

experiment.edit(entry=entry)

## Adding a basic table to the entry

newContent = {
  "type": "table",
  "content": [
    {
      "type": "table_row",
      "content": [
        {
          "type": "table_cell",
          "attrs": {
            "colspan": 1,
            "rowspan": 1,
            "colwidth": None,
            "background": None
          },
          "content": [
            {
              "type": "paragraph",
              "attrs": {
                "align": None
              },
              "content": [
                {
                  "type": "text",
                  "text": "Column 1"
                }
              ]
            }
          ]
        },
        {
          "type": "table_cell",
          "attrs": {
            "colspan": 1,
            "rowspan": 1,
            "colwidth": None,
            "background": None
          },
          "content": [
            {
              "type": "paragraph",
              "attrs": {
                "align": None
              },
              "content": [
                {
                  "type": "text",
                  "text": "Column 2"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "type": "table_row",
      "content": [
        {
          "type": "table_cell",
          "attrs": {
            "colspan": 1,
            "rowspan": 1,
            "colwidth": None,
            "background": None
          },
          "content": [
            {
              "type": "paragraph",
              "attrs": {
                "align": None
              }
            }
          ]
        },
        {
          "type": "table_cell",
          "attrs": {
            "colspan": 1,
            "rowspan": 1,
            "colwidth": None,
            "background": None
          },
          "content": [
            {
              "type": "paragraph",
              "attrs": {
                "align": None
              }
            }
          ]
        }
      ]
    }
  ]
}

entry['content'].append(newContent)

experiment.edit(entry=entry)

'''
For other elements or formatting options...
Please use the web app to produce the desired result and
inspect the network request sent to see the shape of the JSON document object
'''
HenrivdGeest commented 1 week ago

Thanks! that works, now I get it :)