variantgrid-api 1.8.0__tar.gz → 1.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. variantgrid_api-1.10.0/PKG-INFO +194 -0
  2. variantgrid_api-1.10.0/README.md +173 -0
  3. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/pyproject.toml +4 -4
  4. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api/api_client.py +141 -48
  5. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api/cli.py +68 -8
  6. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api/data_models.py +98 -53
  7. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api/mock_variantgrid_api.py +28 -15
  8. variantgrid_api-1.10.0/src/variantgrid_api.egg-info/PKG-INFO +194 -0
  9. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api.egg-info/SOURCES.txt +1 -0
  10. variantgrid_api-1.10.0/tests/test_alignment_files.py +204 -0
  11. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client.py +29 -23
  12. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client_bulk.py +6 -6
  13. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client_capabilities.py +5 -5
  14. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client_patients.py +125 -45
  15. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_cli.py +53 -0
  16. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_mock_variantgrid_api.py +57 -17
  17. variantgrid_api-1.8.0/PKG-INFO +0 -144
  18. variantgrid_api-1.8.0/README.md +0 -101
  19. variantgrid_api-1.8.0/src/variantgrid_api.egg-info/PKG-INFO +0 -144
  20. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/LICENSE +0 -0
  21. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/setup.cfg +0 -0
  22. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api.egg-info/dependency_links.txt +0 -0
  23. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api.egg-info/entry_points.txt +0 -0
  24. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api.egg-info/requires.txt +0 -0
  25. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/src/variantgrid_api.egg-info/top_level.txt +0 -0
  26. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client_annotation.py +0 -0
  27. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_api_client_validation.py +0 -0
  28. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_data_models.py +0 -0
  29. {variantgrid_api-1.8.0 → variantgrid_api-1.10.0}/tests/test_sequencer_model_from_name.py +0 -0
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.4
2
+ Name: variantgrid_api
3
+ Version: 1.10.0
4
+ Summary: A Python API client for VariantGrid
5
+ Author-email: Dave Lawrence <davmlaw@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/SACGF/variantgrid_api
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: requests
15
+ Requires-Dist: dataclasses-json
16
+ Provides-Extra: test
17
+ Requires-Dist: pytest>=8; extra == "test"
18
+ Requires-Dist: pytest-cov>=5; extra == "test"
19
+ Requires-Dist: responses; extra == "test"
20
+ Dynamic: license-file
21
+
22
+ # variantgrid_api
23
+
24
+ [![PyPi version](https://img.shields.io/pypi/v/variantgrid_api.svg)](https://pypi.org/project/variantgrid_api/) [![Python versions](https://img.shields.io/pypi/pyversions/variantgrid_api.svg)](https://pypi.org/project/variantgrid_api/)
25
+
26
+ Python API client for [VariantGrid](https://github.com/SACGF/variantgrid) Open source Variant database and analysis platform
27
+
28
+ See [changelog](https://github.com/SACGF/variantgrid_api/blob/main/CHANGELOG.md)
29
+
30
+ ## Install
31
+
32
+ ```
33
+ python3 -m pip install variantgrid_api
34
+ ```
35
+
36
+ ## Example
37
+
38
+ ```
39
+ from variantgrid_api.api_client import VariantGridAPI
40
+ from variantgrid_api.data_models import EnrichmentKit
41
+
42
+ api = VariantGridAPI(server="https://variantgrid.com", api_token="YOUR_API_TOKEN")
43
+ enrichment_kit = EnrichmentKit(name="idt_haem", version=1)
44
+ result = api.create_enrichment_kit(enrichment_kit)
45
+ ```
46
+
47
+ ## Annotate a VCF and download it back
48
+
49
+ Upload a VCF, have VariantGrid import + annotate any novel variants, then download the cohort-level annotated
50
+ export (all samples, single-sample VCFs included). Annotation can take a while, so the quickest way in is the
51
+ `vg_api` command line tool: the first call uploads, and running the same command again downloads the result
52
+ once it's ready.
53
+
54
+ ```console
55
+ $ export VARIANTGRID_API_TOKEN=YOUR_API_TOKEN
56
+ $ vg_api annotate_vcf input.vcf.gz -o results/
57
+ Uploaded input.vcf.gz (id=13256).
58
+ Annotating input.vcf.gz - run the same command again later to download.
59
+
60
+ $ vg_api annotate_vcf input.vcf.gz -o results/ # still annotating
61
+ input.vcf.gz: not ready yet - pipeline Success, import 100.0%, 2 annotation runs remaining. Run the same command again later.
62
+
63
+ $ vg_api annotate_vcf input.vcf.gz -o results/ # once it's done
64
+ Annotated vcf written to results/input.vcf_annotated_v254_GRCh38.vcf.gz
65
+ ```
66
+
67
+ Add `--verbose` to log each request, response and the full upload status to stderr.
68
+
69
+ From Python it's `upload_file()` / `poll_upload_status()` / `download_annotated()`, or the blocking
70
+ `annotate_vcf()` one-liner. See
71
+ **[Annotate a VCF](https://github.com/SACGF/variantgrid_api/wiki/Annotate-a-VCF)** on the wiki for batches, the
72
+ submit-now/download-later pattern, and all the options.
73
+
74
+ ## Patients, specimens and extractions
75
+
76
+ VariantGrid can record which patient, specimen and extraction a lab's sequencing came from. This needs a server
77
+ at or after SACGF/variantgrid#1716.
78
+
79
+ ```
80
+ from variantgrid_api.data_models import Patient, Specimen, Extraction, ExternalReference, NucleicAcid
81
+
82
+ api.create_patient(Patient(patient_code="C0000001"))
83
+ api.create_specimen(Specimen(patient="C0000001", reference_id="2600000001"))
84
+ api.create_extraction(Extraction(specimen="2600000001", reference_id="2600000001C",
85
+ nucleic_acid_source=NucleicAcid.DNA))
86
+ api.upload_file("sample.vcf.gz", path=None,
87
+ metadata={"extraction": "2600000001C", "genome_build": "GRCh37"})
88
+ ```
89
+
90
+ A bare string names a record by its local reference. Use `ExternalReference(code=..., external_type=...)` to
91
+ name it by a LIMS identifier instead. See `examples/example_tso500.py` for a full run.
92
+
93
+ Once the sample sheet is registered, link its sequencing samples to their extractions in one call, keyed on
94
+ sample name (what `SequencingSampleLookup.sample_name` holds):
95
+
96
+ ```
97
+ api.link_sequencing_sample_extractions(sample_sheet_lookup, {"sample_1": "2600000001C",
98
+ "sample_2": "2600000002C"})
99
+ ```
100
+
101
+ It returns a list with one `{"sequencing_sample", "match_status", "match_error", "extraction"}` per sample. An
102
+ extraction the server doesn't have yet is `Pending` for that sample only (HTTP 202) and attaches itself once the
103
+ extraction is created; a sample name that isn't on the sheet is a 400 for the whole batch. On a server from
104
+ before SACGF/variantgrid#2176 (no `link_extractions_bulk` feature) the client makes one
105
+ `link_sequencing_sample_extraction` call per sample instead, so pipelines can use the bulk call unconditionally.
106
+ `link_sequencing_sample_extraction` is still there for a single late link. See `examples/example_haem_20_999.py`.
107
+
108
+ ## BAMs and CRAMs
109
+
110
+ A sequencing sample can have several alignment files, eg a BAM and its recalibrated BAM, or a BAM plus a CRAM.
111
+ List them in `SequencingFile.alignment_files` (and `QC.alignment_files`), the file the variant caller ran on first:
112
+
113
+ ```
114
+ from variantgrid_api.data_models import AlignmentFile, SequencingFile, SingleSampleVCF
115
+
116
+ SequencingFile(sample_name="sample_1",
117
+ alignment_files=[AlignmentFile(path="/data/sample_1.bam", aligner=aligner),
118
+ AlignmentFile(path="/data/sample_1.cram", aligner=aligner)],
119
+ vcf_files=[SingleSampleVCF(path="/data/sample_1.vcf.gz", variant_caller=variant_caller)])
120
+ ```
121
+
122
+ `AlignmentFile.file_type` (`AlignmentFileType.BAM` / `CRAM`) is optional and inferred from the path. A server
123
+ without the `alignment_files` feature gets the old wire format instead: one sequencing file record per alignment
124
+ file as `bam_file`, and a QC's first alignment file as its `bam_file`. A CRAM there also needs the
125
+ `cram_alignment_files` feature. `BamFile` and the `bam_file` fields still work but are deprecated.
126
+
127
+ ## Talking to more than one VariantGrid version
128
+
129
+ Servers of different ages accept different calls. The client asks the server which features it has
130
+ (`GET api/v1/capabilities`, fetched once on first use), and each call that needs a newer server
131
+ checks that list first: the patient / specimen / extraction calls, specimen measures,
132
+ `link_sequencing_sample_extraction` and `link_sequencing_sample_extractions`, the annotate flow
133
+ (`poll_upload_status`, `wait_for_annotation`, `download_annotated`, `annotate_vcf`), and `upload_file` with
134
+ `metadata` or `file_type`. A server without the capabilities endpoint counts as legacy and reports no features.
135
+
136
+ By default an unsupported call raises `UnsupportedFeatureError`. To run the same code against old and new
137
+ servers, skip those calls instead: they log a warning and return `None`. Two calls downgrade rather than skip
138
+ when the server has the older form of the feature: `upload_file` on a server without upload metadata drops the
139
+ `metadata` and still uploads the file, and `link_sequencing_sample_extractions` on a server with only
140
+ `link_extraction` makes one call per sample.
141
+
142
+ ```
143
+ from variantgrid_api.api_client import VariantGridAPI, UnsupportedFeaturePolicy
144
+
145
+ api = VariantGridAPI(server, api_token, unsupported_feature_policy=UnsupportedFeaturePolicy.SKIP)
146
+ api.create_patient(patient) # skipped on a server without patients
147
+
148
+ # Uploads only when the server has an importer for this file type
149
+ api.upload_file("sample_CombinedVariantOutput.tsv", path=None,
150
+ file_type="dragen_tso500_combined_variant_output")
151
+ ```
152
+
153
+ Where the fallback isn't simply "do nothing", branch on `api.supports("feature")` or
154
+ `api.accepts_upload("file_type")`. `api.capabilities.version` is useful for logging which server you reached.
155
+ For tests, `MockVariantGridAPI(capabilities=ServerCapabilities.LEGACY)` behaves like an old server.
156
+
157
+ ## DRAGEN TSO 500 run-level files
158
+
159
+ A TSO 500 run's `CombinedVariantOutput.tsv` (the pair's TMB / MSI / GIS) and `MetricsOutput.tsv` (library QC)
160
+ are uploaded with the run's name as `sequencing_run` metadata, the only metadata they take:
161
+
162
+ ```
163
+ from variantgrid_api.data_models import UploadFileType
164
+
165
+ api.upload_file("ExampleSample_CombinedVariantOutput.tsv", path=None,
166
+ metadata={"sequencing_run": sequencing_run.name},
167
+ file_type=UploadFileType.DRAGEN_TSO500_COMBINED_VARIANT_OUTPUT)
168
+ api.upload_file("MetricsOutput.tsv", path=None, metadata={"sequencing_run": sequencing_run.name},
169
+ file_type=UploadFileType.DRAGEN_TSO500_METRICS_OUTPUT)
170
+ ```
171
+
172
+ - **MetricsOutput** requires `sequencing_run` - the file never names its run.
173
+ - **CombinedVariantOutput** names its run 'NA', so the server takes the run from `sequencing_run`. Without it,
174
+ the server uses the registered run whose current sample sheet names the pair's sample IDs, and if no registered
175
+ run names the pair the import fails. Register the run and sample sheet first, and send `sequencing_run` anyway.
176
+
177
+ The server reads TMB / MSI / GIS from the CombinedVariantOutput (SACGF/variantgrid#1904), which replaced
178
+ specimen measures. See `examples/example_tso500.py` for a full run.
179
+
180
+ ## Permission to write sequencing data
181
+
182
+ Posts to the server's `seqauto/api/` endpoints - the sequencing `create_*` calls from `create_experiment` through
183
+ `create_sequencing_data` and the QC calls, and the `link_sequencing_sample_extraction(s)` calls - need a
184
+ superuser's API token, or one belonging to a member of the server's SeqAuto write group (`seqauto_api_write`
185
+ unless the server's `SEQAUTO_API_WRITE_GROUP` setting says otherwise). Anyone else gets a 403
186
+ (`requests.HTTPError`). Reads, such as `sequencing_run_has_vcf()`, need only a valid token.
187
+
188
+ ## Testing
189
+
190
+ ```
191
+ # Install required testing packages
192
+ python3 -m pip install -e ".[test]"
193
+ python3 -m pytest --cov=variantgrid_api
194
+ ```
@@ -0,0 +1,173 @@
1
+ # variantgrid_api
2
+
3
+ [![PyPi version](https://img.shields.io/pypi/v/variantgrid_api.svg)](https://pypi.org/project/variantgrid_api/) [![Python versions](https://img.shields.io/pypi/pyversions/variantgrid_api.svg)](https://pypi.org/project/variantgrid_api/)
4
+
5
+ Python API client for [VariantGrid](https://github.com/SACGF/variantgrid) Open source Variant database and analysis platform
6
+
7
+ See [changelog](https://github.com/SACGF/variantgrid_api/blob/main/CHANGELOG.md)
8
+
9
+ ## Install
10
+
11
+ ```
12
+ python3 -m pip install variantgrid_api
13
+ ```
14
+
15
+ ## Example
16
+
17
+ ```
18
+ from variantgrid_api.api_client import VariantGridAPI
19
+ from variantgrid_api.data_models import EnrichmentKit
20
+
21
+ api = VariantGridAPI(server="https://variantgrid.com", api_token="YOUR_API_TOKEN")
22
+ enrichment_kit = EnrichmentKit(name="idt_haem", version=1)
23
+ result = api.create_enrichment_kit(enrichment_kit)
24
+ ```
25
+
26
+ ## Annotate a VCF and download it back
27
+
28
+ Upload a VCF, have VariantGrid import + annotate any novel variants, then download the cohort-level annotated
29
+ export (all samples, single-sample VCFs included). Annotation can take a while, so the quickest way in is the
30
+ `vg_api` command line tool: the first call uploads, and running the same command again downloads the result
31
+ once it's ready.
32
+
33
+ ```console
34
+ $ export VARIANTGRID_API_TOKEN=YOUR_API_TOKEN
35
+ $ vg_api annotate_vcf input.vcf.gz -o results/
36
+ Uploaded input.vcf.gz (id=13256).
37
+ Annotating input.vcf.gz - run the same command again later to download.
38
+
39
+ $ vg_api annotate_vcf input.vcf.gz -o results/ # still annotating
40
+ input.vcf.gz: not ready yet - pipeline Success, import 100.0%, 2 annotation runs remaining. Run the same command again later.
41
+
42
+ $ vg_api annotate_vcf input.vcf.gz -o results/ # once it's done
43
+ Annotated vcf written to results/input.vcf_annotated_v254_GRCh38.vcf.gz
44
+ ```
45
+
46
+ Add `--verbose` to log each request, response and the full upload status to stderr.
47
+
48
+ From Python it's `upload_file()` / `poll_upload_status()` / `download_annotated()`, or the blocking
49
+ `annotate_vcf()` one-liner. See
50
+ **[Annotate a VCF](https://github.com/SACGF/variantgrid_api/wiki/Annotate-a-VCF)** on the wiki for batches, the
51
+ submit-now/download-later pattern, and all the options.
52
+
53
+ ## Patients, specimens and extractions
54
+
55
+ VariantGrid can record which patient, specimen and extraction a lab's sequencing came from. This needs a server
56
+ at or after SACGF/variantgrid#1716.
57
+
58
+ ```
59
+ from variantgrid_api.data_models import Patient, Specimen, Extraction, ExternalReference, NucleicAcid
60
+
61
+ api.create_patient(Patient(patient_code="C0000001"))
62
+ api.create_specimen(Specimen(patient="C0000001", reference_id="2600000001"))
63
+ api.create_extraction(Extraction(specimen="2600000001", reference_id="2600000001C",
64
+ nucleic_acid_source=NucleicAcid.DNA))
65
+ api.upload_file("sample.vcf.gz", path=None,
66
+ metadata={"extraction": "2600000001C", "genome_build": "GRCh37"})
67
+ ```
68
+
69
+ A bare string names a record by its local reference. Use `ExternalReference(code=..., external_type=...)` to
70
+ name it by a LIMS identifier instead. See `examples/example_tso500.py` for a full run.
71
+
72
+ Once the sample sheet is registered, link its sequencing samples to their extractions in one call, keyed on
73
+ sample name (what `SequencingSampleLookup.sample_name` holds):
74
+
75
+ ```
76
+ api.link_sequencing_sample_extractions(sample_sheet_lookup, {"sample_1": "2600000001C",
77
+ "sample_2": "2600000002C"})
78
+ ```
79
+
80
+ It returns a list with one `{"sequencing_sample", "match_status", "match_error", "extraction"}` per sample. An
81
+ extraction the server doesn't have yet is `Pending` for that sample only (HTTP 202) and attaches itself once the
82
+ extraction is created; a sample name that isn't on the sheet is a 400 for the whole batch. On a server from
83
+ before SACGF/variantgrid#2176 (no `link_extractions_bulk` feature) the client makes one
84
+ `link_sequencing_sample_extraction` call per sample instead, so pipelines can use the bulk call unconditionally.
85
+ `link_sequencing_sample_extraction` is still there for a single late link. See `examples/example_haem_20_999.py`.
86
+
87
+ ## BAMs and CRAMs
88
+
89
+ A sequencing sample can have several alignment files, eg a BAM and its recalibrated BAM, or a BAM plus a CRAM.
90
+ List them in `SequencingFile.alignment_files` (and `QC.alignment_files`), the file the variant caller ran on first:
91
+
92
+ ```
93
+ from variantgrid_api.data_models import AlignmentFile, SequencingFile, SingleSampleVCF
94
+
95
+ SequencingFile(sample_name="sample_1",
96
+ alignment_files=[AlignmentFile(path="/data/sample_1.bam", aligner=aligner),
97
+ AlignmentFile(path="/data/sample_1.cram", aligner=aligner)],
98
+ vcf_files=[SingleSampleVCF(path="/data/sample_1.vcf.gz", variant_caller=variant_caller)])
99
+ ```
100
+
101
+ `AlignmentFile.file_type` (`AlignmentFileType.BAM` / `CRAM`) is optional and inferred from the path. A server
102
+ without the `alignment_files` feature gets the old wire format instead: one sequencing file record per alignment
103
+ file as `bam_file`, and a QC's first alignment file as its `bam_file`. A CRAM there also needs the
104
+ `cram_alignment_files` feature. `BamFile` and the `bam_file` fields still work but are deprecated.
105
+
106
+ ## Talking to more than one VariantGrid version
107
+
108
+ Servers of different ages accept different calls. The client asks the server which features it has
109
+ (`GET api/v1/capabilities`, fetched once on first use), and each call that needs a newer server
110
+ checks that list first: the patient / specimen / extraction calls, specimen measures,
111
+ `link_sequencing_sample_extraction` and `link_sequencing_sample_extractions`, the annotate flow
112
+ (`poll_upload_status`, `wait_for_annotation`, `download_annotated`, `annotate_vcf`), and `upload_file` with
113
+ `metadata` or `file_type`. A server without the capabilities endpoint counts as legacy and reports no features.
114
+
115
+ By default an unsupported call raises `UnsupportedFeatureError`. To run the same code against old and new
116
+ servers, skip those calls instead: they log a warning and return `None`. Two calls downgrade rather than skip
117
+ when the server has the older form of the feature: `upload_file` on a server without upload metadata drops the
118
+ `metadata` and still uploads the file, and `link_sequencing_sample_extractions` on a server with only
119
+ `link_extraction` makes one call per sample.
120
+
121
+ ```
122
+ from variantgrid_api.api_client import VariantGridAPI, UnsupportedFeaturePolicy
123
+
124
+ api = VariantGridAPI(server, api_token, unsupported_feature_policy=UnsupportedFeaturePolicy.SKIP)
125
+ api.create_patient(patient) # skipped on a server without patients
126
+
127
+ # Uploads only when the server has an importer for this file type
128
+ api.upload_file("sample_CombinedVariantOutput.tsv", path=None,
129
+ file_type="dragen_tso500_combined_variant_output")
130
+ ```
131
+
132
+ Where the fallback isn't simply "do nothing", branch on `api.supports("feature")` or
133
+ `api.accepts_upload("file_type")`. `api.capabilities.version` is useful for logging which server you reached.
134
+ For tests, `MockVariantGridAPI(capabilities=ServerCapabilities.LEGACY)` behaves like an old server.
135
+
136
+ ## DRAGEN TSO 500 run-level files
137
+
138
+ A TSO 500 run's `CombinedVariantOutput.tsv` (the pair's TMB / MSI / GIS) and `MetricsOutput.tsv` (library QC)
139
+ are uploaded with the run's name as `sequencing_run` metadata, the only metadata they take:
140
+
141
+ ```
142
+ from variantgrid_api.data_models import UploadFileType
143
+
144
+ api.upload_file("ExampleSample_CombinedVariantOutput.tsv", path=None,
145
+ metadata={"sequencing_run": sequencing_run.name},
146
+ file_type=UploadFileType.DRAGEN_TSO500_COMBINED_VARIANT_OUTPUT)
147
+ api.upload_file("MetricsOutput.tsv", path=None, metadata={"sequencing_run": sequencing_run.name},
148
+ file_type=UploadFileType.DRAGEN_TSO500_METRICS_OUTPUT)
149
+ ```
150
+
151
+ - **MetricsOutput** requires `sequencing_run` - the file never names its run.
152
+ - **CombinedVariantOutput** names its run 'NA', so the server takes the run from `sequencing_run`. Without it,
153
+ the server uses the registered run whose current sample sheet names the pair's sample IDs, and if no registered
154
+ run names the pair the import fails. Register the run and sample sheet first, and send `sequencing_run` anyway.
155
+
156
+ The server reads TMB / MSI / GIS from the CombinedVariantOutput (SACGF/variantgrid#1904), which replaced
157
+ specimen measures. See `examples/example_tso500.py` for a full run.
158
+
159
+ ## Permission to write sequencing data
160
+
161
+ Posts to the server's `seqauto/api/` endpoints - the sequencing `create_*` calls from `create_experiment` through
162
+ `create_sequencing_data` and the QC calls, and the `link_sequencing_sample_extraction(s)` calls - need a
163
+ superuser's API token, or one belonging to a member of the server's SeqAuto write group (`seqauto_api_write`
164
+ unless the server's `SEQAUTO_API_WRITE_GROUP` setting says otherwise). Anyone else gets a 403
165
+ (`requests.HTTPError`). Reads, such as `sequencing_run_has_vcf()`, need only a valid token.
166
+
167
+ ## Testing
168
+
169
+ ```
170
+ # Install required testing packages
171
+ python3 -m pip install -e ".[test]"
172
+ python3 -m pytest --cov=variantgrid_api
173
+ ```
@@ -1,21 +1,21 @@
1
1
  [build-system]
2
- requires = ["setuptools", "wheel"]
2
+ requires = ["setuptools>=77.0.0", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "variantgrid_api"
7
- version = "1.8.0"
7
+ version = "1.10.0"
8
8
  description = "A Python API client for VariantGrid"
9
9
  authors = [
10
10
  { name = "Dave Lawrence", email = "davmlaw@gmail.com" }
11
11
  ]
12
12
  readme = "README.md"
13
- license = {file = "LICENSE"}
13
+ license = "MIT"
14
+ license-files = ["LICENSE"]
14
15
  requires-python = ">=3.8"
15
16
  classifiers = [
16
17
  "Development Status :: 3 - Alpha",
17
18
  "Intended Audience :: Developers",
18
- "License :: OSI Approved :: MIT License",
19
19
  "Programming Language :: Python :: 3",
20
20
  ]
21
21
  dependencies = [