|
2 | 2 | import sys |
3 | 3 | from datetime import datetime |
4 | 4 | from typing import Iterable, List, Optional, Tuple, Union, overload |
| 5 | +import traceback |
5 | 6 |
|
6 | 7 | import numpy as np |
7 | 8 | import logging |
|
11 | 12 | from ..inventory.indexes import (CatalogIndex, ComponentIndex, |
12 | 13 | DatasetIndex, ParameterIndex, |
13 | 14 | SpeasyIndex, TimetableIndex) |
14 | | -from ...config import core as core_cfg, amda as amda_cfg |
| 15 | +from ...config import core as core_cfg |
15 | 16 | from ...products import * |
16 | 17 | from ...data_providers import (AmdaWebservice, CdaWebservice, CsaWebservice, |
17 | | - SscWebservice, GenericArchive) |
| 18 | + SscWebservice, GenericArchive, UiowaEphTool) |
18 | 19 | from ..http import is_server_up |
19 | 20 |
|
20 | 21 | log = logging.getLogger(__name__) |
|
33 | 34 | uiowaephtool = None |
34 | 35 |
|
35 | 36 |
|
| 37 | +def _is_server_up(ws_class): |
| 38 | + """Check if the webservice server is up. Will first look for an 'is_server_up' method in the class, |
| 39 | + then for a 'BASE_URL' attribute to use the generic 'is_server_up' function finally returns True if none of these are found. |
| 40 | +
|
| 41 | + Parameters |
| 42 | + ---------- |
| 43 | + ws_class : class |
| 44 | + The webservice class to check. |
| 45 | + Returns |
| 46 | + ------- |
| 47 | + bool |
| 48 | + True if the server is up, False otherwise. |
| 49 | + """ |
| 50 | + if hasattr(ws_class, 'is_server_up'): |
| 51 | + return ws_class.is_server_up() |
| 52 | + elif hasattr(ws_class, 'BASE_URL'): |
| 53 | + return is_server_up(ws_class.BASE_URL) |
| 54 | + return True |
| 55 | + |
| 56 | + |
| 57 | +def _safe_init_provider(ws_class, names, ignore_disabled_status=False): |
| 58 | + """Initialize a data provider safely, catching exceptions and disabling the provider if initialization fails. |
| 59 | +
|
| 60 | + Parameters |
| 61 | + ---------- |
| 62 | + ws_class : class |
| 63 | + The webservice class to initialize. |
| 64 | + names : list of str |
| 65 | + The names under which to register the provider, the first name is considered the main name. |
| 66 | + ignore_disabled_status : bool, optional |
| 67 | + If True, ignore the disabled status from configuration and attempt to initialize the provider anyway. |
| 68 | +
|
| 69 | + Returns |
| 70 | + ------- |
| 71 | + None |
| 72 | +
|
| 73 | + Raises |
| 74 | + ------ |
| 75 | + RuntimeError |
| 76 | + If the server is not running. |
| 77 | + """ |
| 78 | + try: |
| 79 | + if ignore_disabled_status or not core_cfg.disabled_providers().intersection(set(names)): |
| 80 | + main_name = names[0] |
| 81 | + if _is_server_up(ws_class): |
| 82 | + globals()[main_name] = ws_class() |
| 83 | + for name in names: |
| 84 | + PROVIDERS[name] = globals()[main_name] |
| 85 | + else: |
| 86 | + raise RuntimeError(f'{main_name} is not running') |
| 87 | + except Exception: # pylint: disable=broad-except |
| 88 | + log.warning(f"Provider {names} initialization failed, disabling provider") |
| 89 | + log.warning(f"Exception: {traceback.format_exc()}") |
| 90 | + |
| 91 | + |
36 | 92 | def init_amda(ignore_disabled_status=False): |
37 | | - global amda |
38 | | - if ignore_disabled_status or 'amda' not in core_cfg.disabled_providers(): |
39 | | - if AmdaWebservice.is_server_up(): |
40 | | - amda = AmdaWebservice() |
41 | | - sys.modules[__name__].amda = amda |
42 | | - PROVIDERS['amda'] = amda |
43 | | - else: |
44 | | - log.warning(f"AMDA server {amda_cfg.entry_point()} is down, disabling AMDA provider") |
| 93 | + _safe_init_provider(AmdaWebservice, ['amda'], ignore_disabled_status=ignore_disabled_status) |
45 | 94 |
|
46 | 95 |
|
47 | 96 | def init_csa(ignore_disabled_status=False): |
48 | | - global csa |
49 | 97 | if os.environ.get("HTTP_PROXY", None) is not None: |
50 | 98 | log.warning("CSA webservice does not support proxy servers, disabling CSA provider") |
51 | 99 | log.warning("See https://github.com/astropy/astroquery/issues/3228") |
52 | | - return |
53 | | - if ignore_disabled_status or 'csa' not in core_cfg.disabled_providers(): |
54 | | - if is_server_up(CsaWebservice.BASE_URL): |
55 | | - csa = CsaWebservice() |
56 | | - sys.modules[__name__].csa = csa |
57 | | - PROVIDERS['csa'] = csa |
58 | | - else: |
59 | | - log.warning(f"CSA server {CsaWebservice.BASE_URL} is down, disabling CSA provider") |
| 100 | + else: |
| 101 | + _safe_init_provider(CsaWebservice, ['csa'], ignore_disabled_status=ignore_disabled_status) |
60 | 102 |
|
61 | 103 |
|
62 | 104 | def init_cdaweb(ignore_disabled_status=False): |
63 | | - global cda |
64 | | - if ignore_disabled_status or not core_cfg.disabled_providers().intersection({'cda', 'cdaweb'}): |
65 | | - if is_server_up(CdaWebservice.BASE_URL): |
66 | | - cda = CdaWebservice() |
67 | | - sys.modules[__name__].cda = cda |
68 | | - PROVIDERS['cda'] = cda |
69 | | - PROVIDERS['cdaweb'] = cda |
70 | | - else: |
71 | | - log.warning(f"CDA server {CdaWebservice.BASE_URL} is down, disabling CDA provider") |
| 105 | + _safe_init_provider(CdaWebservice, ['cda', 'cdaweb'], ignore_disabled_status=ignore_disabled_status) |
72 | 106 |
|
73 | 107 |
|
74 | 108 | def init_sscweb(ignore_disabled_status=False): |
75 | | - global ssc |
76 | | - if ignore_disabled_status or not core_cfg.disabled_providers().intersection({'ssc', 'sscweb'}): |
77 | | - if is_server_up(SscWebservice.BASE_URL): |
78 | | - ssc = SscWebservice() |
79 | | - sys.modules[__name__].ssc = ssc |
80 | | - PROVIDERS['ssc'] = ssc |
81 | | - PROVIDERS['sscweb'] = ssc |
82 | | - else: |
83 | | - log.warning(f"SSC server {SscWebservice.BASE_URL} is down, disabling SSC provider") |
| 109 | + _safe_init_provider(SscWebservice, ['ssc', 'sscweb'], ignore_disabled_status=ignore_disabled_status) |
84 | 110 |
|
85 | 111 |
|
86 | 112 | def init_archive(ignore_disabled_status=False): |
87 | | - global archive |
88 | | - if ignore_disabled_status or not core_cfg.disabled_providers().intersection({'archive', 'generic_archive'}): |
89 | | - archive = GenericArchive() |
90 | | - sys.modules[__name__].archive = archive |
91 | | - PROVIDERS['archive'] = archive |
92 | | - PROVIDERS['generic_archive'] = archive |
| 113 | + _safe_init_provider(GenericArchive, ['archive', 'generic_archive'], ignore_disabled_status=ignore_disabled_status) |
93 | 114 |
|
94 | 115 |
|
95 | 116 | def init_uiowaephtool(ignore_disabled_status=False): |
96 | | - global uiowaephtool |
97 | | - if ignore_disabled_status or not core_cfg.disabled_providers().intersection({'UiowaEphTool', 'uiowaephtool'}): |
98 | | - if is_server_up("https://planet.physics.uiowa.edu"): |
99 | | - from ...data_providers.uiowa_eph_tool import UiowaEphTool |
100 | | - uiowaephtool = UiowaEphTool() |
101 | | - sys.modules[__name__].uiowaephtool = uiowaephtool |
102 | | - PROVIDERS['uiowaephtool'] = uiowaephtool |
103 | | - PROVIDERS['UiowaEphTool'] = uiowaephtool |
104 | | - else: |
105 | | - log.warning("UiowaEphTool server https://planet.physics.uiowa.edu is down, disabling UiowaEphTool provider") |
| 117 | + _safe_init_provider(UiowaEphTool, ['uiowaephtool', 'UiowaEphTool'], ignore_disabled_status=ignore_disabled_status) |
106 | 118 |
|
107 | 119 |
|
108 | 120 | def init_providers(ignore_disabled_status=False): |
|
0 commit comments