scdataloader 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import gc
2
2
  import time
3
- from typing import Callable, Optional, Union
3
+ from typing import Callable, List, Optional, Union
4
4
  from uuid import uuid4
5
5
 
6
6
  import anndata as ad
@@ -16,7 +16,7 @@ from upath import UPath
16
16
  from scdataloader import utils as data_utils
17
17
 
18
18
  FULL_LENGTH_ASSAYS = [
19
- "EFO: 0700016",
19
+ "EFO:0700016",
20
20
  "EFO:0008930",
21
21
  "EFO:0008931",
22
22
  ]
@@ -49,18 +49,18 @@ class Preprocessor:
49
49
  maxdropamount: int = 50,
50
50
  madoutlier: int = 5,
51
51
  pct_mt_outlier: int = 8,
52
- batch_keys: list[str] = [
52
+ batch_keys: List[str] = [
53
53
  "assay_ontology_term_id",
54
54
  "self_reported_ethnicity_ontology_term_id",
55
55
  "sex_ontology_term_id",
56
56
  "donor_id",
57
57
  "suspension_type",
58
58
  ],
59
- skip_validate: bool = False,
59
+ skip_validate: bool = True,
60
60
  additional_preprocess: Optional[Callable[[AnnData], AnnData]] = None,
61
61
  additional_postprocess: Optional[Callable[[AnnData], AnnData]] = None,
62
62
  do_postp: bool = True,
63
- organisms: list[str] = ["NCBITaxon:9606", "NCBITaxon:10090"],
63
+ organisms: List[str] = ["NCBITaxon:9606", "NCBITaxon:10090"],
64
64
  use_raw: bool = True,
65
65
  keepdata: bool = False,
66
66
  drop_non_primary: bool = False,
@@ -145,9 +145,14 @@ class Preprocessor:
145
145
  if self.additional_preprocess is not None:
146
146
  adata = self.additional_preprocess(adata)
147
147
  if "organism_ontology_term_id" not in adata[0].obs.columns:
148
- raise ValueError(
149
- "organism_ontology_term_id not found in adata.obs, you need to add an ontology term id for the organism of your anndata"
150
- )
148
+ if "organism_ontology_term_id" in adata.uns:
149
+ adata.obs["organism_ontology_term_id"] = adata.uns[
150
+ "organism_ontology_term_id"
151
+ ]
152
+ else:
153
+ raise ValueError(
154
+ "organism_ontology_term_id not found in adata.obs, you need to add an ontology term id for the organism of your anndata"
155
+ )
151
156
  if adata.obs["organism_ontology_term_id"].iloc[0] not in self.organisms:
152
157
  raise ValueError(
153
158
  "we cannot work with this organism",
@@ -357,6 +362,8 @@ class Preprocessor:
357
362
  adata.obs["batches"] = adata.obs[batches].apply(
358
363
  lambda x: ",".join(x.dropna().astype(str)), axis=1
359
364
  )
365
+ if "highly_variable" in adata.var.columns:
366
+ adata.var = adata.var.drop(columns=["highly_variable"])
360
367
  if self.n_hvg_for_postp:
361
368
  try:
362
369
  sc.pp.highly_variable_genes(
@@ -380,10 +387,13 @@ class Preprocessor:
380
387
  )
381
388
  print("starting PCA")
382
389
  adata.obsm["X_pca"] = sc.pp.pca(
383
- adata.layers["norm"][:, adata.var.highly_variable]
384
- if "highly_variable" in adata.var.columns
385
- else adata.layers["norm"],
386
- n_comps=200 if adata.shape[0] > 200 else adata.shape[0] - 2,
390
+ (
391
+ adata.layers["norm"][:, adata.var["highly_variable"]]
392
+ if "highly_variable" in adata.var.columns
393
+ else adata.layers["norm"]
394
+ ),
395
+ n_comps=50 if adata.shape[0] > 1000 else adata.shape[0] // 20,
396
+ chunked=adata.shape[0] > 100_000,
387
397
  )
388
398
 
389
399
  # additional
@@ -448,12 +458,14 @@ class LaminPreprocessor(Preprocessor):
448
458
  cache: bool = True,
449
459
  keep_files: bool = True,
450
460
  force_lamin_cache: bool = False,
461
+ assays_to_drop: List[str] = ["EFO:0008939"],
451
462
  **kwargs,
452
463
  ):
453
464
  super().__init__(*args, **kwargs)
454
465
  self.cache = cache
455
466
  self.keep_files = keep_files
456
467
  self.force_lamin_cache = force_lamin_cache
468
+ self.assays_to_drop = assays_to_drop
457
469
 
458
470
  def __call__(
459
471
  self,
@@ -499,11 +511,14 @@ class LaminPreprocessor(Preprocessor):
499
511
  if backed.obs.is_primary_data.sum() == 0:
500
512
  print(f"{file.key} only contains non primary cells.. dropping")
501
513
  # Save the stem_uid to a file to avoid loading it again
502
- with open("nonprimary.txt", "a") as f:
503
- f.write(f"{file.stem_uid}\n")
504
- continue
514
+ with open("nonprimary.txt", "a") as f:
515
+ f.write(f"{file.stem_uid}\n")
516
+ continue
505
517
  else:
506
518
  print("Warning: couldn't check unicity from is_primary_data column")
519
+ if backed.obs.assay_ontology_term_id[0] in self.assays_to_drop:
520
+ print(f"{file.key} is in the assay drop list.. dropping")
521
+ continue
507
522
  if backed.shape[1] < 1000:
508
523
  print(
509
524
  f"{file.key} only contains less than 1000 genes and is likely not scRNAseq... dropping"
@@ -577,7 +592,7 @@ class LaminPreprocessor(Preprocessor):
577
592
  try:
578
593
  myfile = ln.Artifact.from_anndata(
579
594
  adata,
580
- revises=file,
595
+ # revises=file,
581
596
  description=description + " p" + str(i),
582
597
  version=version,
583
598
  )
scdataloader/utils.py CHANGED
@@ -1,5 +1,7 @@
1
1
  import io
2
2
  import os
3
+ import random
4
+ import string
3
5
  import urllib
4
6
  from collections import Counter
5
7
  from functools import lru_cache
@@ -13,6 +15,7 @@ import torch
13
15
  from anndata import AnnData
14
16
  from biomart import BiomartServer
15
17
  from django.db import IntegrityError
18
+ from lamindb.errors import DoesNotExist
16
19
  from scipy.sparse import csr_matrix
17
20
  from scipy.stats import median_abs_deviation
18
21
  from torch import Tensor
@@ -32,7 +35,9 @@ def fileToList(filename: str, strconv: callable = lambda x: x) -> list:
32
35
  return [strconv(val[:-1]) for val in f.readlines()]
33
36
 
34
37
 
35
- def listToFile(li: list, filename: str, strconv: callable = lambda x: str(x)) -> None:
38
+ def listToFile(
39
+ li: List[str], filename: str, strconv: callable = lambda x: str(x)
40
+ ) -> None:
36
41
  """
37
42
  listToFile loads a list with [a,b,..] into an input file a\\n b\\n..
38
43
 
@@ -56,6 +61,23 @@ def slurm_restart_count(use_mine: bool = False):
56
61
  return int(os.getenv("SLURM_RESTART_COUNT", 0))
57
62
 
58
63
 
64
+ def revert_to_raw(adata, mode="logp1"):
65
+ res = adata.X
66
+ if mode == "rlogp1":
67
+ res = np.exp(res) - 1
68
+ elif mode == "logp1":
69
+ res = (2**res) - 1
70
+ elif mode == "sqrt":
71
+ res = (res**2) - 1
72
+ res = (
73
+ (res.T / np.array([res[i][res[i] != 0].min() for i in range(res.shape[0])]))
74
+ .round()
75
+ .T
76
+ ) # .sum()
77
+ adata.X = res
78
+ return adata
79
+
80
+
59
81
  def createFoldersFor(filepath: str):
60
82
  """
61
83
  will recursively create folders if needed until having all the folders required to save the file in this filepath
@@ -68,7 +90,7 @@ def createFoldersFor(filepath: str):
68
90
 
69
91
 
70
92
  def _fetchFromServer(
71
- ensemble_server: str, attributes: list, database: str = "hsapiens_gene_ensembl"
93
+ ensemble_server: str, attributes: List[str], database: str = "hsapiens_gene_ensembl"
72
94
  ):
73
95
  """
74
96
  Fetches data from the specified ensemble server.
@@ -274,7 +296,7 @@ def get_descendants(val, df):
274
296
  return r_onto | ontos
275
297
 
276
298
 
277
- def get_ancestry_mapping(all_elem: list, onto_df: pd.DataFrame):
299
+ def get_ancestry_mapping(all_elem: List[str], onto_df: pd.DataFrame):
278
300
  """
279
301
  This function generates a mapping of all elements to their ancestors in the ontology dataframe.
280
302
 
@@ -370,12 +392,14 @@ def load_dataset_local(
370
392
  return dataset
371
393
 
372
394
 
373
- def load_genes(organisms: Union[str, list] = "NCBITaxon:9606"): # "NCBITaxon:10090",
395
+ def load_genes(
396
+ organisms: Union[str, List[str]] = "NCBITaxon:9606",
397
+ ): # "NCBITaxon:10090",
374
398
  """
375
399
  Loads genes from the given organisms.
376
400
 
377
401
  Args:
378
- organisms (Union[str, list]): The organisms to load genes from.
402
+ organisms (Union[str, List[str]]): The organisms to load genes from.
379
403
 
380
404
  Returns:
381
405
  pd.DataFrame: The genes dataframe.
@@ -583,6 +607,54 @@ def load_genes(organisms: Union[str, list] = "NCBITaxon:9606"): # "NCBITaxon:10
583
607
  return organismdf
584
608
 
585
609
 
610
+ def _adding_scbasecamp_genes(
611
+ species=[],
612
+ ):
613
+ if len(species) == 0:
614
+ species = set(
615
+ bt.Organism.using("laminlabs/arc-virtual-cell-atlas").df().ontology_id
616
+ )
617
+ -set(["NCBITaxon:10090", "NCBITaxon:9606"])
618
+ species = list(species)
619
+ if len(bt.Organism.filter(ontology_id="NCBITaxon:9593")) == 0:
620
+ bt.Organism(
621
+ name="gorilla gorilla",
622
+ ontology_id="NCBITaxon:9593",
623
+ scientific_name="Gorilla gorilla gorilla",
624
+ ).save()
625
+ if len(bt.Organism.filter(ontology_id="NCBITaxon:9594")) == 0:
626
+ bt.Organism(
627
+ name="rice",
628
+ ontology_id="NCBITaxon:4530",
629
+ scientific_name="Oryza sativa (main)",
630
+ ).save()
631
+
632
+ for i in species:
633
+ print(i)
634
+ df = (
635
+ bt.Gene.using("laminlabs/arc-virtual-cell-atlas")
636
+ .filter(organism__ontology_id=i)
637
+ .all()
638
+ .df()
639
+ )
640
+ genes = []
641
+ org = bt.Organism.filter(ontology_id=i).one()
642
+ ido = org.id
643
+ for row in df.to_dict(orient="records"):
644
+ row["organism_id"] = ido
645
+ gene = bt.Gene(
646
+ ensembl_gene_id=row["ensembl_gene_id"],
647
+ stable_id=row["stable_id"],
648
+ description=row["description"],
649
+ symbol=row["symbol"],
650
+ biotype=row["biotype"],
651
+ organism=org,
652
+ _skip_validation=True,
653
+ )
654
+ genes.append(gene)
655
+ ln.save(genes, ignore_conflicts=True)
656
+
657
+
586
658
  def populate_my_ontology(
587
659
  sex: List[str] = ["PATO:0000384", "PATO:0000383"],
588
660
  celltypes: List[str] = [],
@@ -591,7 +663,8 @@ def populate_my_ontology(
591
663
  tissues: List[str] = [],
592
664
  diseases: List[str] = [],
593
665
  dev_stages: List[str] = [],
594
- organisms_clade: List[str] = ["vertebrates", "plants"],
666
+ organisms_clade: List[str] = ["vertebrates", "plants", "metazoa"],
667
+ genes_from: List[str] = ["NCBITaxon:10090", "NCBITaxon:9606"],
595
668
  ):
596
669
  """
597
670
  creates a local version of the lamin ontologies and add the required missing values in base ontologies
@@ -607,8 +680,6 @@ def populate_my_ontology(
607
680
  `df["assay_ontology_term_id"].unique()`
608
681
 
609
682
  Args:
610
- lb (lamindb): lamindb instance.
611
- organisms (list, optional): List of organisms. Defaults to ["NCBITaxon:10090", "NCBITaxon:9606"].
612
683
  sex (list, optional): List of sexes. Defaults to ["PATO:0000384", "PATO:0000383"].
613
684
  celltypes (list, optional): List of cell types. Defaults to [].
614
685
  ethnicities (list, optional): List of ethnicities. Defaults to [].
@@ -616,6 +687,7 @@ def populate_my_ontology(
616
687
  tissues (list, optional): List of tissues. Defaults to [].
617
688
  diseases (list, optional): List of diseases. Defaults to [].
618
689
  dev_stages (list, optional): List of developmental stages. Defaults to [].
690
+ organisms_clade (list, optional): List of organisms clade. Defaults to ["vertebrates", "plants"].
619
691
  """
620
692
  # cell type
621
693
  if celltypes is not None:
@@ -626,17 +698,17 @@ def populate_my_ontology(
626
698
  records = bt.CellType.from_values(names, field="ontology_id")
627
699
  ln.save(records)
628
700
  bt.CellType(name="unknown", ontology_id="unknown").save()
629
- # Organism
701
+ # OrganismClade
630
702
  if organisms_clade is not None:
631
703
  records = []
632
704
  for organism_clade in organisms_clade:
633
705
  names = bt.Organism.public(organism=organism_clade).df().index
634
- source = bt.PublicSource.filter(
635
- name="ensembl", organism=organism_clade
636
- ).last()
637
- records += [
638
- bt.Organism.from_source(name=name, source=source) for name in names
639
- ]
706
+ source = bt.Source.filter(name="ensembl", organism=organism_clade).last()
707
+ for name in names:
708
+ try:
709
+ records.append(bt.Organism.from_source(name=name, source=source))
710
+ except DoesNotExist:
711
+ print(f"Organism {name} not found in source {source}")
640
712
  nrecords = []
641
713
  prevrec = set()
642
714
  for rec in records:
@@ -652,7 +724,7 @@ def populate_my_ontology(
652
724
  # Phenotype
653
725
  if sex is not None:
654
726
  names = bt.Phenotype.public().df().index if not sex else sex
655
- source = bt.PublicSource.filter(name="pato").first()
727
+ source = bt.Source.filter(name="pato").first()
656
728
  records = [
657
729
  bt.Phenotype.from_source(ontology_id=i, source=source) for i in names
658
730
  ]
@@ -693,7 +765,7 @@ def populate_my_ontology(
693
765
  if dev_stages is not None:
694
766
  if len(dev_stages) == 0:
695
767
  bt.DevelopmentalStage.import_source()
696
- source = bt.PublicSource.filter(organism="mouse", name="mmusdv").last()
768
+ source = bt.Source.filter(organism="mouse", name="mmusdv").last()
697
769
  bt.DevelopmentalStage.import_source(source=source)
698
770
  else:
699
771
  names = (
@@ -716,7 +788,7 @@ def populate_my_ontology(
716
788
  bt.Disease(name="normal", ontology_id="PATO:0000461").save()
717
789
  bt.Disease(name="unknown", ontology_id="unknown").save()
718
790
  # genes
719
- for organism in ["NCBITaxon:10090", "NCBITaxon:9606"]:
791
+ for organism in genes_from:
720
792
  # convert onto to name
721
793
  organism = bt.Organism.filter(ontology_id=organism).one().name
722
794
  names = bt.Gene.public(organism=organism).df()["ensembl_gene_id"]
@@ -733,6 +805,29 @@ def populate_my_ontology(
733
805
  ln.save(records)
734
806
 
735
807
 
808
+ def random_str(stringLength=6, stype="all", withdigits=True):
809
+ """
810
+ Generate a random string of letters and digits
811
+
812
+ Args:
813
+ stringLength (int, optional): the amount of char. Defaults to 6.
814
+ stype (str, optional): one of lowercase, uppercase, all. Defaults to 'all'.
815
+ withdigits (bool, optional): digits allowed in the string? Defaults to True.
816
+
817
+ Returns:
818
+ str: random string
819
+ """
820
+ if stype == "lowercase":
821
+ lettersAndDigits = string.ascii_lowercase
822
+ elif stype == "uppercase":
823
+ lettersAndDigits = string.ascii_uppercase
824
+ else:
825
+ lettersAndDigits = string.ascii_letters
826
+ if withdigits:
827
+ lettersAndDigits += string.digits
828
+ return "".join(random.choice(lettersAndDigits) for i in range(stringLength))
829
+
830
+
736
831
  def is_outlier(adata: AnnData, metric: str, nmads: int):
737
832
  """
738
833
  is_outlier detects outliers in adata.obs[metric]
@@ -798,11 +893,16 @@ def translate(
798
893
  obj = bt.Disease
799
894
  elif t == "self_reported_ethnicity_ontology_term_id":
800
895
  obj = bt.Ethnicity
896
+ elif t == "organism_ontology_term_id":
897
+ obj = bt.Organism
801
898
  else:
802
899
  return None
803
900
  if type(val) is str:
804
901
  return {val: obj.filter(ontology_id=val).one().name}
805
- elif type(val) is list or type(val) is set:
806
- return {i: obj.filter(ontology_id=i).one().name for i in set(val)}
807
902
  elif type(val) is dict or type(val) is Counter:
808
903
  return {obj.filter(ontology_id=k).one().name: v for k, v in val.items()}
904
+ elif type(val) is set:
905
+ return {i: obj.filter(ontology_id=i).one().name for i in val}
906
+ else:
907
+ rl = {i: obj.filter(ontology_id=i).one().name for i in set(val)}
908
+ return [rl.get(i, None) for i in val]
@@ -1,29 +1,29 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scdataloader
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: a dataloader for single cell data in lamindb
5
5
  Project-URL: repository, https://github.com/jkobject/scDataLoader
6
6
  Author-email: jkobject <jkobject@gmail.com>
7
7
  License-Expression: MIT
8
8
  License-File: LICENSE
9
9
  Keywords: dataloader,lamindb,pytorch,scPRINT,scRNAseq
10
- Requires-Python: <3.14,>=3.10
10
+ Requires-Python: <3.13,>=3.10
11
11
  Requires-Dist: anndata>=0.9.0
12
12
  Requires-Dist: biomart>=0.9.0
13
13
  Requires-Dist: cellxgene-census>=0.1.0
14
14
  Requires-Dist: django>=4.0.0
15
15
  Requires-Dist: ipykernel>=6.20.0
16
16
  Requires-Dist: jupytext>=1.16.0
17
- Requires-Dist: lamindb[bionty,cellregistry,jupyter,zarr]==1.0.4
17
+ Requires-Dist: lamindb[bionty,jupyter,zarr]==1.6.2
18
18
  Requires-Dist: leidenalg>=0.8.0
19
19
  Requires-Dist: lightning>=2.3.0
20
20
  Requires-Dist: matplotlib>=3.5.0
21
- Requires-Dist: numpy==1.26.0
21
+ Requires-Dist: numpy<=2.2.0
22
22
  Requires-Dist: pandas>=2.0.0
23
23
  Requires-Dist: pytorch-lightning>=2.3.0
24
24
  Requires-Dist: scikit-misc>=0.5.0
25
25
  Requires-Dist: seaborn>=0.11.0
26
- Requires-Dist: torch==2.2.0
26
+ Requires-Dist: torch>=2.2.0
27
27
  Requires-Dist: torchdata>=0.5.0
28
28
  Requires-Dist: zarr>=2.10.0
29
29
  Provides-Extra: dev
@@ -0,0 +1,16 @@
1
+ scdataloader/__init__.py,sha256=Z5HURehoWw1GrecImmTXIkv4ih8Q5RxNQWPm8zjjXOA,226
2
+ scdataloader/__main__.py,sha256=xPOtrEpQQQZUGTnm8KTvsQcA_jR45oMG_VHqd0Ny7_M,8677
3
+ scdataloader/base.py,sha256=M1gD59OffRdLOgS1vHKygOomUoAMuzjpRtAfM3SBKF8,338
4
+ scdataloader/collator.py,sha256=pITHfsWUkrUW7lMfgXfs1AfekgcfW9XfGHwi9LlKwm8,13651
5
+ scdataloader/config.py,sha256=nM8J11z2-lornryy1KxDE9675Rcxge4RGhdmpeiMhuI,7173
6
+ scdataloader/data.json,sha256=Zb8c27yk3rwMgtAU8kkiWWAyUwYBrlCqKUyEtaAx9i8,8785
7
+ scdataloader/data.py,sha256=aiSpw4rd5L162ox2kuD-8ujWNix5fvVlXozdlfthMNU,18176
8
+ scdataloader/datamodule.py,sha256=pGPPuxDrWz0GPBUz_vb4FUprbuNKkjq1hjr46m-fRVU,35783
9
+ scdataloader/mapped.py,sha256=h9YKQ8SG9tyZL8c6_Wu5Xov5ODGK6FzVuFopz58xwN4,29887
10
+ scdataloader/preprocess.py,sha256=4iqHqeSVE-oKRvwD0KKl_QH6HQWVYSMRPo9QNSq-3Pk,39179
11
+ scdataloader/utils.py,sha256=Z6td0cIphrYDLVrPrV8q4jUC_HtwGQmi-NcbpdbWrns,31034
12
+ scdataloader-2.0.2.dist-info/METADATA,sha256=QsyNBOyn_U9_TjFVbN-5WIGIkmKWf2sSksZUzKcNlqE,10314
13
+ scdataloader-2.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ scdataloader-2.0.2.dist-info/entry_points.txt,sha256=VXAN1m_CjbdLJ6SKYR0sBLGDV4wvv31ri7fWWuwbpno,60
15
+ scdataloader-2.0.2.dist-info/licenses/LICENSE,sha256=rGy_eYmnxtbOvKs7qt5V0czSWxJwgX_MlgMyTZwDHbc,1073
16
+ scdataloader-2.0.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,16 +0,0 @@
1
- scdataloader/__init__.py,sha256=Z5HURehoWw1GrecImmTXIkv4ih8Q5RxNQWPm8zjjXOA,226
2
- scdataloader/__main__.py,sha256=3aZnqYrH8XDT9nW9Dbb3o9kr-sx1STmXDQHxBo_h_q0,8719
3
- scdataloader/base.py,sha256=M1gD59OffRdLOgS1vHKygOomUoAMuzjpRtAfM3SBKF8,338
4
- scdataloader/collator.py,sha256=pC5PVvxwyE7e84cdr5YC4ae85NbJubk6bfldIfOLFNE,12039
5
- scdataloader/config.py,sha256=nM8J11z2-lornryy1KxDE9675Rcxge4RGhdmpeiMhuI,7173
6
- scdataloader/data.json,sha256=Zb8c27yk3rwMgtAU8kkiWWAyUwYBrlCqKUyEtaAx9i8,8785
7
- scdataloader/data.py,sha256=skUBLX07cxC9gl4X0zDQ3rUpm0EJoUjngvdhL4lo5IA,18633
8
- scdataloader/datamodule.py,sha256=fKYjQlli9wm3uCJbD6FedooNSorjl5vfg5LuwDCQkQU,34388
9
- scdataloader/mapped.py,sha256=0erd1vCfCnUkdMuFO4Md0d78gNeNaHSWwRVXN4zhtQQ,29802
10
- scdataloader/preprocess.py,sha256=CA0pvfcfZ_nMhso7vl9MfKhKfaJbYwANqHfsa5Vyco4,38425
11
- scdataloader/utils.py,sha256=YzTCV1IkfXIaQmtdTXJvo_Vj1l_Dhau7UUM_BBccvL0,27939
12
- scdataloader-2.0.0.dist-info/METADATA,sha256=rNBXB06aOnCNTu8LjijBTReTototB2tRnGmnHaFtyVE,10328
13
- scdataloader-2.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
- scdataloader-2.0.0.dist-info/entry_points.txt,sha256=VXAN1m_CjbdLJ6SKYR0sBLGDV4wvv31ri7fWWuwbpno,60
15
- scdataloader-2.0.0.dist-info/licenses/LICENSE,sha256=rGy_eYmnxtbOvKs7qt5V0czSWxJwgX_MlgMyTZwDHbc,1073
16
- scdataloader-2.0.0.dist-info/RECORD,,