data-retrieval-module 1.0.0__tar.gz → 1.0.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 (37) hide show
  1. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/CHANGELOG.md +23 -0
  2. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/PKG-INFO +2 -1
  3. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/__init__.py +19 -3
  4. data_retrieval_module-1.0.2/data_retrieval/data_provider/__init__.py +5 -0
  5. data_retrieval_module-1.0.2/data_retrieval/data_provider/database/__init__.py +4 -0
  6. data_retrieval_module-1.0.2/data_retrieval/data_provider/database/database_data_provider.py +121 -0
  7. data_retrieval_module-1.0.2/data_retrieval/data_provider/database/sqlite3_data_provider.py +388 -0
  8. data_retrieval_module-1.0.2/data_retrieval/data_provider/rest_api/__init__.py +12 -0
  9. data_retrieval_module-1.0.2/data_retrieval/data_provider/rest_api/rest_api_data_provider.py +265 -0
  10. data_retrieval_module-1.0.2/data_retrieval/foreign_exchange/__init__.py +3 -0
  11. data_retrieval_module-1.0.2/data_retrieval/foreign_exchange/forex_data_provider_base.py +140 -0
  12. data_retrieval_module-1.0.2/data_retrieval/foreign_exchange/forex_data_provider_wrapper.py +148 -0
  13. data_retrieval_module-1.0.2/data_retrieval/foreign_exchange/forex_python_data_provider.py +161 -0
  14. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/model/__init__.py +2 -1
  15. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/model/data_provider.py +0 -1
  16. data_retrieval_module-1.0.2/data_retrieval/model/data_provider_wrapper.py +428 -0
  17. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/model/exceptions.py +23 -2
  18. data_retrieval_module-1.0.2/data_retrieval/utils/__init__.py +0 -0
  19. data_retrieval_module-1.0.2/data_retrieval/utils/date_utils.py +54 -0
  20. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval_module.egg-info/PKG-INFO +2 -1
  21. data_retrieval_module-1.0.2/data_retrieval_module.egg-info/SOURCES.txt +34 -0
  22. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval_module.egg-info/requires.txt +1 -0
  23. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/pyproject.toml +3 -2
  24. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/tests/test_basic.py +1 -1
  25. data_retrieval_module-1.0.0/data_retrieval_module.egg-info/SOURCES.txt +0 -21
  26. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/LICENSE +0 -0
  27. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/MANIFEST.in +0 -0
  28. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/Makefile +0 -0
  29. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/README.md +0 -0
  30. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/model/data_module.py +0 -0
  31. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval/py.typed +0 -0
  32. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval_module.egg-info/dependency_links.txt +0 -0
  33. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/data_retrieval_module.egg-info/top_level.txt +0 -0
  34. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/requirements-test.txt +0 -0
  35. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/setup.cfg +0 -0
  36. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/setup.py +0 -0
  37. {data_retrieval_module-1.0.0 → data_retrieval_module-1.0.2}/tests/__init__.py +0 -0
@@ -42,6 +42,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
42
42
  - CI/CD ready setup
43
43
  - Package publishing configuration
44
44
 
45
+ ## [1.0.1] - 2026-01-25
46
+
47
+ ### Added
48
+ - Foreign Exchange data provider module
49
+ - `Forex_DataProvider_Base` abstract base class for forex data providers
50
+ - `ForexPython_DataProvider` concrete implementation using Python libraries
51
+ - `Forex_DataProvider_Wrapper` wrapper for enhanced functionality
52
+ - Utility modules
53
+ - `date_utils` module for date/time utilities
54
+ - Enhanced data provider wrapper functionality
55
+ - Examples for forex data sources
56
+
57
+ ### Features
58
+ - **Forex Data Support**: Complete foreign exchange data provider framework
59
+ - **Utility Functions**: Date and time utilities for data processing
60
+ - **Enhanced Wrappers**: Improved data provider wrapper capabilities
61
+ - **Example Code**: Forex data source examples and usage patterns
62
+
63
+ ### Documentation
64
+ - Added forex provider documentation
65
+ - Updated package exports to include new modules
66
+ - Enhanced examples with forex data sources
67
+
45
68
  ## [Unreleased]
46
69
 
47
70
  ### Planned
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-retrieval-module
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: A standardized interface for data providers with sync and async support
5
5
  Author-email: AbigailWilliams1692 <abigail.williams@example.com>
6
6
  Maintainer-email: AbigailWilliams1692 <abigail.williams@example.com>
@@ -28,6 +28,7 @@ Requires-Python: >=3.8
28
28
  Description-Content-Type: text/markdown
29
29
  License-File: LICENSE
30
30
  Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
31
+ Requires-Dist: forex-python>=1.0.0
31
32
  Provides-Extra: dev
32
33
  Requires-Dist: pytest>=7.0.0; extra == "dev"
33
34
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
@@ -28,7 +28,17 @@ from data_retrieval.model.exceptions import (
28
28
  from data_retrieval.data_provider.rest_api import RestAPI_DataProvider
29
29
 
30
30
  # Database providers
31
- from data_retrieval.data_provider.database import Database_DataProvider
31
+ from data_retrieval.data_provider.database import (
32
+ Database_DataProvider,
33
+ SQLite3_DataProvider,
34
+ )
35
+
36
+ # Foreign Exchange providers
37
+ from data_retrieval.foreign_exchange import (
38
+ Forex_DataProvider_Base,
39
+ ForexPython_DataProvider,
40
+ Forex_DataProvider_Wrapper,
41
+ )
32
42
 
33
43
  #######################################################################
34
44
  # Public API
@@ -51,11 +61,17 @@ __all__ = [
51
61
 
52
62
  # Database providers
53
63
  "Database_DataProvider",
64
+ "SQLite3_DataProvider",
65
+
66
+ # Foreign Exchange providers
67
+ "Forex_DataProvider_Base",
68
+ "ForexPython_DataProvider",
69
+ "Forex_DataProvider_Wrapper",
54
70
  ]
55
71
 
56
72
  #######################################################################
57
73
  # Version Information
58
74
  #######################################################################
59
- __version__ = "1.0.0"
75
+ __version__ = "1.0.2"
60
76
  __author__ = "AbigailWilliams1692"
61
- __email__ = "abigail.williams@example.com"
77
+ __email__ = "alfred.xy1020@gmail.com"
@@ -0,0 +1,5 @@
1
+ #######################################################################
2
+ # Project: Data Retrieval Module
3
+ # File: __init__.py
4
+ # Description: Data provider package initialization
5
+ #######################################################################
@@ -0,0 +1,4 @@
1
+ from .database_data_provider import Database_DataProvider
2
+ from .sqlite3_data_provider import SQLite3_DataProvider
3
+
4
+ __all__ = ["Database_DataProvider", "SQLite3_DataProvider"]
@@ -0,0 +1,121 @@
1
+ #######################################################################
2
+ # Project: Data Retrieval Module
3
+ # File: db_provider.py
4
+ # Description: Database data provider implementations
5
+ # Author: AbigailWilliams1692
6
+ # Created: 2026-01-14
7
+ # Updated: 2026-01-19
8
+ #######################################################################
9
+
10
+ #######################################################################
11
+ # Import Packages
12
+ #######################################################################
13
+ # Standard Packages
14
+ import datetime
15
+ import logging
16
+ from abc import ABC, abstractmethod
17
+ from typing import Any, Dict, List, Optional
18
+
19
+ # Third-party Packages
20
+
21
+ # Local Packages
22
+ from data_retrieval.model.data_provider import DataProvider
23
+
24
+
25
+ #######################################################################
26
+ # Database Data Provider (Synchronous)
27
+ #######################################################################
28
+ class Database_DataProvider(DataProvider, ABC):
29
+ """
30
+ Base class for database data providers.
31
+
32
+ This class extends the DataProvider base class to provide database-specific
33
+ functionality for synchronous data retrieval operations. It serves as a
34
+ foundation for implementing various database connection types and query
35
+ operations.
36
+ """
37
+
38
+ ###################################################################
39
+ # Class Attributes
40
+ ###################################################################
41
+ __name = "Database_DataProvider"
42
+ __type = "Database_DataProvider"
43
+
44
+ ###################################################################
45
+ # Constructor Method
46
+ ###################################################################
47
+ def __init__(
48
+ self,
49
+ instance_id: Optional[int] = None,
50
+ logger: Optional[logging.Logger] = None,
51
+ log_level: Optional[int] = logging.INFO,
52
+ **config,
53
+ ) -> None:
54
+ """
55
+ Initialize the Database_DataProvider with the given parameters.
56
+
57
+ :param instance_id: Unique identifier for this provider instance.
58
+ :param logger: Logger instance for logging operations.
59
+ :param log_level: Logging level for the provider.
60
+ :param config: Additional configuration parameters for the database connection.
61
+ """
62
+ # Super Initialize
63
+ super().__init__(
64
+ instance_id=instance_id,
65
+ logger=logger,
66
+ log_level=log_level,
67
+ **config
68
+ )
69
+
70
+ ###################################################################
71
+ # Utility Methods
72
+ ###################################################################
73
+ def format_sql_query(self, sql: str, params: Dict[str, Any]) -> str:
74
+ """
75
+ Format the SQL query string with the given key-value pairs.
76
+
77
+ :param sql: the SQL query template string with placeholders.
78
+ :param params: Dict[str, Any]: a Dictionary of key-value pairs used to parametrize the SQL query.
79
+ :return: the formatted SQL query string.
80
+ """
81
+ for key, value in params.items():
82
+ placeholder = ":" + key
83
+
84
+ # Covert the value to string based on its type
85
+ if isinstance(value, str):
86
+ value_to_replace = "'" + str(value) + "'"
87
+ elif isinstance(value, (int, float)):
88
+ value_to_replace = str(value)
89
+ elif isinstance(value, datetime.date):
90
+ value_to_replace = "'" + value.strftime("%Y-%m-%d") + "'"
91
+ elif isinstance(value, List):
92
+ value_to_replace = "'" + self.stringify_a_list_of_items_with_apostrophe(item_list=value) + "'"
93
+ else:
94
+ raise TypeError(f"Unsupported value type: {type(value)} for parameter '{key}'")
95
+
96
+ # Replace all the placeholders in the SQL string
97
+ sql = sql.replace(placeholder, value_to_replace, count=-1)
98
+
99
+ return sql
100
+
101
+ @staticmethod
102
+ def stringify_a_list_of_items_with_apostrophe(item_list: List[Any]) -> str:
103
+ """
104
+ Convert a list of items into a comma-separated string with each item wrapped in apostrophes.
105
+
106
+ :param item_list: List of items to convert.
107
+ :return: String representation of items wrapped in apostrophes and separated by commas.
108
+ """
109
+ item_str_list = [f"'{str(item)}'" for item in item_list]
110
+ return ",".join(item_str_list)
111
+
112
+ @staticmethod
113
+ def generate_markers(size: int, marker: str = "?") -> str:
114
+ """
115
+ Generate placeholder markers joined by ','.
116
+
117
+ :param size: Number of markers to generate.
118
+ :param marker: Marker string to use (default is "?").
119
+ :return: String of markers joined by commas.
120
+ """
121
+ return ",".join([marker] * size)
@@ -0,0 +1,388 @@
1
+ #!/usr/bin/env python3
2
+ ########################################################################
3
+ # File: database_service.py
4
+ # Description: SQLite3 database data provider
5
+ # Author: AbigailWilliams1692
6
+ # Creation Date: 2026-01-29
7
+ # Version: 1.0.0
8
+ # License: MIT License
9
+ ########################################################################
10
+
11
+ ########################################################################
12
+ # Import Libraries
13
+ ########################################################################
14
+ # Standard Packages
15
+ import logging
16
+ import sqlite3
17
+ from enum import Enum
18
+ from typing import Any, Dict, List, Optional, Tuple, Union
19
+
20
+ # Third-party Packages
21
+ from data_retrieval.data_provider.database.database_data_provider import (
22
+ Database_DataProvider,
23
+ )
24
+
25
+
26
+ ########################################################################
27
+ # SQLite3 Data Provider Class
28
+ ########################################################################
29
+ class SQLite3FetchMode(str, Enum):
30
+ """
31
+ Enum for fetch modes.
32
+ """
33
+ ALL = "all"
34
+ ONE = "one"
35
+ MANY = "many"
36
+ LAST_ID = "last_id"
37
+ NONE = "none"
38
+
39
+
40
+ class SQLite3_DataProvider(Database_DataProvider):
41
+ """
42
+ SQLite3 data provider class.
43
+ """
44
+
45
+ ###################################################################
46
+ # Class Attributes
47
+ ###################################################################
48
+ __name = "SQLite3_DataProvider"
49
+
50
+ ###################################################################
51
+ # Constructor Method
52
+ ###################################################################
53
+ def __init__(
54
+ self,
55
+ db_file_path: str,
56
+ instance_id: Optional[int] = None,
57
+ logger: Optional[logging.Logger] = None,
58
+ log_level: Optional[int] = logging.INFO,
59
+ **config,
60
+ ) -> None:
61
+ """
62
+ Initialize the DatabaseService with the given parameters.
63
+
64
+ :param db_file_path: Path to the SQLite database file (.db).
65
+ :param instance_id: Unique identifier for this provider instance.
66
+ :param logger: Logger instance for logging operations.
67
+ :param log_level: Logging level for the provider.
68
+ :param config: Additional configuration parameters.
69
+ """
70
+ # Super Initialize
71
+ super().__init__(
72
+ instance_id=instance_id,
73
+ logger=logger,
74
+ log_level=log_level,
75
+ **config,
76
+ )
77
+
78
+ # Initialize the DatabaseService attributes
79
+ ## Store the database path
80
+ self._db_file_path = db_file_path
81
+ ## Initialize the cursor
82
+ self._cursor: Optional[sqlite3.Cursor] = None
83
+ ## Connect to the datbase file
84
+ self.connect()
85
+
86
+ # Update data methods
87
+ self.update_data_methods(
88
+ new_methods={
89
+ "execute": self.execute,
90
+ "execute_many": self.execute_many,
91
+ "fetch_one": self.fetch_one,
92
+ "fetch_many": self.fetch_many,
93
+ "fetch_all": self.fetch_all,
94
+ }
95
+ )
96
+
97
+ ###################################################################
98
+ # Getter & Setter Methods
99
+ ###################################################################
100
+ def get_db_file_path(self) -> str:
101
+ """
102
+ Get the database file path.
103
+
104
+ :return: The path to the SQLite database file.
105
+ """
106
+ return self._db_file_path
107
+
108
+ def set_db_file_path(self, db_file_path: str) -> None:
109
+ """
110
+ Set the database file path.
111
+
112
+ :param db_file_path: The path to the SQLite database file.
113
+ :return: None.
114
+ """
115
+ self._db_file_path = db_file_path
116
+
117
+ def get_cursor(self) -> Optional[sqlite3.Cursor]:
118
+ """
119
+ Get the database cursor.
120
+
121
+ :return: The SQLite cursor object.
122
+ """
123
+ return self._cursor
124
+
125
+ def set_cursor(self, cursor: sqlite3.Cursor) -> None:
126
+ """
127
+ Set the database cursor.
128
+
129
+ :param cursor: The SQLite cursor object.
130
+ :return: None.
131
+ """
132
+ self._cursor = cursor
133
+
134
+ ###################################################################
135
+ # Connection Methods
136
+ ###################################################################
137
+ def _connect(self, *args, **kwargs) -> None:
138
+ """
139
+ Connect to the SQLite database.
140
+
141
+ Creates a connection to the SQLite database file specified by db_file_path.
142
+ If the file does not exist, SQLite will create it.
143
+
144
+ :param args: Positional arguments (unused).
145
+ :param kwargs: Keyword arguments (unused).
146
+ :return: None.
147
+ :raises sqlite3.Error: If connection fails.
148
+ """
149
+ # Connect to the database
150
+ conn = sqlite3.connect(self.get_db_file_path())
151
+
152
+ # Set row factory to return rows as sqlite3.Row objects
153
+ conn.row_factory = sqlite3.Row
154
+
155
+ # Set connection and cursor
156
+ self.set_connection(connection=conn)
157
+ self.set_cursor(conn.cursor())
158
+
159
+ def _disconnect(self) -> None:
160
+ """
161
+ Disconnect from the SQLite database.
162
+
163
+ Closes the cursor and connection to the database.
164
+
165
+ :param args: Positional arguments (unused).
166
+ :param kwargs: Keyword arguments (unused).
167
+ :return: None.
168
+ :raises sqlite3.Error: If disconnection fails.
169
+ """
170
+ if self._cursor is not None:
171
+ self._cursor.close()
172
+ self._cursor = None
173
+
174
+ conn = self.get_connection()
175
+ if conn is not None:
176
+ conn.close()
177
+ self.set_connection(connection=None)
178
+
179
+ ###################################################################
180
+ # Core Instance Method: Execute
181
+ ###################################################################
182
+ def execute(
183
+ self,
184
+ sql: str,
185
+ params: Optional[Union[Tuple, Dict[str, Any]]] = None,
186
+ fetch_mode: str = SQLite3FetchMode.ALL,
187
+ commit: bool = True,
188
+ **kwargs,
189
+ ) -> Any:
190
+ """
191
+ Execute a SQL query on the SQLite database.
192
+
193
+ :param sql: The SQL query string to execute.
194
+ :param params: Optional parameters for parameterized queries.
195
+ Can be a tuple for positional params or dict for named params.
196
+ :param fetch: Fetch mode - "all", "one", "many", or "none".
197
+ - "all": Fetch all results (fetchall).
198
+ - "one": Fetch single result (fetchone).
199
+ - "many": Fetch specified number of results (fetchmany).
200
+ - "none": Don't fetch results (for INSERT/UPDATE/DELETE).
201
+ :param commit: Whether to commit the transaction after execution.
202
+ :param kwargs: Additional keyword arguments.
203
+ - fetch_size: Number of rows to fetch when fetch="many".
204
+ :return: Query results based on fetch mode, or lastrowid for INSERT operations.
205
+ :raises sqlite3.Error: If query execution fails.
206
+ :raises ValueError: If invalid fetch mode is specified.
207
+ """
208
+ # Check if the database is connected
209
+ self.check_db_connection()
210
+
211
+ # Get the connection and the cursor
212
+ conn = self.get_connection()
213
+ cursor = self.get_cursor()
214
+
215
+ # Execute the query with or without parameters
216
+ if params is not None:
217
+ cursor.execute(sql, params)
218
+ else:
219
+ cursor.execute(sql)
220
+
221
+ # Commit if requested
222
+ if commit:
223
+ conn.commit()
224
+
225
+ # Fetch results based on mode
226
+ if fetch_mode == "all":
227
+ return cursor.fetchall()
228
+ elif fetch_mode == "one":
229
+ return cursor.fetchone()
230
+ elif fetch_mode == "many":
231
+ fetch_size = kwargs.get("fetch_size", 100)
232
+ return cursor.fetchmany(fetch_size)
233
+ elif fetch_mode == "last_id":
234
+ return cursor.lastrowid
235
+ elif fetch_mode == "none":
236
+ return None
237
+ else:
238
+ raise ValueError(f"Invalid fetch mode: {fetch_mode}. Must be 'all', 'one', 'many', or 'none'.")
239
+
240
+ def execute_many(
241
+ self,
242
+ sql: str,
243
+ params_list: List[Union[Tuple, Dict[str, Any]]],
244
+ fetch_mode: str = "all",
245
+ commit: bool = True,
246
+ ) -> None:
247
+ """
248
+ Execute a SQL statement on the SQLite database multiple times with different parameters.
249
+
250
+ :param sql: The SQL statement to execute.
251
+ :param params_list: List of parameter tuples or dicts.
252
+ :param commit: Whether to commit the transaction (default: True).
253
+ :return: None.
254
+ """
255
+ # Check if the database is connected
256
+ self.check_db_connection()
257
+
258
+ # Get the connection and the cursor
259
+ conn = self.get_connection()
260
+ cursor = self.get_cursor()
261
+
262
+ # Execute the query with multiple parameter groups
263
+ cursor.executemany(sql, params_list)
264
+
265
+ # Commit if requested
266
+ if commit:
267
+ conn.commit()
268
+
269
+ # Fetch results based on mode
270
+ if fetch_mode == "all":
271
+ return cursor.fetchall()
272
+ elif fetch_mode == "one":
273
+ return cursor.fetchone()
274
+ elif fetch_mode == "many":
275
+ fetch_size = kwargs.get("fetch_size", 100)
276
+ return cursor.fetchmany(fetch_size)
277
+ elif fetch_mode == "last_id":
278
+ return cursor.lastrowid
279
+ elif fetch_mode == "none":
280
+ return None
281
+ else:
282
+ raise ValueError(f"Invalid fetch mode: {fetch_mode}. Must be 'all', 'one', 'many', or 'none'.")
283
+
284
+ ###################################################################
285
+ # Core Instance Methods: Fetch One/Many/All
286
+ ###################################################################
287
+ def fetch_one(
288
+ self,
289
+ sql: str,
290
+ params: Optional[Union[Tuple, Dict[str, Any]]] = None,
291
+ ) -> Optional[sqlite3.Row]:
292
+ """
293
+ Execute a SELECT query and fetch a single result.
294
+
295
+ :param sql: The SQL SELECT query.
296
+ :param params: Optional parameters for parameterized queries.
297
+ :return: Single result row or None.
298
+ """
299
+ return self.execute(sql=sql, params=params, fetch="one")
300
+
301
+ def fetch_many(
302
+ self,
303
+ sql: str,
304
+ params: Optional[Union[Tuple, Dict[str, Any]]] = None,
305
+ fetch_size: int = 100,
306
+ ) -> List[sqlite3.Row]:
307
+ """
308
+ Execute a SELECT query and fetch multiple results.
309
+
310
+ :param sql: The SQL SELECT query.
311
+ :param params: Optional parameters for parameterized queries.
312
+ :param fetch_size: Number of rows to fetch (default: 100).
313
+ :return: List of result rows.
314
+ """
315
+ return self.execute(sql=sql, params=params, fetch="many", fetch_size=fetch_size)
316
+
317
+ def fetch_all(
318
+ self,
319
+ sql: str,
320
+ params: Optional[Union[Tuple, Dict[str, Any]]] = None,
321
+ ) -> List[sqlite3.Row]:
322
+ """
323
+ Execute a SELECT query and fetch all results.
324
+
325
+ :param sql: The SQL SELECT query.
326
+ :param params: Optional parameters for parameterized queries.
327
+ :return: List of all result rows.
328
+ """
329
+ return self.execute(sql=sql, params=params, fetch="all")
330
+
331
+ ###################################################################
332
+ # Core Instance Method: Commit
333
+ ###################################################################
334
+ def commit(self) -> None:
335
+ """
336
+ Commit the current transaction.
337
+ """
338
+ self.check_db_connection()
339
+ self.get_connection().commit()
340
+
341
+ ###################################################################
342
+ # Core Instance Method: Rollback
343
+ ###################################################################
344
+ def rollback(self) -> None:
345
+ """
346
+ Rollback the current transaction.
347
+
348
+ :return: None.
349
+ """
350
+ self.check_db_connection()
351
+ self.get_connection().rollback()
352
+
353
+ ###################################################################
354
+ # Utility Methods
355
+ ###################################################################
356
+ def check_db_connection(self) -> None:
357
+ """
358
+ Check connection and raise sqlite3.OperationalError if not connected.
359
+ """
360
+ if not self.is_connected():
361
+ raise sqlite3.OperationalError("Database is not connected. Call connect() first.")
362
+
363
+ def table_exists(self, table_name: str) -> bool:
364
+ """
365
+ Check if a table exists in the database.
366
+
367
+ :param table_name: Name of the table to check.
368
+ :return: True if table exists, False otherwise.
369
+ """
370
+ sql = """
371
+ SELECT name
372
+ FROM sqlite_master
373
+ WHERE type='table'
374
+ AND name=?
375
+ """
376
+ result = self.fetch_one(sql=sql, params=(table_name,))
377
+ return result is not None
378
+
379
+ def get_table_info(self, table_name: str) -> List[sqlite3.Row]:
380
+ """
381
+ Get column information for a table.
382
+
383
+ :param table_name: Name of the table.
384
+ :return: List of column information rows.
385
+ """
386
+ self.check_db_connection()
387
+ sql = f"PRAGMA table_info({table_name})"
388
+ return self.fetch_all(sql=sql)
@@ -0,0 +1,12 @@
1
+ #######################################################################
2
+ # Project: Data Retrieval Module
3
+ # File: __init__.py
4
+ # Description: REST API data provider package initialization
5
+ # Author: AbigailWilliams1692
6
+ # Created: 2026-01-14
7
+ # Updated: 2026-01-18
8
+ #######################################################################
9
+
10
+ from .rest_api_data_provider import RestAPI_DataProvider
11
+
12
+ __all__ = ["RestAPI_DataProvider"]