Skip to content

Commit 5891ca2

Browse files
committed
delete unused item mapper API endpoint
1 parent dbde400 commit 5891ca2

3 files changed

Lines changed: 74 additions & 202 deletions

File tree

webtool/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ def time_this(func):
177177
import webtool.views.views_explorer # noqa: E402
178178
import webtool.views.api_standalone # noqa: E402
179179
import webtool.views.api_tool # noqa: E402
180-
import webtool.views.api_map_item # noqa: E402
181180

182181
app.register_blueprint(webtool.views.views_restart.component)
183182
app.register_blueprint(webtool.views.views_admin.component)
@@ -188,7 +187,6 @@ def time_this(func):
188187
app.register_blueprint(webtool.views.views_explorer.component)
189188
app.register_blueprint(webtool.views.api_standalone.component)
190189
app.register_blueprint(webtool.views.api_tool.component)
191-
app.register_blueprint(webtool.views.api_map_item.component)
192190

193191
@app.before_request
194192
def before_request():

webtool/views/api_map_item.py

Lines changed: 0 additions & 199 deletions
This file was deleted.

webtool/views/api_tool.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from flask_login import login_required, current_user
1515

1616
from webtool.lib.helpers import error, setting_required, parse_markdown
17-
from webtool.views.api_map_item import MissingMappedFieldEncoder
1817

1918
from common.lib.exceptions import QueryParametersException, JobNotFoundException, \
2019
QueryNeedsExplicitConfirmationException, QueryNeedsFurtherInputException, DataSetException
@@ -24,6 +23,7 @@
2423
from common.lib.helpers import UserInput, call_api
2524
from common.lib.user import User
2625
from backend.lib.worker import BasicWorker
26+
from common.lib.item_mapping import MissingMappedField
2727

2828
component = Blueprint("toolapi", __name__)
2929
api_ratelimit = current_app.limiter.shared_limit("3 per second", scope="api")
@@ -33,6 +33,21 @@
3333

3434
csv.field_size_limit(1024 * 1024 * 1024)
3535

36+
def _get_search_class(modules, datasource_id):
37+
"""
38+
Look up the search/import class for a datasource.
39+
40+
Abstracts the ModuleCollector convention where worker keys append a suffix
41+
to the datasource ID. Most use `-search`, some (e.g. twitter-import) use
42+
`-import`. Returns None if no matching worker is found.
43+
44+
TODO: ModuleCollector should expose this directly.
45+
"""
46+
return (
47+
modules.workers.get(f"{datasource_id}-search")
48+
or modules.workers.get(f"{datasource_id}-import")
49+
)
50+
3651
@component.route("/api/")
3752
@api_ratelimit
3853
def openapi_overview():
@@ -1415,6 +1430,64 @@ def export_packed_dataset(key=None, component=None):
14151430
else:
14161431
return error(406, error="Dataset component unknown")
14171432

1433+
@component.route("/api/datasources/")
1434+
@api_ratelimit
1435+
@current_app.openapi.endpoint("tool")
1436+
def list_datasources():
1437+
"""
1438+
List all available datasources with map_item support.
1439+
1440+
Returns all datasources that have a map_item function, including a flag
1441+
indicating if they're from Zeeschuimer. Caller can filter as needed.
1442+
1443+
:return: JSON object with array of datasource metadata
1444+
1445+
:return-schema: {
1446+
type=object,
1447+
properties={
1448+
datasources={
1449+
type=array,
1450+
items={
1451+
type=object,
1452+
properties={
1453+
id={type=string},
1454+
name={type=string},
1455+
has_map_item={type=boolean},
1456+
is_from_zeeschuimer={type=boolean}
1457+
}
1458+
}
1459+
}
1460+
}
1461+
}
1462+
"""
1463+
1464+
available = []
1465+
for datasource_id, metadata in g.modules.datasources.items():
1466+
search_class = _get_search_class(g.modules, datasource_id)
1467+
if not search_class:
1468+
continue
1469+
1470+
available.append({
1471+
"id": datasource_id,
1472+
"name": metadata.get("name", datasource_id),
1473+
"is_from_zeeschuimer": getattr(search_class, "is_from_zeeschuimer", False),
1474+
"has_map_item": hasattr(search_class, "map_item") and callable(getattr(search_class, "map_item"))
1475+
})
1476+
1477+
return jsonify({
1478+
"datasources": sorted(available, key=lambda x: x["id"])
1479+
}), 200
1480+
1481+
class MissingMappedFieldEncoder(json.JSONEncoder):
1482+
"""Custom JSON encoder to serialize MissingMappedField objects."""
1483+
1484+
def default(self, obj):
1485+
if isinstance(obj, MissingMappedField):
1486+
return {
1487+
"__missing": True,
1488+
"value": obj.value
1489+
}
1490+
return super().default(obj)
14181491

14191492
@component.route("/api/dataset/<string:key>/items/", methods=["GET", "HEAD"])
14201493
@api_ratelimit

0 commit comments

Comments
 (0)