elsander: @stephen-hoover Wanted to flag this for you, since you might have more context on the original decision here.

@salilgupta1 , can you note in the description that this closes #345 ?
stephen-hoover: > @stephen-hoover Wanted to flag this for you, since you might have more context on the original decision here.

Thanks for the flag, but I don't recall being involved in any discussions around the initial implementation of this part of the code.


diff --git a/civis/resources/_resources.py b/civis/resources/_resources.py
index 0a10aa3..cbe0ec5 100644
--- a/civis/resources/_resources.py
+++ b/civis/resources/_resources.py
@@ -132,6 +132,16 @@ def docs_from_properties(properties, level=0):
     return docs
 
 
+def deprecated_notice(deprecation_warning):
+    """ Return a doc string element for the deprecation notice. The
+    doc string can be an empty string if the warning is None
+    """
+    if deprecation_warning is None:
+        return ""
+
+    return "Deprecation warning!\n------------------\n" + deprecation_warning
+
+
 def doc_from_responses(responses):
     """ Return a doc string element from a responses object. The
     doc string describes the returned objects of a function.
@@ -411,13 +421,14 @@ def parse_method(verb, operation, path):
     summary = operation["summary"]
     params = operation.get("parameters", [])
     responses = operation["responses"]
-    deprecated = operation.get('deprecated', False)
-    if 'deprecated' in summary.lower() or deprecated:
+    deprecation_warning = operation.get("x-deprecation-warning", None)
+    if 'deprecated' in summary.lower():
         return None
 
     args, param_doc = parse_params(params, summary, verb)
     response_doc = doc_from_responses(responses)
-    docs = join_doc_elements(param_doc, response_doc)
+    deprecation_notice = deprecated_notice(deprecation_warning)
+    docs = join_doc_elements(deprecation_notice, param_doc, response_doc)
     name = parse_method_name(verb, path)
 
     method = create_method(args, verb, name, path, docs)

Add `ignore_deprecated` flag to `APIClient`
The API client currently ignores any endpoints with a deprecation warning. This means that endpoints effectively cannot be deprecated-- once they are tagged deprecated, they are inaccessible from the client.

One option would be to automatically pull in these endpoints, which would allow for deprecation, but would make deprecated endpoints visible to new users, which may not be desirable. 

The alternative I'd propose is to add an `ignore_deprecated` flag when instantiating the client, which defaults to `True`. This means that existing code based on newly deprecated endpoints would still break, but could be updated to work until the endpoint is removed entirely.
diff --git a/civis/tests/test_resources.py b/civis/tests/test_resources.py
index 4c46091..2ce2d59 100644
--- a/civis/tests/test_resources.py
+++ b/civis/tests/test_resources.py
@@ -126,6 +126,18 @@ def test_docs_from_properties():
     assert sorted(y) == sorted(['    - a : string', '    - b : integer'])
 
 
+def test_deprecated_notice():
+    deprecation_warning = "This endpoint is no longer supported"
+    notice = _resources.deprecated_notice(deprecation_warning)
+
+    assert "Deprecation warning!" in notice
+    assert deprecation_warning in notice
+
+
+def test_deprecated_notice_handles_none():
+    assert _resources.deprecated_notice(None) == ""
+
+
 def test_doc_from_responses():
     responses = OrderedDict([('200', OrderedDict([('description', 'success'), ('schema', OrderedDict([('type', 'array'), ('items', OrderedDict([('type', 'object'), ('properties', OrderedDict([('id', OrderedDict([('description', 'The ID of the credential.'), ('type', 'integer')])), ('name', OrderedDict([('description', 'The name identifying the credential'), ('type', 'string')])), ('type', OrderedDict([('description', "The credential's type."), ('type', 'string')])), ('username', OrderedDict([('description', 'The username for the credential.'), ('type', 'string')])), ('description', OrderedDict([('description', 'A long description of the credential.'), ('type', 'string')])), ('owner', OrderedDict([('description', 'The name of the user who this credential belongs to.'), ('type', 'string')])), ('remoteHostId', OrderedDict([('description', 'The ID of the remote host associated with this credential.'), ('type', 'integer')])), ('remoteHostName', OrderedDict([('description', 'The name of the remote host associated with this credential.'), ('type', 'string')])), ('createdAt', OrderedDict([('description', 'The creation time for this credential.'), ('type', 'string'), ('format', 'time')])), ('updatedAt', OrderedDict([('description', 'The last modification time for this credential.'), ('type', 'string'), ('format', 'time')]))]))]))]))]))])  # noqa: E501
     x = _resources.doc_from_responses(responses)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov flake8
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
cbor2==5.4.2.post1
certifi==2021.5.30
charset-normalizer==2.0.12
-e git+https://github.com/civisanalytics/civis-python.git@dd27663851748fdfac7a29b7fc4cb496b1ba38b3#egg=civis
Click==7.0
cloudpickle==1.6.0
coverage==6.2
flake8==5.0.4
idna==3.10
importlib-metadata==4.2.0
iniconfig==1.1.1
joblib==0.14.1
jsonref==0.2
jsonschema==3.0.0
mccabe==0.7.0
packaging==21.3
pluggy==1.0.0
pubnub==4.8.1
py==1.11.0
pycodestyle==2.9.1
pycryptodomex==3.21.0
pyflakes==2.5.0
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
pytest-cov==4.0.0
PyYAML==5.4.1
requests==2.27.1
six==1.17.0
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: civis-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - cbor2==5.4.2.post1
      - charset-normalizer==2.0.12
      - click==7.0
      - cloudpickle==1.6.0
      - coverage==6.2
      - flake8==5.0.4
      - idna==3.10
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - joblib==0.14.1
      - jsonref==0.2
      - jsonschema==3.0.0
      - mccabe==0.7.0
      - packaging==21.3
      - pluggy==1.0.0
      - pubnub==4.8.1
      - py==1.11.0
      - pycodestyle==2.9.1
      - pycryptodomex==3.21.0
      - pyflakes==2.5.0
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pyyaml==5.4.1
      - requests==2.27.1
      - six==1.17.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/civis-python

civis/tests/test_resources.py::test_deprecated_notice civis/tests/test_resources.py::test_deprecated_notice_handles_none
civis/tests/test_resources.py::test_create_method_iterator_kwarg civis/tests/test_resources.py::test_create_method_no_iterator_kwarg civis/tests/test_resources.py::test_exclude_resource civis/tests/test_resources.py::test_property_type civis/tests/test_resources.py::test_name_and_type_doc civis/tests/test_resources.py::test_docs_from_property civis/tests/test_resources.py::test_docs_from_properties civis/tests/test_resources.py::test_doc_from_responses civis/tests/test_resources.py::test_iterable_method civis/tests/test_resources.py::test_split_method_params civis/tests/test_resources.py::test_parse_param civis/tests/test_resources.py::test_parse_params civis/tests/test_resources.py::test_parse_param_body civis/tests/test_resources.py::test_parse_method_name civis/tests/test_resources.py::test_duplicate_names_generated_from_api_spec civis/tests/test_resources.py::test_expired_api_key civis/tests/test_resources.py::test_create_method_unexpected_kwargs civis/tests/test_resources.py::test_create_method_too_many_pos_args civis/tests/test_resources.py::test_create_method_multiple_values civis/tests/test_resources.py::test_create_method_keyword_only civis/tests/test_resources.py::test_generate_classes_maybe_cached civis/tests/test_resources.py::test_parse_api_spec_names civis/tests/test_resources.py::test_add_no_underscore_compatibility
civis/resources/_resources.py
civis/resources/_resources.py