tlpytools 0.2.0__tar.gz → 0.2.2__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 (60) hide show
  1. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/copilot-instructions.md +2 -2
  2. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/workflows/deploy.yml +1 -1
  3. {tlpytools-0.2.0 → tlpytools-0.2.2}/CHANGELOG.md +17 -0
  4. {tlpytools-0.2.0 → tlpytools-0.2.2}/DEVELOPER_GUIDE.md +4 -4
  5. {tlpytools-0.2.0 → tlpytools-0.2.2}/PKG-INFO +1 -1
  6. {tlpytools-0.2.0 → tlpytools-0.2.2}/pyproject.toml +1 -1
  7. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/__init__.py +1 -1
  8. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/orchestrator.py +71 -27
  9. {tlpytools-0.2.0 → tlpytools-0.2.2}/uv.lock +1 -1
  10. {tlpytools-0.2.0 → tlpytools-0.2.2}/.env.example +0 -0
  11. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/skills/README.md +0 -0
  12. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/skills/prepare-official-release/SKILL.md +0 -0
  13. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/workflows/code-formatting-pr.yml +0 -0
  14. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/workflows/code-formatting.yml +0 -0
  15. {tlpytools-0.2.0 → tlpytools-0.2.2}/.github/workflows/test.yml +0 -0
  16. {tlpytools-0.2.0 → tlpytools-0.2.2}/.gitignore +0 -0
  17. {tlpytools-0.2.0 → tlpytools-0.2.2}/.pre-commit-config.yaml +0 -0
  18. {tlpytools-0.2.0 → tlpytools-0.2.2}/.python-version +0 -0
  19. {tlpytools-0.2.0 → tlpytools-0.2.2}/ENVIRONMENT_VARIABLES.md +0 -0
  20. {tlpytools-0.2.0 → tlpytools-0.2.2}/Makefile +0 -0
  21. {tlpytools-0.2.0 → tlpytools-0.2.2}/README.md +0 -0
  22. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/adls_server.md +0 -0
  23. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/azure_credential_manager.md +0 -0
  24. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/README.md +0 -0
  25. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/orca_cloud_workflow.drawio +0 -0
  26. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/orca_detailed_steps.drawio +0 -0
  27. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/orca_file_structure.drawio +0 -0
  28. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/orca_local_workflow.drawio +0 -0
  29. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/diagrams/orca_main_features.drawio +0 -0
  30. {tlpytools-0.2.0 → tlpytools-0.2.2}/docs/unified_logging.md +0 -0
  31. {tlpytools-0.2.0 → tlpytools-0.2.2}/requirements.txt +0 -0
  32. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/examples/batchtask.py +0 -0
  33. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/examples/data_files/example.csv +0 -0
  34. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/examples/mydataproject.py +0 -0
  35. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/examples/readwritedata.py +0 -0
  36. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/examples/unified_logging.py +0 -0
  37. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/adls_server.py +0 -0
  38. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/azure_credential.py +0 -0
  39. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/config.py +0 -0
  40. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/data.py +0 -0
  41. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/data_store.py +0 -0
  42. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/env_config.py +0 -0
  43. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/log.py +0 -0
  44. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/README.md +0 -0
  45. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/__init__.py +0 -0
  46. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/__main__.py +0 -0
  47. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/batch_task_runner.py +0 -0
  48. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/cli.py +0 -0
  49. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/orca_model_config_barebone.yaml +0 -0
  50. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/orca/orca_model_config_example.yaml +0 -0
  51. {tlpytools-0.2.0 → tlpytools-0.2.2}/src/tlpytools/sql_server.py +0 -0
  52. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/README.md +0 -0
  53. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/__init__.py +0 -0
  54. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/conftest.py +0 -0
  55. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/run_tests.py +0 -0
  56. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/test_azure_credential.py +0 -0
  57. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/test_basic.py +0 -0
  58. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/test_core.py +0 -0
  59. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/test_orca_integration.py +0 -0
  60. {tlpytools-0.2.0 → tlpytools-0.2.2}/tests/test_orca_unit.py +0 -0
@@ -98,8 +98,8 @@ Interpretation for agent PRs:
98
98
 
99
99
  Observed result:
100
100
  - Build succeeds and produces:
101
- - `dist/tlpytools-0.2.0.tar.gz`
102
- - `dist/tlpytools-0.2.0-py3-none-any.whl`
101
+ - `dist/tlpytools-0.2.2.tar.gz`
102
+ - `dist/tlpytools-0.2.2-py3-none-any.whl`
103
103
 
104
104
  ### 5) Run
105
105
  - ORCA CLI (module form):
@@ -4,7 +4,7 @@ on:
4
4
  workflow_dispatch:
5
5
  inputs:
6
6
  version:
7
- description: 'Version number to release (e.g., 0.2.0)'
7
+ description: 'Version number to release (e.g., 0.2.2)'
8
8
  required: true
9
9
  type: string
10
10
  prerelease:
@@ -2,6 +2,23 @@
2
2
 
3
3
  All notable changes to TLPyTools will be documented in this file.
4
4
 
5
+ ## [0.2.2]
6
+
7
+ ### Fixed
8
+ * Fix python path leaks by cleaning up PYTHONPATH and PYTHONHOME during sub component model runs
9
+ * Clear stale errors when resuming or starting new runs on old scenario folders
10
+
11
+ ## [0.2.1]
12
+
13
+ ### Changed
14
+ - **ORCA logger naming improvement:**
15
+ - Replaced random UUID-based logger name with a git-aware identifier resolved from the ORCA project working directory
16
+ - Added `_resolve_logger_name()` method to `OrcaLogger` with the following priority:
17
+ 1. Git tag pointing at HEAD → `orca_{tag}` (e.g. `orca_v0.3.0`)
18
+ 2. Git short SHA (first 7 characters) → `orca_{sha}` (e.g. `orca_a1b2c3d`)
19
+ 3. Random session UUID fallback → `session_{uuid8}` (e.g. `session_03d2bb45`)
20
+ - Git version is resolved from `os.getcwd()` (the user's project folder) rather than the tlpytools package directory
21
+
5
22
  ## [0.2.0]
6
23
 
7
24
  ### Changed
@@ -200,7 +200,7 @@ make check-all
200
200
  4. Click **"Run workflow"** button
201
201
  5. Fill in the required information:
202
202
  - **Branch**: Select `main` (or your release branch)
203
- - **Version number**: Enter the new version (e.g., `0.2.0`)
203
+ - **Version number**: Enter the new version (e.g., `0.2.2`)
204
204
  - **Is this a pre-release?**: Check if this is a pre-release version
205
205
 
206
206
  #### 3. Monitor the Release
@@ -219,7 +219,7 @@ After the workflow completes:
219
219
 
220
220
  ```bash
221
221
  # Verify the package is available on PyPI
222
- pip install tlpytools==0.2.0 # Replace with your version
222
+ pip install tlpytools==0.2.2 # Replace with your version
223
223
 
224
224
  # Test installation in a fresh environment
225
225
  python -c "import tlpytools; print(tlpytools.__version__)"
@@ -235,8 +235,8 @@ TLPyTools follows semantic versioning (SemVer):
235
235
 
236
236
  Examples:
237
237
  - `0.1.7` → `0.1.8` (patch release)
238
- - `0.1.8` → `0.2.0` (minor release)
239
- - `0.2.0` → `1.0.0` (major release)
238
+ - `0.1.8` → `0.2.2` (minor release)
239
+ - `0.2.2` → `1.0.0` (major release)
240
240
 
241
241
  ### Pre-releases
242
242
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tlpytools
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: TransLink's Python Tools - A comprehensive toolkit for transportation modeling and forecasting
5
5
  Project-URL: Homepage, https://github.com/TransLinkForecasting/tlpytools
6
6
  Project-URL: Bug Tracker, https://github.com/TransLinkForecasting/tlpytools/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tlpytools"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "TransLink's Python Tools - A comprehensive toolkit for transportation modeling and forecasting"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10.0, <3.13"
@@ -2,7 +2,7 @@
2
2
  TLPyTools - A set of tools for building models at the TransLink Forecasting Team
3
3
  """
4
4
 
5
- __version__ = "0.2.0"
5
+ __version__ = "0.2.2"
6
6
 
7
7
  # Core modules that should always be available (minimal dependencies)
8
8
  from . import log
@@ -120,10 +120,8 @@ class OrcaLogger:
120
120
 
121
121
  def _setup_logger(self):
122
122
  """Set up the logger with consistent formatting and handlers."""
123
- # Create a unique logger name for each instance to avoid conflicts
124
- import uuid
125
-
126
- logger_name = f"orca_{uuid.uuid4().hex[:8]}"
123
+ # Determine logger name from git tag, git SHA, or random session ID
124
+ logger_name = self._resolve_logger_name()
127
125
 
128
126
  # Create logger
129
127
  self._logger = logging.getLogger(logger_name)
@@ -172,6 +170,53 @@ class OrcaLogger:
172
170
 
173
171
  self._logger.info("=" * 80)
174
172
 
173
+ def _resolve_logger_name(self) -> str:
174
+ """
175
+ Resolve a stable logger name using git metadata when available.
176
+
177
+ Priority:
178
+ 1. Git tag pointing at HEAD -> f"orca_{tag}"
179
+ 2. Git SHA (first 7 chars) -> f"orca_{sha}"
180
+ 3. Random session UUID -> f"session_{uuid8}"
181
+ """
182
+ project_cwd = os.getcwd()
183
+ try:
184
+ # Priority 1: git tag pointing exactly at HEAD
185
+ tag_result = subprocess.run(
186
+ ["git", "describe", "--tags", "--exact-match", "HEAD"],
187
+ capture_output=True,
188
+ text=True,
189
+ timeout=5,
190
+ cwd=project_cwd,
191
+ )
192
+ if tag_result.returncode == 0:
193
+ git_version = tag_result.stdout.strip()
194
+ if git_version:
195
+ return f"orca_{git_version}"
196
+ except Exception:
197
+ pass
198
+
199
+ try:
200
+ # Priority 2: short git SHA (7 characters)
201
+ sha_result = subprocess.run(
202
+ ["git", "rev-parse", "--short=7", "HEAD"],
203
+ capture_output=True,
204
+ text=True,
205
+ timeout=5,
206
+ cwd=project_cwd,
207
+ )
208
+ if sha_result.returncode == 0:
209
+ git_sha = sha_result.stdout.strip()
210
+ if git_sha:
211
+ return f"orca_{git_sha}"
212
+ except Exception:
213
+ pass
214
+
215
+ # Priority 3: random session UUID fallback
216
+ import uuid
217
+
218
+ return f"session_{uuid.uuid4().hex[:8]}"
219
+
175
220
  def _log_system_info(self):
176
221
  """
177
222
  Log detailed system information.
@@ -3692,16 +3737,15 @@ class OrcaOrchestrator:
3692
3737
 
3693
3738
  # Create a platform-specific command to set the PYTHONPATH
3694
3739
  # Use step_directory instead of os.getcwd() for consistency
3740
+ # PYTHONHOME and PYTHONPATH are cleared first to prevent the parent
3741
+ # Python process (e.g. Jupyter/tlpytools env) from leaking its
3742
+ # library paths into the component subprocess
3695
3743
  if os.name == "nt": # Windows
3696
3744
  # On Windows, use SET command
3697
- pythonpath_cmd = (
3698
- f"set PYTHONPATH={ORCA_DIR};{step_directory};%PYTHONPATH% && "
3699
- )
3745
+ pythonpath_cmd = f"set PYTHONHOME= && set PYTHONPATH={ORCA_DIR};{step_directory} && "
3700
3746
  else: # Unix/Linux/Mac
3701
3747
  # On Unix-like systems, use export command
3702
- pythonpath_cmd = (
3703
- f"export PYTHONPATH={ORCA_DIR}:{step_directory}:$PYTHONPATH && "
3704
- )
3748
+ pythonpath_cmd = f"unset PYTHONHOME && export PYTHONPATH={ORCA_DIR}:{step_directory} && "
3705
3749
 
3706
3750
  # Modify the command to ensure environment can be found
3707
3751
  modified_command = f"{pythonpath_cmd}{command}"
@@ -6224,8 +6268,8 @@ class OrcaOrchestrator:
6224
6268
  # Reload configuration to pick up any YAML changes
6225
6269
  self.reload_configuration()
6226
6270
 
6227
- # Update status
6228
- self.state.update(status="running")
6271
+ # Update status and clear any stale error from a previous failed run
6272
+ self.state.update(status="running", error=None)
6229
6273
 
6230
6274
  # Add safety counter to prevent infinite loops
6231
6275
  max_steps = self.state.get("total_iterations", 1) * len(
@@ -6289,8 +6333,8 @@ class OrcaOrchestrator:
6289
6333
  self.logger.error("Error executing step: %s", step_name)
6290
6334
  return False
6291
6335
 
6292
- # Update state to reflect completion
6293
- self.state.update(status="completed")
6336
+ # Update state to reflect completion and clear any previously recorded error
6337
+ self.state.update(status="completed", error=None)
6294
6338
  self.logger.info("Model run completed successfully")
6295
6339
  return True
6296
6340
 
@@ -6311,8 +6355,8 @@ class OrcaOrchestrator:
6311
6355
  # Reload configuration to pick up any YAML changes
6312
6356
  self.reload_configuration()
6313
6357
 
6314
- # Update status
6315
- self.state.update(status="running")
6358
+ # Update status and clear any stale error from a previous failed run
6359
+ self.state.update(status="running", error=None)
6316
6360
 
6317
6361
  # Add safety counter to prevent infinite loops
6318
6362
  max_steps = self.state.get("total_iterations", 1) * len(
@@ -6392,8 +6436,8 @@ class OrcaOrchestrator:
6392
6436
 
6393
6437
  return False
6394
6438
 
6395
- # Update state to reflect completion
6396
- self.state.update(status="completed")
6439
+ # Update state to reflect completion and clear any previously recorded error
6440
+ self.state.update(status="completed", error=None)
6397
6441
 
6398
6442
  # Final sync to cloud after completion
6399
6443
  self.logger.info("Final state sync to cloud after model completion")
@@ -6450,12 +6494,12 @@ class OrcaOrchestrator:
6450
6494
  current_iter,
6451
6495
  max_iteration,
6452
6496
  )
6453
- self.state.update(status="completed")
6497
+ self.state.update(status="completed", error=None)
6454
6498
  return True
6455
6499
 
6456
- # Update status to running if not already
6500
+ # Update status to running if not already, clearing any stale error
6457
6501
  if self.state.get("status") != "running":
6458
- self.state.update(status="running")
6502
+ self.state.update(status="running", error=None)
6459
6503
 
6460
6504
  # Get the next step to execute
6461
6505
  step_name = self.state.get_next_step()
@@ -6472,7 +6516,7 @@ class OrcaOrchestrator:
6472
6516
  # Check if we've exceeded the total iterations
6473
6517
  if self.state.is_all_iterations_complete():
6474
6518
  self.logger.info("All iterations completed")
6475
- self.state.update(status="completed")
6519
+ self.state.update(status="completed", error=None)
6476
6520
  return True
6477
6521
 
6478
6522
  # Get the first step of the new iteration
@@ -6507,7 +6551,7 @@ class OrcaOrchestrator:
6507
6551
 
6508
6552
  # Check if we just completed the last iteration
6509
6553
  if self.state.is_all_iterations_complete():
6510
- self.state.update(status="completed")
6554
+ self.state.update(status="completed", error=None)
6511
6555
  self.logger.info("Model run completed successfully")
6512
6556
 
6513
6557
  self.logger.info("Step '%s' completed successfully", step_name)
@@ -6552,12 +6596,12 @@ class OrcaOrchestrator:
6552
6596
  current_iter,
6553
6597
  max_iteration,
6554
6598
  )
6555
- self.state.update(status="completed")
6599
+ self.state.update(status="completed", error=None)
6556
6600
  return True
6557
6601
 
6558
- # Update status to running if not already
6602
+ # Update status to running if not already, clearing any stale error
6559
6603
  if self.state.get("status") != "running":
6560
- self.state.update(status="running")
6604
+ self.state.update(status="running", error=None)
6561
6605
 
6562
6606
  # Remember the starting iteration
6563
6607
  starting_iter = self.state.get_display_iteration()
@@ -6579,7 +6623,7 @@ class OrcaOrchestrator:
6579
6623
 
6580
6624
  # Check if we've completed all iterations
6581
6625
  if self.state.is_all_iterations_complete():
6582
- self.state.update(status="completed")
6626
+ self.state.update(status="completed", error=None)
6583
6627
  self.logger.info("All iterations completed")
6584
6628
 
6585
6629
  return True
@@ -4601,7 +4601,7 @@ wheels = [
4601
4601
 
4602
4602
  [[package]]
4603
4603
  name = "tlpytools"
4604
- version = "0.2.0"
4604
+ version = "0.2.2"
4605
4605
  source = { editable = "." }
4606
4606
  dependencies = [
4607
4607
  { name = "azure-core" },
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
File without changes
File without changes
File without changes