From 0688fb4aaa868a87934cb171b327cf84f2c6e479 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 12:45:11 +0100 Subject: [PATCH 01/20] feat: add draft rdf metadata schema --- assets/schema.ttl | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 assets/schema.ttl diff --git a/assets/schema.ttl b/assets/schema.ttl new file mode 100644 index 00000000..e1a81490 --- /dev/null +++ b/assets/schema.ttl @@ -0,0 +1,78 @@ +@prefix ex: +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix xsd: . +@prefix bioschemas: . +@prefix taxon: . +@prefix schema: . +@prefix mondo: . +@prefix ror: . +@prefix smoc: . + +# Classes + +smoc:MODO a rdfs:Class ; + rdfs:label "Multi-Omics Digital Object" ; + rdfs:comment "A digital object which can contain multiple omics data records and samples" . + +smoc:CRAMFile a rdfs:Class ; + rdfs:label "CRAM file" ; + rdfs:comment "A file containing aligned genomic intervals" . + +smoc:ZarrArchive a rdfs:Class ; + rdfs:label "Zarr archive" ; + rdfs:comment "A Zarr archive containing metadata and nested array. Part of a digital object." . + +smoc:Reference a rdfs:Class ; + rdfs:label "Reference genome" ; + rdfs:comment "A genome assembly used as reference coordinate system for aligning data records." + +smoc:BioSample a rdfs:Class ; + rdfs:label "Biological sample" ; + rdfs:comment "A sample of biological material." . + +smoc:Taxon a rdfs:Class ; + rdfs:label "Taxon" ; + rdfs:comment "A taxonomic unit describing a biological entity" . + +smoc:OmicsType a rdfs:Class ; + rdfs:label "Omics type" ; + rdfs:comment "A type of omics field, tied to a biological molecule" ; + +# Properties + +smoc:hasTaxonomicRange a rdf:Property ; + rdfs:domain smoc:BioSample ; + rdfs:range smoc:Taxon ; + rdfs:label "has taxonomic range" . + +smoc:hasSample a rdf:Property ; + rdfs:domain smoc:MODO, + +smoc:hasRecord a rdf:Property ; + rdfs:domain smoc:MODO ; + rdfs:range smoc:Record ; + rdfs:label "has record" . + +smoc:hasReference a rdf:Property ; + rdfs:domain smoc:MODO, smoc:Record ; + rdfs:range smoc:Reference . + +smoc:hasOmicsType a rdf:Property ; + rdfs:domain smoc:Record ; + rdfs:range smoc:OmicsType . + +smoc:hasLocation a rdf:property ; + rdfs:domain smoc:MODO, smoc:CRAMFile, smoc:Reference, smoc:ZarrArchive ; + rdfs:range xsd:string, xsd:uri ; + rdfs:label "has location" ; + rdfs:comment "The location of a resource, either on the filesystem or online" . + + +# Named individuals + +smoc:Genomics a smoc:OmicsType . +smoc:Transcriptomics a smoc:OmicsType . +smoc:Proteomics a smoc:OmicsType . +smoc:Metabolomics a smoc:OmicsType . From 67a8fb53ac05c501598029dd05571df47afac7a3 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 13:03:11 +0100 Subject: [PATCH 02/20] feat: add taxid in schema --- assets/schema.ttl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/schema.ttl b/assets/schema.ttl index e1a81490..d0c6de92 100644 --- a/assets/schema.ttl +++ b/assets/schema.ttl @@ -1,4 +1,4 @@ -@prefix ex: +@prefix ex: . @prefix rdf: . @prefix rdfs: . @prefix skos: . @@ -32,6 +32,7 @@ smoc:BioSample a rdfs:Class ; rdfs:label "Biological sample" ; rdfs:comment "A sample of biological material." . +# In practice, we should use http://purl.obolibrary.org/obo/ncbitaxon.owl smoc:Taxon a rdfs:Class ; rdfs:label "Taxon" ; rdfs:comment "A taxonomic unit describing a biological entity" . @@ -43,7 +44,7 @@ smoc:OmicsType a rdfs:Class ; # Properties smoc:hasTaxonomicRange a rdf:Property ; - rdfs:domain smoc:BioSample ; + rdfs:domain smoc:BioSample, smoc:Reference ; rdfs:range smoc:Taxon ; rdfs:label "has taxonomic range" . @@ -69,6 +70,9 @@ smoc:hasLocation a rdf:property ; rdfs:label "has location" ; rdfs:comment "The location of a resource, either on the filesystem or online" . +smoc:hasTaxId a rdf:Property ; + rdfs:domain smoc:Taxon ; + rdfs:range xsd:integer # Named individuals From b005f9118b7461511531f3add48f63e7f85ce7a3 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 15:47:36 +0100 Subject: [PATCH 03/20] test: add test data --- data/ex1/demo1.cram | Bin 0 -> 47724 bytes data/ex1/demo2.cram | Bin 0 -> 47724 bytes data/ex1/ecoli_ref.fa | 199 ++++++++++++++++++++++++++++++++++++++++++ data/ex1/metadata.ttl | 28 ++++++ 4 files changed, 227 insertions(+) create mode 100644 data/ex1/demo1.cram create mode 100644 data/ex1/demo2.cram create mode 100644 data/ex1/ecoli_ref.fa create mode 100644 data/ex1/metadata.ttl diff --git a/data/ex1/demo1.cram b/data/ex1/demo1.cram new file mode 100644 index 0000000000000000000000000000000000000000..448c6facf4e7dae420b6bdee25f46c9dfd39eaec GIT binary patch literal 47724 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 vvYXj|UZh}1&;-IyAbBA000007.3 Escherichia coli O157:H7 str. Sakai DNA, part of genome +AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTCTCTGACAGCAGCTTCTGAACTG +GTTACCTGCCGTGAGTAAATTAAAATTTTATTGACTTAGGTCACTAAATACTTTAACCAATATAGGCATAGCGCACAGAC +AGATAAAAATTACAGAGTACACAACATCCATGAAACGCATTAGCACCACCATTACCACCACCATCACCACCACCATCACC +ATTACCATTACCACAGGTAACGGTGCGGGCTGACGCGTACAGGAAACACAGAAAAAAGCCCGCACCTGACAGTGCGGGCT +TTTTTTTCGACCAAAGGTAACGAGGTAACAACCATGCGAGTGTTGAAGTTCGGCGGTACATCAGTGGCAAATGCAGAACG +TTTTCTGCGGGTTGCCGATATTCTGGAAAGCAATGCCAGGCAGGGGCAGGTGGCCACCGTCCTCTCTGCCCCCGCCAAAA +TCACCAACCACCTGGTGGCGATGATTGAAAAAACCATTAGCGGCCAGGATGCTTTACCCAATATCAGCGATGCCGAACGT +ATTTTTGCCGAACTTCTGACGGGACTCGCCGCCGCCCAGCCGGGATTCCCGCTGGCGCAATTGAAAACTTTCGTCGACCA +GGAATTTGCCCAAATAAAACATGTCCTGCATGGCATTAGTTTGTTAGGGCAGTGCCCGGATAGCATTAACGCTGCGCTGA +TTTGCCGTGGCGAGAAAATGTCGATCGCCATTATGGCCGGCGTATTAGAAGCGCGCGGTCACAACGTTACCGTTATCGAT +CCGGTCGAAAAACTGCTGGCAGTGGGGCATTACCTCGAATCTACTGTCGATATTGCAGAGTCCACCCGCCGTATTGCGGC +AAGTCGTATTCCGGCTGATCACATGGTGCTGATGGCAGGTTTCACCGCCGGTAATGAAAAAGGCGAACTGGTGGTACTTG +GACGCAACGGTTCCGACTACTCCGCGGCGGTGCTGGCTGCCTGTTTACGCGCCGATTGTTGCGAGATTTGGACGGACGTT +GACGGGGTATATACCTGCGACCCGCGTCAGGTGCCCGATGCGAGGTTGTTGAAATCGATGTCCTACCAGGAAGCGATGGA +GCTTTCCTACTTCGGCGCTAAAGTTCTTCACCCCCGCACCATTACCCCCATCGCCCAGTTCCAGATCCCTTGCCTGATTA +AAAATACCGGAAATCCTCAAGCTCCAGGTACGCTCATTGGTGCCAGTCGTGATGAAGACGAATTACCGGTCAAGGGCATT +TCCAATCTGAATAATATGGCAATGTTCAGCGTTTCCGGCCCGGGGATGAAAGGAATGGTCGGCATGGCGGCGCGCGTCTT +TGCTGCAATGTCACGCGCCCGTATTTCCGTGGTGCTGATTACGCAATCATCTTCCGAATACAGTATCAGTTTCTGCGTTC +CGCAAAGCGACTGTGTGCGAGCTGAACGGGCAATGCAGGAAGAGTTCTACCTGGAACTGAAAGAAGGCTTACTGGAGCCG +CTGGCGGTGACGGAACGGCTGGCCATTATCTCGGTGGTAGGTGATGGTATGCGCACCTTGCGTGGGATCTCGGCGAAATT +CTTTGCCGCGCTGGCCCGCGCCAATATCAACATTGTCGCTATTGCTCAGGGATCTTCTGAACGCTCAATCTCTGTCGTGG +TAAATAACGATGATGCGACCACTGGCGTGCGCGTTACTCATCAGATGCTGTTCAATACCGATCAGGTTATCGAAGTGTTT +GTGATTGGCGTCGGTGGCGTTGGCGGTGCGCTGCTGGAGCAACTGAAGCGTCAGCAAAGCTGGTTGAAGAATAAACATAT +CGACTTACGTGTCTGCGGTGTTGCTAACTCGAAGGCTCTGCTCACCAATGTGCATGGCCTAAATCTGGAAAACTGGCAGG +AAGAACTGGCGCAAGCCAAAGAGCCGTTTAATCTCGGGCGCTTAATTCGCCTCGTGAAAGAATATCATCTGCTGAACCCG +GTCATTGTTGACTGCACCTCCAGCCAGGCAGTGGCGGATCAATATGCCGACTTCCTGCGCGAAGGTTTCCACGTTGTCAC +GCCGAACAAAAAGGCCAACACCTCGTCGATGGATTACTACCATCTGTTGCGTCATGCGGCTGAAAAATCGCGGCGTAAAT +TCCTCTATGACACCAACGTTGGGGCTGGATTACCGGTTATTGAGAACCTGCAAAATCTGCTCAATGCTGGTGATGAATTG +ATGAAGTTCTCCGGCATTCTTTCAGGTTCGCTTTCTTATATCTTCGGCAAGTTAGACGAAGGCATGAGTTTCTCCGAGGC +GACTACGCTGGCGCGGGAAATGGGTTATACCGAACCGGATCCGCGAGATGATCTTTCTGGTATGGATGTAGCGCGTAAAC +TATTAATTCTCGCTCGTGAAACGGGACGTGAACTGGAGCTGGCGGATATTGAAATTGAACCTGTGCTGCCCGCAGAGTTT +AACGCTGAGGGTGATGTTGCCGCTTTTATGGCGAATCTGTCACAGCTCGACGATCTCTTTGCCGCGCGCGTGGCGAAGGC +CCGTGATGAAGGAAAAGTTTTGCGCTATGTTGGCAATATTGATGAAGATGGCGTCTGCCGCGTGAAGATTGCCGAAGTGG +ATGGTAATGATCCGCTGTTCAAAGTGAAAAATGGCGAAAACGCCCTGGCCTTTTATAGCCACTATTATCAGCCGCTGCCG +TTGGTGCTGCGCGGATATGGTGCGGGCAATGACGTTACCGCTGCCGGTGTCTTTGCCGATCTGCTACGTACCCTCTCATG +GAAGTTAGGAGTCTGACATGGTTAAAGTTTATGCCCCGGCTTCCAGTGCCAATATGAGCGTCGGGTTTGATGTGCTCGGG +GCGGCGGTGACACCCGTTGATGGTGCATTGCTCGGAGATGTAGTCACGGTTGAGTCGGCAGAGACATTCAGTCTCAACAA +CCTCGGACGCTTTGCCGATAAGCTGCCGTCAGAACCACGGGAAAATATCGTTTATCAGTGCTGGGAGCGTTTTTGCCAGG +AGCTGGGCAAGCAAATTCCAGTGGCGATGACTCTGGAAAAGAATATGCCGATCGGTTCGGGCTTAGGCTCCAGCGCCTGT +TCGGTGGTCGCGGCTCTGATGGCGATGAATGAACACTGCGGCAAGCCGCTTAATGACACCCGTTTGCTGGCTTTGATGGG +CGAGCTGGAAGGACGAATCTCCGGCAGCATTCATTACGACAACGTGGCACCGTGTTTTCTTGGTGGTATGCAGTTGATGA +TCGAAGAAAACGACATCATCAGCCAGCAAGTGCCAGGGTTTGATGAGTGGCTGTGGGTGCTGGCGTATCCGGGGATTAAA +GTCTCGACGGCAGAAGCCCGGGCTATTTTACCGGCGCAGTATCGCCGCCAGGATTGCATTGCGCACGGGCGACACTTGGC +AGGCTTCATTCACGCCTGCTATTCCCGTCAGCCTGAGCTTGCCGCGAAGCTGATGAAAGATGTTATCGCAGAACCCTACC +GTGAACGGTTACTGCCTGGCTTCCGGCAGGCGCGGCAGGCGGTCGCGGAAATCGGCGCGGTAGCGAGCGGTATCTCCGGC +TCCGGCCCGACCTTGTTTGCTCTGTGTGACAAGCCGGATACCGCCCAGCGCGTTGCCGACTGGTTGGGTAAGAACTACCT +GCAAAATCAGGAAGGTTTTGTTCATATTTGCCGGCTGGATACGGCGGGCGCACGAGTACTGGAAAACTAAATGAAACTCT +ACAATCTTAAAGATCACAATGAGCAGGTCAGCTTTGCGCAAGCCGTAACCCAGGGGTTGGGCAAAAATCAGGGGCTGTTT +TTTCCGCACGACCTGCCGGAATTCAGCCTGACTGAAATTGATGAGATGCTGAAGCTGGATTTTGTCACCCGCAGTGCGAA +GATCCTCTCGGCGTTTATTGGTGATGAAATCCCGCAGGAAATCCTGGAAGAGCGCGTGCGCGCGGCGTTTGCCTTCCCGG +CTCCGGTCGCCAATGTTGAAAGCGATGTCGGTTGTCTGGAATTGTTCCACGGGCCAACGCTGGCATTTAAAGATTTCGGC +GGTCGCTTTATGGCACAAATGCTGACCCATATTGCGGGCGATAAGCCAGTGACCATTCTGACCGCGACCTCCGGTGATAC +CGGAGCGGCAGTGGCTCATGCTTTCTACGGTTTACCGAATGTGAAAGTGGTTATCCTTTATCCACGAGGCAAAATCAGTC +CACTGCAAGAAAAACTGTTCTGTACATTGGGCGGCAATATCGAAACTGTTGCCATCGACGGCGATTTCGATGCCTGTCAG +GCGCTGGTGAAGCAGGCGTTTGATGATGAAGAGCTGAAAGTGGCGCTGGGGTTAAACTCAGCTAACTCGATTAACATTAG +CCGGTTGCTGGCGCAGATTTGCTACTACTTTGAAGCAGTTGCGCAGCTGCCGCAGGAAGCGCGCAACCAGCTGGTTGTCT +CGGTGCCAAGCGGAAACTTCGGCGATTTGACGGCGGGTCTGCTGGCGAAGTCACTCGGTCTGCCGGTGAAACGTTTTATT +GCTGCGACCAACGTGAACGATACCGTGCCACGTTTCCTGCATGACGGTCAGTGGTCACCCAAAGCGACTCAGGCGACGTT +ATCCAACGCGATGGACGTGAGTCAGCCGAACAACTGGCCGCGTGTGGAAGAGTTGTTCCGCCGCAAAATCTGGCAACTGA +AAGAGCTGGGTTATGCCGCCGTGGATGATGAAACCACGCAACAGACAATGCGTGAGTTAAAAGAACTGGGCTACACTTCG +GAGCCGCACGCTGCCGTAGCGTATCGTGCGCTGCGTGACCAGTTGAATCCAGGCGAATATGGCTTGTTCCTCGGCACCGC +GCATCCGGCGAAATTTAAAGAGAGCGTGGAAGCGATTCTCGGTGAAACGTTGGATCTGCCAAAAGAGCTGGCAGAACGTG +CCGATTTACCCTTGCTTTCGCATAATCTGCCCGCCGATTTTGCTGCGTTGCGTAAATTGATGATGAATCATCAGTAACAT +CTATTCATTATCTCAATCAGGCCGGGTTTGCTTTTATGCAGCCCGGCTTTTTTGTGAAGAAAATATGGAGAGAAACGACA +GGGAAAAAGGAGAAATTCTCAATAAATGCGGTAACTTAGAGATTAGGATTGCGGAGAATAACAACCGCCGCTCTCATCGC +GTAATCTCCGGATATCGACCCATAACGGGCAATGATAAAAGGAGTAACCTGTGAAAAAGATGCAATCTATCGTACTCGCA +CTTTCCCTGGTTCTGGTCGCTCCCATGGCAACGCAGGCTGCGGAAATTACGTTAGTCCCGTCAGTAAAATTACAGATAGG +CGATCGTGATAATCGCGGTTATTACTGGGATGGCGGTCACTGGCGCGACCACGGCTGGTGGAAACAACATTATGAATGGC +GAGGCAATCGCTGGCACCCACACGGACCGCCGCCACCGCCGCGTCACCATAAGAAAGCTCATCATGATCATCACGGCGGT +CATGGTCCAGGCAAACATCACCGCTAAATGACAAATGCCGGGTAACAATCCGGCATTCAGCGCCTGATGCGACGCTGGCG +CGTCTTATCAGGCCTACGTGAATTCTGCAATATATTGAATCTGCATGCTTTTGTAGGCCGGATAAGGCGTTCACGCCGCA +TCCGGCATTGACTACAAACTTAACGCTGCTCGTAGCGTTTAAACACCAGTTCGCCATTGCTGGAGGAAGCTTCATCAAAG +AAGTAACCTTCGCTATTAAAACCAGTCAGTTGCTCTGGTTTGGTCAGCCGATTTTCAATAATGAAACGACTCATCAGACC +GCGTGCTTTCTTAGCGTAGAAGCTGATTATCTTAAATTTGCCGTTCTTCTCATCGAGGAACACCGGCTTGATAATCTCGG +CATTCAATTTCTTCGGCTTCACCGATTTAAAATACTCATCTGACGCCAGATTAATCACCACATTATCGCCTTGTGCTGCG +AGCGCCTCGTTCAGCTTGTTGGTGATGATATCTCCCCAGAATTGATACAGATCTTTCCCTCGGGCATTCTCAAGACGGAT +CCCCATTTCCAGACGATAAGGCTGCATTAAATCGAGCGGGCGGAGTACGCCATACAAGCCGGAAAGCATTCGCAAATGCT +GTTGGGCAAAATCGAAATCGTCTTCGCTGAAGGTTTCGGCCTGCAAGCCGGTGTAGACATCACCTTTAAACGCCAGAATC +GCCTGGCGGGCATTCTCCGGCGTGAAATCTGGCTGCCAGTCATGAAAGCGAGCGGCGTTGATACCTGCCAGTTTGTCGCT +GATACGCATCAGCGTGCTAATCTGCGGAGGCGTCAGTTTCCGCGCTTCATGGATCAACTGCTGGGAATTGTCTAACAGCT +CCGGCAGTGTATATCGCGTGGTGGTCAACGGGCTTTGGTAATCAAGCGTTTTCGCAGGTGAAATAAGAATCAGCATATCC +AGTCCTTGCAGGAAATTTATGCCGACTTTAGCAAAAAAAGAGAATGAGTTGATCGATAGTTGTGATTACTCCTGCGAAAC +ATCATCCCACGCGTCCCGAGAAAGCTGGCGACCGATATCCGGATAACGCAACGGATCAAACACCGGGCGCACGCCGAGTT +TACGCTGGCGTAGATAATCACTGGCAATGGTATGAACCACAGGCGAGAGCAGTAATATGGCAGTCAAATTGGTAATAGCC +ATGCAGGCCATTATGATATCTGCCAGTTGCCACATCAGCGGAAGACTTAGCAAGGTGCCGCCGATGACCGTTGCGAAGGT +GCAGATCCGCAAACACCAGATCGCTTTAGGGTTGTTCAGGCGTAAAAAGAAGAGATTGTTTTCGGCATAAATGTAGTTGG +CAACGATGGAGCTGAAGGCAAACAGAATAACCACGAGGGTAACAAATTCAGCACCCCAGGAACCCATTAGCACCCGCATC +GCCTTCTGGATAAGCTGAATACCTTCCAGCGGCATGTAGGTTGTGCCGTTACCCGCCAGTAATATCAGCATGGCGCTTGC +CGTACAGATGACCAGGGTGTCGATAAAAATGCCAATCATCTGGACAATTCCTTGCGCTGCCGGATGCGGAGGCCAGGACG +CCGCTGCCGCTGCCGCGTTTGGCGTCGACCCCATTCCCGCCTCATTGGAAAACATACTGCGCTGAAAACCGTTAGTAATC +GCCTGGCTTAAGGTATATCCCGCCGCGCCGCCTGCCGCTTCCTGCCAGCCAAAAGCACTCTCAAAAATAGACCAAATGAC +GTGGGGAAGTTGCCCGATATTTATTACGCAAATCACCAGGCTGGTCAGTACCCAGATTATCGCCATCAACGGGACAAACC +CCTGCATGAGCCGGGCGACGCCATGAAGACCGCGAATGATTGCCAGCAGAGCAAAGACAGCAAGAATAATGCCTGTCACC +AGCGGGGGAAAATCAAAAGAAAAACTCAGAGCTCGGGCAACAGCGTTTGCCTGAACTCCGCTGAAAATTATGCCGTAGGC +GATGAGCAAAAAGACGGCGAACAGAACGCCCATCCAGCGCATCCCCAGCCCGCGCGCCATATACCATGCCGGTCCGCCAC +GAAACTGCCCATTGACGTCACGTTCTTTATAAAGTTGTGCAAGGGAACATTCGGCAAACGAGGTCGCCATGCCGATAAAC +GCGGCAACCCACATCCAAAAGACGGCTCCAGGTCCACCGGCGGTAATAGCCAGCGCAACGCCGGCCAGGTTGCCGCTACC +CACGCGCGCCGCAAGACTGGTACACAATGACTGAAATGAGGTTAAACCGCCTGGCTGTGGATGAATGCTATTTTTAAGAC +TTTTGCCAAACTGGCGGATGTAGCGAAACTGCACAAATCCGGTGCGAAAAGTGAACCAACAACCTGCGCCGAAGAGCAGG +TAAATCATTACCGATCCCCAAAGGACGCTGTTAATAAAGGAGAAAAAATCTGGCATGCATATCCCTCTTATTGCCGGTCG +CGATGACTTTCCTGTGTAAACGTTACCAATTGTTTAAGAAGTATATACGCTACGAGGTACTTGATAACTTCTGCGTAGCA +TACATGAGGTTTTGTTTAAAAATGGCGGGCGATATCAACGCAGTGTCAGAAATCCGAAACAGTCTCGCCTGGCGATAACC +GTCTTGTCGGCGGTTGCGCTGACGTTGCGTCGTGATATCATCAGGGCAGACCGGTTACATCCCCCTAACAAGCTGTTTAA +AGAGAAATACTATCATGACGGACAAATTGACCTCCCTTCGTCAGTACACCACCGTAGTGGCCGACACTGGGGACATCGCG +GCAATGAAGCTGTATCAACCGCAGGATGCCACAACCAACCCTTCTCTCATTCTTAACGCAGCGCAGATTCCGGAATACCG +TAAGTTGATTGATGATGCTGTCGCCTGGGCGAAACAGCAGAGCAACGATCGCGCGCAGCAGATCGTGGACGCGACTGACA +AACTGGCAGTAAATATTGGTCTGGAAATCCTGAAACTGGTTCCGGGCCGTATCTCAACTGAAGTTGATGCGCGTCTTTCC +TATGACACAGAAGCGTCAATTGCGAAAGCAAAACGCCTGATCAAACTCTACAACGATGCAGGTATTAGCAACGATCGTAT +TCTGATCAAACTGGCTTCTACCTGGCAGGGTATCCGTGCTGCGGAACAGCTGGAAAAAGAAGGTATCAACTGTAACCTGA +CCCTGCTGTTCTCCTTCGCTCAGGCTCGTGCTTGTGCGGAAGCGGGCGTGTTCCTGATCTCGCCGTTTGTTGGCCGTATT +CTTGACTGGTACAAAGCGAATACCGATAAGAAAGAGTACGCTCCGGCAGAAGATCCGGGCGTGGTTTCTGTATCTGAAAT +CTACCAGTACTACAAAGAGCACGGTTATGAAACCGTGGTTATGGGCGCAAGCTTCCGTAACATCGGCGAAATTCTGGAAC +TGGCAGGCTGCGACCGTCTGACCATCGCACCGGCACTGCTGAAAGAGCTGGCTGAGAGCGAAGGGGCTATCGAACGTAAA +CTGTCTTACACCGGCGAAGTGAAAGCGCGTCCGGCGCGTATCACTGAGTCCGAGTTCCTGTGGCAGCACAACCAGGATCC +AATGGCAGTAGATAAACTGGCGGAAGGTATCCGTAAGTTTGCTATTGACCAGGAAAAACTGGAAAAAATGATCGGCGATC +TGCTGTAATCATTCTTAGCGTGACCGGGAAGTCGGTCACGCTACCTCTTCTGAAGCCTGTCTGTCACTCCCTTCGCAGTG +TATCATTCTGTTTAACGAGACTGTTTAAACGGAAAAATCTTGATGAATACTTTACGTATTGGCTTAGTTTCCATCTCTGA +TCGCGCATCCAGCGGCGTTTATCAGGATAAAGGTATCCCTGCGCTGGAAGAATGGCTGACATCGGCGCTAACCACGCCGT +TTGAACTGGAAACCCGCTTAATCCCCGATGAGCAGGCGATCATCGAGCAAACGTTGTGTGAGCTGGTGGATGAAATGAGT +TGCCATCTGGTGCTCACCACGGGCGGAACTGGCCCGGCGCGTCGTGACGTAACGCCCGATGCGACGCTGGCAGTAGCGGA +CCGCGAGATGCCTGGCTTTGGTGAACAGATGCGCCAGATCAGCCTGCATTTTGTACCAACTGCGATCCTTTCGCGTCAGG +TGGGTGTGATTCGCAAACAGGCGCTGATCCTTAACTTACCCGGTCAGCCGAAGTCTATTAAAGAGACGCTGGAAGGTGTG +AAGGACGCTGAGGGTAACGTTGTGGTACACGGTATTTTTGCCAGCGTACCGTACTGCATTCAGTTGCTGGAAGGGCCATA +CGTTGAAACGGCACCAGAAGTGGTTGCTGCATTCAGACCGAAGAGTGCAAGACGCGACGTTAGCGAATAAAAAAATCCCC +CCGAGCGGGGGGATCTCAAGACAATTAGTGGGATTCACCAATCGGCAGAACGGTGCGACCAAACTGCTCGTTCAGTACTT +CACCCATCGCCAGATAGATTGCGCTGGCACCGCAGATCAGACCAATCCAGCCGGCAAAGTGGATGATTGCGGCGTTACCG +GCAATGTTACCGATCGCCAGCAGGGCAAACAGCACGGTCAGGCTAAAGAAAACGAATTGCAGAACGCGTGCGCCTTTCAG +CGTGCCGAAGAACATAAACAGCGTAAATACGCCCCACAGACCCAGGTAGACACCAAGGAACTGTGCATTTGGCGCATCGG +TCAGACCCAGTTTCGGCATCAGCAGAATCGCAACCAGCGTCAGCCAGAAAGAACCGTAAGAGGTGAATGCGGTTAAACCG +AAAGTGTTGCCTTTTTTGTACTCCAGCAGACCAGCAAAAATTTGCGCGATGCCGCCGTAGAAAATGCCCATGGCAAGAAT +AATACCGTCCAGAGCGAAATAACCTACGTTGTGCAGGTTAAGCAGAATGGTGGTCATGCCGAAGCCCATCAGGCCCAGCG +GTGCCGGATTAGCCAACTTAGTGTTGCCCATAATTCCTCAAAAATCATCATCGAATGAATGGTGAAATAATTTCCCTGAA +TAACTGTAGTGTTTTCAGGGCGCGGCATAATAATCAGCCAGTGGGGCAGTGTCTACGATCTTTTGAGGGGAAAATGAAAA +TTTTCCCCGGTTTCCGGTATCAGACCTGAGTGGCGCTAACCATCCGGCGCAGGCAGGCGATTTGCAGTACGGCTGGAATC +GTCACGCGATAGGAGCTGCCGCTGACCGCTTTAACCCCATTTAGTGCCGCGCCTACAGGGCCTCCCAGCCCCGCGCCGCG +CAGCAAACCATGCCCAAGTACGCTCATTGCTGCGTGGGTGCGTAAAATGCGGGTCAGTTGGCTGGAAAGCAGATGCGACA +CGCCTTTTGCCAATAATTTGTCTTTCATCAGCAGCGGCAGCAGCTCTTCCAGCTCATTCACCCTGGCATCGACCGCGTGC +AGAAACTCCTGCTTATGTTCCTCGTCCATTTTCTTCCAGGTATTACGCAGAAATTGTTCCAGTAACTGTTGCTCAATTTC +AAACGTAGACATCTCTTTGTCGGCTTTCAGCTTCAATCGTTTTGAAACATCGAGCAAAATGGCCCGATACAATTTACCGT +GTCCGCGCAGTTTGTTGGCGATACTATCGCCACCAAAATGCTGTAATTCTCCAGCAATCAGCTGCCAGTTGCGGCGATGT +TGCTCGGGATGTCCTTCCATCGATTTAAACAGTTCGTTGCGCATCAGTACGCTGGAGAGGCGAGTTTTGCCTTTTTCATT +ATGGGTGAGCAGCCGGGCGAAATTTGCTAACTGTTCCTCACTACAATGCTGGAGAAAATCCAGATCTGAATCATTCAGGT +AATTAACATTCATTTTTTGTGGCTTCTATATTCTGGCGTTAGTCGTCGCCGATAATTTTCAGCGTGGCCATATCCGATGA +GTTCACCGTATGACCGGAAAAGGTGATTTTTGAGACGCAGCGTTTATTGTCGTTATCGCTGTTAATGTTGATCCAGTCAG +TGGTTTGCCCTTCTTTTATTTCTGAAGGAATATTCAGGCTCTGACTGGCGCTACGGGCGGCTTTGAAATAAACCGATGCA +CCGCTTAACTGTAAATCGCCATGGTCGGCAGAGAGTTGTATGCGTTTCACAATGCGACAAACAGGAAGTTTCAGCGCCAG +AGCGTTGGTTTCGTTACGCGGCATTGCAATGACGCCGAGGAGTTTATGGTCGTTTGCCTGCGCCGTGCAGCACAGCATCA +GGCTAATCGCCAGGCTGGCGGAAATCGTAAAAACGGATTTCATAAGGATTCTCTTAGTGGGAAGAGGTAGGGGGATGAAT +ACCCACTAGTTTACTGCTGATAAAGAGAAGATTCAGGCACGTAATCTTTTCTTTTTATTACAATTTTTTGATGAATACCT +TGACTGCGATTCATTCTTTATATGAATAAAATTGCTGTCAATTTTACGTCTTGTCCTGCCATATCGCGAAATTTCTGCGC +AAAAGCACAAAAAATTTTTGCATCTCCCCCTTGATGACGTGGGTTACGACCCCATTTAGTAGTCAACCGCAGTGAGTGAG +TCTGCAAAAAAATGAAATTGGGCAGTTGAAACCAGACGTTTCGCCCCTATTACAGACTCACAACCACATGATGACCGAAT +ATATAGTGGAGACGTTTAGATGGGTAAAATAATTGGTATCGACCTGGGTACTACCAACTCTTGTGTAGCGATTATGGATG +GCACCACTCCTCGTGTGCTGGAGAACGCCGAAGGCGATCGCACCACGCCTTCTATCATTGCCTATACCCAGGATGGTGAA +ACTCTGGTTGGTCAGCCGGCTAAACGTCAGGCAGTGACGAACCCGCAAAACACCCTGTTTGCGATTAAACGCCTGATTGG +CCGCCGCTTCCAGGACGAAGAAGTACAGCGTGATGTTTCCATCATGCCGTTCAAAATTATTGCTGCTGATAACGGCGACG +CATGGGTCGAAGTTAAAGGCCAGAAAATGGCACCGCCGCAGATTTCTGCTGAAGTGCTGAAAAAAATGAAGAAAACCGCT +GAAGATTACCTGGGTGAACCGGTAACTGAAGCTGTTATCACCGTACCGGCATACTTTAACGATGCTCAGCGTCAGGCAAC +CAAAGACGCAGGCCGTATCGCTGGTCTGGAAGTAAAACGTATCATCAACGAACCGACCGCAGCTGCGCTGGCTTACGGTC +TGGACAAAGGTACTGGCAACCGTACTATCGCGGTTTATGACTTGGGTGGTGGTACTTTCGATATTTCTATTATCGAAATC +GACGAAGTTGACGGCGAAAAAACCTTCGAAGTTCTGGCAACCAACGGTGATACCCACCTGGGTGGTGAAGACTTCGACAG +CCGTCTGATCAACTATCTGGTTGAAGAATTCAAGAAAGATCAGGGCATTGACCTGCGCAACGATCCGCTGGCAATGCAGC +GCCTGAAAGAAGCGGCAGAAAAAGCGAAAATCGAACTGTCTTCCGCTCAGCAGACCGACGTTAACCTGCCGTACATCACT +GCAGACGCGACCGGTCCGAAACACATGAACATCAAAGTGACTCGTGCGAAACTGGAAAGCCTGGTTGAAGATCTGGTTAA +CCGTTCCATCGAGCCGCTGAAAGTTGCGCTGCAGGACGCTGGCCTGTCCGTATCTGATATCGACGACGTTATCCTCGTTG +GTGGTCAGACTCGTATGCCAATGGTTCAGAAGAAAGTTGCTGAGTTCTTTGGTAAAGAGCCGCGTAAAGACGTTAACCCG +GACGAAGCTGTAGCAATCGGTGCTGCTGTTCAGGGTGGTGTTCTGACTGGTGACGTAAAAGACGTACTGCTGCTGGATGT +TACCCCGCTGTCTCTGGGTATCGAAACCATGGGCGGTGTGATGACGACGCTGATCGCGAAAAACACCACTATCCCGACCA +AGCACAGCCAGGTGTTCTCTACCGCTGAAGACAACCAGTCTGCGGTAACCATCCATGTGCTGCAGGGTGAACGTAAACGT +GCGGCTGACAACAAATCTCTGGGTCAGTTCAACCTGGATGGTATCAACCCGGCACCGCGCGGCATGCCGCAGATCGAAGT +TACCTTCGATATCGATGCTGACGGTATCCTGCACGTTTCCGCGAAAGATAAAAACAGCGGTAAAGAGCAGAAGATCACCA +TCAAGGCGTCTTCTGGTCTGAACGAAGATGAAATCCAGAAAATGGTACGCGACGCCGAAGCTAACGCCGAAGCTGACCGT +AAGTTTGAAGAGCTGGTACAGACTCGCAACCAGGGCGACCATCTGCTGCACAGCACCCGTAAGCAGGTTGAAGAAGCAGG +CGACAAACTGCCGGCTGACGACAAAACTGCTATCGAGTCTGCGCTGACTGCACTGGAAACTGCTCTGAAAGGTGAAGACA +AAGCCGCTATCGAAGCGAAAATGCAGGAACTGGCACAGGTTTCCCAGAAACTGATGGAAATCGCCCAGCAGCAACATGCC +CAGCAGCAGACTGCCGGTGCTGATGCTTCTGCAAACAACGCGAAAGATGACGATGTTGTCGACGCTGAATTTGAAGAAGT +CAAAGACAAAAAATAATCGCCCTATAAACGGGTAATTATACTGACACGGGCGAAGGGGAATTTCCTCTCCGCCCGTGCAT +TCATCTAGGGGCAATTTAAAAAAGATGGCTAAGCAAGATTATTACGAGATTTTAGGCGTTTCCAAAACAGCGGAAGAGCG +TGAAATCAAAAAGGCCTACAAACGCCTGGCCATGAAATACCACCCGGACCGTAACCAGGGTGACAAAGAGGCCGAGGCGA +AATTTAAAGAGATCAAGGAAGCTTATGAAGTTCTGACCGACTCGCAAAAACGTGCGGCATACGATCAGTATGGTCATGCT +GCGTTTGAGCAAGGTGGCATGGGCGGCGGCGGTTTTGGCGGCGGCGCAGACTTCAGCGATATTTTTGGTGACGTTTTCGG +CGATATTTTTGGCGGCGGACGTGGTCGTCAACGTGCGGCGCGCGGTGCTGATTTACGCTATAACATGGAGCTCACCCTCG +AAGAAGCTGTACGTGGCGTGACCAAAGAGATCCGCATTCCGACTCTGGAAGAGTGTGACGTTTGCCACGGTAGCGGTGCA +AAACCAGGTACACAGCCGCAGACCTGTCCGACCTGTCATGGTTCTGGTCAGGTGCAGATGCGCCAGGGTTTCTTTGCCGT +GCAGCAGACCTGTCCACACTGTCAGGGCCGCGGTACGCTGATCAAAGATCCGTGCAACAAATGTCATGGTCATGGTCGTG +TTGAGCGCAGCAAAACGCTGTCCGTTAAAATCCCGGCAGGGGTGGACACTGGAGACCGCATCCGTCTTGCGGGCGAAGGT +GAAGCGGGTGAACACGGCGCACCGGCAGGCGATCTGTACGTTCAGGTTCAGGTTAAACAGCACCCGATTTTCGAGCGTGA +AGGCAACAACCTGTATTGCGAAGTCCCGATCAACTTCGCTATGGCGGCGCTGGGTGGTGAAATCGAAGTACCGACCCTTG +ATGGTCGCGTCAAACTGAAAGTGCCTGGCGAAACCCAGACCGGTAAGCTATTCCGTATGCGCGGTAAAGGCGTCAAGTCT +GTCCGCGGTGGCGCACAGGGTGATTTGCTGTGCCGCGTTGTCGTCGAAACACCGGTAGGCCTGAACGAGAAGCAGAAACA +GCTGCTGCAAGAGCTGCAAGAAAGCTTCGGTGGCCCAACCGGCGAGCACAACAGCCCGCGCTCAAAGAGCTTCTTTGATG +GTGTGAAGAAGTTTTTTGACGACCTGACCCGCTAACCTCCCCAAAAGCCTGCCCGTGGGCAGGCCTGGGTAAAAATAGGG +TGCGTTGAAGATATGCGAGCACCTGTAAAGTGGCGGGGATCACTCCCCGCCGTTGCTCTTACTCGGATTCGTAAGCCGTG +AAAACAGCAACCTCCGTCTGGCCAGTTCGGATGTGAACCTCACAGAGGTCTTTTCTCGTTACCAGCGCCGCCACTACGGC +GGTGATACAGATGACGATCAGGGCGACAATCATCACCTTATGCTGCTTCATTGCTCTCTTCTCCTTGACCTTACGGTCAG +TAAGAGGCACTCTACATGTGTTCAGCATATAGGGGGCCTCGGGTTGATGGTAAAATATCACTCGGGGCTTTTCTCTATCT +GCCGTTCAGCTAATGCCTGAGACAGACAGCCTCAAGCACCCGCCGCTATTATATCGCTCTCTTTAACCCATTCTGTTTTA +TCGATTCTAATCCGGAAGACGCCTCGCATTTTTATGGCGTAATTTTTTAATGATTTAATTATTTAACTTTAATTTATCTC diff --git a/data/ex1/metadata.ttl b/data/ex1/metadata.ttl new file mode 100644 index 00000000..370160fd --- /dev/null +++ b/data/ex1/metadata.ttl @@ -0,0 +1,28 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix xsd: . +@prefix ex: . +@prefix smoc: . +@prefix taxon: . +@prefix mondo: . +@prefix ror: . + + + +ex:Bob a smoc:BioSample ; + smoc:hasTaxonomicRange ex:ecoli. + +ex:Alice a smoc:BioSample ; + smoc:hasTaxonomicRange ex:ecoli . + +ex:human a smoc:Taxon ; + smoc:hasTaxId 562 . + +ex:demo1cram a smoc:CRAMFile; + smoc:hasSample ex:Bob ; + smoc:hasLocation "demo1.cram" . + +ex:demo2cram a smoc:CRAMFile; + smoc:hasSample ex:Alice ; + smoc:hasLocation "demo2.cram" . From ef2a9ecf04a609610c1fb24869af9540031df45d Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 15:47:53 +0100 Subject: [PATCH 04/20] feat: add pkg skeleton --- modo/api.py | 62 ++++ modo/cram.py | 21 ++ modo/meta.py | 4 + modo/models.py | 51 +++ poetry.lock | 956 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 24 ++ 6 files changed, 1118 insertions(+) create mode 100644 modo/api.py create mode 100644 modo/cram.py create mode 100644 modo/meta.py create mode 100644 modo/models.py create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/modo/api.py b/modo/api.py new file mode 100644 index 00000000..f14d18b7 --- /dev/null +++ b/modo/api.py @@ -0,0 +1,62 @@ +from enum import Enum +from pathlib import Path +from typing import Optional + +import rdflib +import zarr + + +# Below is an enum of omics types (genomics, transcriptomics, proteomics, metabolomics) +class OmicsType(Enum): + GENOMICS = "smoc:Genomics" + TRANSCRIPTOMICS = "smoc:Transcriptomics" + PROTEOMICS = "smoc:Proteomics" + METABOLOMICS = "smoc:Metabolomics" + + +class MODO: + """Multi-Omics Digital Object + A digital archive containing several multi-omics data and records + + Examples + -------- + >>> from modo import MODO + >>> modo = MODO("path/to/digital_object") + >>> modo.list_samples() + ["Bob", "Alice"] + >>> modo.list_files() + ["demo1.cram", "demo2.cram"] + >>> modo.query("SELECT *") + >>> + SELECT ?path + WHERE { + [] rdf:type smoc:CRAMFile ; + smoc:hasLocation ?path . + smoc:hasSample ex:Bob . + } + """ + + def __init__(self, path: Path): + # self.zarr: zarr.hierarchy.Group = zarr.open(path) + self.path: Path = path + # TODO: Use metadata embedded in zarr file + # so that individual arrays / groups can + # have their own metadata + self.metadata = rdflib.Graph().parse(Path(path / "metadata.ttl")) + + def list_samples(self): + return self.metadata.query( + """ + SELECT ?sample + WHERE { + ?sample rdf:type smoc:BioSample . + } + """ + ) + + def list_files(self): + return self.path.rglob("*") + + def query(self, query: str): + """Use SPARQL to query the metadata graph""" + return self.metadata.query(query) diff --git a/modo/cram.py b/modo/cram.py new file mode 100644 index 00000000..b424386a --- /dev/null +++ b/modo/cram.py @@ -0,0 +1,21 @@ +"""Utilities to interact with genomic intervals in CRAM files.""" +from pathlib import Path +from pysam import AlignmentFile, AlignmentHeader +from rdflib import Graph + + +def slice(cram_path: AlignmentFile, coords: str) -> AlignmentFile: + """Return a slice of the CRAM File. + + Examples + -------- + >>> slice(my_cram, "chr1:100-200") + """ + ... + + +def extract_metadata(AlignmentHeader) -> Graph: + ... + + +# TODO: Add functions to edit CRAM files (liftover) diff --git a/modo/meta.py b/modo/meta.py new file mode 100644 index 00000000..6934808c --- /dev/null +++ b/modo/meta.py @@ -0,0 +1,4 @@ +import rdflib + +def list_samples(graph): + graph.subject_objec diff --git a/modo/models.py b/modo/models.py new file mode 100644 index 00000000..945171f3 --- /dev/null +++ b/modo/models.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass + +from calamus import fields +from calamus.schema import JsonLDSchema +from rdflib import Graph +from rdflib.namespace import Namespace + +SMOC = Namespace("http://smoc.ethz.ch/") +BIO = Namespace("http://bioschemas.org/") + + +@dataclass +class Reference(JsonLDSchema): + location: str + + class Meta: + rdf_type = SMOC.Reference + + +@dataclass +class CRAMFile(JsonLDSchema): + location: str + reference: Reference + + class Meta: + rdf_type = SMOC.CRAMFile + + +@dataclass +class Organization(JsonLDSchema): + name: str + + class Meta: + rdf_type = SMOC.Organization + + +@dataclass +class Taxon(JsonLDSchema): + taxid: int + + class Meta: + rdf_type = SMOC.Taxon + + +@dataclass +class BioSample(JsonLDSchema): + taxonomic_range: Taxon + collector: Organization + + class Meta: + rdf_type = BIO.BioSample diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..417247da --- /dev/null +++ b/poetry.lock @@ -0,0 +1,956 @@ +# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand. + +[[package]] +name = "asciitree" +version = "0.3.3" +description = "Draws ASCII trees." +optional = false +python-versions = "*" +files = [ + {file = "asciitree-0.3.3.tar.gz", hash = "sha256:4aa4b9b649f85e3fcb343363d97564aa1fb62e249677f2e18a96765145cc0f6e"}, +] + +[[package]] +name = "black" +version = "23.12.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67f19562d367468ab59bd6c36a72b2c84bc2f16b59788690e02bbcb140a77175"}, + {file = "black-23.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbd75d9f28a7283b7426160ca21c5bd640ca7cd8ef6630b4754b6df9e2da8462"}, + {file = "black-23.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:593596f699ca2dcbbbdfa59fcda7d8ad6604370c10228223cd6cf6ce1ce7ed7e"}, + {file = "black-23.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:12d5f10cce8dc27202e9a252acd1c9a426c83f95496c959406c96b785a92bb7d"}, + {file = "black-23.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e73c5e3d37e5a3513d16b33305713237a234396ae56769b839d7c40759b8a41c"}, + {file = "black-23.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba09cae1657c4f8a8c9ff6cfd4a6baaf915bb4ef7d03acffe6a2f6585fa1bd01"}, + {file = "black-23.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace64c1a349c162d6da3cef91e3b0e78c4fc596ffde9413efa0525456148873d"}, + {file = "black-23.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:72db37a2266b16d256b3ea88b9affcdd5c41a74db551ec3dd4609a59c17d25bf"}, + {file = "black-23.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fdf6f23c83078a6c8da2442f4d4eeb19c28ac2a6416da7671b72f0295c4a697b"}, + {file = "black-23.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39dda060b9b395a6b7bf9c5db28ac87b3c3f48d4fdff470fa8a94ab8271da47e"}, + {file = "black-23.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7231670266ca5191a76cb838185d9be59cfa4f5dd401b7c1c70b993c58f6b1b5"}, + {file = "black-23.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:193946e634e80bfb3aec41830f5d7431f8dd5b20d11d89be14b84a97c6b8bc75"}, + {file = "black-23.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcf91b01ddd91a2fed9a8006d7baa94ccefe7e518556470cf40213bd3d44bbbc"}, + {file = "black-23.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:996650a89fe5892714ea4ea87bc45e41a59a1e01675c42c433a35b490e5aa3f0"}, + {file = "black-23.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdbff34c487239a63d86db0c9385b27cdd68b1bfa4e706aa74bb94a435403672"}, + {file = "black-23.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:97af22278043a6a1272daca10a6f4d36c04dfa77e61cbaaf4482e08f3640e9f0"}, + {file = "black-23.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ead25c273adfad1095a8ad32afdb8304933efba56e3c1d31b0fee4143a1e424a"}, + {file = "black-23.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c71048345bdbced456cddf1622832276d98a710196b842407840ae8055ade6ee"}, + {file = "black-23.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a832b6e00eef2c13b3239d514ea3b7d5cc3eaa03d0474eedcbbda59441ba5d"}, + {file = "black-23.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:6a82a711d13e61840fb11a6dfecc7287f2424f1ca34765e70c909a35ffa7fb95"}, + {file = "black-23.12.0-py3-none-any.whl", hash = "sha256:a7c07db8200b5315dc07e331dda4d889a56f6bf4db6a9c2a526fa3166a81614f"}, + {file = "black-23.12.0.tar.gz", hash = "sha256:330a327b422aca0634ecd115985c1c7fd7bdb5b5a2ef8aa9888a82e2ebe9437a"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "cachetools" +version = "5.3.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, + {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, +] + +[[package]] +name = "calamus" +version = "0.4.2" +description = "calamus is a library built on top of marshmallow to allow (de-)Serialization of Python classes to JSON-LD." +optional = false +python-versions = ">=3.7.1,<4.0.0" +files = [ + {file = "calamus-0.4.2-py3-none-any.whl", hash = "sha256:3d1121a379ee850a44de540ce091ae8482d539c6257a711b471cfbe0ee5a1e39"}, + {file = "calamus-0.4.2.tar.gz", hash = "sha256:86a3b52aa737062c291e0f4cd7cdebc2e8aee9d88292982770b426dc1f086212"}, +] + +[package.dependencies] +lazy-object-proxy = ">=1.4.3,<2.0.0" +marshmallow = ">=3.14.0,<4.0.0" +pyld = ">=2.0.2,<3.0.0" +rdflib = ">=6.0.0,<7.0.0" + +[package.extras] +docs = ["Jinja2 (>=3.0.0,<3.1.0)", "sphinx (>=3.0.3,<4.0.0)", "sphinx-rtd-theme (>=0.4.3,<0.5.0)", "sphinxcontrib-spelling (>=5.0.0,<6.0.0)"] + +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.3.3" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d874434e0cb7b90f7af2b6e3309b0733cde8ec1476eb47db148ed7deeb2a9494"}, + {file = "coverage-7.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee6621dccce8af666b8c4651f9f43467bfbf409607c604b840b78f4ff3619aeb"}, + {file = "coverage-7.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1367aa411afb4431ab58fd7ee102adb2665894d047c490649e86219327183134"}, + {file = "coverage-7.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f0f8f0c497eb9c9f18f21de0750c8d8b4b9c7000b43996a094290b59d0e7523"}, + {file = "coverage-7.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db0338c4b0951d93d547e0ff8d8ea340fecf5885f5b00b23be5aa99549e14cfd"}, + {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d31650d313bd90d027f4be7663dfa2241079edd780b56ac416b56eebe0a21aab"}, + {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9437a4074b43c177c92c96d051957592afd85ba00d3e92002c8ef45ee75df438"}, + {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9e17d9cb06c13b4f2ef570355fa45797d10f19ca71395910b249e3f77942a837"}, + {file = "coverage-7.3.3-cp310-cp310-win32.whl", hash = "sha256:eee5e741b43ea1b49d98ab6e40f7e299e97715af2488d1c77a90de4a663a86e2"}, + {file = "coverage-7.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:593efa42160c15c59ee9b66c5f27a453ed3968718e6e58431cdfb2d50d5ad284"}, + {file = "coverage-7.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c944cf1775235c0857829c275c777a2c3e33032e544bcef614036f337ac37bb"}, + {file = "coverage-7.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eda7f6e92358ac9e1717ce1f0377ed2b9320cea070906ece4e5c11d172a45a39"}, + {file = "coverage-7.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c854c1d2c7d3e47f7120b560d1a30c1ca221e207439608d27bc4d08fd4aeae8"}, + {file = "coverage-7.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:222b038f08a7ebed1e4e78ccf3c09a1ca4ac3da16de983e66520973443b546bc"}, + {file = "coverage-7.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff4800783d85bff132f2cc7d007426ec698cdce08c3062c8d501ad3f4ea3d16c"}, + {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fc200cec654311ca2c3f5ab3ce2220521b3d4732f68e1b1e79bef8fcfc1f2b97"}, + {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:307aecb65bb77cbfebf2eb6e12009e9034d050c6c69d8a5f3f737b329f4f15fb"}, + {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ffb0eacbadb705c0a6969b0adf468f126b064f3362411df95f6d4f31c40d31c1"}, + {file = "coverage-7.3.3-cp311-cp311-win32.whl", hash = "sha256:79c32f875fd7c0ed8d642b221cf81feba98183d2ff14d1f37a1bbce6b0347d9f"}, + {file = "coverage-7.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:243576944f7c1a1205e5cd658533a50eba662c74f9be4c050d51c69bd4532936"}, + {file = "coverage-7.3.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a2ac4245f18057dfec3b0074c4eb366953bca6787f1ec397c004c78176a23d56"}, + {file = "coverage-7.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f9191be7af41f0b54324ded600e8ddbcabea23e1e8ba419d9a53b241dece821d"}, + {file = "coverage-7.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c0b1b8b5a4aebf8fcd227237fc4263aa7fa0ddcd4d288d42f50eff18b0bac4"}, + {file = "coverage-7.3.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee453085279df1bac0996bc97004771a4a052b1f1e23f6101213e3796ff3cb85"}, + {file = "coverage-7.3.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1191270b06ecd68b1d00897b2daddb98e1719f63750969614ceb3438228c088e"}, + {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:007a7e49831cfe387473e92e9ff07377f6121120669ddc39674e7244350a6a29"}, + {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:af75cf83c2d57717a8493ed2246d34b1f3398cb8a92b10fd7a1858cad8e78f59"}, + {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:811ca7373da32f1ccee2927dc27dc523462fd30674a80102f86c6753d6681bc6"}, + {file = "coverage-7.3.3-cp312-cp312-win32.whl", hash = "sha256:733537a182b5d62184f2a72796eb6901299898231a8e4f84c858c68684b25a70"}, + {file = "coverage-7.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:e995efb191f04b01ced307dbd7407ebf6e6dc209b528d75583277b10fd1800ee"}, + {file = "coverage-7.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbd8a5fe6c893de21a3c6835071ec116d79334fbdf641743332e442a3466f7ea"}, + {file = "coverage-7.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:50c472c1916540f8b2deef10cdc736cd2b3d1464d3945e4da0333862270dcb15"}, + {file = "coverage-7.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e9223a18f51d00d3ce239c39fc41410489ec7a248a84fab443fbb39c943616c"}, + {file = "coverage-7.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f501e36ac428c1b334c41e196ff6bd550c0353c7314716e80055b1f0a32ba394"}, + {file = "coverage-7.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:475de8213ed95a6b6283056d180b2442eee38d5948d735cd3d3b52b86dd65b92"}, + {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:afdcc10c01d0db217fc0a64f58c7edd635b8f27787fea0a3054b856a6dff8717"}, + {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:fff0b2f249ac642fd735f009b8363c2b46cf406d3caec00e4deeb79b5ff39b40"}, + {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a1f76cfc122c9e0f62dbe0460ec9cc7696fc9a0293931a33b8870f78cf83a327"}, + {file = "coverage-7.3.3-cp38-cp38-win32.whl", hash = "sha256:757453848c18d7ab5d5b5f1827293d580f156f1c2c8cef45bfc21f37d8681069"}, + {file = "coverage-7.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad2453b852a1316c8a103c9c970db8fbc262f4f6b930aa6c606df9b2766eee06"}, + {file = "coverage-7.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b15e03b8ee6a908db48eccf4e4e42397f146ab1e91c6324da44197a45cb9132"}, + {file = "coverage-7.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89400aa1752e09f666cc48708eaa171eef0ebe3d5f74044b614729231763ae69"}, + {file = "coverage-7.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c59a3e59fb95e6d72e71dc915e6d7fa568863fad0a80b33bc7b82d6e9f844973"}, + {file = "coverage-7.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ede881c7618f9cf93e2df0421ee127afdfd267d1b5d0c59bcea771cf160ea4a"}, + {file = "coverage-7.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3bfd2c2f0e5384276e12b14882bf2c7621f97c35320c3e7132c156ce18436a1"}, + {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f3bad1a9313401ff2964e411ab7d57fb700a2d5478b727e13f156c8f89774a0"}, + {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:65d716b736f16e250435473c5ca01285d73c29f20097decdbb12571d5dfb2c94"}, + {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a702e66483b1fe602717020a0e90506e759c84a71dbc1616dd55d29d86a9b91f"}, + {file = "coverage-7.3.3-cp39-cp39-win32.whl", hash = "sha256:7fbf3f5756e7955174a31fb579307d69ffca91ad163467ed123858ce0f3fd4aa"}, + {file = "coverage-7.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cad9afc1644b979211989ec3ff7d82110b2ed52995c2f7263e7841c846a75348"}, + {file = "coverage-7.3.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:d299d379b676812e142fb57662a8d0d810b859421412b4d7af996154c00c31bb"}, + {file = "coverage-7.3.3.tar.gz", hash = "sha256:df04c64e58df96b4427db8d0559e95e2df3138c9916c96f9f6a4dd220db2fdb7"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "distlib" +version = "0.3.8" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.0" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "fasteners" +version = "0.19" +description = "A python package that provides useful locks" +optional = false +python-versions = ">=3.6" +files = [ + {file = "fasteners-0.19-py3-none-any.whl", hash = "sha256:758819cb5d94cdedf4e836988b74de396ceacb8e2794d21f82d131fd9ee77237"}, + {file = "fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c"}, +] + +[[package]] +name = "filelock" +version = "3.13.1" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "frozendict" +version = "2.3.10" +description = "A simple immutable dictionary" +optional = false +python-versions = ">=3.6" +files = [ + {file = "frozendict-2.3.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df2d2afa5af41bfa09dc9d5a8e6d73ae39b677a8572200c65a5ea353387ffccd"}, + {file = "frozendict-2.3.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b10df7f5d8637b1af319434f99dc25ca6f5537e28b293e4c405ebfb4bf9581fa"}, + {file = "frozendict-2.3.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da22a3e873f365f97445c49afc1e6d5198ed6d172f3efaf0e9fde0edcca3cea1"}, + {file = "frozendict-2.3.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89218738e2122b50bf8a0444083dbe2de280402e9c2ef0929c0db0f93ff11271"}, + {file = "frozendict-2.3.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aa11add43a71fd47523fbd011be5cc011df79e25ec0b0339fc0d728623aaa7ec"}, + {file = "frozendict-2.3.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:af267bd6d98cbc10580105dc76f28f7156856fa48a5bbcadd40edb85f93657ae"}, + {file = "frozendict-2.3.10-cp310-cp310-win_amd64.whl", hash = "sha256:c112024df64b8926a315d7e36b860967fcad8aae0c592b9f117589391373e893"}, + {file = "frozendict-2.3.10-cp310-cp310-win_arm64.whl", hash = "sha256:a0065db2bc76628853dd620bd08c1ca44ad0b711e92e89b4156493153add6f9d"}, + {file = "frozendict-2.3.10-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:93634af5a6d71762aebc7d78bdce92890b7e612588faf887c9eaf752dc7ccdb1"}, + {file = "frozendict-2.3.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b4d05e231dc1a2ec874f847fd7348cbee469555468efb875a89994ecde31a81"}, + {file = "frozendict-2.3.10-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d40d0644f19365fc6cc428db31c0f113fa550bd15920262f9d77ccf6556d87b"}, + {file = "frozendict-2.3.10-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:12b40526219f9583b30690011288bca4d6cce8724cda96b3c3ab08b67c5a7f09"}, + {file = "frozendict-2.3.10-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:6b552fffeba8e41b43ce10cc0fc467e048a7c9a71ae3241057510342132555b9"}, + {file = "frozendict-2.3.10-cp36-cp36m-win_amd64.whl", hash = "sha256:07208e4718cb70aa259ac886c19b96a4aad1cf00e9199f211746f738951bbf7c"}, + {file = "frozendict-2.3.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e8bec6d11f7254e405290cb1b081caffa0c18b6aa779130da9a546349c56be83"}, + {file = "frozendict-2.3.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b089c7e8c95d8b043e82e7da26e165f4220d7310efaad5e94445db7e3bc8321e"}, + {file = "frozendict-2.3.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08a5829d708657c9d5ad58f4a7e4baa73a3d57290f9613bdd909d481fc203a3a"}, + {file = "frozendict-2.3.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1c015852dacf144dbeadf203673d8c714f788fcc2b810a36504994b3c4f5a436"}, + {file = "frozendict-2.3.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb9f15a5ed924be2b1cb3654b7ea3b7bae265ff39e2b5784d42bd4a6e1353e45"}, + {file = "frozendict-2.3.10-cp37-cp37m-win_amd64.whl", hash = "sha256:809bb9c6c657bded925710a309bb2a2350bdbfdc9371df427f1a93cb8ab7ec3e"}, + {file = "frozendict-2.3.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ff7a9cca3a3a1e584349e859d028388bd96a5475f76721471b73797472c6db17"}, + {file = "frozendict-2.3.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0cdd496933ddb428f3854bea9ffdce0245bb27c27909f663ad396409fb4dffb5"}, + {file = "frozendict-2.3.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9df392b655fadaa0174c1923e6205b30ad1ccca248e8e146e63a8147a355ee01"}, + {file = "frozendict-2.3.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7901828700f36fe12486705afe7afc5583434390c8f69b5419de1b6c566fb00d"}, + {file = "frozendict-2.3.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c9aa28ce48d848ee520409533fd0254de4caf025c5cf1b9f27c98c1dd8cf90aa"}, + {file = "frozendict-2.3.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0856af4f5b4288b2270e0b74078fad5cbaf4f799326b82183865f6f367008b2c"}, + {file = "frozendict-2.3.10-cp38-cp38-win_amd64.whl", hash = "sha256:ac41c671ff33cbefc0f06c4b2a630d18ab59f5256f45f57d5632252ae4a8c07a"}, + {file = "frozendict-2.3.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:893205dc5a4e5c4b24e5822ceb21ef14fed8ca4afae7ac688e2fc24294c85225"}, + {file = "frozendict-2.3.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e78c5ac5d71f3b73f07ff9d9e3cc32dfbf7954f2c57c2d0e1fe8f1600e980b40"}, + {file = "frozendict-2.3.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c4ca4cc42bc30b20476616411d4b49aae6084760b99251f1cbdfed879ae53ea"}, + {file = "frozendict-2.3.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c865962216f7cfd6dac8693f4de431a9d98a7225185ff23613ecd10c42423adc"}, + {file = "frozendict-2.3.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:99b2f47b292cc4d68f6679918e8e9e6dc5e816924d8369d07018be56b93fb20f"}, + {file = "frozendict-2.3.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e7abf4539b73c8e5680dd2fdbd19ca4fc3e2b2f3666f80f022217839bb859fd"}, + {file = "frozendict-2.3.10-cp39-cp39-win_amd64.whl", hash = "sha256:901e774629fc63f84d24b5e46b59de1eed22392ee98b7f92e694a127d541edac"}, + {file = "frozendict-2.3.10-cp39-cp39-win_arm64.whl", hash = "sha256:6f8681c0ffe92be9aba40c9b9960c48f0ae7f6ea585af2b93fc9542cc3865969"}, + {file = "frozendict-2.3.10-py3-none-any.whl", hash = "sha256:66cded65f144393b4226bda9fe9ac2f42451d2d603e8a486015744bb566a7008"}, + {file = "frozendict-2.3.10.tar.gz", hash = "sha256:aadc83510ce82751a0bb3575231f778bc37cbb373f5f05a52b888e26cbb92f79"}, +] + +[[package]] +name = "identify" +version = "2.5.33" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, + {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, +] + +[package.extras] +license = ["ukkonen"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "lazy-object-proxy" +version = "1.9.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] + +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, + {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + +[[package]] +name = "marshmallow" +version = "3.20.1" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.20.1-py3-none-any.whl", hash = "sha256:684939db93e80ad3561392f47be0230743131560a41c5110684c16e21ade0a5c"}, + {file = "marshmallow-3.20.1.tar.gz", hash = "sha256:5d2371bbe42000f2b3fb5eaa065224df7d8f8597bc19a1bbfa5bfe7fba8da889"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["flake8 (==6.0.0)", "flake8-bugbear (==23.7.10)", "mypy (==1.4.1)", "pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"] +docs = ["alabaster (==0.7.13)", "autodocsumm (==0.2.11)", "sphinx (==7.0.1)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"] +lint = ["flake8 (==6.0.0)", "flake8-bugbear (==23.7.10)", "mypy (==1.4.1)", "pre-commit (>=2.4,<4.0)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "nodeenv" +version = "1.8.0" +description = "Node.js virtual environment builder" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] + +[package.dependencies] +setuptools = "*" + +[[package]] +name = "numcodecs" +version = "0.12.1" +description = "A Python package providing buffer compression and transformation codecs for use in data storage and communication applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "numcodecs-0.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d37f628fe92b3699e65831d5733feca74d2e33b50ef29118ffd41c13c677210e"}, + {file = "numcodecs-0.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:941b7446b68cf79f089bcfe92edaa3b154533dcbcd82474f994b28f2eedb1c60"}, + {file = "numcodecs-0.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e79bf9d1d37199ac00a60ff3adb64757523291d19d03116832e600cac391c51"}, + {file = "numcodecs-0.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:82d7107f80f9307235cb7e74719292d101c7ea1e393fe628817f0d635b7384f5"}, + {file = "numcodecs-0.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eeaf42768910f1c6eebf6c1bb00160728e62c9343df9e2e315dc9fe12e3f6071"}, + {file = "numcodecs-0.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:135b2d47563f7b9dc5ee6ce3d1b81b0f1397f69309e909f1a35bb0f7c553d45e"}, + {file = "numcodecs-0.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a191a8e347ecd016e5c357f2bf41fbcb026f6ffe78fff50c77ab12e96701d155"}, + {file = "numcodecs-0.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:21d8267bd4313f4d16f5b6287731d4c8ebdab236038f29ad1b0e93c9b2ca64ee"}, + {file = "numcodecs-0.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2f84df6b8693206365a5b37c005bfa9d1be486122bde683a7b6446af4b75d862"}, + {file = "numcodecs-0.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:760627780a8b6afdb7f942f2a0ddaf4e31d3d7eea1d8498cf0fd3204a33c4618"}, + {file = "numcodecs-0.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c258bd1d3dfa75a9b708540d23b2da43d63607f9df76dfa0309a7597d1de3b73"}, + {file = "numcodecs-0.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e04649ea504aff858dbe294631f098fbfd671baf58bfc04fc48d746554c05d67"}, + {file = "numcodecs-0.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:caf1a1e6678aab9c1e29d2109b299f7a467bd4d4c34235b1f0e082167846b88f"}, + {file = "numcodecs-0.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c17687b1fd1fef68af616bc83f896035d24e40e04e91e7e6dae56379eb59fe33"}, + {file = "numcodecs-0.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29dfb195f835a55c4d490fb097aac8c1bcb96c54cf1b037d9218492c95e9d8c5"}, + {file = "numcodecs-0.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:2f1ba2f4af3fd3ba65b1bcffb717fe65efe101a50a91c368f79f3101dbb1e243"}, + {file = "numcodecs-0.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2fbb12a6a1abe95926f25c65e283762d63a9bf9e43c0de2c6a1a798347dfcb40"}, + {file = "numcodecs-0.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2207871868b2464dc11c513965fd99b958a9d7cde2629be7b2dc84fdaab013b"}, + {file = "numcodecs-0.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abff3554a6892a89aacf7b642a044e4535499edf07aeae2f2e6e8fc08c9ba07f"}, + {file = "numcodecs-0.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:ef964d4860d3e6b38df0633caf3e51dc850a6293fd8e93240473642681d95136"}, + {file = "numcodecs-0.12.1.tar.gz", hash = "sha256:05d91a433733e7eef268d7e80ec226a0232da244289614a8f3826901aec1098e"}, +] + +[package.dependencies] +numpy = ">=1.7" + +[package.extras] +docs = ["mock", "numpydoc", "sphinx (<7.0.0)", "sphinx-issues"] +msgpack = ["msgpack"] +test = ["coverage", "flake8", "pytest", "pytest-cov"] +test-extras = ["importlib-metadata"] +zfpy = ["zfpy (>=1.0.0)"] + +[[package]] +name = "numpy" +version = "1.26.2" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f"}, + {file = "numpy-1.26.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440"}, + {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75"}, + {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00"}, + {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe"}, + {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523"}, + {file = "numpy-1.26.2-cp310-cp310-win32.whl", hash = "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9"}, + {file = "numpy-1.26.2-cp310-cp310-win_amd64.whl", hash = "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919"}, + {file = "numpy-1.26.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841"}, + {file = "numpy-1.26.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1"}, + {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a"}, + {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b"}, + {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7"}, + {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8"}, + {file = "numpy-1.26.2-cp311-cp311-win32.whl", hash = "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186"}, + {file = "numpy-1.26.2-cp311-cp311-win_amd64.whl", hash = "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d"}, + {file = "numpy-1.26.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0"}, + {file = "numpy-1.26.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75"}, + {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7"}, + {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6"}, + {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6"}, + {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec"}, + {file = "numpy-1.26.2-cp312-cp312-win32.whl", hash = "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167"}, + {file = "numpy-1.26.2-cp312-cp312-win_amd64.whl", hash = "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e"}, + {file = "numpy-1.26.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef"}, + {file = "numpy-1.26.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2"}, + {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3"}, + {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818"}, + {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210"}, + {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36"}, + {file = "numpy-1.26.2-cp39-cp39-win32.whl", hash = "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80"}, + {file = "numpy-1.26.2-cp39-cp39-win_amd64.whl", hash = "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841"}, + {file = "numpy-1.26.2.tar.gz", hash = "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.1.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[[package]] +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pre-commit" +version = "3.6.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, + {file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + +[[package]] +name = "pyld" +version = "2.0.3" +description = "Python implementation of the JSON-LD API" +optional = false +python-versions = "*" +files = [ + {file = "PyLD-2.0.3.tar.gz", hash = "sha256:287445f888c3a332ccbd20a14844c66c2fcbaeab3c99acd506a0788e2ebb2f82"}, +] + +[package.dependencies] +cachetools = "*" +frozendict = "*" +lxml = "*" + +[package.extras] +aiohttp = ["aiohttp"] +cachetools = ["cachetools"] +frozendict = ["frozendict"] +requests = ["requests"] + +[[package]] +name = "pyparsing" +version = "3.1.1" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pysam" +version = "0.22.0" +description = "Package for reading, manipulating, and writing genomic data" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pysam-0.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:116278a7caa122b2b8acc56d13b3599be9b1236f27a12488bffc306858ff0d57"}, + {file = "pysam-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da2f1af461e44d5c2c7210d458ee216f8ab98486adf1eea6c88eea5c1058a62f"}, + {file = "pysam-0.22.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:021fbf6874ad998aba19be33828ad9d23d52273643793488ac4b12917d714c68"}, + {file = "pysam-0.22.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:26199e403855b9da45341d25682e0df27013687d9cb1b4fd328136fbd506292b"}, + {file = "pysam-0.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9bfebf89b1dc2ff6f88d64b5f05d8630deb89562b22764f8ee7f6fa9e677bb91"}, + {file = "pysam-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:942dd4a2263996bc2daa21200886e9fde027f32ce8820e7832b20bbdb97eb393"}, + {file = "pysam-0.22.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:83776ba587eb9575a209efed1cedb49d69c5fa6cc520dd722a0a09d0bb4e9b87"}, + {file = "pysam-0.22.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:4779a99d1ece17a98724d87a5c10c455cf212b3baa3a8399d3d072e4d0ae5ba0"}, + {file = "pysam-0.22.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bb61bf30c15f6767403b423b04c293e96fd7635457b506c849aafcf48fc13242"}, + {file = "pysam-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32042e0bf3c5dd8554769442c2e1f7b6ada902c33ee44c616d0403e7acd12ee3"}, + {file = "pysam-0.22.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f23b2f47528b94e8abe3b700103fb1214c623ae1c1b8125ecf22d4d33d76720f"}, + {file = "pysam-0.22.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:cfd2b858c7405cf38c730cba779ddf9f8cff28b4842c6440e64781650dcb9a52"}, + {file = "pysam-0.22.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:87dbf72f3e61fd6d3f92b1b683d9a9e797b6cc213ffcd971899f24a16f9f6e8f"}, + {file = "pysam-0.22.0-cp36-cp36m-manylinux_2_28_aarch64.whl", hash = "sha256:9af1cd3d07fd4c84e9b3d8a46c65b25f95278185bc6d44c4a48951679d5189ac"}, + {file = "pysam-0.22.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:f73d7923c89618fb7024875ed8eddc5fb0c911f430e3495de482fcee48143e45"}, + {file = "pysam-0.22.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ffe5c98725fea54b1b2aa8f14a60ee9ceaed32c04460d1b861a62603dcd7153"}, + {file = "pysam-0.22.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:34f5653a82138d28a8e86205785a0398eb6c89f776b4145ff42783168757323c"}, + {file = "pysam-0.22.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:9d3ebb1515c2fd9b11823469e5b211ca3cc89e976c00c284a2190804c9f11726"}, + {file = "pysam-0.22.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b8e18520e7a79bad91b44cf9199c7fa42cec5c3020024d7ef9a7161d0099bf8"}, + {file = "pysam-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a98d1ddca64943f3ead507721e52466aea2f7303e549d4960a2eb1d9fff8e3d7"}, + {file = "pysam-0.22.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:6d6aa2346b11ad35e88c65eb0067321318c25c7f35f75c98061173eabefcf8b0"}, + {file = "pysam-0.22.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4f6657a09c81333adb5545cf9a20d4c2ca1686acf8609ad58f13b3ec1b52a9cf"}, + {file = "pysam-0.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:93eb12be3822fb387e5438811f62a0f5e56c1edd5c830aaa316fb50d3d0bc181"}, + {file = "pysam-0.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9ba53f9b0b2c5cb57908855cdb35a31b34c5211d215aa01bdb3e9b3d05c659cc"}, + {file = "pysam-0.22.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:1b84f99aa04e30bd1cc35c01bd41c2b7680131f56c71a740805aff8086f24b56"}, + {file = "pysam-0.22.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:481e4efbfbc07b6b92194a005cb9a98006c8378024f41c7b66c58b14f6e77f9c"}, + {file = "pysam-0.22.0.tar.gz", hash = "sha256:ab7a46973cf0ab8c6ac327f4c3fb67698d7ccbeef8631a716898c6ba01ef3e45"}, +] + +[[package]] +name = "pytest" +version = "7.4.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "rdflib" +version = "6.3.2" +description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "rdflib-6.3.2-py3-none-any.whl", hash = "sha256:36b4e74a32aa1e4fa7b8719876fb192f19ecd45ff932ea5ebbd2e417a0247e63"}, + {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, +] + +[package.dependencies] +isodate = ">=0.6.0,<0.7.0" +pyparsing = ">=2.1.0,<4" + +[package.extras] +berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] +html = ["html5lib (>=1.0,<2.0)"] +lxml = ["lxml (>=4.3.0,<5.0.0)"] +networkx = ["networkx (>=2.0.0,<3.0.0)"] + +[[package]] +name = "setuptools" +version = "69.0.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, + {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typing-extensions" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, +] + +[[package]] +name = "virtualenv" +version = "20.25.0" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + +[[package]] +name = "zarr" +version = "2.16.1" +description = "An implementation of chunked, compressed, N-dimensional arrays for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zarr-2.16.1-py3-none-any.whl", hash = "sha256:de4882433ccb5b42cc1ec9872b95e64ca3a13581424666b28ed265ad76c7056f"}, + {file = "zarr-2.16.1.tar.gz", hash = "sha256:4276cf4b4a653431042cd53ff2282bc4d292a6842411e88529964504fb073286"}, +] + +[package.dependencies] +asciitree = "*" +fasteners = "*" +numcodecs = ">=0.10.0" +numpy = ">=1.20,<1.21.0 || >1.21.0" + +[package.extras] +docs = ["numcodecs[msgpack]", "numpydoc", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx-issues", "sphinx-rtd-theme"] +jupyter = ["ipytree (>=0.2.2)", "ipywidgets (>=8.0.0)", "notebook"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "16920717ee2f5851381d3ccf3c69b636bed73174c4771dbb7eb8349438fdeac1" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..6befbbd2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[tool.poetry] +name = "modo" +version = "0.1.0" +description = "SMOC Multi-Omics Digital Object PoC" +authors = ["SDSC-ORDES"] +license = "MIT" +readme = "README.md" +packages = [{include = "smoc_poc"}] + +[tool.poetry.dependencies] +python = "^3.10" +rdflib = "^6.3" +zarr = "^2.16.1" +calamus = "^0.4.2" +pysam = "^0.22.0" + +[tool.poetry.group.dev.dependencies] +pre-commit = "^3.6.0" +black = "^23.12.0" +pytest-cov = "^4.1.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" From 1652e97e049bfe155ac5c6867b9b9bf7842985f9 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 15:48:15 +0100 Subject: [PATCH 05/20] fix: schema syntax --- assets/schema.ttl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/schema.ttl b/assets/schema.ttl index d0c6de92..006bb6f1 100644 --- a/assets/schema.ttl +++ b/assets/schema.ttl @@ -20,13 +20,13 @@ smoc:CRAMFile a rdfs:Class ; rdfs:label "CRAM file" ; rdfs:comment "A file containing aligned genomic intervals" . -smoc:ZarrArchive a rdfs:Class ; - rdfs:label "Zarr archive" ; - rdfs:comment "A Zarr archive containing metadata and nested array. Part of a digital object." . +smoc:Array a rdfs:Class ; + rdfs:label "Array" ; + rdfs:comment "An array inside a Zarr archive containing data and metadata. Part of a digital object." . smoc:Reference a rdfs:Class ; rdfs:label "Reference genome" ; - rdfs:comment "A genome assembly used as reference coordinate system for aligning data records." + rdfs:comment "A genome assembly used as reference coordinate system for aligning data records." . smoc:BioSample a rdfs:Class ; rdfs:label "Biological sample" ; @@ -39,7 +39,7 @@ smoc:Taxon a rdfs:Class ; smoc:OmicsType a rdfs:Class ; rdfs:label "Omics type" ; - rdfs:comment "A type of omics field, tied to a biological molecule" ; + rdfs:comment "A type of omics field, tied to a biological molecule" . # Properties @@ -49,7 +49,7 @@ smoc:hasTaxonomicRange a rdf:Property ; rdfs:label "has taxonomic range" . smoc:hasSample a rdf:Property ; - rdfs:domain smoc:MODO, + rdfs:domain smoc:MODO, smoc:CRAMFile . smoc:hasRecord a rdf:Property ; rdfs:domain smoc:MODO ; @@ -61,18 +61,18 @@ smoc:hasReference a rdf:Property ; rdfs:range smoc:Reference . smoc:hasOmicsType a rdf:Property ; - rdfs:domain smoc:Record ; + rdfs:domain smoc:Array ; rdfs:range smoc:OmicsType . smoc:hasLocation a rdf:property ; - rdfs:domain smoc:MODO, smoc:CRAMFile, smoc:Reference, smoc:ZarrArchive ; - rdfs:range xsd:string, xsd:uri ; + rdfs:domain smoc:MODO, smoc:CRAMFile, smoc:Reference ; + rdfs:range xsd:anyURI ; rdfs:label "has location" ; rdfs:comment "The location of a resource, either on the filesystem or online" . smoc:hasTaxId a rdf:Property ; rdfs:domain smoc:Taxon ; - rdfs:range xsd:integer + rdfs:range xsd:integer . # Named individuals From be618d0538fed3bb9be14b05d1d5ebee04b79948 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 16:26:26 +0100 Subject: [PATCH 06/20] fix: drop unused query --- modo/api.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/modo/api.py b/modo/api.py index f14d18b7..daa5672d 100644 --- a/modo/api.py +++ b/modo/api.py @@ -27,13 +27,6 @@ class MODO: >>> modo.list_files() ["demo1.cram", "demo2.cram"] >>> modo.query("SELECT *") - >>> - SELECT ?path - WHERE { - [] rdf:type smoc:CRAMFile ; - smoc:hasLocation ?path . - smoc:hasSample ex:Bob . - } """ def __init__(self, path: Path): From d21cbbd6728b61c054e49e405677e65692bd2cf1 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 16:26:34 +0100 Subject: [PATCH 07/20] add placeholder cram api --- modo/cram.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modo/cram.py b/modo/cram.py index b424386a..6c3689d2 100644 --- a/modo/cram.py +++ b/modo/cram.py @@ -15,7 +15,20 @@ def slice(cram_path: AlignmentFile, coords: str) -> AlignmentFile: def extract_metadata(AlignmentHeader) -> Graph: + """Extract metadata from the CRAM file header and + convert specific attributes to an RDF graph according + to the modo schema.""" + # NOTE: Not a priority ... +def validata_cram_files(cram_path: str) -> bool: + """Validate CRAM files using pysam. + Checks if the file is sorted and has an index.""" + # TODO: + # Check if sorted + # Check if index exists + # Check if reference exists + + # TODO: Add functions to edit CRAM files (liftover) From 24cfbc118457920d45768cf0afeab0bb6daf1a57 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 16:51:59 +0100 Subject: [PATCH 08/20] fix typos --- modo/cram.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modo/cram.py b/modo/cram.py index 6c3689d2..f13869ff 100644 --- a/modo/cram.py +++ b/modo/cram.py @@ -11,6 +11,7 @@ def slice(cram_path: AlignmentFile, coords: str) -> AlignmentFile: -------- >>> slice(my_cram, "chr1:100-200") """ + # https://htsget.readthedocs.io/en/stable/index.html ... @@ -22,9 +23,10 @@ def extract_metadata(AlignmentHeader) -> Graph: ... -def validata_cram_files(cram_path: str) -> bool: +def validate_cram_files(cram_path: str): """Validate CRAM files using pysam. Checks if the file is sorted and has an index.""" + # NOTE: Not a priority # TODO: # Check if sorted # Check if index exists From b0df581213a8409353e1f22ad50596341ed35b70 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:11:36 +0100 Subject: [PATCH 09/20] chore: add makefile --- Makefile | 23 +++++++++++++++ poetry.lock | 77 +++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 3 files changed, 63 insertions(+), 39 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..384b39ef --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +.PHONY: install +install: ## Install with the poetry and add pre-commit hooks + @echo "🚀 Installing packages with poetry" + @poetry install + @poetry run pre-commit install + +.PHONY: check +check: ## Run code quality tools. + @echo "🚀 Checking Poetry lock file consistency with 'pyproject.toml': Running poetry lock --check" + @poetry lock --check + @echo "🚀 Linting code: Running pre-commit" + @poetry run pre-commit run -a + +.PHONY: test +test: ## Test the code with pytest + @echo "🚀 Testing code: Running pytest" + @poetry run pytest + +.PHONY: help +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + +.DEFAULT_GOAL := help diff --git a/poetry.lock b/poetry.lock index 417247da..92ad9ed8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -329,47 +329,48 @@ six = "*" [[package]] name = "lazy-object-proxy" -version = "1.9.0" +version = "1.10.0" description = "A fast and thorough lazy object proxy." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 6befbbd2..e018ed7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "SMOC Multi-Omics Digital Object PoC" authors = ["SDSC-ORDES"] license = "MIT" readme = "README.md" -packages = [{include = "smoc_poc"}] +packages = [{include = "modo"}] [tool.poetry.dependencies] python = "^3.10" From 04b413349f942d0b0485033b002e3ac12a2e0917 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:12:13 +0100 Subject: [PATCH 10/20] chore: add pre-commit config --- .pre-commit-config.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..48ee0308 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/psf/black + rev: 22.10.0 + hooks: + - id: black From 92b60fbbbe6225fc8c6f0bb984c9f08b988bcdba Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:53:59 +0100 Subject: [PATCH 11/20] fix(api): add type hints, fix doctests --- modo/api.py | 54 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/modo/api.py b/modo/api.py index daa5672d..0051e789 100644 --- a/modo/api.py +++ b/modo/api.py @@ -1,44 +1,53 @@ from enum import Enum from pathlib import Path -from typing import Optional +from typing import Generator, Optional import rdflib import zarr -# Below is an enum of omics types (genomics, transcriptomics, proteomics, metabolomics) -class OmicsType(Enum): - GENOMICS = "smoc:Genomics" - TRANSCRIPTOMICS = "smoc:Transcriptomics" - PROTEOMICS = "smoc:Proteomics" - METABOLOMICS = "smoc:Metabolomics" - - class MODO: """Multi-Omics Digital Object - A digital archive containing several multi-omics data and records + A digital archive containing several multi-omics data and records. + The archive contains: + * A zarr file, with array-based data + * A metadata file, with RDF metadata describing and pointing to the actual data + * CRAM files, with genomic-interval data Examples -------- - >>> from modo import MODO - >>> modo = MODO("path/to/digital_object") - >>> modo.list_samples() - ["Bob", "Alice"] - >>> modo.list_files() - ["demo1.cram", "demo2.cram"] - >>> modo.query("SELECT *") + >>> demo = MODO("data/ex1") + + # List identifiers of samples in the archive + >>> demo.list_samples() + ['http://example.org/bac1', 'http://example.org/bac2'] + + # List files in the archive + >>> [file.name for file in demo.list_files()] + ['demo1.cram', 'demo2.cram', 'ecoli_ref.fa', 'metadata.ttl', 'archive.zarr'] + + # Query the metadata graph to find the location of the + # CRAM files for the sample bac1 + >>> bac1_files = demo.query(''' + ... SELECT ?path + ... WHERE { + ... [] rdf:type smoc:CRAMFile ; + ... smoc:hasSample ex:bac1 ; + ... smoc:hasLocation ?path . + ... } + ... ''').serialize(format="csv").decode() """ def __init__(self, path: Path): # self.zarr: zarr.hierarchy.Group = zarr.open(path) - self.path: Path = path + self.path: Path = Path(path) # TODO: Use metadata embedded in zarr file # so that individual arrays / groups can # have their own metadata - self.metadata = rdflib.Graph().parse(Path(path / "metadata.ttl")) + self.metadata = rdflib.Graph().parse(self.path / "metadata.ttl") - def list_samples(self): - return self.metadata.query( + def list_samples(self) -> list[str]: + samples = self.metadata.query( """ SELECT ?sample WHERE { @@ -46,8 +55,9 @@ def list_samples(self): } """ ) + return [str(res.sample) for res in samples] - def list_files(self): + def list_files(self) -> Generator[Path, None, None]: return self.path.rglob("*") def query(self, query: str): From 760e10f6da12e58b21d713086569329bd9b135c7 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:54:27 +0100 Subject: [PATCH 12/20] test(cram): fix path in doctest --- modo/cram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modo/cram.py b/modo/cram.py index f13869ff..23eb4f1e 100644 --- a/modo/cram.py +++ b/modo/cram.py @@ -9,7 +9,7 @@ def slice(cram_path: AlignmentFile, coords: str) -> AlignmentFile: Examples -------- - >>> slice(my_cram, "chr1:100-200") + >>> slice("data/ex1/demo1.cram", "chr1:100-200") """ # https://htsget.readthedocs.io/en/stable/index.html ... From a4a3ff8933411cfa72b9c8f9b3da428e9c38a23a Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:54:45 +0100 Subject: [PATCH 13/20] chore: add tooling configs in pyproject.toml --- pyproject.toml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e018ed7c..10213e8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "SMOC Multi-Omics Digital Object PoC" authors = ["SDSC-ORDES"] license = "MIT" readme = "README.md" -packages = [{include = "modo"}] +packages = [{ include = "modo" }] [tool.poetry.dependencies] python = "^3.10" @@ -22,3 +22,13 @@ pytest-cov = "^4.1.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +# Tooling configuration + +[tool.pytest.ini_options] +addopts = ["--doctest-modules"] +testpaths = ["modo", "tests"] + +[tool.black] +line-length = 79 +target-version = ["py38", "py39", "py310"] From 925b154705ef68e7d69a92551b17ea259f8be732 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:55:05 +0100 Subject: [PATCH 14/20] test: add api tests --- tests/test_modo.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/test_modo.py diff --git a/tests/test_modo.py b/tests/test_modo.py new file mode 100644 index 00000000..88533901 --- /dev/null +++ b/tests/test_modo.py @@ -0,0 +1,7 @@ +"""Tests for the multi-omics digital object (modo) API +""" +from modo.api import MODO + + +def test_read_modo(): + MODO("data/ex1") From 81623b25037d3569c93bd8feaa177917956b1eac Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 17:55:30 +0100 Subject: [PATCH 15/20] test: rename samples in test data --- data/ex1/metadata.ttl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data/ex1/metadata.ttl b/data/ex1/metadata.ttl index 370160fd..de963bb8 100644 --- a/data/ex1/metadata.ttl +++ b/data/ex1/metadata.ttl @@ -10,19 +10,19 @@ -ex:Bob a smoc:BioSample ; - smoc:hasTaxonomicRange ex:ecoli. +ex:bac1 a smoc:BioSample ; + smoc:hasTaxonomicRange ex:ecoli . -ex:Alice a smoc:BioSample ; +ex:bac2 a smoc:BioSample ; smoc:hasTaxonomicRange ex:ecoli . -ex:human a smoc:Taxon ; +ex:ecoli a smoc:Taxon ; smoc:hasTaxId 562 . -ex:demo1cram a smoc:CRAMFile; - smoc:hasSample ex:Bob ; +ex:demo1cram a smoc:CRAMFile ; + smoc:hasSample ex:bac1 ; smoc:hasLocation "demo1.cram" . -ex:demo2cram a smoc:CRAMFile; - smoc:hasSample ex:Alice ; +ex:demo2cram a smoc:CRAMFile ; + smoc:hasSample ex:bac2 ; smoc:hasLocation "demo2.cram" . From 4ea5701e61b0eb7103f0c38041df11efeb44788e Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 18:08:42 +0100 Subject: [PATCH 16/20] ci: add pytest action + align python versions with test matrix --- .github/workflows/poetry-pytest.yml | 39 +++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/poetry-pytest.yml diff --git a/.github/workflows/poetry-pytest.yml b/.github/workflows/poetry-pytest.yml new file mode 100644 index 00000000..6c37b7af --- /dev/null +++ b/.github/workflows/poetry-pytest.yml @@ -0,0 +1,39 @@ +name: tests + +on: [push] + +jobs: + + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10"] + steps: + # https://github.com/actions/checkout + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # https://github.com/actions/setup-python + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + # https://github.com/snok/install-poetry + - name: Install Poetry + uses: snok/install-poetry@v1 + + - name: Install Dependencies + run: poetry install + if: steps.cache.outputs.cache-hit != 'true' + + - name: Code Quality + run: poetry run black . --check + + - name: Test with pytest + env: + GITHUB_TOKEN: ${{ secrets.ACCESS_GITHUB_TOKEN }} + GITLAB_TOKEN: ${{ secrets.GITLAB_ACCESS_TOKEN }} + run: make test diff --git a/pyproject.toml b/pyproject.toml index 10213e8b..c573687e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,4 +31,4 @@ testpaths = ["modo", "tests"] [tool.black] line-length = 79 -target-version = ["py38", "py39", "py310"] +target-version = ["py39", "py310"] From 1c52ccecf72fa9b6f3b595c5c4c788c13381ad43 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 18:11:39 +0100 Subject: [PATCH 17/20] chore: black fmt --- modo/meta.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modo/meta.py b/modo/meta.py index 6934808c..2479aabd 100644 --- a/modo/meta.py +++ b/modo/meta.py @@ -1,4 +1,5 @@ import rdflib + def list_samples(graph): graph.subject_objec From dce507049733bf01e48ed4a839994f0cd9149479 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 18:13:29 +0100 Subject: [PATCH 18/20] test: add gitkeep file to retain test empty dir --- data/ex1/archive.zarr/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/ex1/archive.zarr/.gitkeep diff --git a/data/ex1/archive.zarr/.gitkeep b/data/ex1/archive.zarr/.gitkeep new file mode 100644 index 00000000..e69de29b From 6198bcd724866f6312adc2b93d4520ebb9ccc4dd Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 18:22:41 +0100 Subject: [PATCH 19/20] refactor: skip zarr (sub)files in MODO.list_files --- modo/api.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modo/api.py b/modo/api.py index 0051e789..51cd8f99 100644 --- a/modo/api.py +++ b/modo/api.py @@ -24,7 +24,7 @@ class MODO: # List files in the archive >>> [file.name for file in demo.list_files()] - ['demo1.cram', 'demo2.cram', 'ecoli_ref.fa', 'metadata.ttl', 'archive.zarr'] + ['demo1.cram', 'demo2.cram', 'ecoli_ref.fa', 'metadata.ttl'] # Query the metadata graph to find the location of the # CRAM files for the sample bac1 @@ -58,7 +58,14 @@ def list_samples(self) -> list[str]: return [str(res.sample) for res in samples] def list_files(self) -> Generator[Path, None, None]: - return self.path.rglob("*") + """Lists files in the archive recursively (except for the zarr file).""" + for path in self.path.glob("*"): + if path.name == "archive.zarr": + continue + elif path.is_file(): + yield path + for file in path.rglob("*"): + yield file def query(self, query: str): """Use SPARQL to query the metadata graph""" From 432a95774bb91e861796bc8917e48fb3f9f7a5fa Mon Sep 17 00:00:00 2001 From: cmdoret Date: Fri, 15 Dec 2023 18:26:10 +0100 Subject: [PATCH 20/20] test(api): consistent sorting order in output filelist --- modo/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modo/api.py b/modo/api.py index 51cd8f99..c73f6a88 100644 --- a/modo/api.py +++ b/modo/api.py @@ -23,7 +23,7 @@ class MODO: ['http://example.org/bac1', 'http://example.org/bac2'] # List files in the archive - >>> [file.name for file in demo.list_files()] + >>> sorted([file.name for file in demo.list_files()]) ['demo1.cram', 'demo2.cram', 'ecoli_ref.fa', 'metadata.ttl'] # Query the metadata graph to find the location of the