Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test_app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
container-job:
runs-on: ubuntu-latest
timeout-minutes: 20
container: python:3.12.8
container: python:3.11.9

services:
postgres:
Expand Down
50 changes: 42 additions & 8 deletions api/routes/annotate.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from fastapi import APIRouter, Depends, Path

from api.dependencies import get_async_core
from collector_db.enums import URLMetadataAttributeType
from core.AsyncCore import AsyncCore
from core.DTOs.GetNextURLForRelevanceAnnotationResponse import GetNextURLForRelevanceAnnotationResponse
from core.DTOs.RelevanceAnnotationInfo import RelevanceAnnotationPostInfo
from core.DTOs.GetNextURLForAnnotationResponse import GetNextURLForAnnotationResponse
from core.DTOs.RecordTypeAnnotationPostInfo import RecordTypeAnnotationPostInfo
from core.DTOs.RelevanceAnnotationPostInfo import RelevanceAnnotationPostInfo
from security_manager.SecurityManager import get_access_info, AccessInfo

annotate_router = APIRouter(
Expand All @@ -17,8 +19,11 @@
async def get_next_url_for_relevance_annotation(
access_info: AccessInfo = Depends(get_access_info),
async_core: AsyncCore = Depends(get_async_core),
) -> GetNextURLForRelevanceAnnotationResponse:
result = await async_core.get_next_url_for_relevance_annotation(user_id=access_info.user_id)
) -> GetNextURLForAnnotationResponse:
result = await async_core.get_next_url_for_annotation(
user_id=access_info.user_id,
metadata_type=URLMetadataAttributeType.RELEVANT
)
return result


Expand All @@ -28,14 +33,43 @@
metadata_id: int = Path(description="The metadata id for the associated URL metadata"),
async_core: AsyncCore = Depends(get_async_core),
access_info: AccessInfo = Depends(get_access_info)
) -> GetNextURLForRelevanceAnnotationResponse:
) -> GetNextURLForAnnotationResponse:
"""
Post URL annotation and get next URL to annotate
"""
result = await async_core.submit_and_get_next_url_for_annotation(
user_id=access_info.user_id,
metadata_id=metadata_id,
annotation=str(relevance_annotation_post_info.is_relevant),
metadata_type = URLMetadataAttributeType.RELEVANT

Check failure on line 44 in api/routes/annotate.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] api/routes/annotate.py#L44 <251>

unexpected spaces around keyword / parameter equals
Raw output
./api/routes/annotate.py:44:22: E251 unexpected spaces around keyword / parameter equals

Check failure on line 44 in api/routes/annotate.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] api/routes/annotate.py#L44 <251>

unexpected spaces around keyword / parameter equals
Raw output
./api/routes/annotate.py:44:24: E251 unexpected spaces around keyword / parameter equals
)
return result

@annotate_router.get("/record-type")
async def get_next_url_for_record_type_annotation(

Check warning on line 49 in api/routes/annotate.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] api/routes/annotate.py#L49 <103>

Missing docstring in public function
Raw output
./api/routes/annotate.py:49:1: D103 Missing docstring in public function
access_info: AccessInfo = Depends(get_access_info),
async_core: AsyncCore = Depends(get_async_core),
) -> GetNextURLForAnnotationResponse:
result = await async_core.get_next_url_for_annotation(
user_id=access_info.user_id,
metadata_type=URLMetadataAttributeType.RECORD_TYPE
)
return result

@annotate_router.post("/record-type/{metadata_id}")
async def annotate_url_for_record_type_and_get_next_url(
record_type_annotation_post_info: RecordTypeAnnotationPostInfo,
metadata_id: int = Path(description="The metadata id for the associated URL metadata"),
async_core: AsyncCore = Depends(get_async_core),
access_info: AccessInfo = Depends(get_access_info)
) -> GetNextURLForAnnotationResponse:
"""
Post URL annotation and get next URL to annotate
"""
await async_core.submit_url_relevance_annotation(
result = await async_core.submit_and_get_next_url_for_annotation(
user_id=access_info.user_id,
metadata_id=metadata_id,
annotation=relevance_annotation_post_info
annotation=record_type_annotation_post_info.record_type.value,
metadata_type=URLMetadataAttributeType.RECORD_TYPE
)
result = await async_core.get_next_url_for_relevance_annotation(user_id=access_info.user_id)
return result
19 changes: 12 additions & 7 deletions collector_db/AsyncDatabaseClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from core.DTOs.GetTasksResponse import GetTasksResponse, GetTasksResponseTaskInfo
from core.DTOs.GetURLsResponseInfo import GetURLsResponseInfo, GetURLsResponseMetadataInfo, GetURLsResponseErrorInfo, \
GetURLsResponseInnerInfo
from core.DTOs.RelevanceAnnotationInfo import RelevanceAnnotationPostInfo
from core.DTOs.RelevanceAnnotationPostInfo import RelevanceAnnotationPostInfo

Check warning on line 26 in collector_db/AsyncDatabaseClient.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/AsyncDatabaseClient.py#L26 <401>

'core.DTOs.RelevanceAnnotationPostInfo.RelevanceAnnotationPostInfo' imported but unused
Raw output
./collector_db/AsyncDatabaseClient.py:26:1: F401 'core.DTOs.RelevanceAnnotationPostInfo.RelevanceAnnotationPostInfo' imported but unused
from core.enums import BatchStatus


Expand Down Expand Up @@ -232,10 +232,11 @@
url_metadata.validation_status = validation_status

@session_manager
async def get_next_url_for_relevance_annotation(
async def get_next_url_for_annotation(

Check warning on line 235 in collector_db/AsyncDatabaseClient.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/AsyncDatabaseClient.py#L235 <102>

Missing docstring in public method
Raw output
./collector_db/AsyncDatabaseClient.py:235:1: D102 Missing docstring in public method
self,
session: AsyncSession,
user_id: int
user_id: int,
metadata_type: URLMetadataAttributeType
) -> URLAnnotationInfo:
# Get a URL, its relevancy metadata ID, and HTML data
# For a URL which has not yet been annotated by this user id
Expand All @@ -246,10 +247,11 @@
URL.id.label("url_id"),
URL.url,
URLMetadata.id.label("metadata_id"),
URLMetadata.value,
)
.join(URLMetadata)
# Metadata must be relevant
.where(URLMetadata.attribute == URLMetadataAttributeType.RELEVANT.value)
.where(URLMetadata.attribute == metadata_type.value)
# Metadata must not be validated
.where(URLMetadata.validation_status == ValidationStatus.PENDING_VALIDATION.value)
# URL must have HTML content entries
Expand All @@ -274,6 +276,7 @@
select(
subquery.c.url,
subquery.c.metadata_id,
subquery.c.value,
URLHTMLContent.content_type,
URLHTMLContent.content,
)
Expand All @@ -291,9 +294,10 @@
annotation_info = URLAnnotationInfo(
url=result[0][0],
metadata_id=result[0][1],
suggested_value=result[0][2],
html_infos=[]
)
for _, _, content_type, content in result:
for _, _, _, content_type, content in result:
html_info = URLHTMLContentInfo(
content_type=content_type,
content=content
Expand All @@ -307,11 +311,12 @@
session: AsyncSession,
user_id: int,
metadata_id: int,
annotation_info: RelevanceAnnotationPostInfo):
annotation: str
):
annotation = MetadataAnnotation(
metadata_id=metadata_id,
user_id=user_id,
value=str(annotation_info.is_relevant)
value=annotation
)
session.add(annotation)

Expand Down
3 changes: 2 additions & 1 deletion collector_db/DTOs/URLAnnotationInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
class URLAnnotationInfo(BaseModel):
metadata_id: int
url: str
html_infos: list[URLHTMLContentInfo]
html_infos: list[URLHTMLContentInfo]
suggested_value: str

Check warning on line 10 in collector_db/DTOs/URLAnnotationInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/DTOs/URLAnnotationInfo.py#L10 <292>

no newline at end of file
Raw output
./collector_db/DTOs/URLAnnotationInfo.py:10:25: W292 no newline at end of file
20 changes: 18 additions & 2 deletions collector_db/StatementComposer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

from sqlalchemy import Select, select, exists, Table, func, Subquery

from collector_db.enums import URLMetadataAttributeType
from collector_db.models import URL, URLHTMLContent, URLMetadata
from collector_db.enums import URLMetadataAttributeType, ValidationStatus

Check warning on line 4 in collector_db/StatementComposer.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/StatementComposer.py#L4 <401>

'collector_db.enums.ValidationStatus' imported but unused
Raw output
./collector_db/StatementComposer.py:4:1: F401 'collector_db.enums.ValidationStatus' imported but unused
from collector_db.models import URL, URLHTMLContent, URLMetadata, MetadataAnnotation
from collector_manager.enums import URLStatus


Expand Down Expand Up @@ -33,6 +33,22 @@
)
))

@staticmethod
def exclude_url_annotated_by_user(

Check warning on line 37 in collector_db/StatementComposer.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/StatementComposer.py#L37 <102>

Missing docstring in public method
Raw output
./collector_db/StatementComposer.py:37:1: D102 Missing docstring in public method
statement: Select,
user_id: int
) -> Select:
return (statement.where(
~exists(

Check failure on line 42 in collector_db/StatementComposer.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/StatementComposer.py#L42 <126>

continuation line over-indented for hanging indent
Raw output
./collector_db/StatementComposer.py:42:25: E126 continuation line over-indented for hanging indent
select(MetadataAnnotation.id).
where(
MetadataAnnotation.metadata_id == URLMetadata.id,
MetadataAnnotation.user_id == user_id
)
)
))

Check failure on line 49 in collector_db/StatementComposer.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] collector_db/StatementComposer.py#L49 <126>

continuation line over-indented for hanging indent
Raw output
./collector_db/StatementComposer.py:49:21: E126 continuation line over-indented for hanging indent


@staticmethod
def simple_count_subquery(model, attribute: str, label: str) -> Subquery:
attr_value = getattr(model, attribute)
Expand Down
54 changes: 38 additions & 16 deletions core/AsyncCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
from collector_db.AsyncDatabaseClient import AsyncDatabaseClient
from collector_db.DTOs.TaskInfo import TaskInfo
from collector_db.DTOs.URLAnnotationInfo import URLAnnotationInfo
from collector_db.enums import TaskType
from core.DTOs.GetNextURLForRelevanceAnnotationResponse import GetNextURLForRelevanceAnnotationResponse
from collector_db.enums import TaskType, URLMetadataAttributeType
from core.DTOs.GetNextURLForAnnotationResponse import GetNextURLForAnnotationResponse
from core.DTOs.GetTasksResponse import GetTasksResponse
from core.DTOs.GetURLsResponseInfo import GetURLsResponseInfo
from core.DTOs.RelevanceAnnotationInfo import RelevanceAnnotationPostInfo
from core.DTOs.RelevanceAnnotationRequestInfo import RelevanceAnnotationRequestInfo
from core.DTOs.AnnotationRequestInfo import AnnotationRequestInfo
from core.classes.URLHTMLTaskOperator import URLHTMLTaskOperator
from core.classes.URLRecordTypeTaskOperator import URLRecordTypeTaskOperator
from core.classes.URLRelevanceHuggingfaceTaskOperator import URLRelevanceHuggingfaceTaskOperator
Expand Down Expand Up @@ -66,39 +65,62 @@
await self.run_url_relevance_huggingface_task()
await self.run_url_record_type_task()

async def convert_to_relevance_annotation_request_info(self, url_info: URLAnnotationInfo) -> RelevanceAnnotationRequestInfo:
async def convert_to_annotation_request_info(self, url_info: URLAnnotationInfo) -> AnnotationRequestInfo:

Check warning on line 68 in core/AsyncCore.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/AsyncCore.py#L68 <102>

Missing docstring in public method
Raw output
./core/AsyncCore.py:68:1: D102 Missing docstring in public method
response_html_info = convert_to_response_html_info(
html_content_infos=url_info.html_infos
)

return RelevanceAnnotationRequestInfo(
return AnnotationRequestInfo(
url=url_info.url,
metadata_id=url_info.metadata_id,
html_info=response_html_info
html_info=response_html_info,
suggested_value=url_info.suggested_value
)

async def get_next_url_for_relevance_annotation(self, user_id: int) -> GetNextURLForRelevanceAnnotationResponse:
response = GetNextURLForRelevanceAnnotationResponse()
ua_info: URLAnnotationInfo = await self.adb_client.get_next_url_for_relevance_annotation(user_id=user_id)
async def get_next_url_for_annotation(self, user_id: int, metadata_type: URLMetadataAttributeType) -> GetNextURLForAnnotationResponse:

Check warning on line 80 in core/AsyncCore.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/AsyncCore.py#L80 <102>

Missing docstring in public method
Raw output
./core/AsyncCore.py:80:1: D102 Missing docstring in public method
response = GetNextURLForAnnotationResponse()
ua_info: URLAnnotationInfo = await self.adb_client.get_next_url_for_annotation(
user_id=user_id,
metadata_type=metadata_type
)
if ua_info is None:
return response
# Format result
result = await self.convert_to_relevance_annotation_request_info(url_info=ua_info)
result = await self.convert_to_annotation_request_info(url_info=ua_info)
response.next_annotation = result
return response

async def submit_and_get_next_url_for_annotation(

Check warning on line 93 in core/AsyncCore.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/AsyncCore.py#L93 <102>

Missing docstring in public method
Raw output
./core/AsyncCore.py:93:1: D102 Missing docstring in public method
self,
user_id: int,
metadata_id: int,
annotation: str,
metadata_type: URLMetadataAttributeType
) -> GetNextURLForAnnotationResponse:
await self.submit_url_annotation(
user_id=user_id,
metadata_id=metadata_id,
annotation=annotation,
metadata_type=metadata_type
)
result = await self.get_next_url_for_annotation(
user_id=user_id,
metadata_type=metadata_type
)
return result

async def submit_url_relevance_annotation(
async def submit_url_annotation(

Check warning on line 112 in core/AsyncCore.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/AsyncCore.py#L112 <102>

Missing docstring in public method
Raw output
./core/AsyncCore.py:112:1: D102 Missing docstring in public method
self,
user_id: int,
metadata_id: int,
annotation: RelevanceAnnotationPostInfo
) -> GetNextURLForRelevanceAnnotationResponse:
annotation: str,
metadata_type: URLMetadataAttributeType
) -> GetNextURLForAnnotationResponse:
await self.adb_client.add_relevance_annotation(
user_id=user_id,
metadata_id=metadata_id,
annotation_info=annotation)
return await self.get_next_url_for_relevance_annotation(user_id=user_id)
annotation=annotation)
return await self.get_next_url_for_annotation(user_id=user_id, metadata_type=metadata_type)

async def get_urls(self, page: int, errors: bool) -> GetURLsResponseInfo:
return await self.adb_client.get_urls(page=page, errors=errors)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from html_tag_collector.DataClassTags import ResponseHTMLInfo


class RelevanceAnnotationRequestInfo(BaseModel):
class AnnotationRequestInfo(BaseModel):

Check warning on line 6 in core/DTOs/AnnotationRequestInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/AnnotationRequestInfo.py#L6 <101>

Missing docstring in public class
Raw output
./core/DTOs/AnnotationRequestInfo.py:6:1: D101 Missing docstring in public class
url: str
metadata_id: int
html_info: ResponseHTMLInfo
html_info: ResponseHTMLInfo
suggested_value: str

Check warning on line 10 in core/DTOs/AnnotationRequestInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/AnnotationRequestInfo.py#L10 <292>

no newline at end of file
Raw output
./core/DTOs/AnnotationRequestInfo.py:10:25: W292 no newline at end of file
9 changes: 9 additions & 0 deletions core/DTOs/GetNextURLForAnnotationResponse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Optional

Check warning on line 1 in core/DTOs/GetNextURLForAnnotationResponse.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/GetNextURLForAnnotationResponse.py#L1 <100>

Missing docstring in public module
Raw output
./core/DTOs/GetNextURLForAnnotationResponse.py:1:1: D100 Missing docstring in public module

from pydantic import BaseModel

from core.DTOs.AnnotationRequestInfo import AnnotationRequestInfo


class GetNextURLForAnnotationResponse(BaseModel):

Check warning on line 8 in core/DTOs/GetNextURLForAnnotationResponse.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/GetNextURLForAnnotationResponse.py#L8 <101>

Missing docstring in public class
Raw output
./core/DTOs/GetNextURLForAnnotationResponse.py:8:1: D101 Missing docstring in public class
next_annotation: Optional[AnnotationRequestInfo] = None
9 changes: 0 additions & 9 deletions core/DTOs/GetNextURLForRelevanceAnnotationResponse.py

This file was deleted.

7 changes: 7 additions & 0 deletions core/DTOs/RecordTypeAnnotationPostInfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel

Check warning on line 1 in core/DTOs/RecordTypeAnnotationPostInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/RecordTypeAnnotationPostInfo.py#L1 <100>

Missing docstring in public module
Raw output
./core/DTOs/RecordTypeAnnotationPostInfo.py:1:1: D100 Missing docstring in public module

from core.enums import RecordType


class RecordTypeAnnotationPostInfo(BaseModel):

Check warning on line 6 in core/DTOs/RecordTypeAnnotationPostInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/RecordTypeAnnotationPostInfo.py#L6 <101>

Missing docstring in public class
Raw output
./core/DTOs/RecordTypeAnnotationPostInfo.py:6:1: D101 Missing docstring in public class
record_type: RecordType

Check warning on line 7 in core/DTOs/RecordTypeAnnotationPostInfo.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] core/DTOs/RecordTypeAnnotationPostInfo.py#L7 <292>

no newline at end of file
Raw output
./core/DTOs/RecordTypeAnnotationPostInfo.py:7:28: W292 no newline at end of file
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
from core.DTOs.GetBatchLogsResponse import GetBatchLogsResponse
from core.DTOs.GetBatchStatusResponse import GetBatchStatusResponse
from core.DTOs.GetDuplicatesByBatchResponse import GetDuplicatesByBatchResponse
from core.DTOs.GetNextURLForRelevanceAnnotationResponse import GetNextURLForRelevanceAnnotationResponse
from core.DTOs.GetNextURLForAnnotationResponse import GetNextURLForAnnotationResponse
from core.DTOs.GetTasksResponse import GetTasksResponse
from core.DTOs.GetURLsByBatchResponse import GetURLsByBatchResponse
from core.DTOs.GetURLsResponseInfo import GetURLsResponseInfo
from core.DTOs.MessageCountResponse import MessageCountResponse
from core.DTOs.MessageResponse import MessageResponse
from core.DTOs.RelevanceAnnotationInfo import RelevanceAnnotationPostInfo
from core.DTOs.RecordTypeAnnotationPostInfo import RecordTypeAnnotationPostInfo
from core.DTOs.RelevanceAnnotationPostInfo import RelevanceAnnotationPostInfo
from core.enums import BatchStatus
from util.helper_functions import update_if_not_none

Expand Down Expand Up @@ -175,22 +176,39 @@
)
return MessageCountResponse(**data)

def get_next_relevance_annotation(self) -> GetNextURLForRelevanceAnnotationResponse:
def get_next_relevance_annotation(self) -> GetNextURLForAnnotationResponse:

Check warning on line 179 in tests/test_automated/integration/api/helpers/RequestValidator.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] tests/test_automated/integration/api/helpers/RequestValidator.py#L179 <102>

Missing docstring in public method
Raw output
./tests/test_automated/integration/api/helpers/RequestValidator.py:179:1: D102 Missing docstring in public method
data = self.get(
url=f"/annotate/relevance"
)
return GetNextURLForRelevanceAnnotationResponse(**data)
return GetNextURLForAnnotationResponse(**data)

def get_next_record_type_annotation(self) -> GetNextURLForAnnotationResponse:

Check warning on line 185 in tests/test_automated/integration/api/helpers/RequestValidator.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] tests/test_automated/integration/api/helpers/RequestValidator.py#L185 <102>

Missing docstring in public method
Raw output
./tests/test_automated/integration/api/helpers/RequestValidator.py:185:1: D102 Missing docstring in public method
data = self.get(
url=f"/annotate/record-type"

Check warning on line 187 in tests/test_automated/integration/api/helpers/RequestValidator.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] tests/test_automated/integration/api/helpers/RequestValidator.py#L187 <541>

f-string is missing placeholders
Raw output
./tests/test_automated/integration/api/helpers/RequestValidator.py:187:17: F541 f-string is missing placeholders
)
return GetNextURLForAnnotationResponse(**data)

def post_record_type_annotation_and_get_next(

Check warning on line 191 in tests/test_automated/integration/api/helpers/RequestValidator.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] tests/test_automated/integration/api/helpers/RequestValidator.py#L191 <102>

Missing docstring in public method
Raw output
./tests/test_automated/integration/api/helpers/RequestValidator.py:191:1: D102 Missing docstring in public method
self,
metadata_id: int,
record_type_annotation_post_info: RecordTypeAnnotationPostInfo
) -> GetNextURLForAnnotationResponse:
data = self.post(
url=f"/annotate/record-type/{metadata_id}",
json=record_type_annotation_post_info.model_dump(mode='json')
)
return GetNextURLForAnnotationResponse(**data)

def post_relevance_annotation_and_get_next(
self,
metadata_id: int,
relevance_annotation_post_info: RelevanceAnnotationPostInfo
) -> GetNextURLForRelevanceAnnotationResponse:
) -> GetNextURLForAnnotationResponse:
data = self.post(
url=f"/annotate/relevance/{metadata_id}",
json=relevance_annotation_post_info.model_dump()
json=relevance_annotation_post_info.model_dump(mode='json')
)
return GetNextURLForRelevanceAnnotationResponse(**data)
return GetNextURLForAnnotationResponse(**data)

def get_urls(self, page: int = 1, errors: bool = False) -> GetURLsResponseInfo:
data = self.get(
Expand Down
Loading