• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Unleash / unleash-client-python / 5197933350

pending completion
5197933350

Pull #256

github

web-flow
Merge 8849812dd into d2a193c0b
Pull Request #256: Count metrics for non-existing features

16 of 16 new or added lines in 3 files covered. (100.0%)

831 of 856 relevant lines covered (97.08%)

0.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.06
/UnleashClient/api/features.py
1
from typing import Optional, Tuple
1✔
2

3
import requests
1✔
4
from requests.adapters import HTTPAdapter
1✔
5
from urllib3 import Retry
1✔
6

7
from UnleashClient.constants import FEATURES_URL, REQUEST_RETRIES, REQUEST_TIMEOUT
1✔
8
from UnleashClient.utils import LOGGER, log_resp_info
1✔
9

10

11
# pylint: disable=broad-except
12
def get_feature_toggles(
1✔
13
    url: str,
14
    app_name: str,
15
    instance_id: str,
16
    custom_headers: dict,
17
    custom_options: dict,
18
    project: Optional[str] = None,
19
    cached_etag: str = "",
20
) -> Tuple[dict, str]:
21
    """
22
    Retrieves feature flags from unleash central server.
23

24
    Notes:
25
    * If unsuccessful (i.e. not HTTP status code 200), exception will be caught and logged.
26
      This is to allow "safe" error handling if unleash server goes down.
27

28
    :param url:
29
    :param app_name:
30
    :param instance_id:
31
    :param custom_headers:
32
    :param custom_options:
33
    :param project:
34
    :param cached_etag:
35
    :return: (Feature flags, etag) if successful, ({},'') if not
36
    """
37
    try:
1✔
38
        LOGGER.info("Getting feature flag.")
1✔
39

40
        headers = {"UNLEASH-APPNAME": app_name, "UNLEASH-INSTANCEID": instance_id}
1✔
41

42
        if cached_etag:
1✔
43
            headers["If-None-Match"] = cached_etag
1✔
44

45
        base_url = f"{url}{FEATURES_URL}"
1✔
46
        base_params = {}
1✔
47

48
        if project:
1✔
49
            base_params = {"project": project}
1✔
50

51
        adapter = HTTPAdapter(
1✔
52
            max_retries=Retry(total=REQUEST_RETRIES, status_forcelist=[500, 502, 504])
53
        )
54
        with requests.Session() as session:
1✔
55
            session.mount("https://", adapter)
1✔
56
            session.mount("http://", adapter)
1✔
57
            resp = session.get(
1✔
58
                base_url,
59
                headers={**custom_headers, **headers},
60
                params=base_params,
61
                timeout=REQUEST_TIMEOUT,
62
                **custom_options,
63
            )
64

65
        if resp.status_code not in [200, 304]:
1✔
66
            log_resp_info(resp)
1✔
67
            LOGGER.warning(
1✔
68
                "Unleash Client feature fetch failed due to unexpected HTTP status code."
69
            )
70
            raise Exception(
1✔
71
                "Unleash Client feature fetch failed!"
72
            )  # pylint: disable=broad-exception-raised
73

74
        etag = ""
1✔
75
        if "etag" in resp.headers.keys():
1✔
76
            etag = resp.headers["etag"]
1✔
77

78
        if resp.status_code == 304:
1✔
79
            return None, etag
×
80

81
        return resp.json(), etag
1✔
82
    except Exception as exc:
1✔
83
        LOGGER.exception(
1✔
84
            "Unleash Client feature fetch failed due to exception: %s", exc
85
        )
86

87
    return {}, ""
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc