aio-sf 0.1.0b11__tar.gz → 0.1.0b12__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 (47) hide show
  1. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/PKG-INFO +1 -1
  2. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/exporter/parquet_writer.py +18 -32
  3. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.cursor/rules/api-structure.mdc +0 -0
  4. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.cursor/rules/async-patterns.mdc +0 -0
  5. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.cursor/rules/project-tooling.mdc +0 -0
  6. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.github/workflows/publish.yml +0 -0
  7. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.github/workflows/test.yml +0 -0
  8. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/.gitignore +0 -0
  9. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/LICENSE +0 -0
  10. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/README.md +0 -0
  11. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/RELEASE.md +0 -0
  12. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/pyproject.toml +0 -0
  13. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/pytest.ini +0 -0
  14. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/__init__.py +0 -0
  15. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/__init__.py +0 -0
  16. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/__init__.py +0 -0
  17. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/base.py +0 -0
  18. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/client_credentials.py +0 -0
  19. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/refresh_token.py +0 -0
  20. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/sfdx_cli.py +0 -0
  21. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/auth/static_token.py +0 -0
  22. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/bulk_v2/__init__.py +0 -0
  23. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/bulk_v2/client.py +0 -0
  24. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/bulk_v2/types.py +0 -0
  25. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/client.py +0 -0
  26. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/__init__.py +0 -0
  27. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/batch.py +0 -0
  28. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/client.py +0 -0
  29. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/records.py +0 -0
  30. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/retry.py +0 -0
  31. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/collections/types.py +0 -0
  32. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/describe/__init__.py +0 -0
  33. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/describe/client.py +0 -0
  34. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/describe/types.py +0 -0
  35. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/query/__init__.py +0 -0
  36. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/query/client.py +0 -0
  37. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/query/types.py +0 -0
  38. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/api/types.py +0 -0
  39. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/exporter/__init__.py +0 -0
  40. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/src/aio_sf/exporter/bulk_export.py +0 -0
  41. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/__init__.py +0 -0
  42. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/conftest.py +0 -0
  43. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/test_api_clients.py +0 -0
  44. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/test_auth.py +0 -0
  45. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/test_client.py +0 -0
  46. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/tests/test_retry_and_batch.py +0 -0
  47. {aio_sf-0.1.0b11 → aio_sf-0.1.0b12}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aio-sf
3
- Version: 0.1.0b11
3
+ Version: 0.1.0b12
4
4
  Summary: Async Salesforce library for Python
5
5
  Project-URL: Homepage, https://github.com/callawaycloud/aio-salesforce
6
6
  Project-URL: Repository, https://github.com/callawaycloud/aio-salesforce
@@ -227,17 +227,11 @@ class ParquetWriter:
227
227
 
228
228
  # Apply type-specific conversions
229
229
  if pa.types.is_boolean(field.type):
230
- # Convert string 'true'/'false' to boolean, keeping original values for others
231
- original_series = df[field_name]
232
- mapped_series = original_series.map(
233
- {"true": True, "false": False, None: None}
230
+ # Convert string 'true'/'false' to boolean
231
+ # Use map directly - unmapped values become NaN which is fine for nullable boolean
232
+ df[field_name] = df[field_name].map(
233
+ {"true": True, "false": False, "True": True, "False": False}
234
234
  )
235
- # For values that weren't mapped, keep the original values
236
- # This avoids the fillna FutureWarning by using boolean indexing instead
237
- mask = mapped_series.notna()
238
- result_series = original_series.copy()
239
- result_series.loc[mask] = mapped_series.loc[mask]
240
- df[field_name] = result_series
241
235
  elif pa.types.is_integer(field.type):
242
236
  df[field_name] = pd.to_numeric(df[field_name], errors="coerce").astype(
243
237
  "Int64"
@@ -256,6 +250,12 @@ class ParquetWriter:
256
250
  date_series = df[field_name]
257
251
  if isinstance(date_series, pd.Series):
258
252
  df[field_name] = self._convert_date_strings_to_dates(date_series)
253
+ elif pa.types.is_string(field.type):
254
+ # Ensure string columns contain only strings or None
255
+ # This handles edge cases where non-string values might be present
256
+ df[field_name] = df[field_name].apply(
257
+ lambda x: None if pd.isna(x) else str(x)
258
+ )
259
259
 
260
260
  # Replace empty strings with None for non-string fields
261
261
  if not pa.types.is_string(field.type):
@@ -300,33 +300,19 @@ class ParquetWriter:
300
300
 
301
301
  def _convert_date_strings_to_dates(self, series: pd.Series) -> pd.Series:
302
302
  """
303
- Convert Salesforce ISO date strings to pandas date objects.
303
+ Convert Salesforce ISO date strings to pandas datetime objects.
304
304
 
305
305
  Salesforce returns date in ISO format like '2025-10-01'.
306
+ PyArrow will handle conversion from datetime64 to date32.
306
307
  """
308
+ # Replace empty strings with None first
309
+ series = series.replace({"": None})
307
310
 
308
- def parse_sf_date(date_str):
309
- if pd.isna(date_str) or date_str == "" or date_str is None:
310
- return pd.NaT
311
-
312
- try:
313
- # Handle Salesforce date format (YYYY-MM-DD)
314
- date_str = str(date_str).strip()
315
-
316
- # Use pandas to_datetime for date parsing, then convert to date
317
- return pd.to_datetime(date_str, format="%Y-%m-%d").date()
318
-
319
- except (ValueError, TypeError) as e:
320
- logging.warning(f"Failed to parse date string '{date_str}': {e}")
321
- return pd.NaT
311
+ # Use pandas to_datetime for vectorized conversion
312
+ # This returns datetime64[ns] which PyArrow can convert to date32
313
+ result = pd.to_datetime(series, format="%Y-%m-%d", errors="coerce")
322
314
 
323
- # Apply the conversion function to the series
324
- result = series.apply(parse_sf_date)
325
- if isinstance(result, pd.Series):
326
- return result
327
- else:
328
- # This shouldn't happen, but handle it gracefully
329
- return pd.Series(result, index=series.index)
315
+ return result
330
316
 
331
317
  def close(self) -> None:
332
318
  """Close the parquet writer."""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes