polymo 0.7.2__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {polymo-0.7.2 → polymo-0.8.0}/PKG-INFO +1 -1
  2. {polymo-0.7.2 → polymo-0.8.0}/pyproject.toml +1 -1
  3. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/app.py +28 -17
  4. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/main.js +7 -7
  5. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/config.py +107 -18
  6. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/datasource.py +20 -4
  7. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/rest_client.py +36 -27
  8. {polymo-0.7.2 → polymo-0.8.0}/README.md +0 -0
  9. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/__init__.py +0 -0
  10. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/__init__.py +0 -0
  11. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/countries.yml +0 -0
  12. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/githubrepos.yml +0 -0
  13. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/jsonplaceholder.yml +0 -0
  14. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/jsonplaceholder_endpoints.yml +0 -0
  15. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/multi_endpoints.yml +0 -0
  16. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/examples/weather.yml +0 -0
  17. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/favicon.ico +0 -0
  18. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/favicon.png +0 -0
  19. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/index.html +0 -0
  20. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/logo.png +0 -0
  21. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/logo192.png +0 -0
  22. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/main.css +0 -0
  23. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/static/mockServiceWorker.js +0 -0
  24. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/builder/templates/index.html +0 -0
  25. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/cli.py +0 -0
  26. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/py.typed +0 -0
  27. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/scripts/__init__.py +0 -0
  28. {polymo-0.7.2 → polymo-0.8.0}/src/polymo/scripts/smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: polymo
3
- Version: 0.7.2
3
+ Version: 0.8.0
4
4
  Summary: Declarative REST API ingestion for PySpark
5
5
  Keywords: spark,pyspark,rest,api,ingestion,data-engineering,etl,http
6
6
  Author: Daniel Tom
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "polymo"
3
- version = "0.7.2"
3
+ version = "0.8.0"
4
4
  description = "Declarative REST API ingestion for PySpark"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import json
5
6
  from functools import partial
6
7
  from importlib import metadata, resources
7
8
  from typing import Any, Dict, List, Optional, Tuple
@@ -308,19 +309,25 @@ def _collect_records(
308
309
  config: RestSourceConfig, token: str | None, limit: int
309
310
  ) -> Tuple[List[Dict[str, Any]], List[Dict[str, str]]]:
310
311
  """Collect processed records and dtypes using PySpark DataSource."""
311
- import tempfile
312
- import os
313
- from ..config import dump_config
314
312
 
315
- # Create a temporary config file for Spark to use
316
- with tempfile.NamedTemporaryFile(mode="w", suffix=".yml", delete=False) as f:
317
- config_yaml = dump_config(config)
318
- f.write(config_yaml)
319
- config_path = f.name
313
+ from ..config import config_to_dict
314
+
315
+ if config.auth and not token:
316
+ if config.auth.type == "bearer" and config.auth.token:
317
+ token = config.auth.token
318
+ if config.auth.type == "oauth2" and config.auth.client_secret:
319
+ token = config.auth.client_secret
320
+
321
+ config_dict = config_to_dict(config)
320
322
 
321
323
  spark = _get_or_create_spark()
322
324
  try:
323
- df = _get_preview_df(config_path, token, spark, config.options)
325
+ df = _get_preview_df(
326
+ config_dict=config_dict,
327
+ token=token,
328
+ spark=spark,
329
+ reader_options=config.options
330
+ )
324
331
  records = df.limit(limit).collect()
325
332
  dtypes = df.dtypes
326
333
  record_dicts = [row.asDict(recursive=True) for row in records]
@@ -332,12 +339,12 @@ def _collect_records(
332
339
  return record_dicts, dtype_dicts
333
340
  finally:
334
341
  spark.stop()
335
- os.unlink(config_path)
336
342
 
337
343
 
338
344
  def _get_preview_df(
339
- config_path: str,
340
- token: str | None,
345
+ *,
346
+ config_dict: ConfigDict,
347
+ token: Optional[str],
341
348
  spark: "SparkSession",
342
349
  reader_options: Dict[str, Any],
343
350
  ):
@@ -347,18 +354,22 @@ def _get_preview_df(
347
354
 
348
355
  _get_or_create_spark()
349
356
  spark.dataSource.register(ApiReader)
357
+ config_json = json.dumps(config_dict, sort_keys=True)
358
+ options: Dict[str, str] = {"config_json": config_json}
350
359
 
351
- # Alternative approach: Use the DataSource directly without format registration
352
- # Create the DataSource instance manually
353
- options = {
354
- "config_path": config_path,
355
- }
356
360
  if token is not None:
357
361
  options["token"] = token
362
+
363
+ if source := config_dict.get('source', {}):
364
+ if auth := source.get("auth"):
365
+ if auth.get("type") == "oauth2":
366
+ options["oauth_client_secret"] = token
367
+
358
368
  for key, value in reader_options.items():
359
369
  if key in {"config_path", "token"}:
360
370
  continue
361
371
  options[key] = value
372
+
362
373
  return spark.read.format("polymo").options(**options).load()
363
374
 
364
375