folio-migration-tools 1.10.2__tar.gz → 1.10.3__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 (70) hide show
  1. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/PKG-INFO +1 -1
  2. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/pyproject.toml +6 -4
  3. folio_migration_tools-1.10.3/src/folio_migration_tools/__init__.py +18 -0
  4. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/__main__.py +7 -0
  5. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/circulation_helper.py +23 -8
  6. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/colors.py +7 -0
  7. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/config_file_load.py +7 -0
  8. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/custom_dict.py +17 -0
  9. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/custom_exceptions.py +40 -4
  10. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/extradata_writer.py +12 -0
  11. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/folder_structure.py +16 -0
  12. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/helper.py +7 -0
  13. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/holdings_helper.py +11 -5
  14. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/i18n_config.py +6 -0
  15. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/library_configuration.py +19 -5
  16. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapper_base.py +15 -0
  17. folio_migration_tools-1.10.3/src/folio_migration_tools/mapping_file_transformation/__init__.py +1 -0
  18. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/courses_mapper.py +17 -0
  19. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/holdings_mapper.py +19 -0
  20. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/item_mapper.py +24 -0
  21. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +18 -0
  22. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +26 -9
  23. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/notes_mapper.py +16 -0
  24. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/order_mapper.py +40 -27
  25. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/organization_mapper.py +40 -33
  26. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +17 -0
  27. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/mapping_file_transformation/user_mapper.py +16 -0
  28. folio_migration_tools-1.10.3/src/folio_migration_tools/marc_rules_transformation/__init__.py +1 -0
  29. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/conditions.py +49 -36
  30. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +9 -3
  31. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/hrid_handler.py +16 -1
  32. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/marc_file_processor.py +15 -1
  33. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +7 -0
  34. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +35 -29
  35. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +23 -18
  36. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +46 -27
  37. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_report.py +14 -6
  38. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/__init__.py +2 -0
  39. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/batch_poster.py +34 -18
  40. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/bibs_transformer.py +16 -0
  41. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/courses_migrator.py +15 -0
  42. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/holdings_csv_transformer.py +18 -3
  43. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/holdings_marc_transformer.py +17 -0
  44. folio_migration_tools-1.10.3/src/folio_migration_tools/migration_tasks/inventory_batch_poster.py +424 -0
  45. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/items_transformer.py +16 -0
  46. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/loans_migrator.py +17 -2
  47. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +16 -0
  48. folio_migration_tools-1.10.3/src/folio_migration_tools/migration_tasks/marc_import.py +407 -0
  49. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/migration_task_base.py +49 -17
  50. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/orders_transformer.py +16 -0
  51. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/organization_transformer.py +17 -2
  52. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/requests_migrator.py +15 -0
  53. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/reserves_migrator.py +15 -0
  54. folio_migration_tools-1.10.3/src/folio_migration_tools/migration_tasks/user_importer.py +347 -0
  55. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/migration_tasks/user_transformer.py +16 -0
  56. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/task_configuration.py +7 -0
  57. folio_migration_tools-1.10.3/src/folio_migration_tools/transaction_migration/__init__.py +1 -0
  58. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/transaction_migration/legacy_loan.py +16 -0
  59. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/transaction_migration/legacy_request.py +14 -0
  60. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/transaction_migration/legacy_reserve.py +14 -0
  61. folio_migration_tools-1.10.3/src/folio_migration_tools/transaction_migration/transaction_result.py +41 -0
  62. folio_migration_tools-1.10.2/src/folio_migration_tools/__init__.py +0 -10
  63. folio_migration_tools-1.10.2/src/folio_migration_tools/mapping_file_transformation/__init__.py +0 -0
  64. folio_migration_tools-1.10.2/src/folio_migration_tools/marc_rules_transformation/__init__.py +0 -0
  65. folio_migration_tools-1.10.2/src/folio_migration_tools/transaction_migration/__init__.py +0 -0
  66. folio_migration_tools-1.10.2/src/folio_migration_tools/transaction_migration/transaction_result.py +0 -25
  67. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/README.md +0 -0
  68. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/i18n_cache.py +0 -0
  69. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +0 -0
  70. {folio_migration_tools-1.10.2 → folio_migration_tools-1.10.3}/src/folio_migration_tools/translations/en.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: folio-migration-tools
3
- Version: 1.10.2
3
+ Version: 1.10.3
4
4
  Summary: A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP
5
5
  Keywords: FOLIO,ILS,LSP,Library Systems,MARC21,Library data
6
6
  Author: Theodor Tolstoy, Lisa Sjögren, Brooks Travis, Jeremy Nelson, Clinton Bradford
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "folio_migration_tools"
3
- version = "1.10.2"
3
+ version = "1.10.3"
4
4
  description = "A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP"
5
5
  authors = [
6
6
  {name = "Theodor Tolstoy", email = "github.teddes@tolstoy.se"},
@@ -43,7 +43,6 @@ dev = [
43
43
  "flake8-isort>=6.1.2,<7.0.0",
44
44
  "flake8-docstrings>=1.6.0,<2.0.0",
45
45
  "darglint>=1.8.1,<2.0.0",
46
- "types-requests>=2.28.11.17,<3.0.0",
47
46
  "types-python-dateutil>=2.8.19.11,<3.0.0",
48
47
  "ipykernel>=6.29.5,<7.0.0",
49
48
  "pytest-asyncio>=0.23.0,<0.24.0",
@@ -120,8 +119,8 @@ indent-width = 4
120
119
  target-version = "py310"
121
120
 
122
121
  [tool.ruff.lint]
123
- select = ["B", "B9", "C", "E", "F", "S", "W"]
124
- ignore = ["E741", "S113"]
122
+ select = ["B", "B9", "C", "D", "E", "F", "S", "W"]
123
+ ignore = ["E741", "S113", "D101", "D102", "D103", "D107"]
125
124
 
126
125
  fixable = ["ALL"]
127
126
  unfixable = []
@@ -144,3 +143,6 @@ docstring-code-line-length = "dynamic"
144
143
 
145
144
  [tool.ruff.lint.mccabe]
146
145
  max-complexity = 15
146
+
147
+ [tool.ruff.lint.pydocstyle]
148
+ convention = "google"
@@ -0,0 +1,18 @@
1
+ """FOLIO Migration Tools package for migrating library data to FOLIO LSP."""
2
+
3
+ import importlib.metadata
4
+ from typing import Protocol
5
+
6
+ __version__ = importlib.metadata.version("folio_migration_tools")
7
+
8
+
9
+ class StrCoercible(Protocol):
10
+ """Protocol for objects that can be coerced to string."""
11
+
12
+ def __repr__(self) -> str:
13
+ """Return repr(self)."""
14
+ ...
15
+
16
+ def __str__(self) -> str:
17
+ """Return str(self)."""
18
+ ...
@@ -1,3 +1,10 @@
1
+ """Main entry point for the folio_migration_tools CLI.
2
+
3
+ Provides the command-line interface for running migration tasks. Loads configuration
4
+ files, validates parameters, instantiates appropriate task classes, and executes
5
+ the migration workflow. Supports all transformation and loading tasks.
6
+ """
7
+
1
8
  from importlib import metadata
2
9
  import json
3
10
  import logging
@@ -1,3 +1,10 @@
1
+ """Helper utilities for circulation transactions migration.
2
+
3
+ Provides the CirculationHelper class with methods for validating and posting
4
+ circulation transactions (loans, requests). Handles patron and item lookups,
5
+ loan policy validation, and error handling for circulation operations.
6
+ """
7
+
1
8
  import copy
2
9
  import json
3
10
  import logging
@@ -29,6 +36,13 @@ class CirculationHelper:
29
36
  service_point_id,
30
37
  migration_report: MigrationReport,
31
38
  ):
39
+ """Initialize CirculationHelper with FOLIO client and service point.
40
+
41
+ Args:
42
+ folio_client (FolioClient): FOLIO API client for circulation operations.
43
+ service_point_id: ID of the service point for check-outs and check-ins.
44
+ migration_report (MigrationReport): Report object for tracking statistics.
45
+ """
32
46
  self.folio_client = folio_client
33
47
  self.service_point_id = service_point_id
34
48
  self.missing_patron_barcodes: Set[str] = set()
@@ -72,15 +86,16 @@ class CirculationHelper:
72
86
  return {}
73
87
 
74
88
  def is_checked_out(self, legacy_loan: LegacyLoan) -> bool:
75
- """Makes a deeper check to find out if the loan is already processed.
89
+ """Makes a deeper check to find out if the loan is already checked out in FOLIO.
90
+
76
91
  Looks up the item id, and then searches Loan Storage for any open loans.
77
92
  If there are open loans, returns True. Else False.
78
93
 
79
94
  Args:
80
- legacy_loan (LegacyLoan): _description_
95
+ legacy_loan (LegacyLoan): The legacy loan object to check.
81
96
 
82
97
  Returns:
83
- bool: _description_
98
+ bool: True if the loan is already checked out, False otherwise.
84
99
  """
85
100
  if item := self.get_item_by_barcode(legacy_loan.item_barcode):
86
101
  if self.get_active_loan_by_item_id(item["id"]):
@@ -113,16 +128,16 @@ class CirculationHelper:
113
128
  return {}
114
129
 
115
130
  def check_out_by_barcode(self, legacy_loan: LegacyLoan) -> TransactionResult:
116
- """Checks out a legacy loan using the Endpoint /circulation/check-out-by-barcode
117
- Adds all possible overrides in order to make the transaction go through
131
+ """Checks out a legacy loan using the Endpoint /circulation/check-out-by-barcode.
132
+
133
+ Adds all possible overrides in order to make the transaction go through.
118
134
 
119
135
  Args:
120
- legacy_loan (LegacyLoan): _description_
136
+ legacy_loan (LegacyLoan): The legacy loan object to check.
121
137
 
122
138
  Returns:
123
- TransactionResult: _description_
139
+ TransactionResult: The result of the check-out transaction.
124
140
  """
125
-
126
141
  t0_function = time.time()
127
142
  data = {
128
143
  "itemBarcode": legacy_loan.item_barcode,
@@ -1,3 +1,10 @@
1
+ """Terminal color codes for formatted console output.
2
+
3
+ Defines ANSI escape codes for colorizing terminal output in migration reports
4
+ and progress messages.
5
+ """
6
+
7
+
1
8
  class Bcolors:
2
9
  HEADER = "\033[95m"
3
10
  OKBLUE = "\033[94m"
@@ -1,3 +1,10 @@
1
+ """Configuration file loading and merging utilities.
2
+
3
+ Provides functions for loading JSON configuration files with support for
4
+ inheriting from parent configurations. Handles deep merging of nested
5
+ dictionaries and lists while preserving unique entries.
6
+ """
7
+
1
8
  import json
2
9
  from pathlib import Path
3
10
 
@@ -1,7 +1,21 @@
1
+ """Custom CSV DictReader with case-insensitive field names.
2
+
3
+ Provides the InsensitiveDictReader class that normalizes CSV field names to
4
+ lowercase and strips whitespace, making CSV parsing more forgiving of
5
+ inconsistent header formatting.
6
+ """
7
+
1
8
  import csv
2
9
 
3
10
 
4
11
  class InsensitiveDictReader(csv.DictReader):
12
+ """CSV DictReader with case-insensitive field names.
13
+
14
+ This class extends csv.DictReader to normalize field names by stripping
15
+ leading/trailing whitespace and converting them to lowercase. This allows
16
+ for more forgiving CSV parsing where header formatting may vary.
17
+ """
18
+
5
19
  # This class overrides the csv.fieldnames property, which converts all
6
20
  # fieldnames without leading and trailing
7
21
  # spaces and to lower case.
@@ -14,7 +28,10 @@ class InsensitiveDictReader(csv.DictReader):
14
28
 
15
29
 
16
30
  class InsensitiveDict(dict):
31
+ """Dictionary with case-insensitive key lookup."""
32
+
17
33
  # This class overrides the __getitem__ method to automatically strip()
18
34
  # and lower() the input key
19
35
  def __getitem__(self, key):
36
+ """Get item by key, normalizing to lowercase and stripped."""
20
37
  return dict.__getitem__(self, key.strip().lower())
@@ -1,3 +1,11 @@
1
+ """Custom exception classes for migration transformations.
2
+
3
+ Defines specialized exception types for different transformation error scenarios:
4
+ - TransformationFieldMappingError: Non-critical data issues
5
+ - TransformationRecordFailedError: Critical record-level failures
6
+ - TransformationProcessError: Fatal configuration or process errors
7
+ """
8
+
1
9
  import logging
2
10
  import i18n
3
11
 
@@ -10,15 +18,25 @@ class TransformationError(Exception):
10
18
 
11
19
  class TransformationFieldMappingError(TransformationError):
12
20
  """Raised when the field mapping fails, but the error is not critical.
13
- The issue should be logged for the library to act upon it"""
21
+
22
+ The issue should be logged for the library to act upon it
23
+ """
14
24
 
15
25
  def __init__(self, index_or_id="", message="", data_value: str | StrCoercible = ""):
26
+ """Initialize field mapping error with index, message, and data value.
27
+
28
+ Args:
29
+ index_or_id: Record identifier or row index from source data.
30
+ message: Descriptive error message.
31
+ data_value: The problematic data value.
32
+ """
16
33
  self.index_or_id = index_or_id or ""
17
34
  self.message = message
18
35
  self.data_value: str | StrCoercible = data_value
19
36
  super().__init__(self.message)
20
37
 
21
38
  def __str__(self):
39
+ """Return formatted error message with record context."""
22
40
  return (
23
41
  i18n.t("Data issue. Consider fixing the record. ")
24
42
  + f"\t{self.index_or_id}\t{self.message}\t{self.data_value}"
@@ -35,9 +53,16 @@ class TransformationFieldMappingError(TransformationError):
35
53
 
36
54
 
37
55
  class TransformationRecordFailedError(TransformationError):
38
- """Raised when the field mapping fails, Error is critical and means transformation fails"""
56
+ """Raised when the field mapping fails, Error is critical and means transformation fails."""
39
57
 
40
58
  def __init__(self, index_or_id, message="", data_value=""):
59
+ """Initialize record failure error with context information.
60
+
61
+ Args:
62
+ index_or_id: Record identifier or row index from source data.
63
+ message: Descriptive error message about the failure.
64
+ data_value: The problematic data value.
65
+ """
41
66
  self.index_or_id = index_or_id
42
67
  self.message = message
43
68
  self.data_value: str | StrCoercible = data_value
@@ -45,6 +70,7 @@ class TransformationRecordFailedError(TransformationError):
45
70
  super().__init__(self.message)
46
71
 
47
72
  def __str__(self):
73
+ """Return formatted error message with record context."""
48
74
  return (
49
75
  f"Critical data issue. Record needs fixing"
50
76
  f"\t{self.index_or_id}\t{self.message}\t{self.data_value}"
@@ -61,8 +87,10 @@ class TransformationRecordFailedError(TransformationError):
61
87
 
62
88
 
63
89
  class TransformationProcessError(TransformationError):
64
- """Raised when the transformation fails due to incorrect configuration,
65
- mapping or reference data. This error should take the process to a halt."""
90
+ """Raised when the transformation fails due to incorrect configuration.
91
+
92
+ This error should take the process to a halt when mapping or reference data is incorrect.
93
+ """
66
94
 
67
95
  def __init__(
68
96
  self,
@@ -71,12 +99,20 @@ class TransformationProcessError(TransformationError):
71
99
  " Check configuration, mapping files and reference data",
72
100
  data_value: str | StrCoercible = "",
73
101
  ):
102
+ """Initialize process error with configuration or reference data context.
103
+
104
+ Args:
105
+ index_or_id: Record identifier or context for where error occurred.
106
+ message: Descriptive error message about the process failure.
107
+ data_value: The problematic data or configuration value.
108
+ """
74
109
  self.index_or_id = index_or_id
75
110
  self.message = message
76
111
  self.data_value = data_value
77
112
  super().__init__(self.message)
78
113
 
79
114
  def __str__(self):
115
+ """Return formatted error message with process context."""
80
116
  return (
81
117
  f"Critical Process issue. Check configuration, mapping files and reference data"
82
118
  f"\t{self.index_or_id}\t{self.message}\t{self.data_value}"
@@ -1,3 +1,10 @@
1
+ """Writer for extradata objects generated during transformation.
2
+
3
+ Provides the ExtradataWriter class for buffering and writing extradata objects
4
+ (e.g., organization interfaces, bound-with parts) to separate files during
5
+ migration. Handles buffering, flushing, and file management.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import os
@@ -17,6 +24,11 @@ class ExtradataWriter:
17
24
  return cls.__instance
18
25
 
19
26
  def __init__(self, path_to_file: Path) -> None:
27
+ """Initialize the singleton extradata writer.
28
+
29
+ Args:
30
+ path_to_file (Path): Path to the file where extradata will be written.
31
+ """
20
32
  if type(self).__inited:
21
33
  return
22
34
  self.cache: List[str] = []
@@ -1,3 +1,10 @@
1
+ """Folder structure management for migration tasks.
2
+
3
+ Defines the FolderStructure class that manages the standardized directory layout
4
+ for migration tasks. Creates and manages folders for source data, results, reports,
5
+ logs, and mapping files. Handles path generation and validation.
6
+ """
7
+
1
8
  import logging
2
9
  import sys
3
10
  import time
@@ -15,6 +22,15 @@ class FolderStructure:
15
22
  iteration_identifier: str,
16
23
  add_time_stamp_to_file_names: bool,
17
24
  ):
25
+ """Initialize folder structure for a migration task iteration.
26
+
27
+ Args:
28
+ base_path (Path): Root folder for the migration.
29
+ object_type (FOLIONamespaces): Type of FOLIO object being migrated.
30
+ migration_task_name (str): Name of the migration task.
31
+ iteration_identifier (str): Identifier for this migration iteration.
32
+ add_time_stamp_to_file_names (bool): Whether to add timestamps to output files.
33
+ """
18
34
  logging.info("Validating folder structure")
19
35
 
20
36
  self.object_type: FOLIONamespaces = object_type
@@ -1,3 +1,10 @@
1
+ """General helper utilities for migration tasks.
2
+
3
+ Provides the Helper class with static utility methods for data validation,
4
+ mapping report generation, and common transformation operations used across
5
+ multiple migration tasks.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
 
@@ -1,3 +1,10 @@
1
+ """Helper utilities specific to holdings transformations.
2
+
3
+ Provides the HoldingsHelper class with methods for holdings-specific validations
4
+ and transformations including location handling, call number processing, and
5
+ holdings notes management.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import i18n
@@ -17,14 +24,13 @@ class HoldingsHelper:
17
24
  migration_report: MigrationReport,
18
25
  holdings_type_id_to_exclude_from_merging: str = "Not set",
19
26
  ) -> str:
20
- """Creates a key from values determined by the fields_crieteria in a holding
21
- record to determine uniquenes
27
+ """Create a unique key from holding field values for merging.
22
28
 
23
29
  fields_criterias are limited to the strings and UUID properties on the first level of
24
- the object. If the property is not found, or empty, it will be ignored
30
+ the object. If the property is not found, or empty, it will be ignored.
25
31
 
26
- IF the holdings type id is matched to holdings_type_id_to_exclude_from_merging,
27
- the key will be added with a uuid to prevent merging of this holding
32
+ If the holdings type id is matched to holdings_type_id_to_exclude_from_merging,
33
+ the key will be added with a uuid to prevent merging of this holding.
28
34
 
29
35
  Args:
30
36
  holdings_record (dict): The Holdingsrecord
@@ -1,3 +1,9 @@
1
+ """Internationalization configuration.
2
+
3
+ Defines settings for the i18n library used for translation of user-facing messages
4
+ in migration reports and logs. Configures translation file locations and formats.
5
+ """
6
+
1
7
  from pathlib import Path
2
8
 
3
9
  settings = {
@@ -1,3 +1,10 @@
1
+ """Library and task configuration models.
2
+
3
+ Defines Pydantic models for library-wide configuration (LibraryConfiguration) and
4
+ file definitions (FileDefinition). Handles configuration validation, folder structure
5
+ setup, and migration parameters like HRID handling and iteration identifiers.
6
+ """
7
+
1
8
  from enum import Enum
2
9
  from typing import Annotated
3
10
 
@@ -7,12 +14,14 @@ from pydantic.types import DirectoryPath
7
14
 
8
15
  class HridHandling(str, Enum):
9
16
  """Enum determining how the HRID generation should be handled.
17
+
18
+ Options:
10
19
  - default: Enumerates the HRID, building on the current value in the HRID settings
11
20
  - preserve001: Takes the 001 and uses this as the HRID.
12
21
 
13
22
  Args:
14
- str (_type_): _description_
15
- Enum (_type_): _description_
23
+ str (_type_): The type of HRID handling.
24
+ Enum (_type_): The enumeration of HRID handling options.
16
25
  """
17
26
 
18
27
  default = "default"
@@ -77,7 +86,7 @@ class FileDefinition(BaseModel):
77
86
 
78
87
 
79
88
  class IlsFlavour(str, Enum):
80
- """ """
89
+ """Enum representing different ILS flavours for migration."""
81
90
 
82
91
  aleph = "aleph"
83
92
  voyager = "voyager"
@@ -92,6 +101,8 @@ class IlsFlavour(str, Enum):
92
101
 
93
102
 
94
103
  class FolioRelease(str, Enum):
104
+ """Enum representing different FOLIO releases."""
105
+
95
106
  ramsons = "ramsons"
96
107
  sunflower = "sunflower"
97
108
  trillium = "trillium"
@@ -99,6 +110,8 @@ class FolioRelease(str, Enum):
99
110
 
100
111
 
101
112
  class LibraryConfiguration(BaseModel):
113
+ """Pydantic model for tenant-level configuration."""
114
+
102
115
  gateway_url: Annotated[
103
116
  str,
104
117
  Field(
@@ -249,8 +262,9 @@ class LibraryConfiguration(BaseModel):
249
262
  @model_validator(mode="before")
250
263
  @classmethod
251
264
  def set_error_thresholds_for_debug(cls, values):
252
- """If log_level_debug is true, set error thresholds to very high values to avoid
253
- process shutdown during debugging.
265
+ """If log_level_debug is true, set error thresholds to very high values.
266
+
267
+ This avoids process shutdown during debugging.
254
268
  """
255
269
  if values.get("log_level_debug", False):
256
270
  values["failed_records_threshold"] = 10_000_000
@@ -1,3 +1,10 @@
1
+ """Base class for all data mappers.
2
+
3
+ Provides the MapperBase class with common functionality for transforming legacy
4
+ data to FOLIO format. Handles reference data mapping, field validation, error
5
+ handling, bound-with processing, and statistical code mapping.
6
+ """
7
+
1
8
  import ast
2
9
  import copy
3
10
  import json
@@ -41,6 +48,14 @@ class MapperBase:
41
48
  folio_client: FolioClient,
42
49
  parent_id_map: Dict[str, Tuple] | None = None,
43
50
  ):
51
+ """Initialize the mapper base with configuration and FOLIO client.
52
+
53
+ Args:
54
+ library_configuration (LibraryConfiguration): Library-specific configuration.
55
+ task_configuration (AbstractTaskConfiguration): Task-specific transformation settings.
56
+ folio_client (FolioClient): FOLIO API client for reference data and posting.
57
+ parent_id_map (Dict[str, Tuple] | None): Optional parent id map from prior transform.
58
+ """
44
59
  logging.info("MapperBase initiating")
45
60
  self.parent_id_map: dict[str, tuple] = parent_id_map or {}
46
61
  self.extradata_writer: ExtradataWriter = ExtradataWriter(Path(""))
@@ -0,0 +1 @@
1
+ """Mappers for transforming CSV/JSON data using mapping configuration files."""
@@ -1,3 +1,10 @@
1
+ """Mapper for transforming course data to FOLIO Course Reserves format.
2
+
3
+ Provides the CoursesMapper class for mapping legacy course data to FOLIO course
4
+ records using configured mapping files. Handles course listings, instructors, and
5
+ term/department references.
6
+ """
7
+
1
8
  import i18n
2
9
  from typing import Any
3
10
  from typing import Dict
@@ -27,6 +34,16 @@ class CoursesMapper(MappingFileMapperBase):
27
34
  library_configuration: LibraryConfiguration,
28
35
  task_configuration,
29
36
  ):
37
+ """Initialize CoursesMapper with mapping configurations.
38
+
39
+ Args:
40
+ folio_client (FolioClient): FOLIO API client.
41
+ course_map: Course mapping configuration.
42
+ terms_map: Academic terms mapping configuration.
43
+ departments_map: Department mapping configuration.
44
+ library_configuration (LibraryConfiguration): Library configuration.
45
+ task_configuration: Task configuration for course migration.
46
+ """
30
47
  self.folio_client: FolioClient = folio_client
31
48
  self.user_cache: dict = {}
32
49
  self.notes_mapper: NotesMapper = NotesMapper(
@@ -1,3 +1,10 @@
1
+ """Mapper for transforming holdings data to FOLIO Holdings format.
2
+
3
+ Provides the HoldingsMapper class for mapping legacy holdings data to FOLIO Holdings
4
+ records using configured mapping files. Handles locations, call numbers, notes, and
5
+ bound-with relationships.
6
+ """
7
+
1
8
  import ast
2
9
  import json
3
10
  import logging
@@ -35,6 +42,18 @@ class HoldingsMapper(MappingFileMapperBase):
35
42
  task_config: AbstractTaskConfiguration,
36
43
  statistical_codes_map=None,
37
44
  ):
45
+ """Initialize HoldingsMapper for holdings transformations.
46
+
47
+ Args:
48
+ folio_client (FolioClient): FOLIO API client.
49
+ holdings_map: Mapping configuration for holdings fields.
50
+ location_map: Mapping of legacy to FOLIO locations.
51
+ call_number_type_map: Mapping of legacy to FOLIO call number types.
52
+ instance_id_map: Mapping of legacy to FOLIO instance IDs.
53
+ library_configuration (LibraryConfiguration): Library configuration.
54
+ task_config (AbstractTaskConfiguration): Task configuration.
55
+ statistical_codes_map: Mapping of legacy to FOLIO statistical codes.
56
+ """
38
57
  holdings_schema = folio_client.get_holdings_schema()
39
58
  self.instance_id_map = instance_id_map
40
59
  super().__init__(
@@ -1,3 +1,10 @@
1
+ """Mapper for transforming item data to FOLIO Items format.
2
+
3
+ Provides the ItemMapper class for mapping legacy item data to FOLIO Item records
4
+ using configured mapping files. Handles material types, loan types, statuses, and
5
+ circulation notes.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import sys
@@ -44,6 +51,23 @@ class ItemMapper(MappingFileMapperBase):
44
51
  library_configuration: LibraryConfiguration,
45
52
  task_configuration: AbstractTaskConfiguration,
46
53
  ):
54
+ """Initialize ItemMapper for item transformations.
55
+
56
+ Args:
57
+ folio_client (FolioClient): FOLIO API client.
58
+ items_map: Mapping configuration for item fields.
59
+ material_type_map: Mapping of legacy to FOLIO material types.
60
+ loan_type_map: Mapping of legacy to FOLIO loan types.
61
+ location_map: Mapping of legacy to FOLIO locations.
62
+ call_number_type_map: Mapping of legacy to FOLIO call number types.
63
+ holdings_id_map: Mapping of legacy to FOLIO holdings IDs.
64
+ statistical_codes_map: Mapping of legacy to FOLIO statistical codes.
65
+ item_statuses_map: Mapping of legacy to FOLIO item statuses.
66
+ temporary_loan_type_mapping: Mapping for temporary loan types.
67
+ temporary_location_mapping: Mapping for temporary locations.
68
+ library_configuration (LibraryConfiguration): Library configuration.
69
+ task_configuration (AbstractTaskConfiguration): Task configuration.
70
+ """
47
71
  item_schema = folio_client.get_item_schema()
48
72
  super().__init__(
49
73
  folio_client,
@@ -1,3 +1,9 @@
1
+ """Mapper for transforming manual fee/fine data to FOLIO Accounts format.
2
+
3
+ Provides the ManualFeeFinesMapper class for mapping legacy fee and fine data to FOLIO
4
+ Account records. Handles fee/fine types, owners, amounts, and payment status.
5
+ """
6
+
1
7
  import json
2
8
  import logging
3
9
  import uuid
@@ -34,6 +40,18 @@ class ManualFeeFinesMapper(MappingFileMapperBase):
34
40
  service_point_map,
35
41
  ignore_legacy_identifier: bool = True,
36
42
  ):
43
+ """Initialize ManualFeeFinesMapper for fee/fine transformations.
44
+
45
+ Args:
46
+ folio_client (FolioClient): FOLIO API client.
47
+ library_configuration (LibraryConfiguration): Library configuration.
48
+ task_configuration: Task configuration for fee fines migration.
49
+ feefines_map: Mapping configuration for fee/fine fields.
50
+ feefines_owner_map: Mapping of legacy to FOLIO fee/fine owners.
51
+ feefines_type_map: Mapping of legacy to FOLIO fee/fine types.
52
+ service_point_map: Mapping of legacy to FOLIO service points.
53
+ ignore_legacy_identifier (bool): Whether to ignore legacy identifiers.
54
+ """
37
55
  self.folio_client: FolioClient = folio_client
38
56
  self.composite_feefine_schema = self.get_composite_feefine_schema()
39
57
  self.task_configuration = task_configuration