├── .flake8 ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── pythonapp.yml ├── .gitignore ├── .keats ├── changelog.json └── changelog.md ├── .pre-commit-config.yaml ├── LICENSE ├── Makefile ├── README.md ├── benchlingapi ├── __init__.py ├── __version__.py ├── exceptions.py ├── models │ ├── __init__.py │ ├── base.py │ ├── mixins.py │ ├── models.py │ └── schema.py ├── session.py └── utils.py ├── docs ├── .buildinfo ├── .doctrees │ ├── developer │ │ ├── api_reference.doctree │ │ └── changelog.doctree │ ├── environment.pickle │ ├── exceptions.doctree │ ├── generated │ │ ├── benchlingapi.models.models.AASequence.doctree │ │ ├── benchlingapi.models.models.Annotation.doctree │ │ ├── benchlingapi.models.models.CustomEntity.doctree │ │ ├── benchlingapi.models.models.DNAAlignment.doctree │ │ ├── benchlingapi.models.models.DNASequence.doctree │ │ ├── benchlingapi.models.models.EntitySchema.doctree │ │ ├── benchlingapi.models.models.Oligo.doctree │ │ ├── benchlingapi.models.models.Project.doctree │ │ ├── benchlingapi.models.models.Registry.doctree │ │ ├── benchlingapi.models.models.Task.doctree │ │ ├── benchlingapi.models.models.Translation.doctree │ │ ├── benchlingapi.models.schema.AASequenceSchema.doctree │ │ ├── benchlingapi.models.schema.BatchSchema.doctree │ │ ├── benchlingapi.models.schema.CustomEntitySchema.doctree │ │ ├── benchlingapi.models.schema.DNAAlignmentSchema.doctree │ │ ├── benchlingapi.models.schema.DNASequenceSchema.doctree │ │ ├── benchlingapi.models.schema.EntitySchema.doctree │ │ ├── benchlingapi.models.schema.EntitySchemaSchema.doctree │ │ ├── benchlingapi.models.schema.FieldSchema.doctree │ │ ├── benchlingapi.models.schema.FolderSchema.doctree │ │ ├── benchlingapi.models.schema.OligoSchema.doctree │ │ ├── benchlingapi.models.schema.ProjectSchema.doctree │ │ ├── benchlingapi.models.schema.RegistrySchema.doctree │ │ ├── benchlingapi.models.schema.TaskSchema.doctree │ │ ├── benchlingapi.models.schema.TranslationSchema.doctree │ │ └── benchlingapi.models.schema.UserSummarySchema.doctree │ ├── guidelines.doctree │ ├── index.doctree │ ├── models.doctree │ ├── session.doctree │ ├── usage.doctree │ └── utils.doctree ├── .nojekyll ├── _modules │ ├── benchlingapi │ │ ├── exceptions.html │ │ ├── models │ │ │ ├── base.html │ │ │ ├── mixins.html │ │ │ ├── models.html │ │ │ └── schema.html │ │ ├── session.html │ │ └── utils.html │ ├── index.html │ └── marshmallow │ │ └── schema.html ├── _sources │ ├── developer │ │ ├── api_reference.rst │ │ └── changelog.md │ ├── exceptions.rst │ ├── generated │ │ ├── benchlingapi.models.models.AASequence.rst │ │ ├── benchlingapi.models.models.Annotation.rst │ │ ├── benchlingapi.models.models.CustomEntity.rst │ │ ├── benchlingapi.models.models.DNAAlignment.rst │ │ ├── benchlingapi.models.models.DNASequence.rst │ │ ├── benchlingapi.models.models.EntitySchema.rst │ │ ├── benchlingapi.models.models.Oligo.rst │ │ ├── benchlingapi.models.models.Project.rst │ │ ├── benchlingapi.models.models.Registry.rst │ │ ├── benchlingapi.models.models.Task.rst │ │ ├── benchlingapi.models.models.Translation.rst │ │ ├── benchlingapi.models.schema.AASequenceSchema.rst │ │ ├── benchlingapi.models.schema.BatchSchema.rst │ │ ├── benchlingapi.models.schema.CustomEntitySchema.rst │ │ ├── benchlingapi.models.schema.DNAAlignmentSchema.rst │ │ ├── benchlingapi.models.schema.DNASequenceSchema.rst │ │ ├── benchlingapi.models.schema.EntitySchema.rst │ │ ├── benchlingapi.models.schema.EntitySchemaSchema.rst │ │ ├── benchlingapi.models.schema.FieldSchema.rst │ │ ├── benchlingapi.models.schema.FolderSchema.rst │ │ ├── benchlingapi.models.schema.OligoSchema.rst │ │ ├── benchlingapi.models.schema.ProjectSchema.rst │ │ ├── benchlingapi.models.schema.RegistrySchema.rst │ │ ├── benchlingapi.models.schema.TaskSchema.rst │ │ ├── benchlingapi.models.schema.TranslationSchema.rst │ │ └── benchlingapi.models.schema.UserSummarySchema.rst │ ├── guidelines.rst │ ├── index.rst │ ├── models.rst │ ├── session.rst │ ├── usage.rst │ └── utils.rst ├── _static │ ├── basic.css │ ├── bootstrap-2.3.2 │ │ ├── css │ │ │ ├── bootstrap-responsive.css │ │ │ ├── bootstrap-responsive.min.css │ │ │ ├── bootstrap.css │ │ │ └── bootstrap.min.css │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ ├── bootstrap-3.3.7 │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ ├── bootstrap-sphinx.css │ ├── bootstrap-sphinx.js │ ├── bootswatch-2.3.2 │ │ ├── amelia │ │ │ └── bootstrap.min.css │ │ ├── cerulean │ │ │ └── bootstrap.min.css │ │ ├── cosmo │ │ │ └── bootstrap.min.css │ │ ├── cyborg │ │ │ └── bootstrap.min.css │ │ ├── flatly │ │ │ └── bootstrap.min.css │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ ├── journal │ │ │ └── bootstrap.min.css │ │ ├── readable │ │ │ └── bootstrap.min.css │ │ ├── simplex │ │ │ └── bootstrap.min.css │ │ ├── slate │ │ │ └── bootstrap.min.css │ │ ├── spacelab │ │ │ └── bootstrap.min.css │ │ ├── spruce │ │ │ └── bootstrap.min.css │ │ ├── superhero │ │ │ └── bootstrap.min.css │ │ └── united │ │ │ └── bootstrap.min.css │ ├── bootswatch-3.3.7 │ │ ├── cerulean │ │ │ └── bootstrap.min.css │ │ ├── cosmo │ │ │ └── bootstrap.min.css │ │ ├── cyborg │ │ │ └── bootstrap.min.css │ │ ├── darkly │ │ │ └── bootstrap.min.css │ │ ├── flatly │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── journal │ │ │ └── bootstrap.min.css │ │ ├── lumen │ │ │ └── bootstrap.min.css │ │ ├── paper │ │ │ └── bootstrap.min.css │ │ ├── readable │ │ │ └── bootstrap.min.css │ │ ├── sandstone │ │ │ └── bootstrap.min.css │ │ ├── simplex │ │ │ └── bootstrap.min.css │ │ ├── slate │ │ │ └── bootstrap.min.css │ │ ├── solar │ │ │ └── bootstrap.min.css │ │ ├── spacelab │ │ │ └── bootstrap.min.css │ │ ├── superhero │ │ │ └── bootstrap.min.css │ │ ├── united │ │ │ └── bootstrap.min.css │ │ └── yeti │ │ │ └── bootstrap.min.css │ ├── css │ │ ├── custom.css │ │ └── style.css │ ├── doctools.js │ ├── documentation_options.js │ ├── file.png │ ├── graphviz.css │ ├── jquery-3.4.1.js │ ├── jquery.js │ ├── js │ │ ├── jquery-1.11.0.min.js │ │ └── jquery-fix.js │ ├── language_data.js │ ├── minus.png │ ├── plus.png │ ├── pygments.css │ ├── searchtools.js │ ├── underscore-1.3.1.js │ └── underscore.js ├── developer │ ├── api_reference.html │ └── changelog.html ├── exceptions.html ├── generated │ ├── benchlingapi.models.models.AASequence.html │ ├── benchlingapi.models.models.Annotation.html │ ├── benchlingapi.models.models.CustomEntity.html │ ├── benchlingapi.models.models.DNAAlignment.html │ ├── benchlingapi.models.models.DNASequence.html │ ├── benchlingapi.models.models.EntitySchema.html │ ├── benchlingapi.models.models.Oligo.html │ ├── benchlingapi.models.models.Project.html │ ├── benchlingapi.models.models.Registry.html │ ├── benchlingapi.models.models.Task.html │ ├── benchlingapi.models.models.Translation.html │ ├── benchlingapi.models.schema.AASequenceSchema.html │ ├── benchlingapi.models.schema.BatchSchema.html │ ├── benchlingapi.models.schema.CustomEntitySchema.html │ ├── benchlingapi.models.schema.DNAAlignmentSchema.html │ ├── benchlingapi.models.schema.DNASequenceSchema.html │ ├── benchlingapi.models.schema.EntitySchema.html │ ├── benchlingapi.models.schema.EntitySchemaSchema.html │ ├── benchlingapi.models.schema.FieldSchema.html │ ├── benchlingapi.models.schema.FolderSchema.html │ ├── benchlingapi.models.schema.OligoSchema.html │ ├── benchlingapi.models.schema.ProjectSchema.html │ ├── benchlingapi.models.schema.RegistrySchema.html │ ├── benchlingapi.models.schema.TaskSchema.html │ ├── benchlingapi.models.schema.TranslationSchema.html │ └── benchlingapi.models.schema.UserSummarySchema.html ├── genindex.html ├── guidelines.html ├── index.html ├── models.html ├── objects.inv ├── py-modindex.html ├── search.html ├── searchindex.js ├── session.html ├── usage.html └── utils.html ├── docsrc ├── Makefile ├── _static │ └── css │ │ ├── custom.css_t │ │ └── style.css ├── _templates │ ├── module.rst │ └── sidebar.html ├── conf.py ├── developer │ ├── api_reference.rst │ └── changelog.md ├── exceptions.rst ├── generated │ ├── benchlingapi.models.models.AASequence.rst │ ├── benchlingapi.models.models.Annotation.rst │ ├── benchlingapi.models.models.CustomEntity.rst │ ├── benchlingapi.models.models.DNAAlignment.rst │ ├── benchlingapi.models.models.DNASequence.rst │ ├── benchlingapi.models.models.EntitySchema.rst │ ├── benchlingapi.models.models.Oligo.rst │ ├── benchlingapi.models.models.Project.rst │ ├── benchlingapi.models.models.Registry.rst │ ├── benchlingapi.models.models.Task.rst │ ├── benchlingapi.models.models.Translation.rst │ ├── benchlingapi.models.schema.AASequenceSchema.rst │ ├── benchlingapi.models.schema.BatchSchema.rst │ ├── benchlingapi.models.schema.CustomEntitySchema.rst │ ├── benchlingapi.models.schema.DNAAlignmentSchema.rst │ ├── benchlingapi.models.schema.DNASequenceSchema.rst │ ├── benchlingapi.models.schema.EntitySchema.rst │ ├── benchlingapi.models.schema.EntitySchemaSchema.rst │ ├── benchlingapi.models.schema.FieldSchema.rst │ ├── benchlingapi.models.schema.FolderSchema.rst │ ├── benchlingapi.models.schema.OligoSchema.rst │ ├── benchlingapi.models.schema.ProjectSchema.rst │ ├── benchlingapi.models.schema.RegistrySchema.rst │ ├── benchlingapi.models.schema.TaskSchema.rst │ ├── benchlingapi.models.schema.TranslationSchema.rst │ └── benchlingapi.models.schema.UserSummarySchema.rst ├── guidelines.rst ├── index.rst ├── make.bat ├── models.rst ├── session.rst ├── usage.rst └── utils.rst ├── poetry.lock ├── pyproject.toml ├── tests ├── conftest.py ├── secrets │ ├── config.json │ ├── config.json.enc │ └── config_fake.json ├── test_interface.py ├── test_models │ ├── __init__.py │ ├── test_all_models.py │ ├── test_dna_sequence.py │ ├── test_models.py │ ├── test_other │ │ ├── 424889-14889.ab1 │ │ └── test_dna_sequence_alignment.py │ ├── test_registry.py │ └── test_schema.py └── test_session.py └── tox.ini /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = F401,E203,W503 3 | max-line-length = 100 4 | exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,tests,docsrc 5 | max-complexity = 25 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/pythonapp.yml: -------------------------------------------------------------------------------- 1 | name: Python application 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up Python 3.7 13 | uses: actions/setup-python@v1 14 | with: 15 | python-version: 3.7 16 | - name: Cache 17 | uses: actions/cache@v1.0.0 18 | - name: Install dependencies 19 | run: | 20 | python -m pip install --upgrade pip 21 | pip install poetry 22 | pip install . 23 | - name: Lint with flake8 24 | run: | 25 | pip install flake8 26 | # stop the build if there are Python syntax errors or undefined names 27 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 28 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 29 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 30 | - name: Test with pytest 31 | run: | 32 | pip install pytest 33 | pytest 34 | -------------------------------------------------------------------------------- /.keats/changelog.json: -------------------------------------------------------------------------------- 1 | { 2 | "2.1.12": { 3 | "description": "changes to Session initialization", 4 | "date": "2020-02-12T16:27:14.551407", 5 | "changes": [ 6 | "Users can now specify the home url for the Benchling Session instance. Use Session(api_key, org='myorg') to specify the home url 'myorg.benchling.com/api/v2'. User Session(api_key, home='myorg.benchling.com/api/v2') to specify the home url directly." 7 | ] 8 | }, 9 | "2.1.11": { 10 | "description": "hotfix sharelink bug", 11 | "date": "2019-12-18T13:34:41.244797", 12 | "changes": [] 13 | }, 14 | "2.1.10": { 15 | "description": "fix previous release", 16 | "date": "2019-12-17T17:26:29.569759", 17 | "changes": [] 18 | }, 19 | "2.1.9": { 20 | "description": "fixes sharelink bugs", 21 | "date": "2019-12-17T17:16:09.386482", 22 | "changes": [] 23 | }, 24 | "2.1.8": { 25 | "description": "re-release of 2.1.7 (fixes broken branch)", 26 | "date": "2019-12-17T17:10:53.952392", 27 | "changes": [] 28 | }, 29 | "2.1.7": { 30 | "description": "bug fixes", 31 | "date": "2019-12-17T17:07:16.144945", 32 | "changes": [ 33 | "fixes loading DNASequences from share_links" 34 | ] 35 | }, 36 | "2.1.6": { 37 | "description": "bug fixes", 38 | "date": "2019-12-16T17:06:05.925041", 39 | "changes": [ 40 | "updates DNASequence to work with latest Benchling API update" 41 | ] 42 | }, 43 | "2.1.5": { 44 | "description": "", 45 | "date": "2019-12-12T14:18:00.136712", 46 | "changes": [ 47 | "added 'merge' method to entities", 48 | "fixed bug that arose iwhen trying to save an entity containing fields" 49 | ] 50 | }, 51 | "2.1.4": { 52 | "description": "feature and bug fixes", 53 | "date": "2019-12-12T14:16:27.446507", 54 | "changes": [] 55 | }, 56 | "2.1.3": { 57 | "description": "fixes bug with DNASequence.archived_reason", 58 | "date": "2019-10-23T16:08:47.898865", 59 | "changes": [ 60 | "typo in archive_reason" 61 | ] 62 | }, 63 | "2.1.2": { 64 | "description": "bug fixes", 65 | "date": "2019-10-18T13:44:46.826684", 66 | "changes": [ 67 | "fixes bug where parameters in get_pages was not being inherited", 68 | "adds new 'all_in_registry' function" 69 | ] 70 | }, 71 | "2.1.1": { 72 | "description": "Python 3.5, 3.6, 3.7 support", 73 | "date": "2019-10-17T19:36:37.900149", 74 | "changes": [] 75 | }, 76 | "2.1": { 77 | "description": "Update marshamllow to 3.2", 78 | "date": "2019-10-17T12:42:35.238592", 79 | "changes": [] 80 | }, 81 | "2.0.1": { 82 | "description": "Bug fixes", 83 | "date": "2019-10-16T08:02:35.118447", 84 | "changes": [ 85 | "fixed issue where nested data keys were not properly formatted to and from the benchling server" 86 | ] 87 | }, 88 | "2.0.0": { 89 | "description": "Second major release", 90 | "date": "2019-10-15T21:08:34.511953", 91 | "changes": [ 92 | "all attribute names now lower-underscore case", 93 | "refactoring and bug fixes", 94 | "updates to interface", 95 | "uses benchling api V2" 96 | ] 97 | } 98 | } -------------------------------------------------------------------------------- /.keats/changelog.md: -------------------------------------------------------------------------------- 1 | # benchlingapi change log 2 | ## 2.1.12 3 | **2020-02-12T16:15:11.847504** 4 | changes to Session initialization 5 | 6 | - Users can now specify the home url for the Benchling Session instance. Use Session(api_key, org='myorg') to specify the home url 'myorg.benchling.com/api/v2'. User Session(api_key, home='myorg.benchling.com/api/v2') to specify the home url directly. 7 | 8 | 9 | ## 2.1.11 10 | **2019-12-18T13:34:41.244797** 11 | hotfix sharelink bug 12 | 13 | 14 | 15 | 16 | ## 2.1.10 17 | **2019-12-17T17:26:29.569759** 18 | fix previous release 19 | 20 | 21 | 22 | 23 | ## 2.1.9 24 | **2019-12-17T17:16:09.386482** 25 | fixes sharelink bugs 26 | 27 | 28 | 29 | 30 | ## 2.1.8 31 | **2019-12-17T17:10:53.952392** 32 | re-release of 2.1.7 (fixes broken branch) 33 | 34 | 35 | 36 | 37 | ## 2.1.7 38 | **2019-12-17T17:07:16.144945** 39 | bug fixes 40 | 41 | - fixes loading DNASequences from share_links 42 | 43 | 44 | ## 2.1.6 45 | **2019-12-16T17:06:05.925041** 46 | bug fixes 47 | 48 | - updates DNASequence to work with latest Benchling API update 49 | 50 | 51 | ## 2.1.5 52 | **2019-12-12T14:18:00.136712** 53 | 54 | 55 | - added 'merge' method to entities 56 | - fixed bug that arose iwhen trying to save an entity containing fields 57 | 58 | 59 | ## 2.1.4 60 | **2019-12-12T14:16:27.446507** 61 | feature and bug fixes 62 | 63 | 64 | 65 | 66 | ## 2.1.3 67 | **2019-10-23T16:08:47.898865** 68 | fixes bug with DNASequence.archived_reason 69 | 70 | - typo in archive_reason 71 | 72 | 73 | ## 2.1.2 74 | **2019-10-18T13:44:46.826684** 75 | bug fixes 76 | 77 | - fixes bug where parameters in get_pages was not being inherited 78 | - adds new 'all_in_registry' function 79 | 80 | 81 | ## 2.1.1 82 | **2019-10-17T19:36:37.900149** 83 | Python 3.5, 3.6, 3.7 support 84 | 85 | 86 | 87 | 88 | ## 2.1 89 | **2019-10-17T12:42:35.238592** 90 | Update marshamllow to 3.2 91 | 92 | 93 | 94 | 95 | ## 2.0.1 96 | **2019-10-16T08:02:35.118447** 97 | Bug fixes 98 | 99 | - fixed issue where nested data keys were not properly formatted to and from the benchling server 100 | 101 | 102 | ## 2.0.0 103 | **2019-10-15T21:08:34.511953** 104 | Second major release 105 | 106 | - all attribute names now lower-underscore case 107 | - refactoring and bug fixes 108 | - updates to interface 109 | - uses benchling api V2 110 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: stable 4 | hooks: 5 | - id: black 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v2.3.0 8 | hooks: 9 | - id: forbid-new-submodules 10 | - id: flake8 11 | - repo: https://github.com/myint/docformatter 12 | rev: v1.3 13 | hooks: 14 | - id: docformatter 15 | - repo: https://github.com/asottile/pyupgrade 16 | rev: v1.12.0 17 | hooks: 18 | - id: pyupgrade 19 | args: [--py3-plus] 20 | - repo: https://github.com/asottile/reorder_python_imports 21 | rev: v1.4.0 22 | hooks: 23 | - id: reorder-python-imports 24 | args: [--py3-plus] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Klavins Lab Software 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PIP=pip3 2 | 3 | .PHONY: docs # necessary so it doesn't look for 'docs/makefile html' 4 | 5 | init: 6 | pip install pip -U 7 | curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python 8 | poetry self:update 9 | poetry install 10 | poetry run pre-commit install 11 | 12 | 13 | clean: 14 | rm -rf dist 15 | rm -rf pip-wheel-metadata 16 | rm -rf docs 17 | rm -rf .pytest_cache 18 | 19 | 20 | test: 21 | poetry run python -m pytest 22 | 23 | 24 | lint: 25 | poetry run pylint -E pydent 26 | 27 | 28 | pullversion: 29 | poetry run keats version up 30 | 31 | 32 | docs: | pullversion 33 | @echo "Updating docs" 34 | 35 | # copy README.md to README.rst format for Sphinx documentation 36 | # we can comment this out if we do not want to include the README.md in the sphinx documentation 37 | 38 | poetry run keats changelog up 39 | cp .keats/changelog.md docsrc/developer/changelog.md 40 | 41 | rm -rf docs 42 | cd docsrc && poetry run make html 43 | find docs -type f -exec chmod 444 {} \; 44 | @echo "\033[95m\n\nBuild successful! View the docs homepage at docs/html/index.html.\n\033[0m" 45 | 46 | touch docs/.nojekyll 47 | open ./docs/index.html 48 | 49 | 50 | format: 51 | poetry run upver 52 | poetry run black benchlingapi tests 53 | 54 | 55 | lock: 56 | poetry run upver 57 | poetry update 58 | 59 | 60 | build: 61 | poetry run upver 62 | poetry build 63 | 64 | 65 | release: 66 | sh scripts/release.sh 67 | 68 | 69 | klocs: 70 | find . -name '*.py' | xargs wc -l 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BenchlingAPI 2 | 3 | [![PyPI version](https://badge.fury.io/py/benchlingapi.svg)](https://badge.fury.io/py/benchlingapi) 4 | 5 | The (unofficial) python API wrapper for Benchling. For more information, 6 | see documentation at https://klavinslab.github.io/benchling-api/index. 7 | 8 | ## Installation 9 | 10 | ``` 11 | pip install benchlingapi -U 12 | ``` 13 | 14 | ## Getting Started 15 | 16 | Initialize a session using your Benchling-provided API key: 17 | 18 | ```python 19 | from benchlingapi import Session 20 | session = Session("your_secret_benchling_api_key") 21 | ``` 22 | 23 | From there, you can access various models: 24 | 25 | ```python 26 | session.DNASequence 27 | session.AASequence 28 | session.Oligo 29 | session.Folder 30 | session.Project 31 | session.Registry 32 | session.Translation 33 | session.EntitySchema 34 | session.Batch 35 | session.CustomEntity 36 | ``` 37 | 38 | Finding models: 39 | 40 | ```python 41 | # get one model 42 | dna = session.DNASequence.one() 43 | 44 | # find a specific model by its id 45 | dna = session.DNASequence.find('sdg_4tg23') 46 | 47 | # get the last 50 amino acids 48 | proteins = session.AASequence.last(50) 49 | 50 | # get a registry by name 51 | registry = session.Registry.find_by_name("Klavins Lab Registry") 52 | ``` 53 | 54 | Updating models: 55 | 56 | ```python 57 | dna = session.DNASequence.one() 58 | dna.name = "My new name" 59 | dna.bases = "AGGTAGGGTAGGGCCAGAGA" 60 | 61 | # update the sequence on the server 62 | dna.update() 63 | ``` 64 | 65 | Saving new models: 66 | 67 | ```python 68 | folder = session.Folder.find_by_name("My API Folder") 69 | dna = session.DNASequence( 70 | name = 'my new dna', 71 | bases = 'AGGTAGGATGGCCA', 72 | folder_id = folder.id, 73 | is_circular = False 74 | ) 75 | 76 | # save the dna to your Benchling account 77 | dna.save() 78 | ``` 79 | 80 | Registering models to your registry: 81 | 82 | ```python 83 | dna.set_schema("My DNA Schema") 84 | dna.register() 85 | ``` 86 | 87 | See the documentation for more information: https://klavinslab.github.io/benchling-api/index 88 | 89 | ## Testing 90 | 91 | Testing is done using `pytest`. Tests will create live requests to a Benchling account. 92 | Since testing is done live, a Benchling account will need to be setup along with testing 93 | data. 94 | 95 | To run tests, you must have a Benchling Account with an API key. Tests require a file in 96 | 'tests/secrets/config.json' with the following format: 97 | 98 | ``` 99 | { 100 | "credentials": { 101 | "api_key": "asdahhjwrthsdfgadfadfgadadsfa" 102 | }, 103 | "sharelinks": [ 104 | "https://benchling.com/s/seq-asdfadsfaee" 105 | ], 106 | "project": { 107 | "name": "API" 108 | }, 109 | "trash_folder": { 110 | "name": "API_Trash" 111 | }, 112 | "inventory_folder": { 113 | "name": "API_Inventory" 114 | } 115 | } 116 | ``` 117 | 118 | On the Benchling side of things, in the account liked to the `credentials["api_key"]`, you must 119 | have a project corresponding to the `project["name"]` value above. Within this project, you should 120 | have two folder corresponding to the `trash_folder` and `inventory_folder` values above. Additionally, 121 | you should have at least one example of an AminoAcid, DNASequence, CustomEntity, and Oligo stored within 122 | your `inventory_folder`. Tests will copy the examples from the `inventory_folder` for downstream tests. 123 | After the tests, conclude, inventory in the `trash_folder` will get archived. 124 | 125 | #### Happy Cloning! 126 | -------------------------------------------------------------------------------- /benchlingapi/__init__.py: -------------------------------------------------------------------------------- 1 | """BenchlingAPI.""" 2 | from .__version__ import __authors__ 3 | from .__version__ import __homepage__ 4 | from .__version__ import __repo__ 5 | from .__version__ import __title__ 6 | from .__version__ import __version__ 7 | from benchlingapi.models import schema # must import schema before session 8 | from benchlingapi.session import Session 9 | -------------------------------------------------------------------------------- /benchlingapi/__version__.py: -------------------------------------------------------------------------------- 1 | # __version__.py 2 | # autogenerated by keats 0.2.28 3 | __version__ = "2.1.12" 4 | __name__ = "benchlingapi" 5 | __title__ = "benchlingapi" 6 | __authors__ = ["Justin Vrana "] 7 | __repo__ = None 8 | __homepage__ = "https://www.github.com/klavinslab/benchling-api" 9 | __description__ = "An unofficial python wrapper for the Benchling API" 10 | -------------------------------------------------------------------------------- /benchlingapi/exceptions.py: -------------------------------------------------------------------------------- 1 | r""" 2 | Exceptions (:mod:`benchlingapi.exceptions`) 3 | =========================================== 4 | 5 | .. currentmodule:: benchlingapi.exceptions 6 | 7 | BenchlingAPI exceptions 8 | """ 9 | 10 | 11 | class BenchlingAPIException(Exception): 12 | """Generic Exception for BenchlingAPI caused from the Python API itself.""" 13 | 14 | 15 | class BenchlingLoginError(BenchlingAPIException): 16 | """Errors for incorrect login credentials.""" 17 | 18 | 19 | class ModelNotFoundError(BenchlingAPIException): 20 | """Model not found.""" 21 | 22 | 23 | class SchemaNotFoundError(BenchlingAPIException): 24 | """Schema not found.""" 25 | 26 | 27 | ################################ 28 | # Benchling request exceptions 29 | ################################ 30 | class BenchlingServerException(BenchlingAPIException): 31 | """Exceptions received from the Benchling site.""" 32 | 33 | 34 | class InvalidRegistryId(BenchlingServerException): 35 | """Invalid registry id. 36 | 37 | Id or name exists in the registry. 38 | """ 39 | 40 | 41 | class RegistryValidationError(BenchlingServerException): 42 | """Entities do not match the expected registry schema.""" 43 | 44 | 45 | def exception_dispatch(exception_with_response): 46 | """Dispatches Benchling exceptions (from the site) to Pythonic 47 | exceptions.""" 48 | e = exception_with_response 49 | try: 50 | error_data = e.response.json() 51 | user_msg = error_data["error"]["userMessage"] 52 | if "Invalid entityRegistryId" in user_msg: 53 | raise InvalidRegistryId(str(e)) from e 54 | elif ( 55 | "That name is already used as either an alias or a name in this registry" 56 | in user_msg 57 | ): 58 | raise InvalidRegistryId(str(e)) from e 59 | elif "entities you attempted to register failed validation" in user_msg: 60 | raise RegistryValidationError(str(e)) from e 61 | except KeyError: 62 | pass 63 | raise e 64 | -------------------------------------------------------------------------------- /benchlingapi/models/__init__.py: -------------------------------------------------------------------------------- 1 | r""" 2 | Models (:mod:`benchlingapi.models.models`) 3 | ========================================== 4 | 5 | This module contains the Benchling API models. Models 6 | are accessed from a session instance as follows: 7 | 8 | .. code-block:: python 9 | 10 | from benchlingapi import Session 11 | 12 | session = Session("asdfe8iunaoerhgoaher") 13 | session.DNASequence 14 | session.AASequence 15 | session.Oligo 16 | session.Registry 17 | # and so on 18 | 19 | .. currentmodule:: benchlingapi.models.models 20 | 21 | Models 22 | ------ 23 | 24 | .. autosummary:: 25 | :toctree: generated/ 26 | 27 | DNASequence 28 | AASequence 29 | Oligo 30 | Annotation 31 | Translation 32 | CustomEntity 33 | EntitySchema 34 | Project 35 | Registry 36 | Translation 37 | DNAAlignment 38 | Task 39 | 40 | Schemas 41 | ------- 42 | 43 | Schemas define how JSON data is consumed and produced from the Benchling server. 44 | 45 | .. currentmodule:: benchlingapi.models.schema 46 | 47 | .. autosummary:: 48 | :toctree: generated/ 49 | 50 | DNASequenceSchema 51 | AASequenceSchema 52 | BatchSchema 53 | CustomEntitySchema 54 | DNASequenceSchema 55 | EntitySchema 56 | EntitySchemaSchema 57 | FieldSchema 58 | FolderSchema 59 | OligoSchema 60 | ProjectSchema 61 | RegistrySchema 62 | TranslationSchema 63 | UserSummarySchema 64 | DNAAlignmentSchema 65 | TaskSchema 66 | """ 67 | from benchlingapi.models import schema 68 | from benchlingapi.models.base import ModelRegistry 69 | from benchlingapi.models.models import AASequence 70 | from benchlingapi.models.models import Annotation 71 | from benchlingapi.models.models import Batch 72 | from benchlingapi.models.models import CustomEntity 73 | from benchlingapi.models.models import DNAAlignment 74 | from benchlingapi.models.models import DNASequence 75 | from benchlingapi.models.models import EntitySchema 76 | from benchlingapi.models.models import Folder 77 | from benchlingapi.models.models import Oligo 78 | from benchlingapi.models.models import Project 79 | from benchlingapi.models.models import Registry 80 | from benchlingapi.models.models import Task 81 | from benchlingapi.models.models import Translation 82 | -------------------------------------------------------------------------------- /benchlingapi/models/base.py: -------------------------------------------------------------------------------- 1 | """The base model class and registry for all model instances.""" 2 | import inspect 3 | from distutils.version import LooseVersion 4 | from functools import reduce 5 | 6 | import inflection 7 | from marshmallow import __version__ 8 | from marshmallow import class_registry 9 | 10 | from benchlingapi.exceptions import ModelNotFoundError 11 | from benchlingapi.utils import un_underscore_keys 12 | from benchlingapi.utils import underscore_keys 13 | from benchlingapi.utils import url_build 14 | 15 | 16 | class ModelRegistry(type): 17 | """Stores a list of models that can be accessed by name.""" 18 | 19 | models = {} 20 | 21 | def __init__(cls, name, bases, nmspc): 22 | """Saves model to the registry.""" 23 | super().__init__(name, bases, nmspc) 24 | if not name == "ModelBase": 25 | if name not in ModelRegistry.models: 26 | ModelRegistry.models[name] = cls 27 | 28 | @staticmethod 29 | def get_model(model_name): 30 | """Gets model by model_name.""" 31 | if model_name not in ModelRegistry.models: 32 | raise ModelNotFoundError( 33 | 'Model "{}" not found in ModelRegistry.'.format(model_name) 34 | ) 35 | else: 36 | return ModelRegistry.models[model_name] 37 | 38 | @staticmethod 39 | def models_by_base_classes(): 40 | models_by_base_classes = {} 41 | for m in ModelRegistry.models.values(): 42 | hierarchy = inspect.getmro(m) 43 | for base_model in hierarchy: 44 | models_by_base_classes.setdefault(base_model.__name__, []).append(m) 45 | return models_by_base_classes 46 | 47 | @staticmethod 48 | def filter_models_by_base_classes(bases): 49 | """Filters models registered in the model registry by their base 50 | classes. 51 | 52 | :param bases: base classes 53 | :type bases: type, list, or tuple 54 | :return: type 55 | :rtype: list 56 | """ 57 | if isinstance(bases, list): 58 | model_sets = [] 59 | for only_model in bases: 60 | model_sets.append( 61 | set(ModelRegistry.models_by_base_classes()[only_model.__name__]) 62 | ) 63 | models = reduce(lambda x, y: x.intersection(y), model_sets) 64 | else: 65 | models = ModelRegistry.models_by_base_classes()[bases.__name__] 66 | return models 67 | 68 | def __getattr__(cls, item): 69 | """Special warning for attribute errors. 70 | 71 | Its likely that user may have wanted to use a model interface 72 | instead of the Base class. 73 | """ 74 | raise AttributeError("'{}' has no attribute '{}'".format(cls.__name__, item)) 75 | 76 | @property 77 | def model_name(cls): 78 | """Return this model's name.""" 79 | return cls.__name__ 80 | 81 | 82 | class ModelBaseABC: 83 | """The model base for all BenchlingAPI model instances.""" 84 | 85 | # http = None # initialized with Session calls a model interface 86 | session = None 87 | alias = None 88 | 89 | def __init__(self, **data): 90 | data = underscore_keys(data) 91 | for k, v in data.items(): 92 | setattr(self, k, v) 93 | 94 | @staticmethod 95 | def _url_build(*parts): 96 | return url_build(*parts) 97 | 98 | @property 99 | def model_name(self): 100 | # if self.alias is not None: 101 | # return self.alias 102 | return self.__class__.__name__ 103 | 104 | @classmethod 105 | def _serialization_schema(cls, *args, **kwargs): 106 | schema = class_registry.get_class(cls.__name__ + "Schema") 107 | schema_inst = schema(*args, **kwargs) 108 | schema_inst.context["session"] = cls.session 109 | return schema_inst 110 | 111 | # TODO: remove schema_loader for marshmallow > 3 112 | @staticmethod 113 | def _deserializer(schema_inst, data): 114 | if isinstance(data, list): 115 | data = [underscore_keys(d) for d in data] 116 | else: 117 | data = underscore_keys(data) 118 | result = schema_inst.load(data) 119 | if LooseVersion(__version__) < LooseVersion("3.0.0"): 120 | if len(result.errors) > 0: 121 | raise Exception(str(result.errors)) 122 | result = result.data 123 | return result 124 | 125 | # TODO: remove schema_dumper for marshmallow > 3 126 | @staticmethod 127 | def _serializer(schema_inst, inst): 128 | result = schema_inst.dump(inst) 129 | if LooseVersion(__version__) < LooseVersion("3.0.0"): 130 | if len(result.errors) > 0: 131 | raise Exception(str(result.errors)) 132 | result = result.data 133 | if isinstance(result, list): 134 | return [un_underscore_keys(d) for d in result] 135 | return un_underscore_keys(result) 136 | 137 | @classmethod 138 | def load(cls, data, *args, **kwargs): 139 | schema_inst = cls._serialization_schema(*args, **kwargs) 140 | inst = cls._deserializer(schema_inst, data) 141 | inst.raw = data 142 | return inst 143 | 144 | def dump(self, *args, **kwargs): 145 | schema = self._serialization_schema(*args, **kwargs) 146 | data = self._serializer(schema, self) 147 | return data 148 | 149 | @classmethod 150 | def load_many(cls, data, *args, **kwargs): 151 | schema_inst = cls._serialization_schema(*args, many=True, **kwargs) 152 | # TODO: change for marshmallow > v3 153 | insts = cls._deserializer(schema_inst, data) 154 | for inst_data, inst in zip(data, insts): 155 | if issubclass(type(inst), ModelBase): 156 | inst.raw = inst_data 157 | return insts 158 | 159 | @classmethod 160 | def _tableize(cls): 161 | """Tableize the model name. 162 | 163 | :return: 164 | """ 165 | name = inflection.tableize(cls.__name__) 166 | name = inflection.dasherize(name) 167 | return name 168 | 169 | @classmethod 170 | def _camelize(cls, property=None): 171 | """Camelize the model name. 172 | 173 | :param property: 174 | :return: 175 | """ 176 | name = inflection.underscore(cls.model_name) 177 | if property is not None: 178 | name += "_" + inflection.pluralize(property) 179 | else: 180 | name = inflection.pluralize(name) 181 | name = inflection.camelize(name) 182 | name = name[0].lower() + name[1:] 183 | return name 184 | 185 | @classmethod 186 | def _path(cls, additional_paths=None): 187 | path = [cls._tableize()] 188 | if additional_paths is not None: 189 | if not isinstance(additional_paths, list): 190 | additional_paths = [additional_paths] 191 | path += additional_paths 192 | return cls._url_build(*path) 193 | 194 | def _update_from_other(self, other): 195 | vars(self).update(vars(other)) 196 | 197 | def reload(self): 198 | seq = self.find(self.id) 199 | self._update_from_other(seq) 200 | return self 201 | 202 | @classmethod 203 | def _get(cls, path_params=None, params=None, action=None): 204 | response = cls.session.http.get( 205 | cls._path(additional_paths=path_params), params=params, action=action 206 | ) 207 | return response 208 | # return cls.load(response) 209 | 210 | @classmethod 211 | def _get_pages(cls, path_params=None, params=None, action=None): 212 | pages = cls.session.http.get_pages( 213 | cls._path(additional_paths=path_params), params=params, action=action 214 | ) 215 | return pages 216 | 217 | @classmethod 218 | def _post(cls, data, path_params=None, params=None, action=None): 219 | response = cls.session.http.post( 220 | cls._path(additional_paths=path_params), 221 | json=data, 222 | params=params, 223 | action=action, 224 | ) 225 | return response 226 | 227 | @classmethod 228 | def _patch(cls, data, path_params=None, params=None, action=None): 229 | response = cls.session.http.patch( 230 | cls._path(additional_paths=path_params), 231 | json=data, 232 | params=params, 233 | action=action, 234 | ) 235 | return response 236 | 237 | @classmethod 238 | def _delete(cls, path_params=None, params=None, action=None): 239 | response = cls.session.http.delete( 240 | cls._path(additional_paths=path_params), params=params, action=action 241 | ) 242 | return response 243 | 244 | def copy(self): 245 | return self.load(self.dump()) 246 | 247 | def __repr__(self): 248 | return "<{cls} ({name}) at {id}>".format( 249 | cls=self.__class__.__name__, name=self.__class__.model_name, id=id(self) 250 | ) 251 | 252 | 253 | class ModelBase(ModelBaseABC, metaclass=ModelRegistry): 254 | """Registered model base for BenchlingAPI.""" 255 | 256 | pass 257 | -------------------------------------------------------------------------------- /benchlingapi/models/schema.py: -------------------------------------------------------------------------------- 1 | """Model serialization/deserialization classes.""" 2 | import re 3 | 4 | from marshmallow import fields as mfields 5 | from marshmallow import INCLUDE 6 | from marshmallow import post_dump 7 | from marshmallow import post_load 8 | from marshmallow import Schema 9 | from marshmallow import validate 10 | 11 | 12 | class ModelSchemaMixin: 13 | """Loads model from the Schema name.""" 14 | 15 | @classmethod 16 | def get_model_name(cls): 17 | return re.match(r"(\w+)Schema", cls.__name__).group(1) 18 | 19 | # @classmethod 20 | # def get_model(cls): 21 | # model = ModelRegistry.get_model(cls.get_model_name()) 22 | # return model 23 | 24 | # @pre_dump 25 | # def remove_none(self, obj): 26 | # params = obj 27 | # if hasattr(obj, '__dict__'): 28 | # params = params.__dict__ 29 | # return {k: v for k, v in params.items() if v is not None} 30 | 31 | @post_dump 32 | def remove_ignore(self, data, **kwargs): 33 | return {k: v for k, v in data.items() if v is not None} 34 | 35 | @post_load 36 | def load_model(self, data, **kwrags): 37 | if "session" not in self.context: 38 | raise Exception("Schema does not have a Session instance attached!") 39 | session = self.context["session"] 40 | return session.interface(self.get_model_name())(**data) 41 | 42 | 43 | class EntitySchema(Schema): 44 | entity_registry_id = mfields.String(default=None, allow_none=True) 45 | registry_id = mfields.String(default=None, allow_none=True) 46 | archive_reason = mfields.Dict(allow_none=True) 47 | id = mfields.String() 48 | name = mfields.String(required=True, allow_none=False) 49 | created_at = mfields.String(load_only=True) 50 | modified_at = mfields.String(load_only=True) 51 | creator = mfields.Dict() 52 | custom_fields = mfields.Dict() 53 | fields = mfields.Dict(allow_none=False) 54 | schema = mfields.Nested("EntitySchemaSchema", allow_none=True) 55 | schema_id = mfields.Method("get_schema_id") 56 | aliases = mfields.List(mfields.String()) 57 | folder_id = mfields.String(required=True, allow_none=True) 58 | # schema = mfields.Dict(allow_none=True) 59 | # schema 60 | # entity 61 | # archive_record 62 | # mfields 63 | # custommfields 64 | web_url = mfields.URL() 65 | 66 | class Meta: 67 | unknown = INCLUDE 68 | additional = ("id",) 69 | 70 | def get_schema_id(self, obj): 71 | if hasattr(obj, "schema_id") and obj.schema_id: 72 | return obj.schema_id 73 | elif hasattr(obj, "schema") and obj.schema: 74 | return obj.schema["id"] 75 | 76 | 77 | class CustomEntitySchema(ModelSchemaMixin, EntitySchema): 78 | class Meta: 79 | unknown = INCLUDE 80 | 81 | 82 | class OligoSchema(ModelSchemaMixin, EntitySchema): 83 | length = mfields.Integer() 84 | bases = mfields.String(required=True) 85 | 86 | class Meta: 87 | unknown = INCLUDE 88 | 89 | 90 | class OligoBinding(Schema): 91 | bases = mfields.String() 92 | bind_position = mfields.Integer() 93 | color = mfields.String() 94 | start = mfields.Integer() 95 | end = mfields.Integer() 96 | name = mfields.String() 97 | overhang_length = mfields.Integer() 98 | strand = mfields.Integer() 99 | 100 | class Meta: 101 | unknown = INCLUDE 102 | 103 | 104 | class DNASequenceSchema(ModelSchemaMixin, EntitySchema): 105 | annotations = mfields.Nested("AnnotationSchema", many=True) 106 | length = mfields.Integer() 107 | bases = mfields.String(required=True) 108 | is_circular = mfields.Boolean(required=True) 109 | translations = mfields.Nested("TranslationSchema", many=True) 110 | primers = mfields.Nested("OligoBinding", many=True) 111 | 112 | class Meta: 113 | unknown = INCLUDE 114 | 115 | 116 | class AASequenceSchema(ModelSchemaMixin, EntitySchema): 117 | annotations = mfields.Nested("AnnotationSchema", many=True) 118 | amino_acids = mfields.String(required=True) 119 | length = mfields.Integer() 120 | 121 | class Meta: 122 | unknown = INCLUDE 123 | 124 | 125 | class OligoSchema(ModelSchemaMixin, EntitySchema): 126 | bases = mfields.String(required=True) 127 | length = mfields.Integer() 128 | 129 | class Meta: 130 | unknown = INCLUDE 131 | 132 | 133 | class BatchSchema(EntitySchema): 134 | 135 | entity_id = mfields.String() 136 | 137 | class Meta: 138 | unknown = INCLUDE 139 | 140 | 141 | class AnnotationSchema(ModelSchemaMixin, Schema): 142 | color = mfields.String() 143 | start = mfields.Integer() 144 | end = mfields.Integer() 145 | name = mfields.String() 146 | strand = mfields.Integer(validate=validate.OneOf([0, 1, -1])) 147 | type = mfields.String() 148 | 149 | class Meta: 150 | unknown = INCLUDE 151 | 152 | 153 | class TranslationSchema(Schema): 154 | start = mfields.Integer() 155 | end = mfields.Integer() 156 | strand = mfields.Integer(validate=validate.OneOf([0, 1, -1])) 157 | amino_acids = mfields.String() 158 | regions = mfields.List(mfields.Dict()) 159 | 160 | class Meta: 161 | unknown = INCLUDE 162 | 163 | 164 | # class DNAAlignmentEntrySchema(Schema): 165 | # 166 | # bases = mfields.Str() 167 | # dna_sequence_id: mfields.Str() 168 | # trim_start = mfields.Int() 169 | # trim_end = mfields.Int() 170 | # 171 | # 172 | class DNAAlignmentSchema(ModelSchemaMixin, Schema): 173 | 174 | aligned_sequences = mfields.List(mfields.Dict()) 175 | name = mfields.Str() 176 | 177 | class Meta: 178 | unknown = INCLUDE 179 | 180 | 181 | #################################### 182 | # Common Resources 183 | #################################### 184 | 185 | # class ArchiveRecordSchema(Schema): 186 | # reason = mfields.String() 187 | 188 | 189 | class FieldSchema(Schema): 190 | type = mfields.String(load_only=True) 191 | is_multi = mfields.Boolean(load_only=True) 192 | value = mfields.Raw() 193 | text_value = mfields.String(load_only=True, allow_none=True) 194 | 195 | class Meta: 196 | unknown = INCLUDE 197 | 198 | 199 | class EntitySchemaSchema(Schema): 200 | archive_record = mfields.Dict(allow_none=True) 201 | id = mfields.String() 202 | name = mfields.String(required=True) 203 | type = mfields.String() 204 | field_definitions = mfields.List(mfields.Dict) 205 | prefix = mfields.String() 206 | registry_id = mfields.String(default=None, allow_none=True) 207 | constrain = mfields.Dict() 208 | 209 | class Meta: 210 | unknown = INCLUDE 211 | 212 | 213 | class UserSummarySchema(Schema): 214 | handle = mfields.String() 215 | id = mfields.String() 216 | name = mfields.String(allow_none=True) 217 | 218 | class Meta: 219 | unknown = INCLUDE 220 | 221 | 222 | class TaskSchema(ModelSchemaMixin, Schema): 223 | """Schema for :class:`Task ` 224 | 225 | .. versionadded:: 2.1.3 226 | Added :class:`DNASequence ` 227 | model and corresponding 228 | :class:`Task ` and 229 | :class:`TaskSchema `. 230 | """ 231 | 232 | status = mfields.Str() 233 | errors = mfields.List(mfields.Dict, allow_none=True, required=False) 234 | message = mfields.Str(allow_none=True, required=False) 235 | response = mfields.Dict(allow_none=True, required=False) 236 | id = mfields.Str() 237 | 238 | class Meta: 239 | unknown = INCLUDE 240 | 241 | 242 | #################################### 243 | # Projects and Folders 244 | #################################### 245 | 246 | 247 | class FolderSchema(ModelSchemaMixin, Schema): 248 | id = mfields.String() 249 | name = mfields.String(required=True) 250 | parent_folder_id = mfields.String(allow_none=True) 251 | project_id = mfields.String(required=True) 252 | archive_record = mfields.Dict(allow_none=True) 253 | 254 | class Meta: 255 | unknown = INCLUDE 256 | 257 | 258 | class ProjectSchema(ModelSchemaMixin, Schema): 259 | id = mfields.String() #: the id of the project 260 | name = mfields.String() #: the name of the project 261 | owner = mfields.Nested(UserSummarySchema) #: the owner of the project 262 | archive_record = mfields.Dict(allow_none=True) 263 | 264 | class Meta: 265 | unknown = INCLUDE 266 | 267 | 268 | class RegistrySchema(ModelSchemaMixin, Schema): 269 | id = mfields.String() 270 | name = mfields.String() 271 | owner = mfields.Nested(UserSummarySchema) 272 | 273 | class Meta: 274 | unknown = INCLUDE 275 | -------------------------------------------------------------------------------- /benchlingapi/session.py: -------------------------------------------------------------------------------- 1 | r""" 2 | Session (:mod:`benchlingapi.session`) 3 | ===================================== 4 | 5 | .. currentmodule:: benchlingapi.session 6 | 7 | Main entrypoint for the benchling api. To open a session, 8 | use your *Benchling-provided API key*. From there, you 9 | can access the session-enabled models: 10 | 11 | .. code-block:: python 12 | 13 | from benchlingapi import Session 14 | 15 | api_key = "asdfe8iunaoerhgoaher" 16 | session = Session(api_key) 17 | session.DNASequence 18 | session.AASequence 19 | session.Oligo 20 | session.Registry 21 | 22 | If your homespace URL for benchling is different from `https://benchling.com/api/v2`, you may 23 | specify your organization homespace using the `org` parameter, as in 24 | `https://{org}.benchling.com/api/v2/` 25 | 26 | .. code-block:: python 27 | 28 | org = "myorganization" 29 | session = Session(api_key, org=org) 30 | 31 | You may also specify the homespace directly: 32 | 33 | .. code-block:: python 34 | 35 | home = "https://myorganization.benchling.com/api/v2" 36 | session = Session(api_key, home=home) 37 | 38 | For more information on the models and their methods, see the 39 | :ref:`API model docs ` 40 | """ 41 | from functools import partial 42 | from functools import wraps 43 | from typing import Any 44 | from typing import Generator 45 | from typing import List 46 | from typing import Type 47 | 48 | import requests 49 | 50 | from benchlingapi.exceptions import BenchlingAPIException 51 | from benchlingapi.exceptions import exception_dispatch 52 | from benchlingapi.exceptions import ModelNotFoundError 53 | from benchlingapi.models.base import ModelBase 54 | from benchlingapi.models.base import ModelRegistry 55 | from benchlingapi.models.models import __all__ as allmodels 56 | from benchlingapi.utils import un_underscore_keys 57 | from benchlingapi.utils import url_build 58 | 59 | 60 | class RequestDecorator: 61 | """Wraps a function to raise error with unexpected request status codes.""" 62 | 63 | def __init__(self, status_codes): 64 | if not isinstance(status_codes, list): 65 | status_codes = [status_codes] 66 | self.code = status_codes 67 | 68 | def __call__(self, f): 69 | @wraps(f) 70 | def wrapped_f(*args, **kwargs): 71 | r = f(*args, **kwargs) 72 | if r.status_code not in self.code: 73 | http_codes = { 74 | 400: "BAD REQUEST", 75 | 403: "FORBIDDEN", 76 | 404: "NOT FOUND", 77 | 500: "INTERNAL SERVER ERROR", 78 | 503: "SERVICE UNAVAILABLE", 79 | 504: "SERVER TIMEOUT", 80 | } 81 | msg = "" 82 | if r.status_code in http_codes: 83 | msg = http_codes[r.status_code] 84 | msg += "\nrequest: {}".format(r.request) 85 | msg += "\nurl: {}".format(r.request.path_url) 86 | msg += "\nresponse: {}".format(r.text) 87 | 88 | e = BenchlingAPIException( 89 | "HTTP Response Failed {} {}".format(r.status_code, msg) 90 | ) 91 | e.response = r 92 | exception_dispatch(e) 93 | return r.json() 94 | 95 | return wrapped_f 96 | 97 | 98 | class Http: 99 | """Creates and responds to the Benchling server.""" 100 | 101 | TIMEOUT = 30 #: default request timeout for the session 102 | DEFAULT_HOME = ( 103 | "https://benchling.com/api/v2" 104 | ) #: default home url to use if not provided. 105 | NEXT = "nextToken" #: nextToken key for pagination 106 | 107 | def __init__(self, api_key, home=None): 108 | """ 109 | 110 | .. versionchanged:: 2.1.12 111 | Ad 112 | :param api_key: 113 | :param home: 114 | """ 115 | if home is None: 116 | home = self.DEFAULT_HOME 117 | session = requests.Session() 118 | session.auth = (api_key, "") 119 | self._home = home 120 | self.__session = session 121 | self.post = RequestDecorator([200, 201, 202])(partial(self.request, "post")) 122 | self.get = RequestDecorator(200)(partial(self.request, "get")) 123 | self.delete = RequestDecorator(200)(partial(self.request, "delete")) 124 | self.patch = RequestDecorator([200, 201])(partial(self.request, "patch")) 125 | 126 | def request( 127 | self, method: str, path: str, timeout: int = None, action: str = None, **kwargs 128 | ) -> Any: 129 | 130 | if "json" in kwargs: 131 | kwargs["json"] = un_underscore_keys(kwargs["json"]) 132 | if "params" in kwargs: 133 | kwargs["params"] = un_underscore_keys(kwargs["params"]) 134 | 135 | if timeout is None: 136 | timeout = self.TIMEOUT 137 | if action is not None: 138 | path += ":" + action 139 | return self.__session.request( 140 | method, url_build(self._home, path), timeout=timeout, **kwargs 141 | ) 142 | 143 | def get_pages( 144 | self, path: str, timeout: int = None, action: str = None, **kwargs 145 | ) -> Generator[Any, None, None]: 146 | get_response = partial(self.get, path, timeout=timeout, action=action) 147 | 148 | response = get_response(**kwargs) 149 | 150 | while response is not None: 151 | yield response 152 | 153 | # update params with nextToken 154 | next = response.get(self.NEXT, None) 155 | kwargs.get("params", {}).update({self.NEXT: next}) 156 | 157 | if next: 158 | response = get_response(**kwargs) 159 | else: 160 | response = None 161 | 162 | 163 | class Session: 164 | """The session object. 165 | 166 | This serves as the main interface for using the BenchlingAPI. 167 | """ 168 | 169 | def __init__(self, api_key: str, org: str = None, home: str = None): 170 | """ 171 | Initialize a new Benchling API Session. 172 | 173 | .. versionchanged:: 2.1.12 174 | Added the `org` and `home` arguments to give users more control 175 | over homespace. 176 | 177 | :param api_key: Benchling provided api_key 178 | :param org: optional org name. If provided, sets home URL 179 | to `https://{home}.benchling.com/api/v2` 180 | :param home: optional home name. If not provided, sets home 181 | to `https://benchling.com/api/v2`. See `org` argument. 182 | """ 183 | if org: 184 | home = "https://{org}.benchling.com/api/v2".format(org=org) 185 | self.__http = Http(api_key, home=home) 186 | self.__interfaces = {} 187 | for model_name in allmodels: 188 | model_cls = ModelRegistry.get_model(model_name) 189 | namespace = {"session": self} 190 | mymodel = type(model_name, (model_cls,), namespace) 191 | setattr(self, model_name, mymodel) 192 | self.__interfaces[model_name] = mymodel 193 | 194 | @property 195 | def http(self) -> Http: 196 | """Return the http requester object.""" 197 | return self.__http 198 | 199 | @property 200 | def url(self) -> str: 201 | """Return home benchling url.""" 202 | return self.__http._home 203 | 204 | def help(self): 205 | """Print api documentation url.""" 206 | help_url = "https://docs.benchling.com/reference" 207 | print('Visit "{}"'.format(help_url)) 208 | 209 | @property 210 | def models(self) -> List[str]: 211 | """List all models.""" 212 | return list(ModelRegistry.models.keys()) 213 | 214 | def set_timeout(self, timeout_in_seconds: int): 215 | """Set the request timeout.""" 216 | self.__http.timeout = timeout_in_seconds 217 | 218 | @property 219 | def interfaces(self): 220 | """List all model interfaces.""" 221 | return self.__interfaces 222 | 223 | def interface(self, model_name) -> Type[ModelBase]: 224 | """Return a model interface by name.""" 225 | if model_name not in self.interfaces: 226 | raise ModelNotFoundError('No model by name of "{}"'.format(model_name)) 227 | return self.interfaces[model_name] 228 | -------------------------------------------------------------------------------- /benchlingapi/utils.py: -------------------------------------------------------------------------------- 1 | r""" 2 | Utilities (:mod:`benchlingapi.utils`) 3 | ===================================== 4 | 5 | .. currentmodule:: benchlingapi.utils 6 | 7 | """ 8 | import inflection 9 | 10 | 11 | def url_build(*parts): 12 | """Join parts of a url into a string.""" 13 | return "/".join(p.strip("/") for p in parts) 14 | 15 | 16 | def underscore(k): 17 | """Transform keys like 'benchlingKey' to 'benchling_key'.""" 18 | return inflection.underscore(k) 19 | 20 | 21 | def un_underscore(k): 22 | """Transform keys like 'benchling_key' to 'benchlingKey'.""" 23 | s = inflection.camelize(k) 24 | s = s[0].lower() + s[1:] 25 | return s 26 | 27 | 28 | def _recursive_apply_to_keys(data, func, self_func): 29 | new_data = {} 30 | if data is not None: 31 | for k, v in data.items(): 32 | if isinstance(v, dict): 33 | new_data[func(k)] = self_func(v) 34 | else: 35 | new_data[func(k)] = v 36 | return new_data 37 | return data 38 | 39 | 40 | def underscore_keys(data): 41 | """Recursively transform keys to underscore format.""" 42 | return _recursive_apply_to_keys(data, underscore, underscore_keys) 43 | 44 | 45 | def un_underscore_keys(data): 46 | """Recursively un-transfrom keys from underscore format to benchling 47 | format.""" 48 | return _recursive_apply_to_keys(data, un_underscore, underscore_keys) 49 | -------------------------------------------------------------------------------- /docs/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 9825c4a1f1f445ab695234d670e9d359 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/.doctrees/developer/api_reference.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/developer/api_reference.doctree -------------------------------------------------------------------------------- /docs/.doctrees/developer/changelog.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/developer/changelog.doctree -------------------------------------------------------------------------------- /docs/.doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/.doctrees/exceptions.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/exceptions.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.AASequence.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.AASequence.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Annotation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Annotation.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.CustomEntity.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.CustomEntity.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.DNAAlignment.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.DNAAlignment.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.DNASequence.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.DNASequence.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.EntitySchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.EntitySchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Oligo.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Oligo.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Project.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Project.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Registry.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Registry.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Task.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Task.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.models.Translation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.models.Translation.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.AASequenceSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.AASequenceSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.BatchSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.BatchSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.CustomEntitySchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.CustomEntitySchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.DNAAlignmentSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.DNAAlignmentSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.DNASequenceSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.DNASequenceSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.EntitySchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.EntitySchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.EntitySchemaSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.EntitySchemaSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.FieldSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.FieldSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.FolderSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.FolderSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.OligoSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.OligoSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.ProjectSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.ProjectSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.RegistrySchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.RegistrySchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.TaskSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.TaskSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.TranslationSchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.TranslationSchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/generated/benchlingapi.models.schema.UserSummarySchema.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/generated/benchlingapi.models.schema.UserSummarySchema.doctree -------------------------------------------------------------------------------- /docs/.doctrees/guidelines.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/guidelines.doctree -------------------------------------------------------------------------------- /docs/.doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/index.doctree -------------------------------------------------------------------------------- /docs/.doctrees/models.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/models.doctree -------------------------------------------------------------------------------- /docs/.doctrees/session.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/session.doctree -------------------------------------------------------------------------------- /docs/.doctrees/usage.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/usage.doctree -------------------------------------------------------------------------------- /docs/.doctrees/utils.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.doctrees/utils.doctree -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/.nojekyll -------------------------------------------------------------------------------- /docs/_sources/developer/api_reference.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | Modules 5 | ------- 6 | 7 | .. automodule:: benchlingapi 8 | :members: 9 | :noindex: 10 | -------------------------------------------------------------------------------- /docs/_sources/developer/changelog.md: -------------------------------------------------------------------------------- 1 | # benchlingapi change log 2 | ## 2.1.12 3 | **2020-02-12T16:15:11.847504** 4 | changes to Session initialization 5 | 6 | - Users can now specify the home url for the Benchling Session instance. Use Session(api_key, org='myorg') to specify the home url 'myorg.benchling.com/api/v2'. User Session(api_key, home='myorg.benchling.com/api/v2') to specify the home url directly. 7 | 8 | 9 | ## 2.1.11 10 | **2019-12-18T13:34:41.244797** 11 | hotfix sharelink bug 12 | 13 | 14 | 15 | 16 | ## 2.1.10 17 | **2019-12-17T17:26:29.569759** 18 | fix previous release 19 | 20 | 21 | 22 | 23 | ## 2.1.9 24 | **2019-12-17T17:16:09.386482** 25 | fixes sharelink bugs 26 | 27 | 28 | 29 | 30 | ## 2.1.8 31 | **2019-12-17T17:10:53.952392** 32 | re-release of 2.1.7 (fixes broken branch) 33 | 34 | 35 | 36 | 37 | ## 2.1.7 38 | **2019-12-17T17:07:16.144945** 39 | bug fixes 40 | 41 | - fixes loading DNASequences from share_links 42 | 43 | 44 | ## 2.1.6 45 | **2019-12-16T17:06:05.925041** 46 | bug fixes 47 | 48 | - updates DNASequence to work with latest Benchling API update 49 | 50 | 51 | ## 2.1.5 52 | **2019-12-12T14:18:00.136712** 53 | 54 | 55 | - added 'merge' method to entities 56 | - fixed bug that arose iwhen trying to save an entity containing fields 57 | 58 | 59 | ## 2.1.4 60 | **2019-12-12T14:16:27.446507** 61 | feature and bug fixes 62 | 63 | 64 | 65 | 66 | ## 2.1.3 67 | **2019-10-23T16:08:47.898865** 68 | fixes bug with DNASequence.archived_reason 69 | 70 | - typo in archive_reason 71 | 72 | 73 | ## 2.1.2 74 | **2019-10-18T13:44:46.826684** 75 | bug fixes 76 | 77 | - fixes bug where parameters in get_pages was not being inherited 78 | - adds new 'all_in_registry' function 79 | 80 | 81 | ## 2.1.1 82 | **2019-10-17T19:36:37.900149** 83 | Python 3.5, 3.6, 3.7 support 84 | 85 | 86 | 87 | 88 | ## 2.1 89 | **2019-10-17T12:42:35.238592** 90 | Update marshamllow to 3.2 91 | 92 | 93 | 94 | 95 | ## 2.0.1 96 | **2019-10-16T08:02:35.118447** 97 | Bug fixes 98 | 99 | - fixed issue where nested data keys were not properly formatted to and from the benchling server 100 | 101 | 102 | ## 2.0.0 103 | **2019-10-15T21:08:34.511953** 104 | Second major release 105 | 106 | - all attribute names now lower-underscore case 107 | - refactoring and bug fixes 108 | - updates to interface 109 | - uses benchling api V2 110 | -------------------------------------------------------------------------------- /docs/_sources/exceptions.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.exceptions -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.AASequence.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.AASequence 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: AASequence 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~AASequence.__init__ 17 | ~AASequence.add_alias 18 | ~AASequence.all 19 | ~AASequence.archive 20 | ~AASequence.archive_many 21 | ~AASequence.batches 22 | ~AASequence.bulk_create 23 | ~AASequence.copy 24 | ~AASequence.create_model 25 | ~AASequence.dump 26 | ~AASequence.find 27 | ~AASequence.find_by_name 28 | ~AASequence.find_by_name_in_registry 29 | ~AASequence.find_in_registry 30 | ~AASequence.first 31 | ~AASequence.get 32 | ~AASequence.get_in_registry 33 | ~AASequence.last 34 | ~AASequence.list 35 | ~AASequence.list_archived 36 | ~AASequence.list_in_registry 37 | ~AASequence.list_pages 38 | ~AASequence.load 39 | ~AASequence.load_many 40 | ~AASequence.move 41 | ~AASequence.one 42 | ~AASequence.open 43 | ~AASequence.print_valid_schemas 44 | ~AASequence.register 45 | ~AASequence.register_and_save_name_as_alias 46 | ~AASequence.register_with_custom_id 47 | ~AASequence.registry_dict 48 | ~AASequence.reload 49 | ~AASequence.save 50 | ~AASequence.save_json 51 | ~AASequence.search 52 | ~AASequence.set_schema 53 | ~AASequence.unarchive 54 | ~AASequence.unarchive_many 55 | ~AASequence.unregister 56 | ~AASequence.update 57 | ~AASequence.update_json 58 | ~AASequence.update_model 59 | ~AASequence.valid_schemas 60 | 61 | 62 | 63 | 64 | 65 | .. rubric:: Attributes 66 | 67 | .. autosummary:: 68 | 69 | ~AASequence.CREATE_SCHEMA 70 | ~AASequence.ENTITY_TYPE 71 | ~AASequence.MAX_PAGE_SIZE 72 | ~AASequence.UPDATE_SCHEMA 73 | ~AASequence.alias 74 | ~AASequence.archive_reason 75 | ~AASequence.is_archived 76 | ~AASequence.is_registered 77 | ~AASequence.model_name 78 | ~AASequence.registry 79 | ~AASequence.session 80 | 81 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Annotation.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Annotation 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Annotation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Annotation.__init__ 17 | ~Annotation.copy 18 | ~Annotation.dump 19 | ~Annotation.load 20 | ~Annotation.load_many 21 | ~Annotation.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~Annotation.alias 32 | ~Annotation.model_name 33 | ~Annotation.session 34 | 35 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.CustomEntity.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.CustomEntity 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: CustomEntity 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~CustomEntity.__init__ 17 | ~CustomEntity.add_alias 18 | ~CustomEntity.all 19 | ~CustomEntity.archive 20 | ~CustomEntity.archive_many 21 | ~CustomEntity.batches 22 | ~CustomEntity.bulk_create 23 | ~CustomEntity.copy 24 | ~CustomEntity.create_model 25 | ~CustomEntity.dump 26 | ~CustomEntity.find 27 | ~CustomEntity.find_by_name 28 | ~CustomEntity.find_by_name_in_registry 29 | ~CustomEntity.find_in_registry 30 | ~CustomEntity.first 31 | ~CustomEntity.get 32 | ~CustomEntity.get_in_registry 33 | ~CustomEntity.last 34 | ~CustomEntity.list 35 | ~CustomEntity.list_archived 36 | ~CustomEntity.list_in_registry 37 | ~CustomEntity.list_pages 38 | ~CustomEntity.load 39 | ~CustomEntity.load_many 40 | ~CustomEntity.move 41 | ~CustomEntity.one 42 | ~CustomEntity.open 43 | ~CustomEntity.print_valid_schemas 44 | ~CustomEntity.register 45 | ~CustomEntity.register_and_save_name_as_alias 46 | ~CustomEntity.register_with_custom_id 47 | ~CustomEntity.registry_dict 48 | ~CustomEntity.reload 49 | ~CustomEntity.save 50 | ~CustomEntity.save_json 51 | ~CustomEntity.search 52 | ~CustomEntity.set_schema 53 | ~CustomEntity.unarchive 54 | ~CustomEntity.unarchive_many 55 | ~CustomEntity.unregister 56 | ~CustomEntity.update 57 | ~CustomEntity.update_json 58 | ~CustomEntity.update_model 59 | ~CustomEntity.valid_schemas 60 | 61 | 62 | 63 | 64 | 65 | .. rubric:: Attributes 66 | 67 | .. autosummary:: 68 | 69 | ~CustomEntity.CREATE_SCHEMA 70 | ~CustomEntity.ENTITY_TYPE 71 | ~CustomEntity.MAX_PAGE_SIZE 72 | ~CustomEntity.UPDATE_SCHEMA 73 | ~CustomEntity.alias 74 | ~CustomEntity.archive_reason 75 | ~CustomEntity.is_archived 76 | ~CustomEntity.is_registered 77 | ~CustomEntity.model_name 78 | ~CustomEntity.registry 79 | ~CustomEntity.session 80 | 81 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.DNAAlignment.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.DNAAlignment 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: DNAAlignment 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNAAlignment.__init__ 17 | ~DNAAlignment.copy 18 | ~DNAAlignment.delete 19 | ~DNAAlignment.dump 20 | ~DNAAlignment.find 21 | ~DNAAlignment.get 22 | ~DNAAlignment.load 23 | ~DNAAlignment.load_many 24 | ~DNAAlignment.reload 25 | ~DNAAlignment.submit_alignment 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~DNAAlignment.CLUSTALO 36 | ~DNAAlignment.MAFFT 37 | ~DNAAlignment.alias 38 | ~DNAAlignment.model_name 39 | ~DNAAlignment.session 40 | 41 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.DNASequence.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.DNASequence 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: DNASequence 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNASequence.__init__ 17 | ~DNASequence.add_alias 18 | ~DNASequence.all 19 | ~DNASequence.archive 20 | ~DNASequence.archive_many 21 | ~DNASequence.batches 22 | ~DNASequence.bulk_create 23 | ~DNASequence.copy 24 | ~DNASequence.create_model 25 | ~DNASequence.dump 26 | ~DNASequence.find 27 | ~DNASequence.find_by_name 28 | ~DNASequence.find_by_name_in_registry 29 | ~DNASequence.find_in_registry 30 | ~DNASequence.first 31 | ~DNASequence.from_share_link 32 | ~DNASequence.get 33 | ~DNASequence.get_in_registry 34 | ~DNASequence.last 35 | ~DNASequence.list 36 | ~DNASequence.list_archived 37 | ~DNASequence.list_in_registry 38 | ~DNASequence.list_pages 39 | ~DNASequence.load 40 | ~DNASequence.load_many 41 | ~DNASequence.move 42 | ~DNASequence.one 43 | ~DNASequence.open 44 | ~DNASequence.print_valid_schemas 45 | ~DNASequence.register 46 | ~DNASequence.register_and_save_name_as_alias 47 | ~DNASequence.register_with_custom_id 48 | ~DNASequence.registry_dict 49 | ~DNASequence.reload 50 | ~DNASequence.save 51 | ~DNASequence.save_json 52 | ~DNASequence.search 53 | ~DNASequence.set_schema 54 | ~DNASequence.unarchive 55 | ~DNASequence.unarchive_many 56 | ~DNASequence.unregister 57 | ~DNASequence.update 58 | ~DNASequence.update_json 59 | ~DNASequence.update_model 60 | ~DNASequence.valid_schemas 61 | 62 | 63 | 64 | 65 | 66 | .. rubric:: Attributes 67 | 68 | .. autosummary:: 69 | 70 | ~DNASequence.CREATE_SCHEMA 71 | ~DNASequence.ENTITY_TYPE 72 | ~DNASequence.MAX_PAGE_SIZE 73 | ~DNASequence.UPDATE_SCHEMA 74 | ~DNASequence.alias 75 | ~DNASequence.archive_reason 76 | ~DNASequence.is_archived 77 | ~DNASequence.is_registered 78 | ~DNASequence.model_name 79 | ~DNASequence.registry 80 | ~DNASequence.session 81 | 82 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.EntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.EntitySchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: EntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchema.__init__ 17 | ~EntitySchema.copy 18 | ~EntitySchema.dump 19 | ~EntitySchema.load 20 | ~EntitySchema.load_many 21 | ~EntitySchema.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~EntitySchema.alias 32 | ~EntitySchema.model_name 33 | ~EntitySchema.session 34 | 35 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Oligo.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Oligo 2 | ================================ 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Oligo 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Oligo.__init__ 17 | ~Oligo.bulk_create 18 | ~Oligo.copy 19 | ~Oligo.create_model 20 | ~Oligo.dump 21 | ~Oligo.find 22 | ~Oligo.find_by_name_in_registry 23 | ~Oligo.find_in_registry 24 | ~Oligo.get 25 | ~Oligo.get_in_registry 26 | ~Oligo.list_in_registry 27 | ~Oligo.load 28 | ~Oligo.load_many 29 | ~Oligo.move 30 | ~Oligo.print_valid_schemas 31 | ~Oligo.register 32 | ~Oligo.register_and_save_name_as_alias 33 | ~Oligo.register_with_custom_id 34 | ~Oligo.registry_dict 35 | ~Oligo.reload 36 | ~Oligo.save 37 | ~Oligo.save_json 38 | ~Oligo.set_schema 39 | ~Oligo.unregister 40 | ~Oligo.valid_schemas 41 | 42 | 43 | 44 | 45 | 46 | .. rubric:: Attributes 47 | 48 | .. autosummary:: 49 | 50 | ~Oligo.CREATE_SCHEMA 51 | ~Oligo.ENTITY_TYPE 52 | ~Oligo.alias 53 | ~Oligo.is_registered 54 | ~Oligo.model_name 55 | ~Oligo.registry 56 | ~Oligo.session 57 | 58 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Project.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Project 2 | ================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Project 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Project.__init__ 17 | ~Project.all 18 | ~Project.archive 19 | ~Project.archive_many 20 | ~Project.copy 21 | ~Project.dump 22 | ~Project.find 23 | ~Project.find_by_name 24 | ~Project.first 25 | ~Project.get 26 | ~Project.last 27 | ~Project.list 28 | ~Project.list_pages 29 | ~Project.load 30 | ~Project.load_many 31 | ~Project.one 32 | ~Project.reload 33 | ~Project.search 34 | ~Project.unarchive 35 | ~Project.unarchive_many 36 | 37 | 38 | 39 | 40 | 41 | .. rubric:: Attributes 42 | 43 | .. autosummary:: 44 | 45 | ~Project.MAX_PAGE_SIZE 46 | ~Project.alias 47 | ~Project.archive_reason 48 | ~Project.is_archived 49 | ~Project.model_name 50 | ~Project.session 51 | 52 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Registry.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Registry 2 | =================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Registry 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Registry.__init__ 17 | ~Registry.all 18 | ~Registry.copy 19 | ~Registry.dump 20 | ~Registry.find 21 | ~Registry.find_by_name 22 | ~Registry.find_from_schema_id 23 | ~Registry.find_in_registry 24 | ~Registry.find_registry 25 | ~Registry.first 26 | ~Registry.get 27 | ~Registry.get_entities 28 | ~Registry.get_schema 29 | ~Registry.last 30 | ~Registry.list 31 | ~Registry.list_pages 32 | ~Registry.load 33 | ~Registry.load_many 34 | ~Registry.one 35 | ~Registry.register 36 | ~Registry.register_entities 37 | ~Registry.reload 38 | ~Registry.search 39 | ~Registry.unregister 40 | ~Registry.unregister_entities 41 | 42 | 43 | 44 | 45 | 46 | .. rubric:: Attributes 47 | 48 | .. autosummary:: 49 | 50 | ~Registry.MAX_PAGE_SIZE 51 | ~Registry.alias 52 | ~Registry.entity_schemas 53 | ~Registry.model_name 54 | ~Registry.session 55 | 56 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Task.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Task 2 | =============================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Task 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Task.__init__ 17 | ~Task.copy 18 | ~Task.dump 19 | ~Task.find 20 | ~Task.get 21 | ~Task.load 22 | ~Task.load_many 23 | ~Task.reload 24 | ~Task.wait 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~Task.alias 35 | ~Task.model_name 36 | ~Task.session 37 | 38 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.models.Translation.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Translation 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Translation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Translation.__init__ 17 | ~Translation.copy 18 | ~Translation.dump 19 | ~Translation.load 20 | ~Translation.load_many 21 | ~Translation.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~Translation.alias 32 | ~Translation.model_name 33 | ~Translation.session 34 | 35 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.AASequenceSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.AASequenceSchema 2 | =========================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: AASequenceSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~AASequenceSchema.__init__ 17 | ~AASequenceSchema.dump 18 | ~AASequenceSchema.dumps 19 | ~AASequenceSchema.get_attribute 20 | ~AASequenceSchema.get_model_name 21 | ~AASequenceSchema.get_schema_id 22 | ~AASequenceSchema.handle_error 23 | ~AASequenceSchema.load 24 | ~AASequenceSchema.load_model 25 | ~AASequenceSchema.loads 26 | ~AASequenceSchema.on_bind_field 27 | ~AASequenceSchema.remove_ignore 28 | ~AASequenceSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~AASequenceSchema.TYPE_MAPPING 39 | ~AASequenceSchema.dict_class 40 | ~AASequenceSchema.opts 41 | ~AASequenceSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.BatchSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.BatchSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: BatchSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~BatchSchema.__init__ 17 | ~BatchSchema.dump 18 | ~BatchSchema.dumps 19 | ~BatchSchema.get_attribute 20 | ~BatchSchema.get_schema_id 21 | ~BatchSchema.handle_error 22 | ~BatchSchema.load 23 | ~BatchSchema.loads 24 | ~BatchSchema.on_bind_field 25 | ~BatchSchema.validate 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~BatchSchema.TYPE_MAPPING 36 | ~BatchSchema.dict_class 37 | ~BatchSchema.opts 38 | ~BatchSchema.set_class 39 | 40 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.CustomEntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.CustomEntitySchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: CustomEntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~CustomEntitySchema.__init__ 17 | ~CustomEntitySchema.dump 18 | ~CustomEntitySchema.dumps 19 | ~CustomEntitySchema.get_attribute 20 | ~CustomEntitySchema.get_model_name 21 | ~CustomEntitySchema.get_schema_id 22 | ~CustomEntitySchema.handle_error 23 | ~CustomEntitySchema.load 24 | ~CustomEntitySchema.load_model 25 | ~CustomEntitySchema.loads 26 | ~CustomEntitySchema.on_bind_field 27 | ~CustomEntitySchema.remove_ignore 28 | ~CustomEntitySchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~CustomEntitySchema.TYPE_MAPPING 39 | ~CustomEntitySchema.dict_class 40 | ~CustomEntitySchema.opts 41 | ~CustomEntitySchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.DNAAlignmentSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.DNAAlignmentSchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: DNAAlignmentSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNAAlignmentSchema.__init__ 17 | ~DNAAlignmentSchema.dump 18 | ~DNAAlignmentSchema.dumps 19 | ~DNAAlignmentSchema.from_dict 20 | ~DNAAlignmentSchema.get_attribute 21 | ~DNAAlignmentSchema.get_model_name 22 | ~DNAAlignmentSchema.handle_error 23 | ~DNAAlignmentSchema.load 24 | ~DNAAlignmentSchema.load_model 25 | ~DNAAlignmentSchema.loads 26 | ~DNAAlignmentSchema.on_bind_field 27 | ~DNAAlignmentSchema.remove_ignore 28 | ~DNAAlignmentSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~DNAAlignmentSchema.TYPE_MAPPING 39 | ~DNAAlignmentSchema.dict_class 40 | ~DNAAlignmentSchema.error_messages 41 | ~DNAAlignmentSchema.opts 42 | ~DNAAlignmentSchema.set_class 43 | 44 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.DNASequenceSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.DNASequenceSchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: DNASequenceSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNASequenceSchema.__init__ 17 | ~DNASequenceSchema.dump 18 | ~DNASequenceSchema.dumps 19 | ~DNASequenceSchema.get_attribute 20 | ~DNASequenceSchema.get_model_name 21 | ~DNASequenceSchema.get_schema_id 22 | ~DNASequenceSchema.handle_error 23 | ~DNASequenceSchema.load 24 | ~DNASequenceSchema.load_model 25 | ~DNASequenceSchema.loads 26 | ~DNASequenceSchema.on_bind_field 27 | ~DNASequenceSchema.remove_ignore 28 | ~DNASequenceSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~DNASequenceSchema.TYPE_MAPPING 39 | ~DNASequenceSchema.dict_class 40 | ~DNASequenceSchema.opts 41 | ~DNASequenceSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.EntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.EntitySchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: EntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchema.__init__ 17 | ~EntitySchema.dump 18 | ~EntitySchema.dumps 19 | ~EntitySchema.get_attribute 20 | ~EntitySchema.get_schema_id 21 | ~EntitySchema.handle_error 22 | ~EntitySchema.load 23 | ~EntitySchema.loads 24 | ~EntitySchema.on_bind_field 25 | ~EntitySchema.validate 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~EntitySchema.TYPE_MAPPING 36 | ~EntitySchema.dict_class 37 | ~EntitySchema.opts 38 | ~EntitySchema.set_class 39 | 40 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.EntitySchemaSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.EntitySchemaSchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: EntitySchemaSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchemaSchema.__init__ 17 | ~EntitySchemaSchema.dump 18 | ~EntitySchemaSchema.dumps 19 | ~EntitySchemaSchema.get_attribute 20 | ~EntitySchemaSchema.handle_error 21 | ~EntitySchemaSchema.load 22 | ~EntitySchemaSchema.loads 23 | ~EntitySchemaSchema.on_bind_field 24 | ~EntitySchemaSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~EntitySchemaSchema.TYPE_MAPPING 35 | ~EntitySchemaSchema.dict_class 36 | ~EntitySchemaSchema.opts 37 | ~EntitySchemaSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.FieldSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.FieldSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: FieldSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~FieldSchema.__init__ 17 | ~FieldSchema.dump 18 | ~FieldSchema.dumps 19 | ~FieldSchema.get_attribute 20 | ~FieldSchema.handle_error 21 | ~FieldSchema.load 22 | ~FieldSchema.loads 23 | ~FieldSchema.on_bind_field 24 | ~FieldSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~FieldSchema.TYPE_MAPPING 35 | ~FieldSchema.dict_class 36 | ~FieldSchema.opts 37 | ~FieldSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.FolderSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.FolderSchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: FolderSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~FolderSchema.__init__ 17 | ~FolderSchema.dump 18 | ~FolderSchema.dumps 19 | ~FolderSchema.get_attribute 20 | ~FolderSchema.get_model_name 21 | ~FolderSchema.handle_error 22 | ~FolderSchema.load 23 | ~FolderSchema.load_model 24 | ~FolderSchema.loads 25 | ~FolderSchema.on_bind_field 26 | ~FolderSchema.remove_ignore 27 | ~FolderSchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~FolderSchema.TYPE_MAPPING 38 | ~FolderSchema.dict_class 39 | ~FolderSchema.opts 40 | ~FolderSchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.OligoSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.OligoSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: OligoSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~OligoSchema.__init__ 17 | ~OligoSchema.dump 18 | ~OligoSchema.dumps 19 | ~OligoSchema.get_attribute 20 | ~OligoSchema.get_model_name 21 | ~OligoSchema.get_schema_id 22 | ~OligoSchema.handle_error 23 | ~OligoSchema.load 24 | ~OligoSchema.load_model 25 | ~OligoSchema.loads 26 | ~OligoSchema.on_bind_field 27 | ~OligoSchema.remove_ignore 28 | ~OligoSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~OligoSchema.TYPE_MAPPING 39 | ~OligoSchema.dict_class 40 | ~OligoSchema.opts 41 | ~OligoSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.ProjectSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.ProjectSchema 2 | ======================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: ProjectSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~ProjectSchema.__init__ 17 | ~ProjectSchema.dump 18 | ~ProjectSchema.dumps 19 | ~ProjectSchema.get_attribute 20 | ~ProjectSchema.get_model_name 21 | ~ProjectSchema.handle_error 22 | ~ProjectSchema.load 23 | ~ProjectSchema.load_model 24 | ~ProjectSchema.loads 25 | ~ProjectSchema.on_bind_field 26 | ~ProjectSchema.remove_ignore 27 | ~ProjectSchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~ProjectSchema.TYPE_MAPPING 38 | ~ProjectSchema.dict_class 39 | ~ProjectSchema.opts 40 | ~ProjectSchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.RegistrySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.RegistrySchema 2 | ========================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: RegistrySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~RegistrySchema.__init__ 17 | ~RegistrySchema.dump 18 | ~RegistrySchema.dumps 19 | ~RegistrySchema.get_attribute 20 | ~RegistrySchema.get_model_name 21 | ~RegistrySchema.handle_error 22 | ~RegistrySchema.load 23 | ~RegistrySchema.load_model 24 | ~RegistrySchema.loads 25 | ~RegistrySchema.on_bind_field 26 | ~RegistrySchema.remove_ignore 27 | ~RegistrySchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~RegistrySchema.TYPE_MAPPING 38 | ~RegistrySchema.dict_class 39 | ~RegistrySchema.opts 40 | ~RegistrySchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.TaskSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.TaskSchema 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: TaskSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~TaskSchema.__init__ 17 | ~TaskSchema.dump 18 | ~TaskSchema.dumps 19 | ~TaskSchema.from_dict 20 | ~TaskSchema.get_attribute 21 | ~TaskSchema.get_model_name 22 | ~TaskSchema.handle_error 23 | ~TaskSchema.load 24 | ~TaskSchema.load_model 25 | ~TaskSchema.loads 26 | ~TaskSchema.on_bind_field 27 | ~TaskSchema.remove_ignore 28 | ~TaskSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~TaskSchema.TYPE_MAPPING 39 | ~TaskSchema.dict_class 40 | ~TaskSchema.error_messages 41 | ~TaskSchema.opts 42 | ~TaskSchema.set_class 43 | 44 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.TranslationSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.TranslationSchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: TranslationSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~TranslationSchema.__init__ 17 | ~TranslationSchema.dump 18 | ~TranslationSchema.dumps 19 | ~TranslationSchema.get_attribute 20 | ~TranslationSchema.handle_error 21 | ~TranslationSchema.load 22 | ~TranslationSchema.loads 23 | ~TranslationSchema.on_bind_field 24 | ~TranslationSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~TranslationSchema.TYPE_MAPPING 35 | ~TranslationSchema.dict_class 36 | ~TranslationSchema.opts 37 | ~TranslationSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docs/_sources/generated/benchlingapi.models.schema.UserSummarySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.UserSummarySchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: UserSummarySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~UserSummarySchema.__init__ 17 | ~UserSummarySchema.dump 18 | ~UserSummarySchema.dumps 19 | ~UserSummarySchema.get_attribute 20 | ~UserSummarySchema.handle_error 21 | ~UserSummarySchema.load 22 | ~UserSummarySchema.loads 23 | ~UserSummarySchema.on_bind_field 24 | ~UserSummarySchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~UserSummarySchema.TYPE_MAPPING 35 | ~UserSummarySchema.dict_class 36 | ~UserSummarySchema.opts 37 | ~UserSummarySchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docs/_sources/guidelines.rst: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | Installing the package 5 | ---------------------- 6 | 7 | Download the git repository, cd into the directory and run: 8 | 9 | .. code-block:: 10 | 11 | poetry install 12 | 13 | If **poetry** (https://github.com/sdispater/poetry) is not installed 14 | on, run 15 | 16 | .. code-block:: 17 | 18 | pip install poetry -U 19 | 20 | Adding a new model 21 | ------------------ 22 | 23 | To implement a new model, please refer to the official 24 | `Benchling documentation `_. After, 25 | review the docs, find the appropriate class 26 | :mod:`mixins ` to implement the new model and 27 | inherit the :class:`ModelBase ` 28 | Finally, create a new :mod:`schema `, to 29 | implement the attributes the model will inherit from benchling 30 | results, following the convention of using *under_score* attribute 31 | names. Implement methods using the 32 | `_post`, `_get`, `_get_pages`, `_patch` methods of 33 | :class:`ModelBase ` as needed. 34 | 35 | If developing a new mixin or method in one of the mixin classes, be sure 36 | to develop tests for each model that uses that mixin. See the *tests* folder 37 | for examples on how to do this. 38 | 39 | Running tests 40 | ------------- 41 | 42 | Testing is done using `pytest`. Tests will create live requests to a Benchling account. 43 | Since testing is done live, a Benchling account will need to be setup along with testing 44 | data. 45 | 46 | .. code-block:: json 47 | 48 | { 49 | "credentials": { 50 | "api_key": "asdasdfadsfaghrhrha" 51 | }, 52 | "sharelinks": [ 53 | "https://benchling.com/s/seq-asdffebarha" 54 | ], 55 | "project": { 56 | "name": "API_sasdfs_iuAAXqsdfadsftuk" 57 | }, 58 | "trash_folder": { 59 | "name": "API_Trash" 60 | }, 61 | "inventory_folder": { 62 | "name": "API_Inventory" 63 | } 64 | } 65 | 66 | On the Benchling side of things, in the account liked to the `credentials["api_key"]`, you must 67 | have a project corresponding to the `project["name"]` value above. Within this project, you should 68 | have two folder corresponding to the `trash_folder` and `inventory_folder` values above. Additionally, 69 | you should have at least one example of an AminoAcid, DNASequence, CustomEntity, and Oligo stored within 70 | your `inventory_folder`. Tests will copy the examples from the `inventory_folder` for downstream tests. 71 | After the tests, conclude, inventory in the `trash_folder` will get archived. 72 | 73 | Style 74 | ----- 75 | 76 | Coding format and style is enforced by **black** (https://github.com/psf/black) and 77 | **flake8**. To enforce git-commit hooks, install pre-commits by running: 78 | 79 | .. code-block:: 80 | 81 | poetry run pre-commit install 82 | 83 | Tests 84 | ----- 85 | 86 | .. code-block:: 87 | 88 | poetry run pytest 89 | 90 | .. code-block:: 91 | 92 | tox 93 | 94 | Release 95 | ------- 96 | 97 | Release scripts are enforced by **keats** (https://github.com/jvrana/keats). 98 | 99 | .. code-block:: 100 | 101 | # if you just want to bump the version and changelog 102 | poetry run keats bump 103 | 104 | # release script 105 | poetry run keats release 106 | 107 | Documentation 108 | ------------- 109 | 110 | .. code-block:: 111 | 112 | make docs 113 | -------------------------------------------------------------------------------- /docs/_sources/index.rst: -------------------------------------------------------------------------------- 1 | :github_url: |homepage| 2 | 3 | .. testsetup:: * 4 | 5 | 6 | 7 | Python BenchlingAPI 8 | =================== 9 | 10 | The unofficial Benchling API for Python. |homepage| 11 | 12 | .. code-block:: 13 | 14 | pip install benchlingapi -U 15 | 16 | .. code-block:: python 17 | 18 | from benchlingapi import Session 19 | 20 | api_key = 'aksdj45ywe5yey5y' 21 | session = Session(api_key) 22 | seq = session.DNASequence.last() 23 | print(seq.dump()) 24 | 25 | API Reference 26 | ------------- 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | 31 | session 32 | models 33 | exceptions 34 | utils 35 | 36 | 37 | User Documentation 38 | ------------------ 39 | 40 | The user documentation contains high-level information for users. 41 | 42 | .. toctree:: 43 | :maxdepth: 1 44 | 45 | usage 46 | 47 | Developer Documentation 48 | ----------------------- 49 | 50 | The developer documentation conatins information on how to contribute.. 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | 55 | guidelines 56 | developer/changelog 57 | -------------------------------------------------------------------------------- /docs/_sources/models.rst: -------------------------------------------------------------------------------- 1 | .. _api_models: 2 | 3 | .. automodule:: benchlingapi.models -------------------------------------------------------------------------------- /docs/_sources/session.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.session -------------------------------------------------------------------------------- /docs/_sources/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Installation 5 | ------------ 6 | 7 | .. code-block:: python 8 | 9 | pip install benchlingapi -U 10 | 11 | Session 12 | ------- 13 | 14 | Using the api requires an *api key*. If you do not have one, 15 | you must request one from Benchling. 16 | 17 | .. code-block:: python 18 | 19 | from benchlingapi import Session 20 | 21 | session = Session("sdf44tj-sdflj8na-rf23rfasdf") 22 | 23 | From there, you can access various models: 24 | 25 | .. code-block:: python 26 | 27 | session.DNASequence 28 | session.AASequence 29 | session.Oligo 30 | session.Folder 31 | session.Project 32 | session.Registry 33 | session.Translation 34 | session.EntitySchema 35 | session.Batch 36 | session.CustomEntity 37 | session.DNAAlignment 38 | session.Task 39 | 40 | 41 | Have a look at the :ref:`API model docs ` 42 | for methods available for each model. 43 | 44 | Finding models 45 | ^^^^^^^^^^^^^^ 46 | 47 | .. code-block:: python 48 | 49 | # get one model 50 | dna = session.DNASequence.one() 51 | 52 | # find a specific model by its id 53 | dna = session.DNASequence.find('sdg_4tg23') 54 | 55 | # get the last 50 amino acids 56 | proteins = session.AASequence.last(50) 57 | 58 | # get a registry by name 59 | registry = session.Registry.find_by_name("Klavins Lab Registry") 60 | 61 | 62 | 63 | Updating models 64 | ^^^^^^^^^^^^^^^ 65 | 66 | .. code-block:: python 67 | 68 | dna = session.DNASequence.one() 69 | dna.name = "My new name" 70 | dna.bases = "AGGTAGGGTAGGGCCAGAGA" 71 | 72 | # update the sequence on the server 73 | dna.update() 74 | 75 | 76 | Saving new models 77 | ^^^^^^^^^^^^^^^^^ 78 | 79 | .. code-block:: python 80 | 81 | folder = session.Folder.find_by_name("My API Folder") 82 | dna = session.DNASequence( 83 | name = 'my new dna', 84 | bases = 'AGGTAGGATGGCCA', 85 | folder_id = folder.id, 86 | is_circular = False 87 | ) 88 | 89 | # save the dna to your Benchling account 90 | dna.save() 91 | 92 | 93 | Registering models to your registry 94 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 95 | 96 | .. code-block:: python 97 | 98 | dna.set_schema("My DNA Schema") 99 | dna.register() 100 | 101 | 102 | Submitting DNA Alignments 103 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 104 | 105 | .. testcode:: 106 | 107 | task = session.DNAAlignment.submit_alignment( 108 | algorithm='mafft', 109 | name='my sequence alignment', 110 | template='seq_435g2d', # sequence id of the template 111 | filepaths=[ 112 | 'data/13dfg34.ab1' # filepath to ab1 files 113 | ], 114 | sequences=[ 115 | 'seq_1erv452', # ...or add benchling sequence ids to align 116 | session.DNASequence.one(), # ...or a DNASequence instances to align 117 | ], 118 | rawfiles=None # only use if you have base64 data handy 119 | ) 120 | 121 | # wait until the alignment is finished 122 | task.wait() 123 | 124 | # print the alignment 125 | print(task.response) 126 | 127 | # or grab the alignment 128 | alignment = task.response_class 129 | 130 | # from there, you can delete the alignment 131 | alignment.delete() 132 | 133 | -------------------------------------------------------------------------------- /docs/_sources/utils.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.utils -------------------------------------------------------------------------------- /docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/_static/bootstrap-3.3.7/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /docs/_static/bootstrap-sphinx.css: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-sphinx.css 3 | * ~~~~~~~~~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- Bootstrap theme. 6 | */ 7 | 8 | /* 9 | * Imports to aggregate everything together. 10 | */ 11 | 12 | @import url("./basic.css"); 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | @import url("./bootswatch-3.3.7/cosmo/bootstrap.min.css"); 22 | 23 | 24 | 25 | /* 26 | * Styles 27 | */ 28 | 29 | .navbar-inverse .brand { 30 | color: #FFF; 31 | } 32 | 33 | /* 34 | * Reset navbar styles from overrides in: 35 | * https://bitbucket.org/birkenfeld/sphinx/commits/78d8ebf76b630ab4073a7328af9d91e8123b8d96 36 | */ 37 | .navbar .container { 38 | padding-top: 0; 39 | } 40 | 41 | /* 42 | * Reset the logo image dimensions. Sites like RTD can override with bad 43 | * results on mobile (mega-huge logo...) 44 | * 45 | * https://github.com/ryan-roemer/sphinx-bootstrap-theme/issues/142 46 | */ 47 | .navbar-brand img { 48 | width: auto; 49 | height: 100%; 50 | } 51 | 52 | .page-top { 53 | top: 0px; 54 | } 55 | 56 | 57 | 58 | 59 | 60 | body { 61 | 62 | padding-top: 60px; 63 | 64 | } 65 | .page-top { 66 | 67 | top: 60px; 68 | 69 | } 70 | 71 | 72 | 73 | .navbar-inner { 74 | padding-left: 12px !important; 75 | padding-right: 12px !important; 76 | } 77 | 78 | 79 | table { 80 | border: 0; 81 | } 82 | 83 | .highlighttable .code pre { 84 | font-size: 12px; 85 | } 86 | 87 | .highlighttable .linenos pre { 88 | word-break: normal; 89 | font-size: 12px; 90 | } 91 | 92 | div.highlight { 93 | background: none; 94 | } 95 | 96 | a.headerlink { 97 | margin-left: 0.25em; 98 | } 99 | 100 | a.footnote-reference { 101 | vertical-align: super; 102 | font-size: 75%; 103 | } 104 | 105 | table.footnote td.label { 106 | color: inherit; 107 | font-size: 100%; 108 | display: block; 109 | line-height: normal; 110 | background: inherit; 111 | } 112 | 113 | table.footnote { 114 | width: auto; 115 | margin-bottom: 0px; 116 | } 117 | 118 | table.field-list { 119 | width: auto; 120 | } 121 | 122 | .footer { 123 | width: 100%; 124 | border-top: 1px solid #ccc; 125 | padding-top: 10px; 126 | } 127 | 128 | .bs-sidenav form, .bs-sidenav #sourcelink { 129 | padding: 5px 20px; 130 | } 131 | 132 | 133 | 134 | /* The code below is based on the bootstrap website sidebar */ 135 | 136 | .bs-sidenav.affix { 137 | position: static; 138 | } 139 | 140 | /* First level of nav */ 141 | .bs-sidenav { 142 | margin-top: 30px; 143 | margin-bottom: 30px; 144 | padding-top: 10px; 145 | padding-bottom: 10px; 146 | text-shadow: 0 1px 0 #fff; 147 | background-color: #f7f5fa; 148 | border-radius: 5px; 149 | } 150 | 151 | /* All levels of nav */ 152 | .bs-sidenav .nav > li > a { 153 | display: block; 154 | color: #716b7a; 155 | padding: 5px 20px; 156 | } 157 | .bs-sidenav .nav > li > a:hover, 158 | .bs-sidenav .nav > li > a:focus { 159 | text-decoration: none; 160 | background-color: #e5e3e9; 161 | border-right: 1px solid #dbd8e0; 162 | } 163 | .bs-sidenav .nav > .active > a, 164 | .bs-sidenav .nav > .active:hover > a, 165 | .bs-sidenav .nav > .active:focus > a { 166 | font-weight: bold; 167 | color: #563d7c; 168 | background-color: transparent; 169 | border-right: 1px solid #563d7c; 170 | } 171 | 172 | .bs-sidenav .nav .nav > li > a { 173 | padding-top: 3px; 174 | padding-bottom: 3px; 175 | padding-left: 30px; 176 | font-size: 90%; 177 | } 178 | 179 | .bs-sidenav .nav .nav .nav > li > a { 180 | padding-top: 3px; 181 | padding-bottom: 3px; 182 | padding-left: 40px; 183 | font-size: 90%; 184 | } 185 | 186 | .bs-sidenav .nav .nav .nav .nav > li > a { 187 | padding-top: 3px; 188 | padding-bottom: 3px; 189 | padding-left: 50px; 190 | font-size: 90%; 191 | } 192 | 193 | /* Show and affix the side nav when space allows it */ 194 | @media screen and (min-width: 992px) { 195 | .bs-sidenav .nav > .active > ul { 196 | display: block; 197 | } 198 | /* Widen the fixed sidenav */ 199 | .bs-sidenav.affix, 200 | .bs-sidenav.affix-bottom { 201 | width: 213px; 202 | } 203 | .bs-sidenav.affix { 204 | position: fixed; /* Undo the static from mobile first approach */ 205 | } 206 | .bs-sidenav.affix-bottom { 207 | position: absolute; /* Undo the static from mobile first approach */ 208 | } 209 | .bs-sidenav.affix-bottom .bs-sidenav, 210 | .bs-sidenav.affix .bs-sidenav { 211 | margin-top: 0; 212 | margin-bottom: 0; 213 | } 214 | } 215 | @media screen and (min-width: 1200px) { 216 | /* Widen the fixed sidenav again */ 217 | .bs-sidenav.affix-bottom, 218 | .bs-sidenav.affix { 219 | width: 263px; 220 | } 221 | } 222 | 223 | 224 | -------------------------------------------------------------------------------- /docs/_static/bootstrap-sphinx.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | /** 3 | * Patch TOC list. 4 | * 5 | * Will mutate the underlying span to have a correct ul for nav. 6 | * 7 | * @param $span: Span containing nested UL"s to mutate. 8 | * @param minLevel: Starting level for nested lists. (1: global, 2: local). 9 | */ 10 | var patchToc = function ($ul, minLevel) { 11 | var findA, 12 | patchTables, 13 | $localLi; 14 | 15 | // Find all a "internal" tags, traversing recursively. 16 | findA = function ($elem, level) { 17 | level = level || 0; 18 | var $items = $elem.find("> li > a.internal, > ul, > li > ul"); 19 | 20 | // Iterate everything in order. 21 | $items.each(function (index, item) { 22 | var $item = $(item), 23 | tag = item.tagName.toLowerCase(), 24 | $childrenLi = $item.children("li"), 25 | $parentLi = $($item.parent("li"), $item.parent().parent("li")); 26 | 27 | // Add dropdowns if more children and above minimum level. 28 | if (tag === "ul" && level >= minLevel && $childrenLi.length > 0) { 29 | $parentLi 30 | .addClass("dropdown-submenu") 31 | .children("a").first().attr("tabindex", -1); 32 | 33 | $item.addClass("dropdown-menu"); 34 | } 35 | 36 | findA($item, level + 1); 37 | }); 38 | }; 39 | 40 | findA($ul); 41 | }; 42 | 43 | /** 44 | * Patch all tables to remove ``docutils`` class and add Bootstrap base 45 | * ``table`` class. 46 | */ 47 | patchTables = function () { 48 | $("table.docutils") 49 | .removeClass("docutils") 50 | .addClass("table") 51 | .attr("border", 0); 52 | }; 53 | 54 | $(window).load(function () { 55 | /* 56 | * Scroll the window to avoid the topnav bar 57 | * https://github.com/twbs/bootstrap/issues/1768 58 | */ 59 | if ($("#navbar.navbar-fixed-top").length > 0) { 60 | var navHeight = $("#navbar").height(), 61 | shiftWindow = function() { scrollBy(0, -navHeight - 10); }; 62 | 63 | if (location.hash) { 64 | setTimeout(shiftWindow, 1); 65 | } 66 | 67 | window.addEventListener("hashchange", shiftWindow); 68 | } 69 | }); 70 | 71 | $(document).ready(function () { 72 | // Add styling, structure to TOC"s. 73 | $(".dropdown-menu").each(function () { 74 | $(this).find("ul").each(function (index, item){ 75 | var $item = $(item); 76 | $item.addClass("unstyled"); 77 | }); 78 | }); 79 | 80 | // Global TOC. 81 | if ($("ul.globaltoc li").length) { 82 | patchToc($("ul.globaltoc"), 1); 83 | } else { 84 | // Remove Global TOC. 85 | $(".globaltoc-container").remove(); 86 | } 87 | 88 | // Local TOC. 89 | $(".bs-sidenav ul").addClass("nav nav-list"); 90 | $(".bs-sidenav > ul > li > a").addClass("nav-header"); 91 | 92 | 93 | // back to top 94 | setTimeout(function () { 95 | var $sideBar = $(".bs-sidenav"); 96 | var $content = $(".content"); 97 | 98 | // Enlarge content if sidebar is larger. 99 | if ($sideBar.outerHeight(true) > $content.outerHeight(true)) { 100 | $content.css("min-height", $sideBar.outerHeight(true)); 101 | } 102 | 103 | $sideBar 104 | // Add affix. 105 | .affix({ 106 | offset: { 107 | top: function () { 108 | var offsetTop = $sideBar.offset().top; 109 | var sideBarMargin = parseInt($sideBar.css("margin-top"), 10); 110 | var navOuterHeight = $("#navbar").outerHeight(true); 111 | 112 | return (this.top = offsetTop - navOuterHeight); 113 | }, 114 | bottom: function () { 115 | return (this.bottom = $(".footer").outerHeight(true)); 116 | } 117 | } 118 | }) 119 | // Trigger to reset if page content is scrolled to bottom. 120 | .trigger("scroll.bs.affix.data-api"); 121 | }, 0); 122 | 123 | 124 | // Local TOC. 125 | patchToc($("ul.localtoc"), 2); 126 | 127 | // Mutate sub-lists (for bs-2.3.0). 128 | $(".dropdown-menu ul").not(".dropdown-menu").each(function () { 129 | var $ul = $(this), 130 | $parent = $ul.parent(), 131 | tag = $parent[0].tagName.toLowerCase(), 132 | $kids = $ul.children().detach(); 133 | 134 | // Replace list with items if submenu header. 135 | if (tag === "ul") { 136 | $ul.replaceWith($kids); 137 | } else if (tag === "li") { 138 | // Insert into previous list. 139 | $parent.after($kids); 140 | $ul.remove(); 141 | } 142 | }); 143 | 144 | // Add divider in page TOC. 145 | $localLi = $("ul.localtoc li"); 146 | if ($localLi.length > 2) { 147 | $localLi.first().after("
  • "); 148 | } 149 | 150 | // Patch tables. 151 | patchTables(); 152 | 153 | // Add Note, Warning styles. (BS v2,3 compatible). 154 | $(".admonition").addClass("alert alert-info") 155 | .filter(".warning, .caution") 156 | .removeClass("alert-info") 157 | .addClass("alert-warning").end() 158 | .filter(".error, .danger") 159 | .removeClass("alert-info") 160 | .addClass("alert-danger alert-error").end(); 161 | 162 | // Inline code styles to Bootstrap style. 163 | $("tt.docutils.literal").not(".xref").each(function (i, e) { 164 | // ignore references 165 | if (!$(e).parent().hasClass("reference")) { 166 | $(e).replaceWith(function () { 167 | return $("").html($(this).html()); 168 | }); 169 | }}); 170 | 171 | // Update sourcelink to remove outerdiv (fixes appearance in navbar). 172 | var $srcLink = $(".nav #sourcelink"); 173 | $srcLink.parent().html($srcLink.html()); 174 | }); 175 | }(window.$jqTheme || window.jQuery)); -------------------------------------------------------------------------------- /docs/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/_static/bootswatch-2.3.2/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-2.3.2/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/bootswatch-3.3.7/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/_static/css/style.css: -------------------------------------------------------------------------------- 1 | h1, h2, h3 { 2 | color: #24372C !important; 3 | } 4 | 5 | a { 6 | color: #9d3170 !important; 7 | } 8 | 9 | a:active, a:hover, a:focus { 10 | color: #b84e70 !important; 11 | } 12 | 13 | blockquote { 14 | font-size: 14px !important; 15 | } 16 | 17 | code { 18 | color: #47539d !important; 19 | font-size: 100% !important; 20 | } 21 | 22 | code.descclassname, code.descname { 23 | padding: 2px 0px; 24 | } 25 | 26 | cite, code.docutils.literal:not(.xref) { 27 | padding: 1px 4px !important; 28 | font-size: 80% !important; 29 | color: #000 !important; 30 | background-color: #F5F5F5 !important; 31 | white-space: nowrap !important; 32 | border-radius: 4px !important; 33 | border: 1px solid #CCC !important; 34 | font-style: normal !important; 35 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace !important; 36 | } 37 | 38 | a code.docutils.literal:not(.xref) { 39 | color: #78589d !important; 40 | background: none !important; 41 | border: none !important; 42 | } 43 | 44 | a:active code.docutils.literal:not(.xref), 45 | a:hover code.docutils.literal:not(.xref), 46 | a:focus code.docutils.literal:not(.xref) { 47 | color: #7b2cb8 !important; 48 | } 49 | 50 | #navbar .dropdown-menu > li > a:active code.docutils.literal:not(.xref), 51 | #navbar .dropdown-menu > li > a:hover code.docutils.literal:not(.xref), 52 | #navbar .dropdown-menu > li > a:focus code.docutils.literal:not(.xref) { 53 | color: #FFF !important; 54 | } 55 | 56 | .label { 57 | display: table-cell !important; 58 | color: #000 !important; 59 | font-size: 100% !important; 60 | text-align: left !important; 61 | width: 6em !important; 62 | } 63 | 64 | table.citation { 65 | border-left: 1px solid #DDD !important; 66 | } 67 | 68 | table.citation td > em { 69 | display: none !important; 70 | } 71 | 72 | .table > tbody > tr > td { 73 | border-top: 1px solid #DDD !important; 74 | } 75 | 76 | #navbar { 77 | background: #212337 !important; 78 | border: none !important; 79 | border-bottom: 4px solid #36819d !important; 80 | } 81 | 82 | #navbar a { 83 | color: #FFF !important; 84 | } 85 | 86 | .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { 87 | background-color: #4e4d9d !important; 88 | } 89 | 90 | .navbar-default .navbar-nav > li > a:active { 91 | background-color: #5c519d !important; 92 | } 93 | 94 | #navbar .dropdown-menu > li > a { 95 | color: #57469d !important; 96 | } 97 | 98 | #navbar .dropdown-menu > li > a:hover { 99 | color: #FFF !important; 100 | background-color: #6a8eb8 !important; 101 | } 102 | 103 | .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { 104 | background-color: #3f51b8 !important; 105 | } -------------------------------------------------------------------------------- /docs/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | */ 33 | jQuery.urldecode = function(x) { 34 | return decodeURIComponent(x).replace(/\+/g, ' '); 35 | }; 36 | 37 | /** 38 | * small helper function to urlencode strings 39 | */ 40 | jQuery.urlencode = encodeURIComponent; 41 | 42 | /** 43 | * This function returns the parsed url parameters of the 44 | * current request. Multiple values per key are supported, 45 | * it will always return arrays of strings for the value parts. 46 | */ 47 | jQuery.getQueryParameters = function(s) { 48 | if (typeof s === 'undefined') 49 | s = document.location.search; 50 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 51 | var result = {}; 52 | for (var i = 0; i < parts.length; i++) { 53 | var tmp = parts[i].split('=', 2); 54 | var key = jQuery.urldecode(tmp[0]); 55 | var value = jQuery.urldecode(tmp[1]); 56 | if (key in result) 57 | result[key].push(value); 58 | else 59 | result[key] = [value]; 60 | } 61 | return result; 62 | }; 63 | 64 | /** 65 | * highlight a given string on a jquery object by wrapping it in 66 | * span elements with the given class name. 67 | */ 68 | jQuery.fn.highlightText = function(text, className) { 69 | function highlight(node, addItems) { 70 | if (node.nodeType === 3) { 71 | var val = node.nodeValue; 72 | var pos = val.toLowerCase().indexOf(text); 73 | if (pos >= 0 && 74 | !jQuery(node.parentNode).hasClass(className) && 75 | !jQuery(node.parentNode).hasClass("nohighlight")) { 76 | var span; 77 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); 78 | if (isInSVG) { 79 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 80 | } else { 81 | span = document.createElement("span"); 82 | span.className = className; 83 | } 84 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 85 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 86 | document.createTextNode(val.substr(pos + text.length)), 87 | node.nextSibling)); 88 | node.nodeValue = val.substr(0, pos); 89 | if (isInSVG) { 90 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); 91 | var bbox = node.parentElement.getBBox(); 92 | rect.x.baseVal.value = bbox.x; 93 | rect.y.baseVal.value = bbox.y; 94 | rect.width.baseVal.value = bbox.width; 95 | rect.height.baseVal.value = bbox.height; 96 | rect.setAttribute('class', className); 97 | addItems.push({ 98 | "parent": node.parentNode, 99 | "target": rect}); 100 | } 101 | } 102 | } 103 | else if (!jQuery(node).is("button, select, textarea")) { 104 | jQuery.each(node.childNodes, function() { 105 | highlight(this, addItems); 106 | }); 107 | } 108 | } 109 | var addItems = []; 110 | var result = this.each(function() { 111 | highlight(this, addItems); 112 | }); 113 | for (var i = 0; i < addItems.length; ++i) { 114 | jQuery(addItems[i].parent).before(addItems[i].target); 115 | } 116 | return result; 117 | }; 118 | 119 | /* 120 | * backward compatibility for jQuery.browser 121 | * This will be supported until firefox bug is fixed. 122 | */ 123 | if (!jQuery.browser) { 124 | jQuery.uaMatch = function(ua) { 125 | ua = ua.toLowerCase(); 126 | 127 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 128 | /(webkit)[ \/]([\w.]+)/.exec(ua) || 129 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 130 | /(msie) ([\w.]+)/.exec(ua) || 131 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || 132 | []; 133 | 134 | return { 135 | browser: match[ 1 ] || "", 136 | version: match[ 2 ] || "0" 137 | }; 138 | }; 139 | jQuery.browser = {}; 140 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; 141 | } 142 | 143 | /** 144 | * Small JavaScript module for the documentation. 145 | */ 146 | var Documentation = { 147 | 148 | init : function() { 149 | this.fixFirefoxAnchorBug(); 150 | this.highlightSearchWords(); 151 | this.initIndexTable(); 152 | if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { 153 | this.initOnKeyListeners(); 154 | } 155 | }, 156 | 157 | /** 158 | * i18n support 159 | */ 160 | TRANSLATIONS : {}, 161 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, 162 | LOCALE : 'unknown', 163 | 164 | // gettext and ngettext don't access this so that the functions 165 | // can safely bound to a different name (_ = Documentation.gettext) 166 | gettext : function(string) { 167 | var translated = Documentation.TRANSLATIONS[string]; 168 | if (typeof translated === 'undefined') 169 | return string; 170 | return (typeof translated === 'string') ? translated : translated[0]; 171 | }, 172 | 173 | ngettext : function(singular, plural, n) { 174 | var translated = Documentation.TRANSLATIONS[singular]; 175 | if (typeof translated === 'undefined') 176 | return (n == 1) ? singular : plural; 177 | return translated[Documentation.PLURALEXPR(n)]; 178 | }, 179 | 180 | addTranslations : function(catalog) { 181 | for (var key in catalog.messages) 182 | this.TRANSLATIONS[key] = catalog.messages[key]; 183 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 184 | this.LOCALE = catalog.locale; 185 | }, 186 | 187 | /** 188 | * add context elements like header anchor links 189 | */ 190 | addContextElements : function() { 191 | $('div[id] > :header:first').each(function() { 192 | $('\u00B6'). 193 | attr('href', '#' + this.id). 194 | attr('title', _('Permalink to this headline')). 195 | appendTo(this); 196 | }); 197 | $('dt[id]').each(function() { 198 | $('\u00B6'). 199 | attr('href', '#' + this.id). 200 | attr('title', _('Permalink to this definition')). 201 | appendTo(this); 202 | }); 203 | }, 204 | 205 | /** 206 | * workaround a firefox stupidity 207 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 208 | */ 209 | fixFirefoxAnchorBug : function() { 210 | if (document.location.hash && $.browser.mozilla) 211 | window.setTimeout(function() { 212 | document.location.href += ''; 213 | }, 10); 214 | }, 215 | 216 | /** 217 | * highlight the search words provided in the url in the text 218 | */ 219 | highlightSearchWords : function() { 220 | var params = $.getQueryParameters(); 221 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 222 | if (terms.length) { 223 | var body = $('div.body'); 224 | if (!body.length) { 225 | body = $('body'); 226 | } 227 | window.setTimeout(function() { 228 | $.each(terms, function() { 229 | body.highlightText(this.toLowerCase(), 'highlighted'); 230 | }); 231 | }, 10); 232 | $('') 234 | .appendTo($('#searchbox')); 235 | } 236 | }, 237 | 238 | /** 239 | * init the domain index toggle buttons 240 | */ 241 | initIndexTable : function() { 242 | var togglers = $('img.toggler').click(function() { 243 | var src = $(this).attr('src'); 244 | var idnum = $(this).attr('id').substr(7); 245 | $('tr.cg-' + idnum).toggle(); 246 | if (src.substr(-9) === 'minus.png') 247 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 248 | else 249 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 250 | }).css('display', ''); 251 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 252 | togglers.click(); 253 | } 254 | }, 255 | 256 | /** 257 | * helper function to hide the search marks again 258 | */ 259 | hideSearchWords : function() { 260 | $('#searchbox .highlight-link').fadeOut(300); 261 | $('span.highlighted').removeClass('highlighted'); 262 | }, 263 | 264 | /** 265 | * make the url absolute 266 | */ 267 | makeURL : function(relativeURL) { 268 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 269 | }, 270 | 271 | /** 272 | * get the current relative url 273 | */ 274 | getCurrentURL : function() { 275 | var path = document.location.pathname; 276 | var parts = path.split(/\//); 277 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 278 | if (this === '..') 279 | parts.pop(); 280 | }); 281 | var url = parts.join('/'); 282 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 283 | }, 284 | 285 | initOnKeyListeners: function() { 286 | $(document).keyup(function(event) { 287 | var activeElementType = document.activeElement.tagName; 288 | // don't navigate when in search box or textarea 289 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { 290 | switch (event.keyCode) { 291 | case 37: // left 292 | var prevHref = $('link[rel="prev"]').prop('href'); 293 | if (prevHref) { 294 | window.location.href = prevHref; 295 | return false; 296 | } 297 | case 39: // right 298 | var nextHref = $('link[rel="next"]').prop('href'); 299 | if (nextHref) { 300 | window.location.href = nextHref; 301 | return false; 302 | } 303 | } 304 | } 305 | }); 306 | } 307 | }; 308 | 309 | // quick alias for translations 310 | _ = Documentation.gettext; 311 | 312 | $(document).ready(function() { 313 | Documentation.init(); 314 | }); 315 | -------------------------------------------------------------------------------- /docs/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '2.1.12', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | HAS_SOURCE: true, 9 | SOURCELINK_SUFFIX: '', 10 | NAVIGATION_WITH_KEYS: false 11 | }; -------------------------------------------------------------------------------- /docs/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/file.png -------------------------------------------------------------------------------- /docs/_static/graphviz.css: -------------------------------------------------------------------------------- 1 | /* 2 | * graphviz.css 3 | * ~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- graphviz extension. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | img.graphviz { 13 | border: 0; 14 | max-width: 100%; 15 | } 16 | 17 | object.graphviz { 18 | max-width: 100%; 19 | } 20 | -------------------------------------------------------------------------------- /docs/_static/js/jquery-fix.js: -------------------------------------------------------------------------------- 1 | // No Conflict in later (our) version of jQuery 2 | window.$jqTheme = jQuery.noConflict(true); -------------------------------------------------------------------------------- /docs/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/minus.png -------------------------------------------------------------------------------- /docs/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/_static/plus.png -------------------------------------------------------------------------------- /docs/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #f8f8f8; } 3 | .highlight .c { color: #8f5902; font-style: italic } /* Comment */ 4 | .highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ 5 | .highlight .g { color: #000000 } /* Generic */ 6 | .highlight .k { color: #204a87; font-weight: bold } /* Keyword */ 7 | .highlight .l { color: #000000 } /* Literal */ 8 | .highlight .n { color: #000000 } /* Name */ 9 | .highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ 10 | .highlight .x { color: #000000 } /* Other */ 11 | .highlight .p { color: #000000; font-weight: bold } /* Punctuation */ 12 | .highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ 13 | .highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ 14 | .highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ 15 | .highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ 16 | .highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ 17 | .highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ 18 | .highlight .gd { color: #a40000 } /* Generic.Deleted */ 19 | .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ 20 | .highlight .gr { color: #ef2929 } /* Generic.Error */ 21 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 22 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 23 | .highlight .go { color: #000000; font-style: italic } /* Generic.Output */ 24 | .highlight .gp { color: #8f5902 } /* Generic.Prompt */ 25 | .highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ 26 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 27 | .highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ 28 | .highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ 29 | .highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ 30 | .highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ 31 | .highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ 32 | .highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ 33 | .highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ 34 | .highlight .ld { color: #000000 } /* Literal.Date */ 35 | .highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ 36 | .highlight .s { color: #4e9a06 } /* Literal.String */ 37 | .highlight .na { color: #c4a000 } /* Name.Attribute */ 38 | .highlight .nb { color: #204a87 } /* Name.Builtin */ 39 | .highlight .nc { color: #000000 } /* Name.Class */ 40 | .highlight .no { color: #000000 } /* Name.Constant */ 41 | .highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ 42 | .highlight .ni { color: #ce5c00 } /* Name.Entity */ 43 | .highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ 44 | .highlight .nf { color: #000000 } /* Name.Function */ 45 | .highlight .nl { color: #f57900 } /* Name.Label */ 46 | .highlight .nn { color: #000000 } /* Name.Namespace */ 47 | .highlight .nx { color: #000000 } /* Name.Other */ 48 | .highlight .py { color: #000000 } /* Name.Property */ 49 | .highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ 50 | .highlight .nv { color: #000000 } /* Name.Variable */ 51 | .highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ 52 | .highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ 53 | .highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ 54 | .highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ 55 | .highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ 56 | .highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ 57 | .highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ 58 | .highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ 59 | .highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ 60 | .highlight .sc { color: #4e9a06 } /* Literal.String.Char */ 61 | .highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ 62 | .highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ 63 | .highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ 64 | .highlight .se { color: #4e9a06 } /* Literal.String.Escape */ 65 | .highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ 66 | .highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ 67 | .highlight .sx { color: #4e9a06 } /* Literal.String.Other */ 68 | .highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ 69 | .highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ 70 | .highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ 71 | .highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ 72 | .highlight .fm { color: #000000 } /* Name.Function.Magic */ 73 | .highlight .vc { color: #000000 } /* Name.Variable.Class */ 74 | .highlight .vg { color: #000000 } /* Name.Variable.Global */ 75 | .highlight .vi { color: #000000 } /* Name.Variable.Instance */ 76 | .highlight .vm { color: #000000 } /* Name.Variable.Magic */ 77 | .highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/docs/objects.inv -------------------------------------------------------------------------------- /docsrc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = BenchlingPyAPI 8 | SOURCEDIR = . 9 | BUILDDIR = ../docs 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | 22 | 23 | html: 24 | # Remove autogenerated autosummary files. Without removal, these files will not be updated 25 | rm -rf $(SOURCEDIR)/developer/_autosummary 26 | 27 | # build the documentation 28 | @$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 29 | 30 | @echo 31 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html" -------------------------------------------------------------------------------- /docsrc/_static/css/style.css: -------------------------------------------------------------------------------- 1 | h1, h2, h3 { 2 | color: #24372C !important; 3 | } 4 | 5 | a { 6 | color: #9d3170 !important; 7 | } 8 | 9 | a:active, a:hover, a:focus { 10 | color: #b84e70 !important; 11 | } 12 | 13 | blockquote { 14 | font-size: 14px !important; 15 | } 16 | 17 | code { 18 | color: #47539d !important; 19 | font-size: 100% !important; 20 | } 21 | 22 | code.descclassname, code.descname { 23 | padding: 2px 0px; 24 | } 25 | 26 | cite, code.docutils.literal:not(.xref) { 27 | padding: 1px 4px !important; 28 | font-size: 80% !important; 29 | color: #000 !important; 30 | background-color: #F5F5F5 !important; 31 | white-space: nowrap !important; 32 | border-radius: 4px !important; 33 | border: 1px solid #CCC !important; 34 | font-style: normal !important; 35 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace !important; 36 | } 37 | 38 | a code.docutils.literal:not(.xref) { 39 | color: #78589d !important; 40 | background: none !important; 41 | border: none !important; 42 | } 43 | 44 | a:active code.docutils.literal:not(.xref), 45 | a:hover code.docutils.literal:not(.xref), 46 | a:focus code.docutils.literal:not(.xref) { 47 | color: #7b2cb8 !important; 48 | } 49 | 50 | #navbar .dropdown-menu > li > a:active code.docutils.literal:not(.xref), 51 | #navbar .dropdown-menu > li > a:hover code.docutils.literal:not(.xref), 52 | #navbar .dropdown-menu > li > a:focus code.docutils.literal:not(.xref) { 53 | color: #FFF !important; 54 | } 55 | 56 | .label { 57 | display: table-cell !important; 58 | color: #000 !important; 59 | font-size: 100% !important; 60 | text-align: left !important; 61 | width: 6em !important; 62 | } 63 | 64 | table.citation { 65 | border-left: 1px solid #DDD !important; 66 | } 67 | 68 | table.citation td > em { 69 | display: none !important; 70 | } 71 | 72 | .table > tbody > tr > td { 73 | border-top: 1px solid #DDD !important; 74 | } 75 | 76 | #navbar { 77 | background: #212337 !important; 78 | border: none !important; 79 | border-bottom: 4px solid #36819d !important; 80 | } 81 | 82 | #navbar a { 83 | color: #FFF !important; 84 | } 85 | 86 | .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { 87 | background-color: #4e4d9d !important; 88 | } 89 | 90 | .navbar-default .navbar-nav > li > a:active { 91 | background-color: #5c519d !important; 92 | } 93 | 94 | #navbar .dropdown-menu > li > a { 95 | color: #57469d !important; 96 | } 97 | 98 | #navbar .dropdown-menu > li > a:hover { 99 | color: #FFF !important; 100 | background-color: #6a8eb8 !important; 101 | } 102 | 103 | .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { 104 | background-color: #3f51b8 !important; 105 | } -------------------------------------------------------------------------------- /docsrc/_templates/module.rst: -------------------------------------------------------------------------------- 1 | {{ fullname }} 2 | {{ underline }} 3 | 4 | .. contents:: 5 | :local: 6 | 7 | .. automodule:: {{fullname}} 8 | 9 | Members 10 | ======= 11 | -------------------------------------------------------------------------------- /docsrc/_templates/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |
    5 |

    Python BenchlingAPI 6 |

    7 |
    8 |
    9 | 10 | 11 |
    12 | 13 |
    -------------------------------------------------------------------------------- /docsrc/developer/api_reference.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | Modules 5 | ------- 6 | 7 | .. automodule:: benchlingapi 8 | :members: 9 | :noindex: 10 | -------------------------------------------------------------------------------- /docsrc/developer/changelog.md: -------------------------------------------------------------------------------- 1 | # benchlingapi change log 2 | ## 2.1.12 3 | **2020-02-12T16:15:11.847504** 4 | changes to Session initialization 5 | 6 | - Users can now specify the home url for the Benchling Session instance. Use Session(api_key, org='myorg') to specify the home url 'myorg.benchling.com/api/v2'. User Session(api_key, home='myorg.benchling.com/api/v2') to specify the home url directly. 7 | 8 | 9 | ## 2.1.11 10 | **2019-12-18T13:34:41.244797** 11 | hotfix sharelink bug 12 | 13 | 14 | 15 | 16 | ## 2.1.10 17 | **2019-12-17T17:26:29.569759** 18 | fix previous release 19 | 20 | 21 | 22 | 23 | ## 2.1.9 24 | **2019-12-17T17:16:09.386482** 25 | fixes sharelink bugs 26 | 27 | 28 | 29 | 30 | ## 2.1.8 31 | **2019-12-17T17:10:53.952392** 32 | re-release of 2.1.7 (fixes broken branch) 33 | 34 | 35 | 36 | 37 | ## 2.1.7 38 | **2019-12-17T17:07:16.144945** 39 | bug fixes 40 | 41 | - fixes loading DNASequences from share_links 42 | 43 | 44 | ## 2.1.6 45 | **2019-12-16T17:06:05.925041** 46 | bug fixes 47 | 48 | - updates DNASequence to work with latest Benchling API update 49 | 50 | 51 | ## 2.1.5 52 | **2019-12-12T14:18:00.136712** 53 | 54 | 55 | - added 'merge' method to entities 56 | - fixed bug that arose iwhen trying to save an entity containing fields 57 | 58 | 59 | ## 2.1.4 60 | **2019-12-12T14:16:27.446507** 61 | feature and bug fixes 62 | 63 | 64 | 65 | 66 | ## 2.1.3 67 | **2019-10-23T16:08:47.898865** 68 | fixes bug with DNASequence.archived_reason 69 | 70 | - typo in archive_reason 71 | 72 | 73 | ## 2.1.2 74 | **2019-10-18T13:44:46.826684** 75 | bug fixes 76 | 77 | - fixes bug where parameters in get_pages was not being inherited 78 | - adds new 'all_in_registry' function 79 | 80 | 81 | ## 2.1.1 82 | **2019-10-17T19:36:37.900149** 83 | Python 3.5, 3.6, 3.7 support 84 | 85 | 86 | 87 | 88 | ## 2.1 89 | **2019-10-17T12:42:35.238592** 90 | Update marshamllow to 3.2 91 | 92 | 93 | 94 | 95 | ## 2.0.1 96 | **2019-10-16T08:02:35.118447** 97 | Bug fixes 98 | 99 | - fixed issue where nested data keys were not properly formatted to and from the benchling server 100 | 101 | 102 | ## 2.0.0 103 | **2019-10-15T21:08:34.511953** 104 | Second major release 105 | 106 | - all attribute names now lower-underscore case 107 | - refactoring and bug fixes 108 | - updates to interface 109 | - uses benchling api V2 110 | -------------------------------------------------------------------------------- /docsrc/exceptions.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.exceptions -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.AASequence.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.AASequence 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: AASequence 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~AASequence.__init__ 17 | ~AASequence.add_alias 18 | ~AASequence.all 19 | ~AASequence.archive 20 | ~AASequence.archive_many 21 | ~AASequence.batches 22 | ~AASequence.bulk_create 23 | ~AASequence.copy 24 | ~AASequence.create_model 25 | ~AASequence.dump 26 | ~AASequence.find 27 | ~AASequence.find_by_name 28 | ~AASequence.find_by_name_in_registry 29 | ~AASequence.find_in_registry 30 | ~AASequence.first 31 | ~AASequence.get 32 | ~AASequence.get_in_registry 33 | ~AASequence.last 34 | ~AASequence.list 35 | ~AASequence.list_archived 36 | ~AASequence.list_in_registry 37 | ~AASequence.list_pages 38 | ~AASequence.load 39 | ~AASequence.load_many 40 | ~AASequence.move 41 | ~AASequence.one 42 | ~AASequence.open 43 | ~AASequence.print_valid_schemas 44 | ~AASequence.register 45 | ~AASequence.register_and_save_name_as_alias 46 | ~AASequence.register_with_custom_id 47 | ~AASequence.registry_dict 48 | ~AASequence.reload 49 | ~AASequence.save 50 | ~AASequence.save_json 51 | ~AASequence.search 52 | ~AASequence.set_schema 53 | ~AASequence.unarchive 54 | ~AASequence.unarchive_many 55 | ~AASequence.unregister 56 | ~AASequence.update 57 | ~AASequence.update_json 58 | ~AASequence.update_model 59 | ~AASequence.valid_schemas 60 | 61 | 62 | 63 | 64 | 65 | .. rubric:: Attributes 66 | 67 | .. autosummary:: 68 | 69 | ~AASequence.CREATE_SCHEMA 70 | ~AASequence.ENTITY_TYPE 71 | ~AASequence.MAX_PAGE_SIZE 72 | ~AASequence.UPDATE_SCHEMA 73 | ~AASequence.alias 74 | ~AASequence.archive_reason 75 | ~AASequence.is_archived 76 | ~AASequence.is_registered 77 | ~AASequence.model_name 78 | ~AASequence.registry 79 | ~AASequence.session 80 | 81 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Annotation.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Annotation 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Annotation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Annotation.__init__ 17 | ~Annotation.copy 18 | ~Annotation.dump 19 | ~Annotation.load 20 | ~Annotation.load_many 21 | ~Annotation.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~Annotation.alias 32 | ~Annotation.model_name 33 | ~Annotation.session 34 | 35 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.CustomEntity.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.CustomEntity 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: CustomEntity 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~CustomEntity.__init__ 17 | ~CustomEntity.add_alias 18 | ~CustomEntity.all 19 | ~CustomEntity.archive 20 | ~CustomEntity.archive_many 21 | ~CustomEntity.batches 22 | ~CustomEntity.bulk_create 23 | ~CustomEntity.copy 24 | ~CustomEntity.create_model 25 | ~CustomEntity.dump 26 | ~CustomEntity.find 27 | ~CustomEntity.find_by_name 28 | ~CustomEntity.find_by_name_in_registry 29 | ~CustomEntity.find_in_registry 30 | ~CustomEntity.first 31 | ~CustomEntity.get 32 | ~CustomEntity.get_in_registry 33 | ~CustomEntity.last 34 | ~CustomEntity.list 35 | ~CustomEntity.list_archived 36 | ~CustomEntity.list_in_registry 37 | ~CustomEntity.list_pages 38 | ~CustomEntity.load 39 | ~CustomEntity.load_many 40 | ~CustomEntity.move 41 | ~CustomEntity.one 42 | ~CustomEntity.open 43 | ~CustomEntity.print_valid_schemas 44 | ~CustomEntity.register 45 | ~CustomEntity.register_and_save_name_as_alias 46 | ~CustomEntity.register_with_custom_id 47 | ~CustomEntity.registry_dict 48 | ~CustomEntity.reload 49 | ~CustomEntity.save 50 | ~CustomEntity.save_json 51 | ~CustomEntity.search 52 | ~CustomEntity.set_schema 53 | ~CustomEntity.unarchive 54 | ~CustomEntity.unarchive_many 55 | ~CustomEntity.unregister 56 | ~CustomEntity.update 57 | ~CustomEntity.update_json 58 | ~CustomEntity.update_model 59 | ~CustomEntity.valid_schemas 60 | 61 | 62 | 63 | 64 | 65 | .. rubric:: Attributes 66 | 67 | .. autosummary:: 68 | 69 | ~CustomEntity.CREATE_SCHEMA 70 | ~CustomEntity.ENTITY_TYPE 71 | ~CustomEntity.MAX_PAGE_SIZE 72 | ~CustomEntity.UPDATE_SCHEMA 73 | ~CustomEntity.alias 74 | ~CustomEntity.archive_reason 75 | ~CustomEntity.is_archived 76 | ~CustomEntity.is_registered 77 | ~CustomEntity.model_name 78 | ~CustomEntity.registry 79 | ~CustomEntity.session 80 | 81 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.DNAAlignment.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.DNAAlignment 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: DNAAlignment 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNAAlignment.__init__ 17 | ~DNAAlignment.copy 18 | ~DNAAlignment.delete 19 | ~DNAAlignment.dump 20 | ~DNAAlignment.find 21 | ~DNAAlignment.get 22 | ~DNAAlignment.load 23 | ~DNAAlignment.load_many 24 | ~DNAAlignment.reload 25 | ~DNAAlignment.submit_alignment 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~DNAAlignment.CLUSTALO 36 | ~DNAAlignment.MAFFT 37 | ~DNAAlignment.alias 38 | ~DNAAlignment.model_name 39 | ~DNAAlignment.session 40 | 41 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.DNASequence.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.DNASequence 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: DNASequence 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNASequence.__init__ 17 | ~DNASequence.add_alias 18 | ~DNASequence.all 19 | ~DNASequence.archive 20 | ~DNASequence.archive_many 21 | ~DNASequence.batches 22 | ~DNASequence.bulk_create 23 | ~DNASequence.copy 24 | ~DNASequence.create_model 25 | ~DNASequence.dump 26 | ~DNASequence.find 27 | ~DNASequence.find_by_name 28 | ~DNASequence.find_by_name_in_registry 29 | ~DNASequence.find_in_registry 30 | ~DNASequence.first 31 | ~DNASequence.from_share_link 32 | ~DNASequence.get 33 | ~DNASequence.get_in_registry 34 | ~DNASequence.last 35 | ~DNASequence.list 36 | ~DNASequence.list_archived 37 | ~DNASequence.list_in_registry 38 | ~DNASequence.list_pages 39 | ~DNASequence.load 40 | ~DNASequence.load_many 41 | ~DNASequence.move 42 | ~DNASequence.one 43 | ~DNASequence.open 44 | ~DNASequence.print_valid_schemas 45 | ~DNASequence.register 46 | ~DNASequence.register_and_save_name_as_alias 47 | ~DNASequence.register_with_custom_id 48 | ~DNASequence.registry_dict 49 | ~DNASequence.reload 50 | ~DNASequence.save 51 | ~DNASequence.save_json 52 | ~DNASequence.search 53 | ~DNASequence.set_schema 54 | ~DNASequence.unarchive 55 | ~DNASequence.unarchive_many 56 | ~DNASequence.unregister 57 | ~DNASequence.update 58 | ~DNASequence.update_json 59 | ~DNASequence.update_model 60 | ~DNASequence.valid_schemas 61 | 62 | 63 | 64 | 65 | 66 | .. rubric:: Attributes 67 | 68 | .. autosummary:: 69 | 70 | ~DNASequence.CREATE_SCHEMA 71 | ~DNASequence.ENTITY_TYPE 72 | ~DNASequence.MAX_PAGE_SIZE 73 | ~DNASequence.UPDATE_SCHEMA 74 | ~DNASequence.alias 75 | ~DNASequence.archive_reason 76 | ~DNASequence.is_archived 77 | ~DNASequence.is_registered 78 | ~DNASequence.model_name 79 | ~DNASequence.registry 80 | ~DNASequence.session 81 | 82 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.EntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.EntitySchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: EntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchema.__init__ 17 | ~EntitySchema.copy 18 | ~EntitySchema.dump 19 | ~EntitySchema.load 20 | ~EntitySchema.load_many 21 | ~EntitySchema.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~EntitySchema.alias 32 | ~EntitySchema.model_name 33 | ~EntitySchema.session 34 | 35 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Oligo.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Oligo 2 | ================================ 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Oligo 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Oligo.__init__ 17 | ~Oligo.bulk_create 18 | ~Oligo.copy 19 | ~Oligo.create_model 20 | ~Oligo.dump 21 | ~Oligo.find 22 | ~Oligo.find_by_name_in_registry 23 | ~Oligo.find_in_registry 24 | ~Oligo.get 25 | ~Oligo.get_in_registry 26 | ~Oligo.list_in_registry 27 | ~Oligo.load 28 | ~Oligo.load_many 29 | ~Oligo.move 30 | ~Oligo.print_valid_schemas 31 | ~Oligo.register 32 | ~Oligo.register_and_save_name_as_alias 33 | ~Oligo.register_with_custom_id 34 | ~Oligo.registry_dict 35 | ~Oligo.reload 36 | ~Oligo.save 37 | ~Oligo.save_json 38 | ~Oligo.set_schema 39 | ~Oligo.unregister 40 | ~Oligo.valid_schemas 41 | 42 | 43 | 44 | 45 | 46 | .. rubric:: Attributes 47 | 48 | .. autosummary:: 49 | 50 | ~Oligo.CREATE_SCHEMA 51 | ~Oligo.ENTITY_TYPE 52 | ~Oligo.alias 53 | ~Oligo.is_registered 54 | ~Oligo.model_name 55 | ~Oligo.registry 56 | ~Oligo.session 57 | 58 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Project.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Project 2 | ================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Project 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Project.__init__ 17 | ~Project.all 18 | ~Project.archive 19 | ~Project.archive_many 20 | ~Project.copy 21 | ~Project.dump 22 | ~Project.find 23 | ~Project.find_by_name 24 | ~Project.first 25 | ~Project.get 26 | ~Project.last 27 | ~Project.list 28 | ~Project.list_pages 29 | ~Project.load 30 | ~Project.load_many 31 | ~Project.one 32 | ~Project.reload 33 | ~Project.search 34 | ~Project.unarchive 35 | ~Project.unarchive_many 36 | 37 | 38 | 39 | 40 | 41 | .. rubric:: Attributes 42 | 43 | .. autosummary:: 44 | 45 | ~Project.MAX_PAGE_SIZE 46 | ~Project.alias 47 | ~Project.archive_reason 48 | ~Project.is_archived 49 | ~Project.model_name 50 | ~Project.session 51 | 52 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Registry.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Registry 2 | =================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Registry 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Registry.__init__ 17 | ~Registry.all 18 | ~Registry.copy 19 | ~Registry.dump 20 | ~Registry.find 21 | ~Registry.find_by_name 22 | ~Registry.find_from_schema_id 23 | ~Registry.find_in_registry 24 | ~Registry.find_registry 25 | ~Registry.first 26 | ~Registry.get 27 | ~Registry.get_entities 28 | ~Registry.get_schema 29 | ~Registry.last 30 | ~Registry.list 31 | ~Registry.list_pages 32 | ~Registry.load 33 | ~Registry.load_many 34 | ~Registry.one 35 | ~Registry.register 36 | ~Registry.register_entities 37 | ~Registry.reload 38 | ~Registry.search 39 | ~Registry.unregister 40 | ~Registry.unregister_entities 41 | 42 | 43 | 44 | 45 | 46 | .. rubric:: Attributes 47 | 48 | .. autosummary:: 49 | 50 | ~Registry.MAX_PAGE_SIZE 51 | ~Registry.alias 52 | ~Registry.entity_schemas 53 | ~Registry.model_name 54 | ~Registry.session 55 | 56 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Task.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Task 2 | =============================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Task 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Task.__init__ 17 | ~Task.copy 18 | ~Task.dump 19 | ~Task.find 20 | ~Task.get 21 | ~Task.load 22 | ~Task.load_many 23 | ~Task.reload 24 | ~Task.wait 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~Task.alias 35 | ~Task.model_name 36 | ~Task.session 37 | 38 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.models.Translation.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.models.Translation 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.models 5 | 6 | .. autoclass:: Translation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Translation.__init__ 17 | ~Translation.copy 18 | ~Translation.dump 19 | ~Translation.load 20 | ~Translation.load_many 21 | ~Translation.reload 22 | 23 | 24 | 25 | 26 | 27 | .. rubric:: Attributes 28 | 29 | .. autosummary:: 30 | 31 | ~Translation.alias 32 | ~Translation.model_name 33 | ~Translation.session 34 | 35 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.AASequenceSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.AASequenceSchema 2 | =========================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: AASequenceSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~AASequenceSchema.__init__ 17 | ~AASequenceSchema.dump 18 | ~AASequenceSchema.dumps 19 | ~AASequenceSchema.get_attribute 20 | ~AASequenceSchema.get_model_name 21 | ~AASequenceSchema.get_schema_id 22 | ~AASequenceSchema.handle_error 23 | ~AASequenceSchema.load 24 | ~AASequenceSchema.load_model 25 | ~AASequenceSchema.loads 26 | ~AASequenceSchema.on_bind_field 27 | ~AASequenceSchema.remove_ignore 28 | ~AASequenceSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~AASequenceSchema.TYPE_MAPPING 39 | ~AASequenceSchema.dict_class 40 | ~AASequenceSchema.opts 41 | ~AASequenceSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.BatchSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.BatchSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: BatchSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~BatchSchema.__init__ 17 | ~BatchSchema.dump 18 | ~BatchSchema.dumps 19 | ~BatchSchema.get_attribute 20 | ~BatchSchema.get_schema_id 21 | ~BatchSchema.handle_error 22 | ~BatchSchema.load 23 | ~BatchSchema.loads 24 | ~BatchSchema.on_bind_field 25 | ~BatchSchema.validate 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~BatchSchema.TYPE_MAPPING 36 | ~BatchSchema.dict_class 37 | ~BatchSchema.opts 38 | ~BatchSchema.set_class 39 | 40 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.CustomEntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.CustomEntitySchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: CustomEntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~CustomEntitySchema.__init__ 17 | ~CustomEntitySchema.dump 18 | ~CustomEntitySchema.dumps 19 | ~CustomEntitySchema.get_attribute 20 | ~CustomEntitySchema.get_model_name 21 | ~CustomEntitySchema.get_schema_id 22 | ~CustomEntitySchema.handle_error 23 | ~CustomEntitySchema.load 24 | ~CustomEntitySchema.load_model 25 | ~CustomEntitySchema.loads 26 | ~CustomEntitySchema.on_bind_field 27 | ~CustomEntitySchema.remove_ignore 28 | ~CustomEntitySchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~CustomEntitySchema.TYPE_MAPPING 39 | ~CustomEntitySchema.dict_class 40 | ~CustomEntitySchema.opts 41 | ~CustomEntitySchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.DNAAlignmentSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.DNAAlignmentSchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: DNAAlignmentSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNAAlignmentSchema.__init__ 17 | ~DNAAlignmentSchema.dump 18 | ~DNAAlignmentSchema.dumps 19 | ~DNAAlignmentSchema.from_dict 20 | ~DNAAlignmentSchema.get_attribute 21 | ~DNAAlignmentSchema.get_model_name 22 | ~DNAAlignmentSchema.handle_error 23 | ~DNAAlignmentSchema.load 24 | ~DNAAlignmentSchema.load_model 25 | ~DNAAlignmentSchema.loads 26 | ~DNAAlignmentSchema.on_bind_field 27 | ~DNAAlignmentSchema.remove_ignore 28 | ~DNAAlignmentSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~DNAAlignmentSchema.TYPE_MAPPING 39 | ~DNAAlignmentSchema.dict_class 40 | ~DNAAlignmentSchema.error_messages 41 | ~DNAAlignmentSchema.opts 42 | ~DNAAlignmentSchema.set_class 43 | 44 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.DNASequenceSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.DNASequenceSchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: DNASequenceSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~DNASequenceSchema.__init__ 17 | ~DNASequenceSchema.dump 18 | ~DNASequenceSchema.dumps 19 | ~DNASequenceSchema.get_attribute 20 | ~DNASequenceSchema.get_model_name 21 | ~DNASequenceSchema.get_schema_id 22 | ~DNASequenceSchema.handle_error 23 | ~DNASequenceSchema.load 24 | ~DNASequenceSchema.load_model 25 | ~DNASequenceSchema.loads 26 | ~DNASequenceSchema.on_bind_field 27 | ~DNASequenceSchema.remove_ignore 28 | ~DNASequenceSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~DNASequenceSchema.TYPE_MAPPING 39 | ~DNASequenceSchema.dict_class 40 | ~DNASequenceSchema.opts 41 | ~DNASequenceSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.EntitySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.EntitySchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: EntitySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchema.__init__ 17 | ~EntitySchema.dump 18 | ~EntitySchema.dumps 19 | ~EntitySchema.get_attribute 20 | ~EntitySchema.get_schema_id 21 | ~EntitySchema.handle_error 22 | ~EntitySchema.load 23 | ~EntitySchema.loads 24 | ~EntitySchema.on_bind_field 25 | ~EntitySchema.validate 26 | 27 | 28 | 29 | 30 | 31 | .. rubric:: Attributes 32 | 33 | .. autosummary:: 34 | 35 | ~EntitySchema.TYPE_MAPPING 36 | ~EntitySchema.dict_class 37 | ~EntitySchema.opts 38 | ~EntitySchema.set_class 39 | 40 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.EntitySchemaSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.EntitySchemaSchema 2 | ============================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: EntitySchemaSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~EntitySchemaSchema.__init__ 17 | ~EntitySchemaSchema.dump 18 | ~EntitySchemaSchema.dumps 19 | ~EntitySchemaSchema.get_attribute 20 | ~EntitySchemaSchema.handle_error 21 | ~EntitySchemaSchema.load 22 | ~EntitySchemaSchema.loads 23 | ~EntitySchemaSchema.on_bind_field 24 | ~EntitySchemaSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~EntitySchemaSchema.TYPE_MAPPING 35 | ~EntitySchemaSchema.dict_class 36 | ~EntitySchemaSchema.opts 37 | ~EntitySchemaSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.FieldSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.FieldSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: FieldSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~FieldSchema.__init__ 17 | ~FieldSchema.dump 18 | ~FieldSchema.dumps 19 | ~FieldSchema.get_attribute 20 | ~FieldSchema.handle_error 21 | ~FieldSchema.load 22 | ~FieldSchema.loads 23 | ~FieldSchema.on_bind_field 24 | ~FieldSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~FieldSchema.TYPE_MAPPING 35 | ~FieldSchema.dict_class 36 | ~FieldSchema.opts 37 | ~FieldSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.FolderSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.FolderSchema 2 | ======================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: FolderSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~FolderSchema.__init__ 17 | ~FolderSchema.dump 18 | ~FolderSchema.dumps 19 | ~FolderSchema.get_attribute 20 | ~FolderSchema.get_model_name 21 | ~FolderSchema.handle_error 22 | ~FolderSchema.load 23 | ~FolderSchema.load_model 24 | ~FolderSchema.loads 25 | ~FolderSchema.on_bind_field 26 | ~FolderSchema.remove_ignore 27 | ~FolderSchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~FolderSchema.TYPE_MAPPING 38 | ~FolderSchema.dict_class 39 | ~FolderSchema.opts 40 | ~FolderSchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.OligoSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.OligoSchema 2 | ====================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: OligoSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~OligoSchema.__init__ 17 | ~OligoSchema.dump 18 | ~OligoSchema.dumps 19 | ~OligoSchema.get_attribute 20 | ~OligoSchema.get_model_name 21 | ~OligoSchema.get_schema_id 22 | ~OligoSchema.handle_error 23 | ~OligoSchema.load 24 | ~OligoSchema.load_model 25 | ~OligoSchema.loads 26 | ~OligoSchema.on_bind_field 27 | ~OligoSchema.remove_ignore 28 | ~OligoSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~OligoSchema.TYPE_MAPPING 39 | ~OligoSchema.dict_class 40 | ~OligoSchema.opts 41 | ~OligoSchema.set_class 42 | 43 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.ProjectSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.ProjectSchema 2 | ======================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: ProjectSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~ProjectSchema.__init__ 17 | ~ProjectSchema.dump 18 | ~ProjectSchema.dumps 19 | ~ProjectSchema.get_attribute 20 | ~ProjectSchema.get_model_name 21 | ~ProjectSchema.handle_error 22 | ~ProjectSchema.load 23 | ~ProjectSchema.load_model 24 | ~ProjectSchema.loads 25 | ~ProjectSchema.on_bind_field 26 | ~ProjectSchema.remove_ignore 27 | ~ProjectSchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~ProjectSchema.TYPE_MAPPING 38 | ~ProjectSchema.dict_class 39 | ~ProjectSchema.opts 40 | ~ProjectSchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.RegistrySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.RegistrySchema 2 | ========================================= 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: RegistrySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~RegistrySchema.__init__ 17 | ~RegistrySchema.dump 18 | ~RegistrySchema.dumps 19 | ~RegistrySchema.get_attribute 20 | ~RegistrySchema.get_model_name 21 | ~RegistrySchema.handle_error 22 | ~RegistrySchema.load 23 | ~RegistrySchema.load_model 24 | ~RegistrySchema.loads 25 | ~RegistrySchema.on_bind_field 26 | ~RegistrySchema.remove_ignore 27 | ~RegistrySchema.validate 28 | 29 | 30 | 31 | 32 | 33 | .. rubric:: Attributes 34 | 35 | .. autosummary:: 36 | 37 | ~RegistrySchema.TYPE_MAPPING 38 | ~RegistrySchema.dict_class 39 | ~RegistrySchema.opts 40 | ~RegistrySchema.set_class 41 | 42 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.TaskSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.TaskSchema 2 | ===================================== 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: TaskSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~TaskSchema.__init__ 17 | ~TaskSchema.dump 18 | ~TaskSchema.dumps 19 | ~TaskSchema.from_dict 20 | ~TaskSchema.get_attribute 21 | ~TaskSchema.get_model_name 22 | ~TaskSchema.handle_error 23 | ~TaskSchema.load 24 | ~TaskSchema.load_model 25 | ~TaskSchema.loads 26 | ~TaskSchema.on_bind_field 27 | ~TaskSchema.remove_ignore 28 | ~TaskSchema.validate 29 | 30 | 31 | 32 | 33 | 34 | .. rubric:: Attributes 35 | 36 | .. autosummary:: 37 | 38 | ~TaskSchema.TYPE_MAPPING 39 | ~TaskSchema.dict_class 40 | ~TaskSchema.error_messages 41 | ~TaskSchema.opts 42 | ~TaskSchema.set_class 43 | 44 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.TranslationSchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.TranslationSchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: TranslationSchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~TranslationSchema.__init__ 17 | ~TranslationSchema.dump 18 | ~TranslationSchema.dumps 19 | ~TranslationSchema.get_attribute 20 | ~TranslationSchema.handle_error 21 | ~TranslationSchema.load 22 | ~TranslationSchema.loads 23 | ~TranslationSchema.on_bind_field 24 | ~TranslationSchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~TranslationSchema.TYPE_MAPPING 35 | ~TranslationSchema.dict_class 36 | ~TranslationSchema.opts 37 | ~TranslationSchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docsrc/generated/benchlingapi.models.schema.UserSummarySchema.rst: -------------------------------------------------------------------------------- 1 | benchlingapi.models.schema.UserSummarySchema 2 | ============================================ 3 | 4 | .. currentmodule:: benchlingapi.models.schema 5 | 6 | .. autoclass:: UserSummarySchema 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~UserSummarySchema.__init__ 17 | ~UserSummarySchema.dump 18 | ~UserSummarySchema.dumps 19 | ~UserSummarySchema.get_attribute 20 | ~UserSummarySchema.handle_error 21 | ~UserSummarySchema.load 22 | ~UserSummarySchema.loads 23 | ~UserSummarySchema.on_bind_field 24 | ~UserSummarySchema.validate 25 | 26 | 27 | 28 | 29 | 30 | .. rubric:: Attributes 31 | 32 | .. autosummary:: 33 | 34 | ~UserSummarySchema.TYPE_MAPPING 35 | ~UserSummarySchema.dict_class 36 | ~UserSummarySchema.opts 37 | ~UserSummarySchema.set_class 38 | 39 | -------------------------------------------------------------------------------- /docsrc/guidelines.rst: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | Installing the package 5 | ---------------------- 6 | 7 | Download the git repository, cd into the directory and run: 8 | 9 | .. code-block:: 10 | 11 | poetry install 12 | 13 | If **poetry** (https://github.com/sdispater/poetry) is not installed 14 | on, run 15 | 16 | .. code-block:: 17 | 18 | pip install poetry -U 19 | 20 | Adding a new model 21 | ------------------ 22 | 23 | To implement a new model, please refer to the official 24 | `Benchling documentation `_. After, 25 | review the docs, find the appropriate class 26 | :mod:`mixins ` to implement the new model and 27 | inherit the :class:`ModelBase ` 28 | Finally, create a new :mod:`schema `, to 29 | implement the attributes the model will inherit from benchling 30 | results, following the convention of using *under_score* attribute 31 | names. Implement methods using the 32 | `_post`, `_get`, `_get_pages`, `_patch` methods of 33 | :class:`ModelBase ` as needed. 34 | 35 | If developing a new mixin or method in one of the mixin classes, be sure 36 | to develop tests for each model that uses that mixin. See the *tests* folder 37 | for examples on how to do this. 38 | 39 | Running tests 40 | ------------- 41 | 42 | Testing is done using `pytest`. Tests will create live requests to a Benchling account. 43 | Since testing is done live, a Benchling account will need to be setup along with testing 44 | data. 45 | 46 | .. code-block:: json 47 | 48 | { 49 | "credentials": { 50 | "api_key": "asdasdfadsfaghrhrha" 51 | }, 52 | "sharelinks": [ 53 | "https://benchling.com/s/seq-asdffebarha" 54 | ], 55 | "project": { 56 | "name": "API_sasdfs_iuAAXqsdfadsftuk" 57 | }, 58 | "trash_folder": { 59 | "name": "API_Trash" 60 | }, 61 | "inventory_folder": { 62 | "name": "API_Inventory" 63 | } 64 | } 65 | 66 | On the Benchling side of things, in the account liked to the `credentials["api_key"]`, you must 67 | have a project corresponding to the `project["name"]` value above. Within this project, you should 68 | have two folder corresponding to the `trash_folder` and `inventory_folder` values above. Additionally, 69 | you should have at least one example of an AminoAcid, DNASequence, CustomEntity, and Oligo stored within 70 | your `inventory_folder`. Tests will copy the examples from the `inventory_folder` for downstream tests. 71 | After the tests, conclude, inventory in the `trash_folder` will get archived. 72 | 73 | Style 74 | ----- 75 | 76 | Coding format and style is enforced by **black** (https://github.com/psf/black) and 77 | **flake8**. To enforce git-commit hooks, install pre-commits by running: 78 | 79 | .. code-block:: 80 | 81 | poetry run pre-commit install 82 | 83 | Tests 84 | ----- 85 | 86 | .. code-block:: 87 | 88 | poetry run pytest 89 | 90 | .. code-block:: 91 | 92 | tox 93 | 94 | Release 95 | ------- 96 | 97 | Release scripts are enforced by **keats** (https://github.com/jvrana/keats). 98 | 99 | .. code-block:: 100 | 101 | # if you just want to bump the version and changelog 102 | poetry run keats bump 103 | 104 | # release script 105 | poetry run keats release 106 | 107 | Documentation 108 | ------------- 109 | 110 | .. code-block:: 111 | 112 | make docs 113 | -------------------------------------------------------------------------------- /docsrc/index.rst: -------------------------------------------------------------------------------- 1 | :github_url: |homepage| 2 | 3 | .. testsetup:: * 4 | 5 | 6 | 7 | Python BenchlingAPI 8 | =================== 9 | 10 | The unofficial Benchling API for Python. |homepage| 11 | 12 | .. code-block:: 13 | 14 | pip install benchlingapi -U 15 | 16 | .. code-block:: python 17 | 18 | from benchlingapi import Session 19 | 20 | api_key = 'aksdj45ywe5yey5y' 21 | session = Session(api_key) 22 | seq = session.DNASequence.last() 23 | print(seq.dump()) 24 | 25 | API Reference 26 | ------------- 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | 31 | session 32 | models 33 | exceptions 34 | utils 35 | 36 | 37 | User Documentation 38 | ------------------ 39 | 40 | The user documentation contains high-level information for users. 41 | 42 | .. toctree:: 43 | :maxdepth: 1 44 | 45 | usage 46 | 47 | Developer Documentation 48 | ----------------------- 49 | 50 | The developer documentation conatins information on how to contribute.. 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | 55 | guidelines 56 | developer/changelog 57 | -------------------------------------------------------------------------------- /docsrc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | set SPHINXPROJ=BenchlingPyAPI 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docsrc/models.rst: -------------------------------------------------------------------------------- 1 | .. _api_models: 2 | 3 | .. automodule:: benchlingapi.models -------------------------------------------------------------------------------- /docsrc/session.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.session -------------------------------------------------------------------------------- /docsrc/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Installation 5 | ------------ 6 | 7 | .. code-block:: python 8 | 9 | pip install benchlingapi -U 10 | 11 | Session 12 | ------- 13 | 14 | Using the api requires an *api key*. If you do not have one, 15 | you must request one from Benchling. 16 | 17 | .. code-block:: python 18 | 19 | from benchlingapi import Session 20 | 21 | session = Session("sdf44tj-sdflj8na-rf23rfasdf") 22 | 23 | From there, you can access various models: 24 | 25 | .. code-block:: python 26 | 27 | session.DNASequence 28 | session.AASequence 29 | session.Oligo 30 | session.Folder 31 | session.Project 32 | session.Registry 33 | session.Translation 34 | session.EntitySchema 35 | session.Batch 36 | session.CustomEntity 37 | session.DNAAlignment 38 | session.Task 39 | 40 | 41 | Have a look at the :ref:`API model docs ` 42 | for methods available for each model. 43 | 44 | Finding models 45 | ^^^^^^^^^^^^^^ 46 | 47 | .. code-block:: python 48 | 49 | # get one model 50 | dna = session.DNASequence.one() 51 | 52 | # find a specific model by its id 53 | dna = session.DNASequence.find('sdg_4tg23') 54 | 55 | # get the last 50 amino acids 56 | proteins = session.AASequence.last(50) 57 | 58 | # get a registry by name 59 | registry = session.Registry.find_by_name("Klavins Lab Registry") 60 | 61 | 62 | 63 | Updating models 64 | ^^^^^^^^^^^^^^^ 65 | 66 | .. code-block:: python 67 | 68 | dna = session.DNASequence.one() 69 | dna.name = "My new name" 70 | dna.bases = "AGGTAGGGTAGGGCCAGAGA" 71 | 72 | # update the sequence on the server 73 | dna.update() 74 | 75 | 76 | Saving new models 77 | ^^^^^^^^^^^^^^^^^ 78 | 79 | .. code-block:: python 80 | 81 | folder = session.Folder.find_by_name("My API Folder") 82 | dna = session.DNASequence( 83 | name = 'my new dna', 84 | bases = 'AGGTAGGATGGCCA', 85 | folder_id = folder.id, 86 | is_circular = False 87 | ) 88 | 89 | # save the dna to your Benchling account 90 | dna.save() 91 | 92 | 93 | Registering models to your registry 94 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 95 | 96 | .. code-block:: python 97 | 98 | dna.set_schema("My DNA Schema") 99 | dna.register() 100 | 101 | 102 | Submitting DNA Alignments 103 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 104 | 105 | .. testcode:: 106 | 107 | task = session.DNAAlignment.submit_alignment( 108 | algorithm='mafft', 109 | name='my sequence alignment', 110 | template='seq_435g2d', # sequence id of the template 111 | filepaths=[ 112 | 'data/13dfg34.ab1' # filepath to ab1 files 113 | ], 114 | sequences=[ 115 | 'seq_1erv452', # ...or add benchling sequence ids to align 116 | session.DNASequence.one(), # ...or a DNASequence instances to align 117 | ], 118 | rawfiles=None # only use if you have base64 data handy 119 | ) 120 | 121 | # wait until the alignment is finished 122 | task.wait() 123 | 124 | # print the alignment 125 | print(task.response) 126 | 127 | # or grab the alignment 128 | alignment = task.response_class 129 | 130 | # from there, you can delete the alignment 131 | alignment.delete() 132 | 133 | -------------------------------------------------------------------------------- /docsrc/utils.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: benchlingapi.utils -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "benchlingapi" 3 | version = "2.1.12" 4 | description = "An unofficial python wrapper for the Benchling API" 5 | authors = ["Justin Vrana "] 6 | homepage = "https://www.github.com/klavinslab/benchling-api" 7 | repository = "https://pypi.org/project/benchlingapi/" 8 | documentation = "http://klavinslab.org/benchling-api/" 9 | readme = 'README.md' 10 | classifiers = [ 11 | "Intended Audience :: Science/Research", 12 | "Topic :: Scientific/Engineering :: Bio-Informatics", 13 | "Development Status :: 4 - Beta" 14 | ] 15 | 16 | [tool.poetry.dependencies] 17 | python = "^3.5.2" 18 | requests = "^2.22" 19 | inflection = "^0.3.1" 20 | urlopen = "^1.0" 21 | bs4 = "^0.0.1" 22 | marshmallow = "^3.2" 23 | 24 | [tool.poetry.dev-dependencies] 25 | black = {version = "^18.3-alpha.0", allows-prereleases = true, python = ">3.6"} 26 | pytest = "^5.0" 27 | pre-commit = "^1.17" 28 | toml = "^0.10.0" 29 | sphinx = "^2.1" 30 | guzzle-sphinx-theme = "^0.7.11" 31 | vcrpy = "^2.0" 32 | keats = {version = "^0.2.27", python = ">3.6"} 33 | sphinx_autodoc_typehints = {version = "^1.8", python = ">3.6"} 34 | sphinx-bootstrap-theme = "^0.7.1" 35 | recommonmark = "^0.6.0" 36 | autodocsumm = "^0.1.11" 37 | flake8 = "^3.7" 38 | tox = "^3.14" 39 | tox-conda = "^0.2.1" 40 | 41 | 42 | [tool.black] 43 | line-length = 88 44 | target-version = ['py36', 'py37', 'py38'] 45 | include = '\.pyi?$' 46 | exclude = ''' 47 | /( 48 | \.eggs 49 | | \.git 50 | | \.hg 51 | | \.mypy_cache 52 | | \.tox 53 | | \.venv 54 | | _build 55 | | buck-out 56 | | build 57 | | dist 58 | # The following are specific to Black, you probably don't want those. 59 | | blib2to3 60 | | tests/data 61 | | profiling 62 | )/ 63 | ''' 64 | 65 | [build-system] 66 | requires = ["poetry>=0.12"] 67 | build-backend = "poetry.masonry.api" 68 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import pytest 5 | import vcr 6 | 7 | from benchlingapi.models import mixins 8 | from benchlingapi.models.base import ModelRegistry 9 | from benchlingapi.session import Session 10 | 11 | 12 | #################### 13 | # Requests Recording 14 | #################### 15 | 16 | 17 | def hash_response(r): 18 | """Hashes a request into a unique name.""" 19 | return "{}:{}:{}".format(r.method, r.uri, r.body) 20 | 21 | 22 | def hash_test_function(func): 23 | if func.cls: 24 | cls = func.cls.__name__ 25 | else: 26 | cls = "None" 27 | return "{module}_{cls}_{name}".format( 28 | module=func.module.__name__, cls=cls, name=func.name 29 | ) 30 | 31 | 32 | def matcher(r1, r2): 33 | return hash_response(r1) == hash_response(r2) 34 | 35 | 36 | myvcr = vcr.VCR() 37 | myvcr.register_matcher("matcher", matcher) 38 | myvcr.match_on = ["matcher"] 39 | myvcr.record_mode = "all" 40 | here = os.path.abspath(os.path.dirname(__file__)) 41 | fixtures_path = os.path.join(here, "fixtures/vcr_cassettes") 42 | 43 | 44 | @pytest.hookimpl(hookwrapper=True) 45 | def pytest_pyfunc_call(pyfuncitem): 46 | cassette_name = hash_test_function(pyfuncitem) 47 | with myvcr.use_cassette(os.path.join(fixtures_path, cassette_name) + ".yaml"): 48 | outcome = yield 49 | 50 | 51 | def config(): 52 | test_dir = os.path.dirname(os.path.abspath(__file__)) 53 | config_location = os.path.join(test_dir, "secrets/config.json") 54 | with open(config_location, "rU") as handle: 55 | return json.load(handle) 56 | 57 | 58 | @pytest.fixture(scope="session") 59 | def session(): 60 | return Session(config()["credentials"]["api_key"]) 61 | 62 | 63 | @pytest.fixture(scope="session") 64 | def project(session): 65 | project_info = config()["project"] 66 | project = session.Project.find_by_name(project_info["name"]) 67 | if project is None: 68 | pytest.skip("Could not find project for {}".format(project_info)) 69 | return project 70 | 71 | 72 | @pytest.fixture(scope="session") 73 | def inv_folder(session, project): 74 | folder_config = config()["inventory_folder"] 75 | 76 | folder = session.Folder.find_by_name(folder_config["name"], project_id=project.id) 77 | if folder is None: 78 | pytest.skip( 79 | "Could not find folder for {}. Please create folder to continue testing.".format( 80 | folder_config 81 | ) 82 | ) 83 | 84 | assert folder.name == "API_Inventory" 85 | assert session.Project.find(folder.project_id).name == project.name 86 | 87 | return folder 88 | 89 | 90 | def clean_up_folder(folder): 91 | # clean up trash fol der 92 | print("Cleaning trash folder") 93 | entity_models = ModelRegistry.filter_models_by_base_classes( 94 | [mixins.InventoryEntityMixin] 95 | ) 96 | for model in entity_models: 97 | 98 | interface = folder.session.interface(model.__name__) 99 | print('Archiving "{}" models...'.format(model.__name__)) 100 | for m in interface.all(folder_id=folder.id): 101 | print("Archiving {}".format(m)) 102 | try: 103 | m.archive(m.ARCHIVE_REASONS.OTHER) 104 | except Exception as e: 105 | print(e) 106 | 107 | 108 | def populate_folder(folder, inventory_folder): 109 | for m in inventory_folder.all_entities(): 110 | print("Copying {} from {} to {}".format(m, folder.name, inventory_folder.name)) 111 | m_copy = m.copy() 112 | m_copy.folder_id = folder.id 113 | m_copy.save() 114 | 115 | 116 | @pytest.fixture(scope="session", autouse=False) 117 | def trash_folder(session, project, inv_folder): 118 | """The session-wide testing folder. 119 | 120 | All entities in the folder get archived at the end of every session. 121 | """ 122 | folder_config = config()["trash_folder"] 123 | 124 | folder = session.Folder.find_by_name(folder_config["name"], project_id=project.id) 125 | if folder is None: 126 | pytest.skip( 127 | "Could not find folder for {}. Please create folder to continue testing.".format( 128 | folder_config 129 | ) 130 | ) 131 | 132 | assert folder.name == "API_Trash" 133 | assert session.Project.find(folder.project_id).name == project.name 134 | 135 | # populating trash folder 136 | # populate_folder(folder, inv_folder) 137 | 138 | yield folder 139 | 140 | clean_up_folder(folder) 141 | 142 | 143 | @pytest.fixture(scope="function") 144 | def example_from_inventory(model, inv_folder, trash_folder): 145 | """Returns a copied example from the inventory folder given a Model 146 | class.""" 147 | interface = inv_folder.session.interface(model.__name__) 148 | example = interface.one(folder_id=inv_folder.id) 149 | if example is None: 150 | pytest.skip( 151 | 'Could not find an example entity for "{}" in "{}"'.format( 152 | model, inv_folder.name 153 | ) 154 | ) 155 | example_copy = example.copy() 156 | example_copy.folder_id = trash_folder.id 157 | data = example_copy.dump(**example_copy.CREATE_SCHEMA) 158 | example_copy.save() 159 | return example_copy 160 | -------------------------------------------------------------------------------- /tests/secrets/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "credentials": { 3 | "api_key": "sk_e9ggflObjQeShULiuAAXqIkDTttuk" 4 | }, 5 | "sharelinks": [ 6 | "https://benchling.com/s/seq-NXGArPyPOl3aVr5K5U1T" 7 | ], 8 | "project": { 9 | "name": "API_sk_e9ggflObjQeShULiuAAXqIkDTttuk" 10 | }, 11 | "trash_folder": { 12 | "name": "API_Trash" 13 | }, 14 | "inventory_folder": { 15 | "name": "API_Inventory" 16 | } 17 | } -------------------------------------------------------------------------------- /tests/secrets/config.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/tests/secrets/config.json.enc -------------------------------------------------------------------------------- /tests/secrets/config_fake.json: -------------------------------------------------------------------------------- 1 | { 2 | "credentials": { 3 | "api_key": "sk_5345345U30J5fAeb43jEj0d4YlJ" 4 | }, 5 | "sharelinks": [ 6 | "https://benchling.com/s/seq24534534-z8EGQeG2X14539yvNZoeFVi" 7 | ] 8 | } -------------------------------------------------------------------------------- /tests/test_interface.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from benchlingapi.models import models 3 | from benchlingapi.exceptions import ModelNotFoundError 4 | 5 | 6 | def test_all_models(session): 7 | 8 | assert len(session.models) == len(models.__all__) 9 | 10 | 11 | def test_model_interface(session): 12 | 13 | for model_name in models.__all__: 14 | interface = session.interface(model_name) 15 | interface_from_attr = getattr(session, model_name) 16 | 17 | print(interface) 18 | 19 | assert type(interface) is type(interface_from_attr) 20 | assert interface is not None 21 | 22 | 23 | def test_raise_no_model(session): 24 | 25 | with pytest.raises(ModelNotFoundError): 26 | session.interface("ModelDoesntExist") 27 | -------------------------------------------------------------------------------- /tests/test_models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/tests/test_models/__init__.py -------------------------------------------------------------------------------- /tests/test_models/test_all_models.py: -------------------------------------------------------------------------------- 1 | from benchlingapi.models.base import ModelRegistry 2 | from benchlingapi.models import models 3 | 4 | 5 | def test__all__models_in_registry(): 6 | missing_models = [] 7 | for expected_model in models.__all__: 8 | if expected_model not in ModelRegistry.models: 9 | missing_models.append(expected_model) 10 | assert ( 11 | not missing_models 12 | ), "There are models in __all__ that are missing from the ModelRegistry." 13 | 14 | 15 | def test_models_registry_in__all__(): 16 | missing_models = [] 17 | for expected_model in ModelRegistry.models.values(): 18 | if expected_model.__name__ not in models.__all__: 19 | missing_models.append(expected_model.__name__) 20 | assert ( 21 | not missing_models 22 | ), "There are models in ModelRegistry that are missing from __all__." 23 | -------------------------------------------------------------------------------- /tests/test_models/test_dna_sequence.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def test_web_link(session): 5 | dnas = session.DNASequence.last(10) 6 | 7 | for dna in dnas: 8 | loaded = session.DNASequence.from_share_link(dna.web_url) 9 | assert loaded.id == dna.id 10 | 11 | 12 | # def test_share_link(session): 13 | # 14 | # # dna = session.DNASequence.from_share_link('https://benchling.com/s/seq-YR1KBSvPlZ8sGOlnOBqe') 15 | # # assert dna 16 | # dna = session.DNASequence.one() 17 | # print(session.DNASequence.find(dna.id)) 18 | # print(session.DNASequence.find('seq_Kzxlbux9')) 19 | # 20 | # # print(session.Folder.find('lib_SjLcTsG4')) 21 | # 22 | # folder = session.Folder.find_by_name('APITrash') 23 | # print(folder) 24 | # print(folder.id) 25 | # print(session.Folder.find(folder.id)) 26 | -------------------------------------------------------------------------------- /tests/test_models/test_models.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from benchlingapi.models import ModelRegistry 4 | from benchlingapi.models.mixins import ArchiveMixin 5 | from benchlingapi.models.mixins import CreateMixin 6 | from benchlingapi.models.mixins import EntityMixin 7 | from benchlingapi.models.mixins import GetMixin 8 | from benchlingapi.models.mixins import InventoryMixin 9 | from benchlingapi.models.mixins import ListMixin 10 | from benchlingapi.models.mixins import RegistryMixin 11 | from benchlingapi.models.models import Folder 12 | from benchlingapi.models.models import Project 13 | 14 | 15 | def pytest_generate_tests(metafunc): 16 | # parameterize with models that match the expected model test 17 | only_models = ModelRegistry.filter_models_by_base_classes(metafunc.cls.only) 18 | 19 | create_params_dict = metafunc.cls.__dict__.get("create_params", {}) 20 | 21 | argdict = {"model": [], "create_params": []} 22 | for m in only_models: 23 | create_params = create_params_dict.get(m.__name__, None) 24 | if isinstance(create_params, list): 25 | for cp in create_params: 26 | argdict["model"].append(m) 27 | argdict["create_params"].append(cp) 28 | else: 29 | argdict["model"].append(m) 30 | argdict["create_params"].append(create_params) 31 | 32 | argnames = [n for n in metafunc.fixturenames if n in argdict] 33 | argvalues = zip(*[argdict[n] for n in argnames]) 34 | 35 | if len(argnames) == 1: 36 | argvalues = [a[0] for a in argvalues] 37 | 38 | metafunc.parametrize(",".join(argnames), argvalues, scope="class") 39 | 40 | 41 | class HasInterface: 42 | @pytest.fixture(scope="function") 43 | def interface(self, session, model): 44 | return session.interface(model.__name__) 45 | 46 | 47 | class HasExample(HasInterface): 48 | @pytest.fixture(scope="function") 49 | def example_model(self, interface, model): 50 | one = interface.one() 51 | if not one: 52 | pytest.skip('Example model "{}" not found'.format(model.__name__)) 53 | return one 54 | 55 | 56 | class TestListMixin(HasExample): 57 | only = ListMixin 58 | 59 | def test_one(self, example_model): 60 | assert example_model 61 | 62 | def test_last_1(self, interface, model): 63 | size1 = interface.last(1) 64 | if len(size1) == 0: 65 | pytest.skip('No models found for "{}"'.format(model)) 66 | assert 1 == len(size1) 67 | assert isinstance(size1[0], model) 68 | 69 | def test_last_20(self, interface, model): 70 | size20 = interface.last(20) 71 | if len(size20) == 0: 72 | pytest.skip('No models found for "{}"'.format(model)) 73 | size_list = interface.list() 74 | assert min(len(size20), len(size_list)) <= 20 75 | assert isinstance(size20[-1], model) 76 | 77 | def test_find_by_name(self, interface, model, example_model): 78 | found = interface.find_by_name(example_model.name) 79 | assert found.name == example_model.name 80 | assert isinstance(found, model) 81 | 82 | def test_list_pages(self, interface, model): 83 | list(interface.list_pages(page_limit=1, page_size=1)) 84 | 85 | 86 | class TestGetMixin(HasExample): 87 | only = [ListMixin, GetMixin] 88 | 89 | def test_find(self, interface, example_model): 90 | assert interface.get(example_model.id) is not None 91 | assert interface.find(example_model.id) is not None 92 | assert interface.find("asdf98qw4hotnof8gyh") is None 93 | 94 | 95 | class TestEntity(HasInterface): 96 | only = EntityMixin 97 | 98 | @pytest.fixture(scope="function") 99 | def example_model(self, interface, model): 100 | one = interface.one() 101 | if not one: 102 | pytest.skip('Example model "{}" not found'.format(model.__name__)) 103 | return one 104 | 105 | def test_find_by_name(self, session, interface, model, example_model): 106 | if not example_model: 107 | pytest.skip('Example model "{}" not found'.format(model.__name__)) 108 | found = interface.find_by_name(example_model.name) 109 | assert found 110 | assert example_model.id == found.id 111 | assert interface.find_by_name("alsjdfoijewfosdiufoasdf") is None 112 | 113 | def test_batches(self, example_model): 114 | batches = example_model.batches() 115 | assert isinstance(batches, list) 116 | 117 | 118 | class TestCreateMixin(HasInterface): 119 | 120 | only = CreateMixin 121 | 122 | create_params = { 123 | "DNASequence": dict( 124 | bases="AGCGTATGTGTGTA", 125 | name="MyNewSeq", 126 | isCircular=False, 127 | schemaId=None, 128 | annotations=[ 129 | { 130 | "color": "#FF9CCD", 131 | "end": 3, 132 | "name": "bla gene", 133 | "start": 1, 134 | "strand": 1, 135 | "type": "gene", 136 | }, 137 | { 138 | "color": "#FF9CCD", 139 | "end": 5, 140 | "name": "bla gene", 141 | "start": 1, 142 | "strand": -1, 143 | "type": "gene", 144 | }, 145 | ], 146 | ), 147 | "AASequence": dict( 148 | aminoAcids="AMVGKLALDLSD", 149 | annotations=[ 150 | { 151 | "color": "#FF9CCD", 152 | "end": 5, 153 | "name": "bla gene", 154 | "start": 1, 155 | "strand": -1, 156 | "type": "gene", 157 | } 158 | ], 159 | schemaId=None, 160 | name="MyProtein", 161 | ), 162 | "CustomEntity": dict(name="MyEntity", aliases=[], schemaId=None), 163 | "Batch": dict(entityId="seq_342322", fields={}), 164 | "Oligo": dict(name="MyOligo", bases="AGTAGCATG"), 165 | } 166 | 167 | @pytest.fixture(scope="function") 168 | def create_param(self, session, trash_folder, create_params, interface): 169 | create_params["folderId"] = trash_folder.id 170 | if "schemaId" in create_params: 171 | schema = interface.valid_schemas()[0][1] 172 | create_params["schemaId"] = schema["id"] 173 | if "entityId" in create_params: 174 | entity = session.CustomEntity.one() 175 | create_params["entityId"] = entity.id 176 | return create_params 177 | 178 | def test_model_constructor(self, interface, create_param): 179 | new_model = interface(**create_param) 180 | assert new_model 181 | 182 | def test_model_save(self, interface, create_param): 183 | new_model = interface(**create_param) 184 | new_model.save() 185 | assert new_model.id 186 | 187 | 188 | class TestArchiveMixin(HasInterface): 189 | 190 | only = [ArchiveMixin, ListMixin, InventoryMixin] 191 | 192 | @pytest.fixture(scope="function") 193 | def example(self, model, example_from_inventory): 194 | if model not in [Project, Folder]: 195 | return example_from_inventory 196 | else: 197 | pytest.skip('Skipping "{}"'.format(model)) 198 | 199 | def test_archive(self, interface, example): 200 | assert not example.is_archived 201 | example.archive() 202 | assert example.is_archived 203 | example.unarchive() 204 | assert not example.is_archived 205 | 206 | # def test_list_archived(self, interface): 207 | # archived = interface.list_archived() 208 | # assert len(archived) > 1 209 | 210 | 211 | class TestRegistryMixin(HasInterface): 212 | only = [RegistryMixin, CreateMixin, ListMixin, InventoryMixin] 213 | 214 | @pytest.fixture(scope="function") 215 | def example(self, model, example_from_inventory): 216 | if model not in [Project, Folder]: 217 | return example_from_inventory 218 | else: 219 | pytest.skip('Skipping "{}"'.format(model)) 220 | 221 | def test_print_valid_schemas(self, example): 222 | example.print_valid_schemas() 223 | 224 | @pytest.fixture(scope="function") 225 | def copy_sample(self, example, interface): 226 | example_copy = example.copy() 227 | example_copy.save() 228 | assert example_copy.id 229 | assert example_copy.id != example.id 230 | return example_copy 231 | 232 | def test_register(self, copy_sample, trash_folder): 233 | valid_schemas = copy_sample.valid_schemas 234 | assert not copy_sample.is_registered 235 | copy_sample.set_schema(valid_schemas()[0][1]["name"]) 236 | copy_sample.register() 237 | assert copy_sample.is_registered 238 | copy_sample.unregister(trash_folder.id) 239 | assert not copy_sample.is_registered 240 | 241 | 242 | # 243 | # def test_dna_share_link(session): 244 | # return 245 | # # dnas = session.DNASequence.last(10) 246 | # # for dna in dnas: 247 | # # assert dna 248 | # # loaded = session.DNASequence.from_share_link(dna.web_url) 249 | # # assert loaded.id == dna.id 250 | -------------------------------------------------------------------------------- /tests/test_models/test_other/424889-14889.ab1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvrana/benchling-api/b92cdf8e12f02d344c2a3b5817bea2904fdd6261/tests/test_models/test_other/424889-14889.ab1 -------------------------------------------------------------------------------- /tests/test_models/test_other/test_dna_sequence_alignment.py: -------------------------------------------------------------------------------- 1 | import os 2 | from uuid import uuid4 3 | 4 | import pytest 5 | 6 | from benchlingapi.exceptions import BenchlingAPIException 7 | 8 | 9 | class TestDNAAlignment: 10 | @pytest.fixture(scope="module") 11 | def make_temporary_sequences(self, session, trash_folder): 12 | """Create a temporary sequence and then archive it.""" 13 | seq_arr = [] 14 | 15 | def temp(sequences): 16 | for seq_str in sequences: 17 | seq_arr.append( 18 | session.DNASequence( 19 | bases=seq_str, 20 | name=str(uuid4()), 21 | folder_id=trash_folder.id, 22 | is_circular=False, 23 | ) 24 | ) 25 | for seq in seq_arr: 26 | seq.save() 27 | 28 | return seq_arr 29 | 30 | yield temp 31 | 32 | for seq in seq_arr: 33 | try: 34 | seq.archive() 35 | except: 36 | pass 37 | 38 | @pytest.mark.parametrize( 39 | "do_delete", [False, True], ids=["keep alignment", "delete alignment"] 40 | ) 41 | def test_alignment_with_other_sequences( 42 | self, session, make_temporary_sequences, do_delete 43 | ): 44 | """This tests that sequences are valid inputs.""" 45 | dnas = make_temporary_sequences( 46 | [ 47 | "actccaattggtgatggtccagtcttgttaccagacaaccattacttatccactcaatctgccttatcc" 48 | "aaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttactgctgctggtattac", 49 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 50 | "actcaatctgccttatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 51 | "gctgctggtattac", 52 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 53 | "actcaatctgcctAAAAAAAtatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 54 | "gctgctggtattacAGGGAGGGAGGAGAGGA", 55 | ] 56 | ) 57 | 58 | for dna in dnas: 59 | print(dna.name) 60 | 61 | template = dnas[0] 62 | other = dnas[1:] 63 | task = session.DNAAlignment.submit_alignment( 64 | algorithm="mafft", 65 | name="my new alignment", 66 | template=template, 67 | filepaths=[], 68 | sequences=other, 69 | ) 70 | 71 | task.wait() 72 | assert task.status == "SUCCEEDED" 73 | if do_delete: 74 | alignment = task.response_class 75 | alignment.delete() 76 | 77 | def test_alignment_with_mixed_files_seqids_and_seqs( 78 | self, session, make_temporary_sequences 79 | ): 80 | """This tests that sequence ids, DNASequence, and filepaths are all 81 | valid inputs for the alignment submission method.""" 82 | dnas = make_temporary_sequences( 83 | [ 84 | "actccaattggtgatggtccagtcttgttaccagacaaccattacttatccactcaatctgccttatcc" 85 | "aaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttactgctgctggtattac", 86 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 87 | "actcaatctgccttatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 88 | "gctgctggtattac", 89 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 90 | "actcaatctgcctAAAAAAAtatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 91 | "gctgctggtattacAGGGAGGGAGGAGAGGA", 92 | ] 93 | ) 94 | 95 | here = os.path.abspath(os.path.dirname(__file__)) 96 | filepath = os.path.join(here, "424889-14889.ab1") 97 | 98 | template = dnas[0] 99 | others = [dnas[1], dnas[2].id] 100 | task = session.DNAAlignment.submit_alignment( 101 | algorithm="mafft", 102 | name="my new alignment", 103 | template=template, 104 | filepaths=[filepath], 105 | sequences=others, 106 | ) 107 | 108 | task.wait() 109 | print(task) 110 | assert task.status == "SUCCEEDED" 111 | 112 | def test_alignment_with_ab1_files(self, session, make_temporary_sequences): 113 | """This tests that filepaths are valid inputs for the alignment 114 | submission method.""" 115 | dnas = make_temporary_sequences( 116 | [ 117 | "actccaattggtgatggtccagtcttgttaccagacaaccattacttatccactcaatctgccttatcc" 118 | "aaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttactgctgctggtattac" 119 | ] 120 | ) 121 | 122 | here = os.path.abspath(os.path.dirname(__file__)) 123 | filepath = os.path.join(here, "424889-14889.ab1") 124 | 125 | template = dnas[0] 126 | task = session.DNAAlignment.submit_alignment( 127 | algorithm="mafft", 128 | name="my new alignment", 129 | template=template, 130 | filepaths=[filepath], 131 | ) 132 | 133 | task.wait() 134 | print(task) 135 | print(dnas[0].id) 136 | 137 | print(template.web_url) 138 | assert task.status == "SUCCEEDED" 139 | 140 | def test_wrong_algorithm(self, session, make_temporary_sequences): 141 | dnas = make_temporary_sequences( 142 | [ 143 | "actccaattggtgatggtccagtcttgttaccagacaaccattacttatccactcaatctgccttatcc" 144 | "aaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttactgctgctggtattac", 145 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 146 | "actcaatctgccttatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 147 | "gctgctggtattac", 148 | "aattggtgatggtccagtactccaattggtgatggtccagtcttgttaccagacaaccattacttatcc" 149 | "actcaatctgcctAAAAAAAtatccaaagatccaaacgaaaagagagaccacatggtcttgttagaatttgttact" 150 | "gctgctggtattacAGGGAGGGAGGAGAGGA", 151 | ] 152 | ) 153 | 154 | for dna in dnas: 155 | print(dna.name) 156 | 157 | template = dnas[0] 158 | other = dnas[1:] 159 | with pytest.raises(BenchlingAPIException): 160 | session.DNAAlignment.submit_alignment( 161 | algorithm="not_an_algorithm", 162 | name="my new alignment", 163 | template=template, 164 | filepaths=[], 165 | sequences=other, 166 | ) 167 | -------------------------------------------------------------------------------- /tests/test_models/test_registry.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from benchlingapi.exceptions import InvalidRegistryId 4 | 5 | 6 | def test_get_entities_in_registry(session): 7 | 8 | registry = session.Registry.one() 9 | models = registry.get_entities(["aqKL003", "aqKL010", "aqqJV010"]) 10 | pass 11 | 12 | 13 | def test_invalid_registry(session): 14 | registries = session.Registry.all() 15 | for registry in registries: 16 | with pytest.raises(InvalidRegistryId): 17 | session.DNASequence.find_in_registry("adsklfherhg", registry_id=registry.id) 18 | 19 | 20 | def test_list_all_in_registry(session): 21 | registry = session.Registry.one() 22 | n = 0 23 | for d in list( 24 | session.DNASequence.all(registry_id=registry.id, page_limit=10, limit=50) 25 | ): 26 | assert d.entity_registry_id 27 | assert d.registry_id == registry.id 28 | n += 1 29 | assert n == 50 30 | -------------------------------------------------------------------------------- /tests/test_models/test_schema.py: -------------------------------------------------------------------------------- 1 | from benchlingapi.models import schema 2 | 3 | 4 | def test_field_schema(): 5 | s = schema.FieldSchema() 6 | d = s.load({"isMulti": True, "textValue": None, "type": "dropdown", "value": []}) 7 | print(s.dump(d)) 8 | -------------------------------------------------------------------------------- /tests/test_session.py: -------------------------------------------------------------------------------- 1 | from benchlingapi import Session 2 | 3 | 4 | def test_session(session): 5 | pass 6 | 7 | 8 | def test_setting_org(): 9 | session = Session('alsdfja;lsdfj', org='myorganization') 10 | assert session.url == 'https://myorganization.benchling.com/api/v2' 11 | 12 | 13 | def test_setting_home(): 14 | home = 'https://myotherorganization.benchling.com/api/v2' 15 | session = Session('alsdfja;lsdfj', home=home) 16 | assert session.url == home -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | isolated_build = true 3 | envlist = 4 | py35,py36,py37 5 | 6 | [testenv] 7 | whitelist_externals = poetry 8 | deps = 9 | commands = 10 | pip install poetry --ignore-installed 11 | poetry install --no-dev 12 | poetry run pip install pytest 13 | poetry run pip install vcrpy 14 | poetry run pytest tests 15 | 16 | --------------------------------------------------------------------------------