pyfunda 3.1.0__tar.gz → 3.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {pyfunda-3.1.0 → pyfunda-3.1.2}/PKG-INFO +9 -5
  2. {pyfunda-3.1.0 → pyfunda-3.1.2}/README.md +6 -2
  3. pyfunda-3.1.0/funda/autocomplete.py → pyfunda-3.1.2/funda/_autocomplete.py +2 -2
  4. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/constants.py +1 -1
  5. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/funda.py +31 -6
  6. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/headers.py +2 -1
  7. {pyfunda-3.1.0 → pyfunda-3.1.2}/pyproject.toml +22 -3
  8. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_autocomplete.py +5 -5
  9. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_client.py +24 -2
  10. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_live.py +20 -0
  11. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_search.py +3 -2
  12. {pyfunda-3.1.0 → pyfunda-3.1.2}/.dockerignore +0 -0
  13. {pyfunda-3.1.0 → pyfunda-3.1.2}/.github/FUNDING.yml +0 -0
  14. {pyfunda-3.1.0 → pyfunda-3.1.2}/.github/workflows/publish.yml +0 -0
  15. {pyfunda-3.1.0 → pyfunda-3.1.2}/.gitignore +0 -0
  16. {pyfunda-3.1.0 → pyfunda-3.1.2}/Dockerfile +0 -0
  17. {pyfunda-3.1.0 → pyfunda-3.1.2}/LICENSE +0 -0
  18. {pyfunda-3.1.0 → pyfunda-3.1.2}/docs/API.md +0 -0
  19. {pyfunda-3.1.0 → pyfunda-3.1.2}/docs/ARCHITECTURE.md +0 -0
  20. {pyfunda-3.1.0 → pyfunda-3.1.2}/docs/DEVELOPMENT.md +0 -0
  21. {pyfunda-3.1.0 → pyfunda-3.1.2}/docs/EXAMPLES.md +0 -0
  22. {pyfunda-3.1.0 → pyfunda-3.1.2}/docs/README.md +0 -0
  23. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/almere_age_rank.py +0 -0
  24. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/analysis.ipynb +0 -0
  25. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/batch_details.py +0 -0
  26. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/broker_due_diligence.py +0 -0
  27. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/enrichment_export.py +0 -0
  28. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/export_to_csv.py +0 -0
  29. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/full_api_walkthrough.py +0 -0
  30. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/neighborhood_market_snapshot.py +0 -0
  31. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/new_listings_alert.py +0 -0
  32. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/poll_new_listings.py +0 -0
  33. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/price_history.py +0 -0
  34. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/price_tracker.py +0 -0
  35. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/search_sold.py +0 -0
  36. {pyfunda-3.1.0 → pyfunda-3.1.2}/examples/similar_sales_comp.py +0 -0
  37. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/__init__.py +0 -0
  38. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_autocomplete_parser.py +0 -0
  39. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_detail_parser.py +0 -0
  40. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_enrichment_parser.py +0 -0
  41. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_parallel.py +0 -0
  42. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_parse_helpers.py +0 -0
  43. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_price_history_parser.py +0 -0
  44. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_search_parser.py +0 -0
  45. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/_transport.py +0 -0
  46. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/exceptions.py +0 -0
  47. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/listing.py +0 -0
  48. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/models.py +0 -0
  49. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/parsing.py +0 -0
  50. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/py.typed +0 -0
  51. {pyfunda-3.1.0 → pyfunda-3.1.2}/funda/search.py +0 -0
  52. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/__init__.py +0 -0
  53. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_enrichment_parser.py +0 -0
  54. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_models.py +0 -0
  55. {pyfunda-3.1.0 → pyfunda-3.1.2}/tests/test_transport_parallel.py +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyfunda
3
- Version: 3.1.0
4
- Summary: Python API for Funda.nl real estate listings
3
+ Version: 3.1.2
4
+ Summary: Python API wrapper for Funda.nl, the Dutch real estate platform. Reverse-engineered mobile API client, no scraping, no Selenium, no CAPTCHA.
5
5
  Project-URL: Homepage, https://github.com/0xMH/pyfunda
6
6
  Project-URL: Repository, https://github.com/0xMH/pyfunda
7
7
  Project-URL: Issues, https://github.com/0xMH/pyfunda/issues
8
8
  Author: 0xMH
9
9
  License-Expression: AGPL-3.0-or-later
10
10
  License-File: LICENSE
11
- Keywords: api,funda,housing,netherlands,real-estate,scraper
11
+ Keywords: api,api-wrapper,client,dutch,funda,funda-api,funda-nl,funda-scraper,housing,housing-api,mobile-api,netherlands,real-estate,real-estate-api,rest-api,reverse-engineering,scraper,sdk
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
@@ -29,9 +29,13 @@ Description-Content-Type: text/markdown
29
29
  [![Python versions](https://img.shields.io/pypi/pyversions/pyfunda)](https://pypi.org/project/pyfunda/)
30
30
  [![License](https://img.shields.io/pypi/l/pyfunda)](https://github.com/0xMH/pyfunda/blob/main/LICENSE)
31
31
 
32
- The only working real Python API for Funda ([funda.nl](https://www.funda.nl)) -- the Netherlands' largest real estate platform.
32
+ **pyfunda** is a Python API wrapper for [Funda.nl](https://www.funda.nl), the Netherlands' largest Dutch real estate platform. It talks to Funda's reverse engineered mobile JSON API, so you get clean typed objects for listings, prices, media, brokers, and price history without HTML scraping, Selenium, a headless browser, or CAPTCHA solving.
33
33
 
34
- > If you find this useful, consider giving it a star -- it helps others discover the project.
34
+ Funda has no public developer API. pyfunda is the only working opensource Python client that hits Funda's app facing `*.funda.io` endpoints directly, the same ones the official Android app uses.
35
+
36
+ Use pyfunda as a Funda API client or Funda Python SDK to fetch Dutch property listings, run search queries by city and price, pull listing detail and media, get broker info and reviews, read price history, and stream new listings. If you have been looking for a working fundascraper alternative or a Netherlands housing API, this is the only Python wrapper hitting the same `*.funda.io` endpoints the Funda Android app uses.
37
+
38
+ > If you find this useful, consider giving it a star, it helps others discover the project.
35
39
 
36
40
  [![Star History Chart](https://api.star-history.com/svg?repos=0xMH/pyfunda&type=Date)](https://star-history.com/#0xMH/pyfunda&Date)
37
41
 
@@ -4,9 +4,13 @@
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/pyfunda)](https://pypi.org/project/pyfunda/)
5
5
  [![License](https://img.shields.io/pypi/l/pyfunda)](https://github.com/0xMH/pyfunda/blob/main/LICENSE)
6
6
 
7
- The only working real Python API for Funda ([funda.nl](https://www.funda.nl)) -- the Netherlands' largest real estate platform.
7
+ **pyfunda** is a Python API wrapper for [Funda.nl](https://www.funda.nl), the Netherlands' largest Dutch real estate platform. It talks to Funda's reverse engineered mobile JSON API, so you get clean typed objects for listings, prices, media, brokers, and price history without HTML scraping, Selenium, a headless browser, or CAPTCHA solving.
8
8
 
9
- > If you find this useful, consider giving it a star -- it helps others discover the project.
9
+ Funda has no public developer API. pyfunda is the only working opensource Python client that hits Funda's app facing `*.funda.io` endpoints directly, the same ones the official Android app uses.
10
+
11
+ Use pyfunda as a Funda API client or Funda Python SDK to fetch Dutch property listings, run search queries by city and price, pull listing detail and media, get broker info and reviews, read price history, and stream new listings. If you have been looking for a working fundascraper alternative or a Netherlands housing API, this is the only Python wrapper hitting the same `*.funda.io` endpoints the Funda Android app uses.
12
+
13
+ > If you find this useful, consider giving it a star, it helps others discover the project.
10
14
 
11
15
  [![Star History Chart](https://api.star-history.com/svg?repos=0xMH/pyfunda&type=Date)](https://star-history.com/#0xMH/pyfunda&Date)
12
16
 
@@ -1,4 +1,4 @@
1
- """Autocomplete payload construction."""
1
+ """Internal autocomplete payload construction."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -14,7 +14,7 @@ from funda.models import JsonDict
14
14
 
15
15
 
16
16
  @dataclass(frozen=True, slots=True)
17
- class _LocationAutocomplete:
17
+ class LocationAutocomplete:
18
18
  value: str
19
19
  timeout: str = "3s"
20
20
  size: int = 10
@@ -36,7 +36,7 @@ API_BROKER_REVIEWS = (
36
36
  )
37
37
 
38
38
  SEARCH_INDEX = "listings-wonen-searcher-alias-prod"
39
- SEARCH_TEMPLATE_ID = "search_result_20250805"
39
+ SEARCH_TEMPLATE_ID = "search_result_20260227"
40
40
  LOCATION_AUTOCOMPLETE_TEMPLATE_ID = "searchbox_20250805"
41
41
  LOCATION_AUTOCOMPLETE_AREA_TYPES = (
42
42
  "country",
@@ -28,7 +28,7 @@ from funda.constants import (
28
28
  PAGE_SIZE,
29
29
  )
30
30
  from funda.exceptions import FundaRequestError, ListingNotFound, PriceHistoryError, SearchError
31
- from funda.autocomplete import _LocationAutocomplete
31
+ from funda._autocomplete import LocationAutocomplete
32
32
  from funda.listing import Listing, LocationSuggestion, PriceHistory
33
33
  from funda.models import JsonDict
34
34
  from funda.parsing import (
@@ -63,7 +63,9 @@ class Funda:
63
63
 
64
64
  timeout: int = 30
65
65
  max_retries: int = DEFAULT_MAX_RETRIES
66
- retry_backoff: float = 0.1
66
+ retry_backoff: float = 0.5
67
+ min_request_interval: float = 0.0
68
+ adaptive_throttle: bool = True
67
69
 
68
70
  _transport: _FundaTransport = field(init=False, repr=False)
69
71
  _parallel_runner: _ParallelRunner["Funda"] | None = field(default=None, init=False, repr=False)
@@ -73,6 +75,8 @@ class Funda:
73
75
  timeout=self.timeout,
74
76
  max_retries=self.max_retries,
75
77
  retry_backoff=self.retry_backoff,
78
+ min_request_interval=self.min_request_interval,
79
+ adaptive_throttle=self.adaptive_throttle,
76
80
  )
77
81
 
78
82
  def close(self) -> None:
@@ -84,7 +88,7 @@ class Funda:
84
88
  def __enter__(self) -> "Funda":
85
89
  return self
86
90
 
87
- def __exit__(self, *args) -> None:
91
+ def __exit__(self, *_) -> None:
88
92
  self.close()
89
93
 
90
94
  def listing(self, listing_id: int | str) -> Listing:
@@ -130,7 +134,7 @@ class Funda:
130
134
  sort: Sequence[Any] | None = None,
131
135
  ) -> list[LocationSuggestion]:
132
136
  """Suggest Funda location identifiers for search-box text."""
133
- autocomplete = _LocationAutocomplete(
137
+ autocomplete = LocationAutocomplete(
134
138
  value=value,
135
139
  size=size,
136
140
  timeout=timeout,
@@ -423,7 +427,9 @@ class Funda:
423
427
  for attempt in range(3):
424
428
  response = self._transport.post(API_SEARCH, profile="search", data=payload)
425
429
  if response.status_code == 200:
426
- return response.json()
430
+ data = response.json()
431
+ self._raise_for_msearch_error(data)
432
+ return data
427
433
  if response.status_code == 400 and attempt < 2:
428
434
  time.sleep(0.1 * (attempt + 1))
429
435
  continue
@@ -434,7 +440,24 @@ class Funda:
434
440
 
435
441
  raise SearchError("Search failed without a response")
436
442
 
437
- def _autocomplete(self, autocomplete: _LocationAutocomplete) -> JsonDict:
443
+ @staticmethod
444
+ def _raise_for_msearch_error(data: JsonDict) -> None:
445
+ """Surface per-query errors that _msearch reports inside an HTTP 200 body.
446
+
447
+ The _msearch/template endpoint answers with HTTP 200 even when the
448
+ individual query fails (for example a rotated/stale search template),
449
+ embedding the failure as ``responses[].error``. Without this check such
450
+ breakage is silently parsed as zero results.
451
+ """
452
+ responses = data.get("responses") if isinstance(data, dict) else None
453
+ for entry in responses or []:
454
+ if isinstance(entry, dict) and entry.get("error"):
455
+ error = entry["error"]
456
+ reason = error.get("reason") if isinstance(error, dict) else str(error)
457
+ status = entry.get("status", "unknown")
458
+ raise SearchError(f"Search failed (status {status}): {reason}")
459
+
460
+ def _autocomplete(self, autocomplete: LocationAutocomplete) -> JsonDict:
438
461
  payload = autocomplete.to_payload()
439
462
  for attempt in range(3):
440
463
  response = self._transport.post(
@@ -484,6 +507,8 @@ class Funda:
484
507
  timeout=self.timeout,
485
508
  max_retries=self.max_retries,
486
509
  retry_backoff=self.retry_backoff,
510
+ min_request_interval=self.min_request_interval,
511
+ adaptive_throttle=self.adaptive_throttle,
487
512
  )
488
513
 
489
514
  def _listing_id_from_input(self, listing_id: int | str) -> str:
@@ -19,7 +19,7 @@ def make_headers(profile: RequestProfile = "listing") -> HeaderList:
19
19
  tid = hex(int(time.time()))[2:] + "00000000"
20
20
 
21
21
  headers = [
22
- ("user-agent", "Dart/3.9 (dart:io)"),
22
+ ("user-agent", "Dart/3.11 (dart:io)"),
23
23
  ("x-datadog-sampling-priority", "0"),
24
24
  ("x-datadog-origin", "rum"),
25
25
  ("tracestate", f"dd=s:0;o:rum;p:{parent_id}"),
@@ -39,6 +39,7 @@ def make_headers(profile: RequestProfile = "listing") -> HeaderList:
39
39
  headers.extend(
40
40
  [
41
41
  ("x-funda-app-platform", "android"),
42
+ ("x-funda-app-version", "7.14.11"),
42
43
  ("content-type", "application/json"),
43
44
  ]
44
45
  )
@@ -4,15 +4,34 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pyfunda"
7
- version = "3.1.0"
8
- description = "Python API for Funda.nl real estate listings"
7
+ version = "3.1.2"
8
+ description = "Python API wrapper for Funda.nl, the Dutch real estate platform. Reverse-engineered mobile API client, no scraping, no Selenium, no CAPTCHA."
9
9
  readme = "README.md"
10
10
  license = "AGPL-3.0-or-later"
11
11
  requires-python = ">=3.10"
12
12
  authors = [
13
13
  { name = "0xMH" }
14
14
  ]
15
- keywords = ["funda", "real-estate", "netherlands", "housing", "api", "scraper"]
15
+ keywords = [
16
+ "funda",
17
+ "funda-api",
18
+ "funda-nl",
19
+ "funda-scraper",
20
+ "real-estate",
21
+ "real-estate-api",
22
+ "netherlands",
23
+ "dutch",
24
+ "housing",
25
+ "housing-api",
26
+ "api",
27
+ "api-wrapper",
28
+ "rest-api",
29
+ "client",
30
+ "sdk",
31
+ "mobile-api",
32
+ "reverse-engineering",
33
+ "scraper",
34
+ ]
16
35
  classifiers = [
17
36
  "Development Status :: 4 - Beta",
18
37
  "Intended Audience :: Developers",
@@ -1,6 +1,6 @@
1
1
  import unittest
2
2
 
3
- from funda.autocomplete import _LocationAutocomplete
3
+ from funda._autocomplete import LocationAutocomplete
4
4
  from funda.constants import (
5
5
  LOCATION_AUTOCOMPLETE_AREA_TYPES,
6
6
  LOCATION_AUTOCOMPLETE_TEMPLATE_ID,
@@ -45,7 +45,7 @@ AUTOCOMPLETE_RESPONSE = {
45
45
 
46
46
  class AutocompleteTests(unittest.TestCase):
47
47
  def test_payload_matches_funda_searchbox_template(self) -> None:
48
- payload = _LocationAutocomplete("almere poor").to_payload()
48
+ payload = LocationAutocomplete("almere poor").to_payload()
49
49
 
50
50
  self.assertEqual(payload["id"], LOCATION_AUTOCOMPLETE_TEMPLATE_ID)
51
51
  self.assertEqual(payload["params"]["value"], "almere poor")
@@ -60,7 +60,7 @@ class AutocompleteTests(unittest.TestCase):
60
60
  )
61
61
 
62
62
  def test_payload_can_limit_area_types_for_vague_area_searches(self) -> None:
63
- payload = _LocationAutocomplete(
63
+ payload = LocationAutocomplete(
64
64
  "amsterdam west",
65
65
  area_types=("city", "municipality", "neighborhood", "wijk"),
66
66
  size=5,
@@ -74,9 +74,9 @@ class AutocompleteTests(unittest.TestCase):
74
74
 
75
75
  def test_invalid_payload_values_fail_before_network(self) -> None:
76
76
  with self.assertRaises(ValueError):
77
- _LocationAutocomplete("").to_payload()
77
+ LocationAutocomplete("").to_payload()
78
78
  with self.assertRaises(ValueError):
79
- _LocationAutocomplete("amsterdam", size=0).to_payload()
79
+ LocationAutocomplete("amsterdam", size=0).to_payload()
80
80
 
81
81
  def test_parse_location_suggestions_maps_geo_hits(self) -> None:
82
82
  suggestions = parse_location_suggestions(AUTOCOMPLETE_RESPONSE)
@@ -2,6 +2,8 @@ import unittest
2
2
  from unittest.mock import patch
3
3
 
4
4
  from funda import Funda, FundaRequestError, Listing, LocationSuggestion
5
+ from funda.constants import LOCATION_AUTOCOMPLETE_TEMPLATE_ID, SEARCH_TEMPLATE_ID
6
+ from funda.exceptions import SearchError
5
7
 
6
8
 
7
9
  class FakeResponse:
@@ -83,7 +85,27 @@ class FundaClientTests(unittest.TestCase):
83
85
  url, payload, json_data = client._transport.posts[0]
84
86
  self.assertIn("_msearch/template", url)
85
87
  self.assertIsNone(json_data)
86
- self.assertIn("search_result_", payload)
88
+ self.assertIn(SEARCH_TEMPLATE_ID, payload)
89
+
90
+ def test_search_raises_on_embedded_msearch_error(self) -> None:
91
+ # _msearch/template answers 200 even when the query fails (e.g. a
92
+ # stale search template), embedding the error inside the body. This
93
+ # must surface as an error rather than being parsed as zero results.
94
+ error_body = {
95
+ "responses": [
96
+ {
97
+ "error": {
98
+ "reason": "No mapping found for [placement_type] in order to sort on",
99
+ },
100
+ "status": 400,
101
+ }
102
+ ]
103
+ }
104
+ client = self.client(FakeResponse(200, error_body))
105
+
106
+ with self.assertRaises(SearchError) as ctx:
107
+ client.search("amsterdam")
108
+ self.assertIn("placement_type", str(ctx.exception))
87
109
 
88
110
  def test_autocomplete_posts_json_payload_and_parses_results(self) -> None:
89
111
  client = self.client(FakeResponse(200, {"hits": {"hits": []}}))
@@ -100,7 +122,7 @@ class FundaClientTests(unittest.TestCase):
100
122
  url, payload, json_data = client._transport.posts[0]
101
123
  self.assertIn("geo-wonen-alias-prod/_search/template", url)
102
124
  self.assertIsNone(payload)
103
- self.assertEqual(json_data["id"], "searchbox_20250805")
125
+ self.assertEqual(json_data["id"], LOCATION_AUTOCOMPLETE_TEMPLATE_ID)
104
126
  self.assertEqual(json_data["params"]["value"], "amsterdam west")
105
127
  self.assertEqual(json_data["params"]["size"], 5)
106
128
  self.assertEqual(
@@ -2,10 +2,30 @@ import os
2
2
  import unittest
3
3
 
4
4
  from funda import Funda
5
+ from funda.constants import SEARCH_TEMPLATE_ID
6
+ from funda.exceptions import SearchError
5
7
 
6
8
 
7
9
  @unittest.skipUnless(os.environ.get("PYFUNDA_LIVE") == "1", "set PYFUNDA_LIVE=1")
8
10
  class LiveFundaSmokeTests(unittest.TestCase):
11
+ def test_search_template_id_is_accepted_by_funda(self) -> None:
12
+ """Guard against Funda rotating the stored search template ID.
13
+
14
+ A stale SEARCH_TEMPLATE_ID makes every search fail server-side with an
15
+ HTTP 400, while the mocked unit tests keep passing. This isolates that
16
+ failure mode with a clear pointer to the constant that needs updating.
17
+ """
18
+ with Funda(timeout=30) as client:
19
+ try:
20
+ results = client.search("amsterdam")
21
+ except SearchError as exc:
22
+ self.fail(
23
+ f"Funda rejected search template {SEARCH_TEMPLATE_ID!r}: {exc}. "
24
+ "Update SEARCH_TEMPLATE_ID in funda/constants.py to the value "
25
+ "used by the current Funda app."
26
+ )
27
+ self.assertTrue(results, "search returned no listings for 'amsterdam'")
28
+
9
29
  def test_core_listing_search_and_parallel_paths(self) -> None:
10
30
  with Funda(timeout=30) as client:
11
31
  listing = client.listing(43117443)
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import unittest
3
3
 
4
+ from funda.constants import SEARCH_INDEX, SEARCH_TEMPLATE_ID
4
5
  from funda.search import _Search
5
6
 
6
7
 
@@ -65,8 +66,8 @@ class SearchTests(unittest.TestCase):
65
66
  lines = payload.splitlines()
66
67
 
67
68
  self.assertEqual(len(lines), 2)
68
- self.assertIn("listings-wonen-searcher", json.loads(lines[0])["index"])
69
- self.assertIn("search_result_", json.loads(lines[1])["id"])
69
+ self.assertEqual(json.loads(lines[0])["index"], SEARCH_INDEX)
70
+ self.assertEqual(json.loads(lines[1])["id"], SEARCH_TEMPLATE_ID)
70
71
 
71
72
 
72
73
  if __name__ == "__main__":
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes