Skip to content

Commit bf22847

Browse files
authored
feat: support feed stable ids as request parameter in the GBFS validator batch function (#1306)
1 parent 0e6d2f3 commit bf22847

File tree

3 files changed

+80
-6
lines changed

3 files changed

+80
-6
lines changed

functions-python/gbfs_validator/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The message published by the batch function to the Pub/Sub topic follows this fo
3030

3131
### Functionality Details
3232

33-
- **`gbfs-validator-batch`**: Triggered per execution ID, this function iterates over all GBFS feeds, preparing and publishing individual messages to the Pub/Sub topic.
33+
- **`gbfs-validator-batch`**: Triggered per execution ID, when the request is a POST request with a JSON body containing `feed_stable_ids`, it publishes events related to only those feeds. Otherwise, it publishes avents of all feeds to the Pub/Sub topic.
3434
- **`gbfs-validator-pubsub`**: Triggered per feed, this function performs the following steps:
3535
1. **Access the autodiscovery URL and update versions**: The function accesses the autodiscovery URL to update the **GBFSVersions** table.
3636
2. **Measure latency and validate the feed**: For each version, the function measures the response latency and validates the feed. The validation summary is stored in GCP, and the total error count is extracted and saved in the **GBFSValidationReport**.
@@ -46,6 +46,13 @@ The `gbfs-validator-batch` function requires the following environment variables
4646
- **`PROJECT_ID`**: The Google Cloud Project ID used to construct the full topic path.
4747
- **`FEEDS_DATABASE_URL`**: The database connection string for accessing the GBFS feeds.
4848

49+
Optional request body parameters for the batch function:
50+
```json
51+
{
52+
"feed_stable_ids": ["feed_id_1", "feed_id_2"]
53+
}
54+
```
55+
4956
### Pub/Sub Function Environment Variables
5057

5158
The `gbfs-validator-pubsub` function requires the following environment variables:

functions-python/gbfs_validator/src/main.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ def gbfs_validator_pubsub(cloud_event: CloudEvent):
101101

102102
@with_db_session
103103
@functions_framework.http
104-
def gbfs_validator_batch(_, db_session: Session):
104+
def gbfs_validator_batch(request, db_session: Session):
105105
"""
106-
HTTP Cloud Function to trigger the GBFS Validator function for multiple datasets.
106+
HTTP Cloud Function to trigger the GBFS Validator function for multiple datasets.
107+
When the request is a POST request with a JSON body containing `feed_stable_ids`,
108+
it processes only those feeds. Otherwise, it processes all feeds in the database.
107109
@param _: The request object.
108110
@return: The response of the function.
109111
"""
@@ -113,9 +115,25 @@ def gbfs_validator_batch(_, db_session: Session):
113115
logging.error("PUBSUB_TOPIC_NAME environment variable not set.")
114116
return "PUBSUB_TOPIC_NAME environment variable not set.", 500
115117

116-
# Get all GBFS feeds from the database
117118
try:
118-
gbfs_feeds = fetch_all_gbfs_feeds(db_session)
119+
feed_stable_ids = None
120+
if request and request.method == "POST" and request.is_json:
121+
request_json = request.get_json()
122+
feed_stable_ids = (
123+
request_json.get("feed_stable_ids") if request_json else None
124+
)
125+
else:
126+
logging.info("Request body not provided or not a valid JSON.")
127+
except Exception as e:
128+
logging.error("Error parsing request body: %s", e)
129+
return "Invalid request body.", 400
130+
131+
try:
132+
if feed_stable_ids:
133+
gbfs_feeds = fetch_gbfs_feeds_by_stable_ids(db_session, feed_stable_ids)
134+
else:
135+
# Get all GBFS feeds from the database
136+
gbfs_feeds = fetch_all_gbfs_feeds(db_session)
119137
except Exception:
120138
return "Error getting all GBFS feeds.", 500
121139

@@ -150,3 +168,15 @@ def gbfs_validator_batch(_, db_session: Session):
150168
f"GBFS Validator batch function triggered successfully for {len(feeds_data)} feeds.",
151169
200,
152170
)
171+
172+
173+
def fetch_gbfs_feeds_by_stable_ids(db_session, feed_stable_ids):
174+
"""Fetch GBFS feeds by their IDs and not deprecated from the database"""
175+
gbfs_feeds = (
176+
db_session.query(Gbfsfeed)
177+
.filter(
178+
Gbfsfeed.stable_id.in_(feed_stable_ids), Gbfsfeed.status != "deprecated"
179+
)
180+
.all()
181+
)
182+
return gbfs_feeds

functions-python/gbfs_validator/tests/test_gbfs_validator.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ def test_gbfs_validator_batch(
7575
):
7676
# Prepare mocks
7777
mock_session = MagicMock()
78-
# mock_database.return_value.start_db_session.return_value = mock_session
7978

8079
mock_publisher = MagicMock()
8180
mock_publisher_client.return_value = mock_publisher
@@ -179,3 +178,41 @@ def test_gbfs_validator_batch_publish_exception(
179178
# Call the function
180179
result = gbfs_validator_batch(None)
181180
self.assertEqual(result[1], 500)
181+
182+
@patch.dict(
183+
os.environ,
184+
{
185+
"PUBSUB_TOPIC_NAME": "mock-topic",
186+
},
187+
)
188+
@patch("main.pubsub_v1.PublisherClient")
189+
@patch("main.fetch_gbfs_feeds_by_stable_ids")
190+
def test_gbfs_validator_batch_by_feed_stable_ids(
191+
self, fetch_gbfs_feeds_by_stable_ids, mock_publisher_client
192+
):
193+
# Prepare mocks
194+
mock_session = MagicMock()
195+
196+
mock_publisher = MagicMock()
197+
mock_publisher_client.return_value = mock_publisher
198+
199+
mock_feed = MagicMock()
200+
mock_feed.stable_id = "mock-stable-id"
201+
mock_feed.id = str(uuid.uuid4())
202+
mock_feed.auto_discovery_url = "http://mock-url.com"
203+
mock_feed.gbfsversions = [MagicMock(version="1.0")]
204+
mock_feed_2 = copy.deepcopy(mock_feed)
205+
mock_feed_2.gbfsversions = []
206+
fetch_gbfs_feeds_by_stable_ids.return_value = [mock_feed, mock_feed_2]
207+
request = MagicMock()
208+
request.method = "POST"
209+
request.is_json = True
210+
request.get_json.return_value = {
211+
"feed_stable_ids": [mock_feed.id, mock_feed_2.id]
212+
}
213+
# Call the function
214+
result = gbfs_validator_batch(request, db_session=mock_session)
215+
self.assertEqual(result[1], 200)
216+
217+
fetch_gbfs_feeds_by_stable_ids.assert_called_once()
218+
self.assertEqual(mock_publisher.publish.call_count, 2)

0 commit comments

Comments
 (0)