lsst-felis 29.2025.2400__py3-none-any.whl → 29.2025.2500__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.

Potentially problematic release.


This version of lsst-felis might be problematic. Click here for more details.

felis/cli.py CHANGED
@@ -38,7 +38,7 @@ from .db.schema import create_database
38
38
  from .db.utils import DatabaseContext, is_mock_url
39
39
  from .diff import DatabaseDiff, FormattedSchemaDiff, SchemaDiff
40
40
  from .metadata import MetaDataBuilder
41
- from .tap_schema import DataLoader, TableManager
41
+ from .tap_schema import DataLoader, MetadataInserter, TableManager
42
42
 
43
43
  __all__ = ["cli"]
44
44
 
@@ -284,14 +284,20 @@ def load_tap_schema(
284
284
 
285
285
 
286
286
  @cli.command("init-tap-schema", help="Initialize a standard TAP_SCHEMA database")
287
- @click.option("--engine-url", envvar="FELIS_ENGINE_URL", help="SQLAlchemy Engine URL")
287
+ @click.option("--engine-url", envvar="FELIS_ENGINE_URL", help="SQLAlchemy Engine URL", required=True)
288
288
  @click.option("--tap-schema-name", help="Name of the TAP_SCHEMA schema in the database")
289
289
  @click.option(
290
290
  "--tap-tables-postfix", help="Postfix which is applied to standard TAP_SCHEMA table names", default=""
291
291
  )
292
+ @click.option(
293
+ "--insert-metadata/--no-insert-metadata",
294
+ is_flag=True,
295
+ help="Insert metadata describing TAP_SCHEMA itself",
296
+ default=True,
297
+ )
292
298
  @click.pass_context
293
299
  def init_tap_schema(
294
- ctx: click.Context, engine_url: str, tap_schema_name: str, tap_tables_postfix: str
300
+ ctx: click.Context, engine_url: str, tap_schema_name: str, tap_tables_postfix: str, insert_metadata: bool
295
301
  ) -> None:
296
302
  """Initialize a standard TAP_SCHEMA database.
297
303
 
@@ -303,6 +309,10 @@ def init_tap_schema(
303
309
  Name of the TAP_SCHEMA schema in the database.
304
310
  tap_tables_postfix
305
311
  Postfix which is applied to standard TAP_SCHEMA table names.
312
+ insert_metadata
313
+ Insert metadata describing TAP_SCHEMA itself.
314
+ If set to False, only the TAP_SCHEMA tables will be created, but no
315
+ metadata will be inserted.
306
316
  """
307
317
  url = make_url(engine_url)
308
318
  engine: Engine | MockConnection
@@ -315,6 +325,9 @@ def init_tap_schema(
315
325
  table_name_postfix=tap_tables_postfix,
316
326
  )
317
327
  mgr.initialize_database(engine)
328
+ if insert_metadata:
329
+ inserter = MetadataInserter(mgr, engine)
330
+ inserter.insert_metadata()
318
331
 
319
332
 
320
333
  @cli.command("validate", help="Validate one or more Felis YAML files")
@@ -465,12 +478,21 @@ def diff(
465
478
  felis dump schema.yaml schema_dump.yaml
466
479
  """,
467
480
  )
481
+ @click.option(
482
+ "--strip-ids/--no-strip-ids",
483
+ is_flag=True,
484
+ help="Strip IDs from the output schema",
485
+ default=False,
486
+ )
468
487
  @click.argument("files", nargs=2, type=click.Path())
469
488
  @click.pass_context
470
489
  def dump(
471
490
  ctx: click.Context,
491
+ strip_ids: bool,
472
492
  files: list[str],
473
493
  ) -> None:
494
+ if strip_ids:
495
+ logger.info("Stripping IDs from the output schema")
474
496
  if files[1].endswith(".json"):
475
497
  format = "json"
476
498
  elif files[1].endswith(".yaml"):
@@ -480,9 +502,9 @@ def dump(
480
502
  schema = Schema.from_uri(files[0], context={"id_generation": ctx.obj["id_generation"]})
481
503
  with open(files[1], "w") as f:
482
504
  if format == "yaml":
483
- schema.dump_yaml(f)
505
+ schema.dump_yaml(f, strip_ids=strip_ids)
484
506
  elif format == "json":
485
- schema.dump_json(f)
507
+ schema.dump_json(f, strip_ids=strip_ids)
486
508
 
487
509
 
488
510
  if __name__ == "__main__":
@@ -0,0 +1,33 @@
1
+ table_name,column_name,utype,ucd,unit,description,datatype,arraysize,xtype,size,principal,indexed,std,column_index
2
+ tap_schema.columns,"""size""",\N,\N,\N,deprecated: use arraysize,int,\N,\N,\N,1,0,1,9
3
+ tap_schema.columns,arraysize,\N,\N,\N,lists the size of variable-length columns in the tableset,char,16*,\N,16,1,0,1,8
4
+ tap_schema.columns,column_index,\N,\N,\N,recommended sort order when listing columns of a table,int,\N,\N,\N,1,0,1,13
5
+ tap_schema.columns,column_name,\N,\N,\N,the column name,char,64*,\N,64,1,0,1,2
6
+ tap_schema.columns,datatype,\N,\N,\N,lists the ADQL datatype of columns in the tableset,char,64*,\N,64,1,0,1,7
7
+ tap_schema.columns,description,\N,\N,\N,describes the columns in the tableset,char,512*,\N,512,1,0,1,6
8
+ tap_schema.columns,indexed,\N,\N,\N,"an indexed column; 1 means 1, 0 means 0",int,\N,\N,\N,1,0,1,11
9
+ tap_schema.columns,principal,\N,\N,\N,"a principal column; 1 means 1, 0 means 0",int,\N,\N,\N,1,0,1,10
10
+ tap_schema.columns,std,\N,\N,\N,"a standard column; 1 means 1, 0 means 0",int,\N,\N,\N,1,0,1,12
11
+ tap_schema.columns,table_name,\N,\N,\N,the table this column belongs to,char,64*,\N,64,1,0,1,1
12
+ tap_schema.columns,ucd,\N,\N,\N,lists the UCDs of columns in the tableset,char,64*,\N,64,1,0,1,4
13
+ tap_schema.columns,unit,\N,\N,\N,lists the unit used for column values in the tableset,char,64*,\N,64,1,0,1,5
14
+ tap_schema.columns,utype,\N,\N,\N,lists the utypes of columns in the tableset,char,512*,\N,512,1,0,1,3
15
+ tap_schema.columns,xtype,\N,\N,\N,a DALI or custom extended type annotation,char,64*,\N,64,1,0,1,7
16
+ tap_schema.key_columns,from_column,\N,\N,\N,column in the from_table,char,64*,\N,64,1,0,1,2
17
+ tap_schema.key_columns,key_id,\N,\N,\N,key to join to tap_schema.keys,char,64*,\N,64,1,0,1,1
18
+ tap_schema.key_columns,target_column,\N,\N,\N,column in the target_table,char,64*,\N,64,1,0,1,3
19
+ tap_schema.keys,description,\N,\N,\N,describes keys in the tableset,char,512*,\N,512,1,0,1,5
20
+ tap_schema.keys,from_table,\N,\N,\N,the table with the foreign key,char,64*,\N,64,1,0,1,2
21
+ tap_schema.keys,key_id,\N,\N,\N,unique key to join to tap_schema.key_columns,char,64*,\N,64,1,0,1,1
22
+ tap_schema.keys,target_table,\N,\N,\N,the table with the primary key,char,64*,\N,64,1,0,1,3
23
+ tap_schema.keys,utype,\N,\N,\N,lists the utype of keys in the tableset,char,512*,\N,512,1,0,1,4
24
+ tap_schema.schemas,description,\N,\N,\N,describes schemas in the tableset,char,512*,\N,512,1,0,1,3
25
+ tap_schema.schemas,schema_index,\N,\N,\N,recommended sort order when listing schemas,int,\N,\N,\N,1,0,1,4
26
+ tap_schema.schemas,schema_name,\N,\N,\N,schema name for reference to tap_schema.schemas,char,64*,\N,64,1,0,1,1
27
+ tap_schema.schemas,utype,\N,\N,\N,lists the utypes of schemas in the tableset,char,512*,\N,512,1,0,1,2
28
+ tap_schema.tables,description,\N,\N,\N,describes tables in the tableset,char,512*,\N,512,1,0,1,5
29
+ tap_schema.tables,schema_name,\N,\N,\N,the schema this table belongs to,char,512*,\N,512,1,0,1,1
30
+ tap_schema.tables,table_index,\N,\N,\N,recommended sort order when listing tables,int,\N,\N,\N,1,0,1,6
31
+ tap_schema.tables,table_name,\N,\N,\N,the fully qualified table name,char,64*,\N,64,1,0,1,2
32
+ tap_schema.tables,table_type,\N,\N,\N,one of: table view,char,8*,\N,8,1,0,1,3
33
+ tap_schema.tables,utype,\N,\N,\N,lists the utype of tables in the tableset,char,512*,\N,512,1,0,1,4
@@ -0,0 +1,8 @@
1
+ key_id,from_column,target_column
2
+ k1,schema_name,schema_name
3
+ k2,table_name,table_name
4
+ k3,from_table,table_name
5
+ k4,target_table,table_name
6
+ k5,key_id,key_id
7
+ k6,from_column,column_name
8
+ k7,target_column,column_name
@@ -0,0 +1,8 @@
1
+ key_id,from_table,target_table,utype,description
2
+ k1,tap_schema.tables,tap_schema.schemas,\N,\N
3
+ k2,tap_schema.columns,tap_schema.tables,\N,\N
4
+ k3,tap_schema.keys,tap_schema.tables,\N,\N
5
+ k4,tap_schema.keys,tap_schema.tables,\N,\N
6
+ k5,tap_schema.key_columns,tap_schema.keys,\N,\N
7
+ k6,tap_schema.key_columns,tap_schema.columns,\N,\N
8
+ k7,tap_schema.key_columns,tap_schema.columns,\N,\N
@@ -0,0 +1,2 @@
1
+ schema_name,utype,description,schema_index
2
+ tap_schema,\N,A TAP-standard-mandated schema to describe tablesets in a TAP 1.1 service,100000
@@ -0,0 +1,6 @@
1
+ schema_name,table_name,table_type,utype,description,table_index
2
+ tap_schema,tap_schema.columns,table,\N,description of columns in this tableset,102000
3
+ tap_schema,tap_schema.key_columns,table,\N,description of foreign key columns in this tableset,104000
4
+ tap_schema,tap_schema.keys,table,\N,description of foreign keys in this tableset,103000
5
+ tap_schema,tap_schema.schemas,table,\N,description of schemas in this tableset,100000
6
+ tap_schema,tap_schema.tables,table,\N,description of tables in this tableset,101000
felis/datamodel.py CHANGED
@@ -633,6 +633,12 @@ class ForeignKeyConstraint(Constraint):
633
633
  referenced_columns: list[str] = Field(alias="referencedColumns")
634
634
  """The columns referenced by the foreign key."""
635
635
 
636
+ on_delete: Literal["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"] | None = None
637
+ """Action to take when the referenced row is deleted."""
638
+
639
+ on_update: Literal["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"] | None = None
640
+ """Action to take when the referenced row is updated."""
641
+
636
642
  @field_serializer("type")
637
643
  def serialize_type(self, value: str) -> str:
638
644
  """Ensure '@type' is included in serialized output.
@@ -1022,6 +1028,26 @@ class SchemaIdVisitor:
1022
1028
  T = TypeVar("T", bound=BaseObject)
1023
1029
 
1024
1030
 
1031
+ def _strip_ids(data: Any) -> Any:
1032
+ """Recursively strip '@id' fields from a dictionary or list.
1033
+
1034
+ Parameters
1035
+ ----------
1036
+ data
1037
+ The data to strip IDs from, which can be a dictionary, list, or any
1038
+ other type. Other types will be returned unchanged.
1039
+ """
1040
+ if isinstance(data, dict):
1041
+ data.pop("@id", None)
1042
+ for k, v in data.items():
1043
+ data[k] = _strip_ids(v)
1044
+ return data
1045
+ elif isinstance(data, list):
1046
+ return [_strip_ids(item) for item in data]
1047
+ else:
1048
+ return data
1049
+
1050
+
1025
1051
  class Schema(BaseObject, Generic[T]):
1026
1052
  """Database schema model.
1027
1053
 
@@ -1388,31 +1414,56 @@ class Schema(BaseObject, Generic[T]):
1388
1414
  yaml_data = yaml.safe_load(source)
1389
1415
  return Schema.model_validate(yaml_data, context=context)
1390
1416
 
1391
- def dump_yaml(self, stream: IO[str] = sys.stdout) -> None:
1417
+ def _model_dump(self, strip_ids: bool = False) -> dict[str, Any]:
1418
+ """Dump the schema as a dictionary with some default arguments
1419
+ applied.
1420
+
1421
+ Parameters
1422
+ ----------
1423
+ strip_ids
1424
+ Whether to strip the IDs from the dumped data. Defaults to `False`.
1425
+
1426
+ Returns
1427
+ -------
1428
+ `dict` [ `str`, `Any` ]
1429
+ The dumped schema data as a dictionary.
1430
+ """
1431
+ data = self.model_dump(by_alias=True, exclude_none=True, exclude_defaults=True)
1432
+ if strip_ids:
1433
+ data = _strip_ids(data)
1434
+ return data
1435
+
1436
+ def dump_yaml(self, stream: IO[str] = sys.stdout, strip_ids: bool = False) -> None:
1392
1437
  """Pretty print the schema as YAML.
1393
1438
 
1394
1439
  Parameters
1395
1440
  ----------
1396
1441
  stream
1397
1442
  The stream to write the YAML data to.
1443
+ strip_ids
1444
+ Whether to strip the IDs from the dumped data. Defaults to `False`.
1398
1445
  """
1446
+ data = self._model_dump(strip_ids=strip_ids)
1399
1447
  yaml.safe_dump(
1400
- self.model_dump(by_alias=True, exclude_none=True, exclude_defaults=True),
1448
+ data,
1401
1449
  stream,
1402
1450
  default_flow_style=False,
1403
1451
  sort_keys=False,
1404
1452
  )
1405
1453
 
1406
- def dump_json(self, stream: IO[str] = sys.stdout) -> None:
1454
+ def dump_json(self, stream: IO[str] = sys.stdout, strip_ids: bool = False) -> None:
1407
1455
  """Pretty print the schema as JSON.
1408
1456
 
1409
1457
  Parameters
1410
1458
  ----------
1411
1459
  stream
1412
1460
  The stream to write the JSON data to.
1461
+ strip_ids
1462
+ Whether to strip the IDs from the dumped data. Defaults to `False`.
1413
1463
  """
1464
+ data = self._model_dump(strip_ids=strip_ids)
1414
1465
  json.dump(
1415
- self.model_dump(by_alias=True, exclude_none=True, exclude_defaults=True),
1466
+ data,
1416
1467
  stream,
1417
1468
  indent=4,
1418
1469
  sort_keys=False,
felis/metadata.py CHANGED
@@ -338,12 +338,17 @@ class MetaDataBuilder:
338
338
  "deferrable": constraint_obj.deferrable or None,
339
339
  "initially": constraint_obj.initially or None,
340
340
  }
341
+
341
342
  constraint: Constraint
342
343
 
343
344
  if isinstance(constraint_obj, datamodel.ForeignKeyConstraint):
344
345
  fk_obj: datamodel.ForeignKeyConstraint = constraint_obj
345
346
  columns = [self._objects[column_id] for column_id in fk_obj.columns]
346
347
  refcolumns = [self._objects[column_id] for column_id in fk_obj.referenced_columns]
348
+ if constraint_obj.on_delete is not None:
349
+ args["ondelete"] = constraint_obj.on_delete
350
+ if constraint_obj.on_update is not None:
351
+ args["onupdate"] = constraint_obj.on_update
347
352
  constraint = ForeignKeyConstraint(columns, refcolumns, **args)
348
353
  elif isinstance(constraint_obj, datamodel.CheckConstraint):
349
354
  check_obj: datamodel.CheckConstraint = constraint_obj
felis/tap_schema.py CHANGED
@@ -21,6 +21,8 @@
21
21
  # You should have received a copy of the GNU General Public License
22
22
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
23
23
 
24
+ import csv
25
+ import io
24
26
  import logging
25
27
  import os
26
28
  import re
@@ -208,7 +210,7 @@ class TableManager:
208
210
  str
209
211
  The path to the standard TAP_SCHEMA schema resource.
210
212
  """
211
- return os.path.join(os.path.dirname(__file__), "schemas", "tap_schema_std.yaml")
213
+ return os.path.join(os.path.dirname(__file__), "config", "tap_schema", "tap_schema_std.yaml")
212
214
 
213
215
  @classmethod
214
216
  def get_tap_schema_std_resource(cls) -> ResourcePath:
@@ -219,7 +221,7 @@ class TableManager:
219
221
  `~lsst.resources.ResourcePath`
220
222
  The standard TAP_SCHEMA schema resource.
221
223
  """
222
- return ResourcePath("resource://felis/schemas/tap_schema_std.yaml")
224
+ return ResourcePath("resource://felis/config/tap_schema/tap_schema_std.yaml")
223
225
 
224
226
  @classmethod
225
227
  def get_table_names_std(cls) -> list[str]:
@@ -708,3 +710,48 @@ class DataLoader:
708
710
  if index.columns and len(index.columns) == 1 and index.columns[0] == column.id:
709
711
  return 1
710
712
  return 0
713
+
714
+
715
+ class MetadataInserter:
716
+ """Insert TAP_SCHEMA self-description rows into the database.
717
+
718
+ Parameters
719
+ ----------
720
+ mgr
721
+ The table manager that contains the TAP_SCHEMA tables.
722
+ engine
723
+ The engine for connecting to the TAP_SCHEMA database.
724
+ """
725
+
726
+ def __init__(self, mgr: TableManager, engine: Engine):
727
+ """Initialize the metadata inserter.
728
+
729
+ Parameters
730
+ ----------
731
+ mgr
732
+ The table manager representing the TAP_SCHEMA tables.
733
+ engine
734
+ The SQLAlchemy engine for connecting to the database.
735
+ """
736
+ self._mgr = mgr
737
+ self._engine = engine
738
+
739
+ def insert_metadata(self) -> None:
740
+ """Insert the TAP_SCHEMA metadata into the database."""
741
+ for table_name in self._mgr.get_table_names_std():
742
+ table = self._mgr[table_name]
743
+ csv_bytes = ResourcePath(f"resource://felis/config/tap_schema/{table_name}.csv").read()
744
+ text_stream = io.TextIOWrapper(io.BytesIO(csv_bytes), encoding="utf-8")
745
+ reader = csv.reader(text_stream)
746
+ headers = next(reader)
747
+ rows = [
748
+ {key: None if value == "\\N" else value for key, value in zip(headers, row)} for row in reader
749
+ ]
750
+ logger.debug(
751
+ "Inserting %d rows into table '%s' with headers: %s",
752
+ len(rows),
753
+ table_name,
754
+ headers,
755
+ )
756
+ with self._engine.begin() as conn:
757
+ conn.execute(table.insert(), rows)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-felis
3
- Version: 29.2025.2400
3
+ Version: 29.2025.2500
4
4
  Summary: A vocabulary for describing catalogs and acting on those descriptions
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
6
  License: GNU General Public License v3 or later (GPLv3+)
@@ -0,0 +1,31 @@
1
+ felis/__init__.py,sha256=HnwWzLaPOSnPzAoppSIHzTrGfixEgvkzJdBxa8-03cw,1294
2
+ felis/cli.py,sha256=g6OrBrIylNLiflSvrLlef86BjoiehV3L5eAvVPrxPog,16911
3
+ felis/datamodel.py,sha256=COXmk1p8qiwdiOrPkTJNCSbg27FIvosF3pFIFusAsnA,45926
4
+ felis/diff.py,sha256=z4ZzUocFYVa2y22BWUAMkeeLORmMtaWIDGTVaUE1OIM,7181
5
+ felis/metadata.py,sha256=79YcaIqeFP-pj9zhWpqXlvw_piUTUwuLrV5_8eVYalQ,13763
6
+ felis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ felis/tap_schema.py,sha256=uu2imuzxyuIUbmW4liC6_h4TW5MW2t4SI9rjtMxcyfI,26372
8
+ felis/types.py,sha256=ifZQjc-Uw5CM3L7hmFUb7wcHY1O_HgJCw6HPqyUkHvk,5510
9
+ felis/config/tap_schema/columns.csv,sha256=9RsyuPObUQ_6myux9vKtlQ-aJgs7rvvxoLf6yYSRWqc,3272
10
+ felis/config/tap_schema/key_columns.csv,sha256=dRezco5ltcM1mG--2DvPsbOxB6cwVaBwczwi3It2vag,210
11
+ felis/config/tap_schema/keys.csv,sha256=6zTXyo-1GNfu5sBWpX-7ZJFAtHrxOys78AViCcdPgu8,377
12
+ felis/config/tap_schema/schemas.csv,sha256=z5g1bW1Y9H8nKLZyH4e5xiBBoK9JezR2Xf8L79K2TZk,138
13
+ felis/config/tap_schema/tables.csv,sha256=o0KioOiL7hw9ntCyKWili-iFMjAaGRMUOE-nM30LBD0,510
14
+ felis/config/tap_schema/tap_schema_std.yaml,sha256=sPW-Vk72nY0PFpCvP5d8L8fWvhkif-x32sGtcfDZ8bU,7131
15
+ felis/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ felis/db/dialects.py,sha256=XTZEbTnfy96GJDNRLCQMbAV6irerC87vhO_HyTIXLbs,3517
17
+ felis/db/schema.py,sha256=NOFXzBoBQcgpoRlgT3LoC70FKp7pCSmFEJ7rU8FIT-c,2101
18
+ felis/db/sqltypes.py,sha256=Q2p3Af3O5-B1ZxQ4M2j_w8SH1o_kp6ezg8h7LmSlfww,11060
19
+ felis/db/utils.py,sha256=jiKQ_SirKRdQITHe8gSiT_i3ckRHZbkAnwUlEHk2u4Y,14116
20
+ felis/db/variants.py,sha256=eahthrbVeV8ZdGamWQccNmWgx6CCscGrU0vQRs5HZK8,5260
21
+ felis/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ felis/tests/postgresql.py,sha256=B_xk4fLual5-viGDqP20r94okuc0pbSvytRH_L0fvMs,4035
23
+ felis/tests/run_cli.py,sha256=Gg8loUIGj9t6KlkRKrEc9Z9b5dtlkpJy94ORuj4BrxU,2503
24
+ lsst_felis-29.2025.2500.dist-info/licenses/COPYRIGHT,sha256=vJAFLFTSF1mhy9eIuA3P6R-3yxTWKQgpig88P-1IzRw,129
25
+ lsst_felis-29.2025.2500.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
26
+ lsst_felis-29.2025.2500.dist-info/METADATA,sha256=waHHJI3LP891BnULx3aiSr0f8DaPPKf9a3lHVkZ_Djo,1433
27
+ lsst_felis-29.2025.2500.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ lsst_felis-29.2025.2500.dist-info/entry_points.txt,sha256=Gk2XFujA_Gp52VBk45g5kim8TDoMDJFPctsMqiq72EM,40
29
+ lsst_felis-29.2025.2500.dist-info/top_level.txt,sha256=F4SvPip3iZRVyISi50CHhwTIAokAhSxjWiVcn4IVWRI,6
30
+ lsst_felis-29.2025.2500.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
31
+ lsst_felis-29.2025.2500.dist-info/RECORD,,
@@ -1,26 +0,0 @@
1
- felis/__init__.py,sha256=HnwWzLaPOSnPzAoppSIHzTrGfixEgvkzJdBxa8-03cw,1294
2
- felis/cli.py,sha256=jx3yBMEFPgvZTJsTKmWMAx--vBuRBDIOJNBbxMZR6fY,16132
3
- felis/datamodel.py,sha256=NYTmxuuU6DqL3r2e137sN9xS_WmD_xYeEYKAQjVA6Qs,44245
4
- felis/diff.py,sha256=z4ZzUocFYVa2y22BWUAMkeeLORmMtaWIDGTVaUE1OIM,7181
5
- felis/metadata.py,sha256=cYx_qizkLBqcoxWV46h4TbwTi1KVJAkuA2OuUmD-K5k,13536
6
- felis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- felis/tap_schema.py,sha256=vO_f1LvFPU6D1vv2SplIzOW_TV36zOOFOfXQIdD0rMI,24781
8
- felis/types.py,sha256=ifZQjc-Uw5CM3L7hmFUb7wcHY1O_HgJCw6HPqyUkHvk,5510
9
- felis/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- felis/db/dialects.py,sha256=XTZEbTnfy96GJDNRLCQMbAV6irerC87vhO_HyTIXLbs,3517
11
- felis/db/schema.py,sha256=NOFXzBoBQcgpoRlgT3LoC70FKp7pCSmFEJ7rU8FIT-c,2101
12
- felis/db/sqltypes.py,sha256=Q2p3Af3O5-B1ZxQ4M2j_w8SH1o_kp6ezg8h7LmSlfww,11060
13
- felis/db/utils.py,sha256=jiKQ_SirKRdQITHe8gSiT_i3ckRHZbkAnwUlEHk2u4Y,14116
14
- felis/db/variants.py,sha256=eahthrbVeV8ZdGamWQccNmWgx6CCscGrU0vQRs5HZK8,5260
15
- felis/schemas/tap_schema_std.yaml,sha256=sPW-Vk72nY0PFpCvP5d8L8fWvhkif-x32sGtcfDZ8bU,7131
16
- felis/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- felis/tests/postgresql.py,sha256=B_xk4fLual5-viGDqP20r94okuc0pbSvytRH_L0fvMs,4035
18
- felis/tests/run_cli.py,sha256=Gg8loUIGj9t6KlkRKrEc9Z9b5dtlkpJy94ORuj4BrxU,2503
19
- lsst_felis-29.2025.2400.dist-info/licenses/COPYRIGHT,sha256=vJAFLFTSF1mhy9eIuA3P6R-3yxTWKQgpig88P-1IzRw,129
20
- lsst_felis-29.2025.2400.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
21
- lsst_felis-29.2025.2400.dist-info/METADATA,sha256=hUHhp37DTyM5vAbFwW5IzcIyghOTQgEDyK2H6u1PoAs,1433
22
- lsst_felis-29.2025.2400.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- lsst_felis-29.2025.2400.dist-info/entry_points.txt,sha256=Gk2XFujA_Gp52VBk45g5kim8TDoMDJFPctsMqiq72EM,40
24
- lsst_felis-29.2025.2400.dist-info/top_level.txt,sha256=F4SvPip3iZRVyISi50CHhwTIAokAhSxjWiVcn4IVWRI,6
25
- lsst_felis-29.2025.2400.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
26
- lsst_felis-29.2025.2400.dist-info/RECORD,,