JasonStoltz: Hey @CorrosiveKid, thank you for the contribution. Before we can merge this, we require that you sign a CLA.
CorrosiveKid: > Hey @CorrosiveKid, thank you for the contribution. Before we can merge this, we require that you sign a CLA: https://www.elastic.co/contributor-agreement.

Done!
diff --git a/README.md b/README.md
index 297cd83..5334f63 100644
--- a/README.md
+++ b/README.md
@@ -145,6 +145,26 @@ The client can be configured to use a managed deploy by adjusting the `base_endp
 [{'id': 'INscMGmhmX4','result': True}]
 ```
 
+### Get Schema
+
+```python
+>>> engine_name = 'favorite-videos'
+>>> client.get_schema(engine_name)
+{'name':'text', 'square_km': 'number', 'square_mi': 'text'}
+```
+
+### Create/Update Schema
+
+```python
+>>> engine_name = 'favorite-videos'
+>>> client.update_schema(engine_name, {'square_km': 'text'})
+{'square_km': 'text'}
+>>> client.update_schema(engine_name, {'square_mi': 'text'})
+{'square_km': 'text', 'square_mi': 'text'}
+>>> client.update_schema(engine_name, {'square_km': 'number'})
+{'square_km': 'number', 'square_mi': 'text'}
+```
+
 ### List Engines
 
 ```python
diff --git a/setup.py b/setup.py
index 9d422f4..3452647 100644
--- a/setup.py
+++ b/setup.py
@@ -18,6 +18,7 @@ setup(
     version=about['__version__'],
     description=about['__description__'],
     long_description=long_description,
+    long_description_content_type='text/markdown',
     url=about['__url__'],
     author=about['__author__'],
     author_email=about['__author_email__'],
diff --git a/swiftype_app_search/client.py b/swiftype_app_search/client.py
index 92e2dd7..7022a27 100644
--- a/swiftype_app_search/client.py
+++ b/swiftype_app_search/client.py
@@ -107,6 +107,28 @@ class Client:
         data = json.dumps(document_ids)
         return self.swiftype_session.request('delete', endpoint, data=data)
 
+    def get_schema(self, engine_name):
+        """
+        Get current schema for an engine.
+
+        :param engine_name: Name of engine.
+        :return: Schema.
+        """
+        endpoint = "engines/{}/schema".format(engine_name)
+        return self.swiftype_session.request('get', endpoint)
+
+    def update_schema(self, engine_name, schema):
+        """
+        Create new schema fields or update the fields if they already exists.
+
+        :param engine_name: Name of engine.
+        :param schema: Schema to be updated as dict.
+        :return: Updated schema.
+        """
+        endpoint = "engines/{}/schema".format(engine_name)
+        data = json.dumps(schema)
+        return self.swiftype_session.request('post', endpoint, data=data)
+
     def list_engines(self, current=1, size=20):
         """
         Lists engines that the api key has access to.

Client should be able to get and create/update engine schema
The python client should have the ability to get the current schema of an engine, or create/update new schema fields on an engine using the follwing app search endpoints.

`GET /api/as/v1/engines/{ENGINE_NAME}/schema`
`POST /api/as/v1/engines/{ENGINE_NAME}/schema`
diff --git a/tests/test_client.py b/tests/test_client.py
index 66c9bfd..3babf11 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -136,6 +136,39 @@ class TestClient(TestCase):
             response = self.client.destroy_documents(self.engine_name, [id])
             self.assertEqual(response, expected_return)
 
+    def test_get_schema(self):
+        expected_return = {
+            'square_km': 'text'
+        }
+
+        with requests_mock.Mocker() as m:
+            url = "{}/engines/{}/schema".format(self.client.swiftype_session.base_url, self.engine_name)
+            m.register_uri('GET',
+                url,
+                json=expected_return,
+                status_code=200
+            )
+
+            response = self.client.get_schema(self.engine_name)
+            self.assertEqual(response, expected_return)
+
+    def test_update_schema(self):
+        expected_return = {
+            'square_mi': 'number',
+            'square_km': 'number'
+        }
+
+        with requests_mock.Mocker() as m:
+            url = "{}/engines/{}/schema".format(self.client.swiftype_session.base_url, self.engine_name)
+            m.register_uri('POST',
+                url,
+                json=expected_return,
+                status_code=200
+            )
+
+            response = self.client.update_schema(self.engine_name, expected_return)
+            self.assertEqual(response, expected_return)
+
     def test_list_engines(self):
         expected_return = [
             { 'name': 'myawesomeengine' }

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest requests_mock
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
charset-normalizer==3.4.1
exceptiongroup==1.2.2
idna==3.10
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
PyJWT==2.10.1
pytest==8.3.5
requests==2.32.3
requests-mock==1.12.1
-e git+https://github.com/swiftype/swiftype-app-search-python.git@0cdae2c7cb6ea259f8c11269adf91ddd052c2bdf#egg=swiftype_app_search
tomli==2.2.1
urllib3==2.3.0

name: swiftype-app-search-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
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pyjwt==2.10.1
      - pytest==8.3.5
      - requests==2.32.3
      - requests-mock==1.12.1
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/swiftype-app-search-python

tests/test_client.py::TestClient::test_get_schema tests/test_client.py::TestClient::test_update_schema
tests/test_client.py::TestClient::test_click tests/test_client.py::TestClient::test_create_engine tests/test_client.py::TestClient::test_deprecated_init_support_with_new_names tests/test_client.py::TestClient::test_deprecated_init_support_with_old_names tests/test_client.py::TestClient::test_deprecated_init_support_with_positional tests/test_client.py::TestClient::test_destroy_documents tests/test_client.py::TestClient::test_destroy_engine tests/test_client.py::TestClient::test_get_documents tests/test_client.py::TestClient::test_get_engine tests/test_client.py::TestClient::test_host_identifier_is_optional tests/test_client.py::TestClient::test_index_document_no_error_key_in_response tests/test_client.py::TestClient::test_index_document_processing_error tests/test_client.py::TestClient::test_index_documents tests/test_client.py::TestClient::test_list_documents tests/test_client.py::TestClient::test_list_engines tests/test_client.py::TestClient::test_list_engines_with_paging tests/test_client.py::TestClient::test_multi_search tests/test_client.py::TestClient::test_query_suggestion tests/test_client.py::TestClient::test_search tests/test_client.py::TestClient::test_update_documents
setup.py README.md swiftype_app_search/client.py
setup.py README.md swiftype_app_search/client.py