python-openpublictransport 0.1.16__tar.gz → 0.1.17__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.
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/PKG-INFO +1 -1
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/pyproject.toml +1 -1
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/efa_base.py +6 -2
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/python_openpublictransport.egg-info/PKG-INFO +1 -1
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/python_openpublictransport.egg-info/SOURCES.txt +1 -0
- python_openpublictransport-0.1.17/tests/test_efa_mimetype.py +87 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/setup.cfg +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/__init__.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/const.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/data/uk_stations.json +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/exceptions.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/models.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/parsers.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/__init__.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/avv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/bart.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/beg.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/bsvg.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/bvg.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/dart.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/db.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/ding.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/entur.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/fptf_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/gtfsde.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/hafas_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/hafas_mgate_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/hvv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/hvv_gti.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/irishrail.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/kvv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/mobiliteit_lu.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/mvv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/national_rail.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/ns.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/nta.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/nvbw.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/nwl.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/oebb.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/otp.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/otp_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/otp_custom.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/rejseplanen.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/rmv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/rvv.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/sbb.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/tpg.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/trafiklab.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/transitous.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/trias_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vagfr.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vbn.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vgn.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vrn.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vrr.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vvo.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/providers/vvs.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/openpublictransport/py.typed +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/python_openpublictransport.egg-info/dependency_links.txt +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/python_openpublictransport.egg-info/requires.txt +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/src/python_openpublictransport.egg-info/top_level.txt +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_efa_platform.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_entur.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hafas_base.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hafas_mgate.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hvv_gti.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_national_rail.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_national_rail_parse.py +0 -0
- {python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_national_rail_static.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-openpublictransport"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.17"
|
|
8
8
|
description = "Python library for public transport APIs (EFA, OTP2, TRIAS, FPTF, HAFAS, GTFS-RT)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -154,7 +154,9 @@ class EFABaseProvider(BaseProvider):
|
|
|
154
154
|
async with self.session.get(url, headers=headers, timeout=aiohttp.ClientTimeout(total=10)) as response:
|
|
155
155
|
if response.status == 200:
|
|
156
156
|
try:
|
|
157
|
-
|
|
157
|
+
# content_type=None: some deployments (VGN) send RapidJSON
|
|
158
|
+
# payloads with a "text/xml;;charset=utf-8" header (issue #79).
|
|
159
|
+
json_data = await response.json(content_type=None)
|
|
158
160
|
if not isinstance(json_data, dict):
|
|
159
161
|
_LOGGER.warning("%s API returned non-dict response: %s", name, type(json_data))
|
|
160
162
|
return None
|
|
@@ -251,7 +253,9 @@ class EFABaseProvider(BaseProvider):
|
|
|
251
253
|
async with self.session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:
|
|
252
254
|
if response.status == 200:
|
|
253
255
|
try:
|
|
254
|
-
|
|
256
|
+
# content_type=None: some deployments (VGN) send RapidJSON
|
|
257
|
+
# payloads with a "text/xml;;charset=utf-8" header (issue #79).
|
|
258
|
+
data = await response.json(content_type=None)
|
|
255
259
|
except (ValueError, aiohttp.ContentTypeError) as e:
|
|
256
260
|
_LOGGER.error("Invalid JSON response from %s API: %s", name, e)
|
|
257
261
|
return []
|
|
@@ -57,6 +57,7 @@ src/python_openpublictransport.egg-info/SOURCES.txt
|
|
|
57
57
|
src/python_openpublictransport.egg-info/dependency_links.txt
|
|
58
58
|
src/python_openpublictransport.egg-info/requires.txt
|
|
59
59
|
src/python_openpublictransport.egg-info/top_level.txt
|
|
60
|
+
tests/test_efa_mimetype.py
|
|
60
61
|
tests/test_efa_platform.py
|
|
61
62
|
tests/test_entur.py
|
|
62
63
|
tests/test_hafas_base.py
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""EFA endpoints that mislabel their JSON payload (issue #79).
|
|
2
|
+
|
|
3
|
+
VGN answers ``outputFormat=RapidJSON`` requests with
|
|
4
|
+
``Content-Type: text/xml;;charset=utf-8``. aiohttp raises ``ContentTypeError``
|
|
5
|
+
for that unless the caller passes ``content_type=None``, so station search
|
|
6
|
+
returned "no results found" even though the body was valid JSON.
|
|
7
|
+
|
|
8
|
+
The fake response below mimics aiohttp: it raises unless the strict content
|
|
9
|
+
type check is disabled — a mock that accepts the kwarg either way cannot catch
|
|
10
|
+
this regression.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import aiohttp
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
from openpublictransport.providers.vgn import VGNProvider
|
|
17
|
+
|
|
18
|
+
STOPFINDER_PAYLOAD = {
|
|
19
|
+
"locations": [
|
|
20
|
+
{
|
|
21
|
+
"id": "de:09564:704",
|
|
22
|
+
"name": "Nürnberg, Rathenauplatz",
|
|
23
|
+
"disassembledName": "Rathenauplatz, Nürnberg",
|
|
24
|
+
"type": "stop",
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
DM_PAYLOAD = {
|
|
30
|
+
"stopEvents": [
|
|
31
|
+
{
|
|
32
|
+
"departureTimePlanned": "2026-08-08T10:00:00Z",
|
|
33
|
+
"transportation": {"number": "U2", "product": {"class": 2, "name": "U-Bahn"}},
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class _XmlMimeResponse:
|
|
40
|
+
"""Response whose body is JSON but whose header claims text/xml."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, payload, status=200):
|
|
43
|
+
self.status = status
|
|
44
|
+
self._payload = payload
|
|
45
|
+
|
|
46
|
+
async def json(self, content_type="application/json"):
|
|
47
|
+
if content_type is not None:
|
|
48
|
+
raise aiohttp.ContentTypeError(
|
|
49
|
+
None,
|
|
50
|
+
(),
|
|
51
|
+
message=("Attempt to decode JSON with unexpected mimetype: text/xml;;charset=utf-8"),
|
|
52
|
+
)
|
|
53
|
+
return self._payload
|
|
54
|
+
|
|
55
|
+
async def __aenter__(self):
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
async def __aexit__(self, *exc):
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class _FakeSession:
|
|
63
|
+
def __init__(self, payload):
|
|
64
|
+
self._payload = payload
|
|
65
|
+
self.urls = []
|
|
66
|
+
|
|
67
|
+
def get(self, url, headers=None, timeout=None):
|
|
68
|
+
self.urls.append(url)
|
|
69
|
+
return _XmlMimeResponse(self._payload)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@pytest.mark.asyncio
|
|
73
|
+
async def test_search_stops_accepts_xml_mimetype():
|
|
74
|
+
session = _FakeSession(STOPFINDER_PAYLOAD)
|
|
75
|
+
results = await VGNProvider(session).search_stops("Rathenauplatz, Nürnberg")
|
|
76
|
+
|
|
77
|
+
assert [r["id"] for r in results] == ["de:09564:704"]
|
|
78
|
+
assert results[0]["place"] == "Nürnberg"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.mark.asyncio
|
|
82
|
+
async def test_fetch_departures_accepts_xml_mimetype():
|
|
83
|
+
session = _FakeSession(DM_PAYLOAD)
|
|
84
|
+
data = await VGNProvider(session).fetch_departures("de:09564:704", "", "", 10)
|
|
85
|
+
|
|
86
|
+
assert data is not None
|
|
87
|
+
assert len(data["stopEvents"]) == 1
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_efa_platform.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hafas_base.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hafas_mgate.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_hvv_gti.py
RENAMED
|
File without changes
|
{python_openpublictransport-0.1.16 → python_openpublictransport-0.1.17}/tests/test_national_rail.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|