1212from platform import machine
1313from typing import List , Optional , Tuple
1414
15+ from tls_requests .utils import get_logger
16+
17+ logger = get_logger ("TLSLibrary" )
18+
1519__all__ = ["TLSLibrary" ]
1620
1721LATEST_VERSION_TAG_NAME = "v1.11.2"
6064
6165PATTERN_RE = re .compile (r"%s-%s.*%s" % (PLATFORM , MACHINE , FILE_EXT ), re .I )
6266PATTERN_UBUNTU_RE = re .compile (r"%s-%s.*%s" % ("ubuntu" , MACHINE , FILE_EXT ), re .I )
63-
6467TLS_LIBRARY_PATH = os .getenv ("TLS_LIBRARY_PATH" )
6568
6669
@@ -131,6 +134,7 @@ class TLSLibrary:
131134 """
132135
133136 _PATH : str = None
137+ _LIBRARY : Optional [ctypes .CDLL ] = None
134138 _STATIC_API_DATA = {
135139 "name" : "v1.11.2" ,
136140 "tag_name" : "v1.11.2" ,
@@ -250,9 +254,9 @@ def cleanup_files(cls, keep_file: str = None):
250254 if is_remove :
251255 try :
252256 os .remove (file_path )
253- print (f"Removed old library file: { file_path } " )
257+ logger . info (f"Removed old library file: { file_path } " )
254258 except OSError as e :
255- print (f"Error removing old library file { file_path } : { e } " )
259+ logger . error (f"Error removing old library file { file_path } : { e } " )
256260
257261 @classmethod
258262 def fetch_api (cls , version : str = None , retries : int = 3 ):
@@ -280,7 +284,7 @@ def _find_release(data, version_: str = None):
280284 _find_release (json .loads (content ))
281285 break
282286 except Exception as ex :
283- print ("Unable to fetch GitHub API: %s" % ex )
287+ logger . error ("Unable to fetch GitHub API: %s" % ex )
284288
285289 if not asset_urls and not ubuntu_urls :
286290 _find_release ([cls ._STATIC_API_DATA ])
@@ -302,10 +306,23 @@ def find(cls) -> str:
302306 def find_all (cls ) -> List [str ]:
303307 return [src for src in glob .glob (os .path .join (BIN_DIR , r"*" )) if src .lower ().endswith (("so" , "dll" , "dylib" ))]
304308
309+ @classmethod
310+ def update (cls ):
311+ """Forces a download of the latest library version."""
312+ logger .info (f"Updating TLS library to version { LATEST_VERSION_TAG_NAME } ..." )
313+ downloaded_fp = cls .download (version = LATEST_VERSION_TAG_NAME )
314+ if downloaded_fp :
315+ cls .cleanup_files (keep_file = downloaded_fp )
316+ logger .info ("Update complete." )
317+ return downloaded_fp
318+ logger .error ("Update failed." )
319+
320+ upgrade = update
321+
305322 @classmethod
306323 def download (cls , version : str = None ) -> str :
307324 try :
308- print (
325+ logger . info (
309326 "System Info - Platform: %s, Machine: %s, File Ext : %s."
310327 % (
311328 PLATFORM ,
@@ -319,7 +336,7 @@ def download(cls, version: str = None) -> str:
319336 download_url = url
320337 break
321338
322- print ("Library Download URL: %s" % download_url )
339+ logger . info ("Library Download URL: %s" % download_url )
323340 if download_url :
324341 destination_name = download_url .split ("/" )[- 1 ]
325342 destination = os .path .join (BIN_DIR , destination_name )
@@ -352,13 +369,12 @@ def download(cls, version: str = None) -> str:
352369 sys .stdout .write (f"\r Downloading { destination_name } : [{ bar } ] { percent :.1f} %" )
353370 sys .stdout .flush ()
354371
355- print () # Newline after download completes
356372 return destination
357373
358374 except (urllib .error .URLError , urllib .error .HTTPError ) as ex :
359- print ("Unable to download file: %s" % ex )
375+ logger . error ("Unable to download file: %s" % ex )
360376 except Exception as e :
361- print ("An unexpected error occurred during download: %s" % e )
377+ logger . error ("An unexpected error occurred during download: %s" % e )
362378
363379 @classmethod
364380 def set_path (cls , fp : str ):
@@ -370,22 +386,32 @@ def load(cls):
370386 Loads the TLS library. It checks for the correct version, downloads it if
371387 the local version is outdated or missing, and then loads it into memory.
372388 """
389+ target_version = cls ._parse_version (LATEST_VERSION_TAG_NAME )
390+
391+ if cls ._LIBRARY and cls ._PATH :
392+ cached_version = cls ._parse_version_from_filename (cls ._PATH )
393+ if cached_version == target_version :
394+ return cls ._LIBRARY
373395
374396 def _load_library (fp_ ):
375397 try :
376398 lib = ctypes .cdll .LoadLibrary (fp_ )
377399 cls .set_path (fp_ )
378- print (f"Successfully loaded TLS library: { fp_ } " )
400+ cls ._LIBRARY = lib
401+ logger .info (f"Successfully loaded TLS library: { fp_ } " )
379402 return lib
380403 except Exception as ex :
381- print (f"Unable to load TLS library '{ fp_ } ', details: { ex } " )
404+ logger . error (f"Unable to load TLS library '{ fp_ } ', details: { ex } " )
382405 try :
383406 os .remove (fp_ )
384407 except (FileNotFoundError , PermissionError ):
385408 pass
386409
387- target_version = cls ._parse_version (LATEST_VERSION_TAG_NAME )
388- print (f"Required library version: { LATEST_VERSION_TAG_NAME } " )
410+ if TLS_LIBRARY_PATH :
411+ logger .info (f"Loading TLS library from environment variable: { TLS_LIBRARY_PATH } " )
412+ return _load_library (TLS_LIBRARY_PATH )
413+
414+ logger .debug (f"Required library version: { LATEST_VERSION_TAG_NAME } " )
389415 local_files = cls .find_all ()
390416 newest_local_version = (0 , 0 , 0 )
391417 newest_local_file = None
@@ -396,24 +422,33 @@ def _load_library(fp_):
396422 if file_version > newest_local_version :
397423 newest_local_version = file_version
398424 newest_local_file = file_path
399- print (
425+ logger . debug (
400426 f"Found newest local library: { newest_local_file } (version { '.' .join (map (str , newest_local_version ))} )"
401427 )
402428 else :
403- print ("No local library found." )
429+ logger . debug ("No local library found." )
404430
405431 if newest_local_version < target_version :
406432 if newest_local_file :
407- print (f"Local library is outdated. Upgrading to { LATEST_VERSION_TAG_NAME } ..." )
433+ logger .warning (
434+ f"Local library is outdated (Found: { '.' .join (map (str , newest_local_version ))} , "
435+ f"Required: { LATEST_VERSION_TAG_NAME } ). "
436+ f"Auto-downloading... To manually upgrade, run: `python -m tls_requests.models.libraries`"
437+ )
408438 else :
409- print (f"Downloading required library version { LATEST_VERSION_TAG_NAME } ..." )
439+ logger . info (f"Downloading required library version { LATEST_VERSION_TAG_NAME } ..." )
410440
411441 downloaded_fp = cls .download (version = LATEST_VERSION_TAG_NAME )
412442 if downloaded_fp :
413443 cls .cleanup_files (keep_file = downloaded_fp )
414444 library = _load_library (downloaded_fp )
415445 if library :
416446 return library
447+
448+ logger .error (
449+ f"Failed to download the required TLS library { LATEST_VERSION_TAG_NAME } . "
450+ "Please check your connection or download it manually from GitHub."
451+ )
417452 raise OSError ("Failed to download the required TLS library." )
418453
419454 if newest_local_file :
@@ -423,3 +458,7 @@ def _load_library(fp_):
423458 return library
424459
425460 raise OSError ("Could not find or load a compatible TLS library." )
461+
462+
463+ if __name__ == "__main__" :
464+ TLSLibrary .update ()
0 commit comments