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
7 changes: 7 additions & 0 deletions src/api/endpoints/annotate/all/get/models/name.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 src/api/endpoints/annotate/all/get/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/models/name.py#L1 <100>

Missing docstring in public module
Raw output
./src/api/endpoints/annotate/all/get/models/name.py:1:1: D100 Missing docstring in public module


class NameAnnotationSuggestion(BaseModel):

Check warning on line 4 in src/api/endpoints/annotate/all/get/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/models/name.py#L4 <101>

Missing docstring in public class
Raw output
./src/api/endpoints/annotate/all/get/models/name.py:4:1: D101 Missing docstring in public class
name: str
suggestion_id: int
endorsement_count: int

Check warning on line 7 in src/api/endpoints/annotate/all/get/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/models/name.py#L7 <292>

no newline at end of file
Raw output
./src/api/endpoints/annotate/all/get/models/name.py:7:27: W292 no newline at end of file
4 changes: 4 additions & 0 deletions src/api/endpoints/annotate/all/get/models/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from src.api.endpoints.annotate.agency.get.dto import GetNextURLForAgencyAgencyInfo
from src.api.endpoints.annotate.all.get.models.location import LocationAnnotationResponseOuterInfo
from src.api.endpoints.annotate.all.get.models.name import NameAnnotationSuggestion
from src.api.endpoints.annotate.dtos.shared.base.response import AnnotationInnerResponseInfoBase
from src.api.endpoints.annotate.relevance.get.dto import RelevanceAnnotationResponseInfo
from src.core.enums import RecordType
Expand All @@ -22,6 +23,9 @@ class GetNextURLForAllAnnotationInnerResponse(AnnotationInnerResponseInfoBase):
suggested_record_type: RecordType | None = Field(
title="What record type, if any, the auto-labeler identified the URL as"
)
name_suggestions: list[NameAnnotationSuggestion] | None = Field(
title="User and Auto-Suggestions for names"
)


class GetNextURLForAllAnnotationResponse(BaseModel):
Expand Down
6 changes: 6 additions & 0 deletions src/api/endpoints/annotate/all/get/queries/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
from src.api.endpoints.annotate.agency.get.dto import GetNextURLForAgencyAgencyInfo
from src.api.endpoints.annotate.agency.get.queries.agency_suggestion_.core import GetAgencySuggestionsQueryBuilder
from src.api.endpoints.annotate.all.get.models.location import LocationAnnotationResponseOuterInfo
from src.api.endpoints.annotate.all.get.models.name import NameAnnotationSuggestion
from src.api.endpoints.annotate.all.get.models.response import GetNextURLForAllAnnotationResponse, \
GetNextURLForAllAnnotationInnerResponse
from src.api.endpoints.annotate.all.get.queries.location_.core import GetLocationSuggestionsQueryBuilder
from src.api.endpoints.annotate.all.get.queries.name.core import GetNameSuggestionsQueryBuilder
from src.api.endpoints.annotate.relevance.get.dto import RelevanceAnnotationResponseInfo
from src.collectors.enums import URLStatus
from src.db.dto_converter import DTOConverter
Expand Down Expand Up @@ -104,6 +106,7 @@ async def run(
joinedload(URL.html_content),
joinedload(URL.auto_relevant_suggestion),
joinedload(URL.auto_record_type_suggestion),
joinedload(URL.name_suggestions),
)

query = query.order_by(
Expand Down Expand Up @@ -133,6 +136,8 @@ async def run(
await GetAgencySuggestionsQueryBuilder(url_id=url.id).run(session)
location_suggestions: LocationAnnotationResponseOuterInfo = \
await GetLocationSuggestionsQueryBuilder(url_id=url.id).run(session)
name_suggestions: list[NameAnnotationSuggestion] = \
await GetNameSuggestionsQueryBuilder(url_id=url.id).run(session)

return GetNextURLForAllAnnotationResponse(
next_annotation=GetNextURLForAllAnnotationInnerResponse(
Expand All @@ -155,5 +160,6 @@ async def run(
]
).run(session),
location_suggestions=location_suggestions,
name_suggestions=name_suggestions
)
)
Empty file.
58 changes: 58 additions & 0 deletions src/api/endpoints/annotate/all/get/queries/name/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from typing import Sequence

Check warning on line 1 in src/api/endpoints/annotate/all/get/queries/name/core.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/queries/name/core.py#L1 <100>

Missing docstring in public module
Raw output
./src/api/endpoints/annotate/all/get/queries/name/core.py:1:1: D100 Missing docstring in public module

from sqlalchemy import select, func, RowMapping
from sqlalchemy.ext.asyncio import AsyncSession

from src.api.endpoints.annotate.all.get.models.name import NameAnnotationSuggestion
from src.db.helpers.session import session_helper as sh
from src.db.models.impl.link.user_name_suggestion.sqlalchemy import LinkUserNameSuggestion
from src.db.models.impl.url.suggestion.name.sqlalchemy import URLNameSuggestion
from src.db.queries.base.builder import QueryBuilderBase


class GetNameSuggestionsQueryBuilder(QueryBuilderBase):

Check warning on line 13 in src/api/endpoints/annotate/all/get/queries/name/core.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/queries/name/core.py#L13 <101>

Missing docstring in public class
Raw output
./src/api/endpoints/annotate/all/get/queries/name/core.py:13:1: D101 Missing docstring in public class

def __init__(

Check warning on line 15 in src/api/endpoints/annotate/all/get/queries/name/core.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/queries/name/core.py#L15 <107>

Missing docstring in __init__
Raw output
./src/api/endpoints/annotate/all/get/queries/name/core.py:15:1: D107 Missing docstring in __init__
self,
url_id: int
):
super().__init__()
self.url_id = url_id

async def run(self, session: AsyncSession) -> list[NameAnnotationSuggestion]:

Check warning on line 22 in src/api/endpoints/annotate/all/get/queries/name/core.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/queries/name/core.py#L22 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/get/queries/name/core.py:22:1: D102 Missing docstring in public method
query = (
select(
URLNameSuggestion.id.label('suggestion_id'),
URLNameSuggestion.suggestion.label('name'),
func.count(
LinkUserNameSuggestion.user_id
).label('endorsement_count'),
)
.outerjoin(
LinkUserNameSuggestion,
LinkUserNameSuggestion.suggestion_id == URLNameSuggestion.id,
)
.where(
URLNameSuggestion.url_id == self.url_id,
)
.group_by(
URLNameSuggestion.id,
URLNameSuggestion.suggestion,
)
.order_by(
func.count(LinkUserNameSuggestion.user_id).desc(),
URLNameSuggestion.id.asc(),
)
.limit(3)
)

mappings: Sequence[RowMapping] = await sh.mappings(session, query=query)
return [
NameAnnotationSuggestion(
**mapping
)
for mapping in mappings
]



Check warning on line 58 in src/api/endpoints/annotate/all/get/queries/name/core.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/get/queries/name/core.py#L58 <391>

blank line at end of file
Raw output
./src/api/endpoints/annotate/all/get/queries/name/core.py:58:1: W391 blank line at end of file
10 changes: 10 additions & 0 deletions src/api/endpoints/annotate/all/post/models/name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import BaseModel

Check warning on line 1 in src/api/endpoints/annotate/all/post/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/models/name.py#L1 <100>

Missing docstring in public module
Raw output
./src/api/endpoints/annotate/all/post/models/name.py:1:1: D100 Missing docstring in public module


class AnnotationPostNameInfo(BaseModel):

Check warning on line 4 in src/api/endpoints/annotate/all/post/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/models/name.py#L4 <101>

Missing docstring in public class
Raw output
./src/api/endpoints/annotate/all/post/models/name.py:4:1: D101 Missing docstring in public class
new_name: str | None = None
existing_name_id: int | None = None

@property
def empty(self) -> bool:

Check warning on line 9 in src/api/endpoints/annotate/all/post/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/models/name.py#L9 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/models/name.py:9:1: D102 Missing docstring in public method
return self.new_name is None and self.existing_name_id is None

Check warning on line 10 in src/api/endpoints/annotate/all/post/models/name.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/models/name.py#L10 <292>

no newline at end of file
Raw output
./src/api/endpoints/annotate/all/post/models/name.py:10:71: W292 no newline at end of file
2 changes: 2 additions & 0 deletions src/api/endpoints/annotate/all/post/models/request.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pydantic import BaseModel, model_validator

from src.api.endpoints.annotate.all.post.models.name import AnnotationPostNameInfo
from src.core.enums import RecordType
from src.core.exceptions import FailedValidationException
from src.db.models.impl.flag.url_validated.enums import URLType
Expand All @@ -10,6 +11,7 @@ class AllAnnotationPostInfo(BaseModel):
record_type: RecordType | None = None
agency_ids: list[int]
location_ids: list[int]
name_info: AnnotationPostNameInfo = AnnotationPostNameInfo()

@model_validator(mode="after")
def forbid_record_type_if_meta_url_or_individual_record(self):
Expand Down
41 changes: 13 additions & 28 deletions src/api/endpoints/annotate/all/post/query.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sqlalchemy.ext.asyncio import AsyncSession

from src.api.endpoints.annotate.all.post.models.request import AllAnnotationPostInfo
from src.api.endpoints.annotate.all.post.requester import AddAllAnnotationsToURLRequester
from src.db.models.impl.flag.url_validated.enums import URLType
from src.db.models.impl.url.suggestion.agency.user import UserUrlAgencySuggestion
from src.db.models.impl.url.suggestion.location.user.sqlalchemy import UserLocationSuggestion
Expand All @@ -24,40 +25,24 @@ def __init__(


async def run(self, session: AsyncSession) -> None:
# Add relevant annotation
relevant_suggestion = UserURLTypeSuggestion(
requester = AddAllAnnotationsToURLRequester(
session=session,
url_id=self.url_id,
user_id=self.user_id,
type=self.post_info.suggested_status
user_id=self.user_id
)
session.add(relevant_suggestion)

# Add relevant annotation
requester.add_relevant_annotation(self.post_info.suggested_status)

# If not relevant, do nothing else
if self.post_info.suggested_status == URLType.NOT_RELEVANT:
return

locations: list[UserLocationSuggestion] = []
for location_id in self.post_info.location_ids:
locations.append(UserLocationSuggestion(
url_id=self.url_id,
user_id=self.user_id,
location_id=location_id
))
session.add_all(locations)
requester.add_location_ids(self.post_info.location_ids)

# TODO (TEST): Add test for submitting Meta URL validation
if self.post_info.record_type is not None:
record_type_suggestion = UserRecordTypeSuggestion(
url_id=self.url_id,
user_id=self.user_id,
record_type=self.post_info.record_type.value
)
session.add(record_type_suggestion)

for agency_id in self.post_info.agency_ids:
agency_suggestion = UserUrlAgencySuggestion(
url_id=self.url_id,
user_id=self.user_id,
agency_id=agency_id,
)
session.add(agency_suggestion)
requester.optionally_add_record_type(self.post_info.record_type)

requester.add_agency_ids(self.post_info.agency_ids)

await requester.optionally_add_name_suggestion(self.post_info.name_info)
95 changes: 95 additions & 0 deletions src/api/endpoints/annotate/all/post/requester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from sqlalchemy.ext.asyncio import AsyncSession

Check warning on line 1 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L1 <100>

Missing docstring in public module
Raw output
./src/api/endpoints/annotate/all/post/requester.py:1:1: D100 Missing docstring in public module

from src.api.endpoints.annotate.all.post.models.name import AnnotationPostNameInfo
from src.core.enums import RecordType
from src.db.models.impl.flag.url_validated.enums import URLType
from src.db.models.impl.link.user_name_suggestion.sqlalchemy import LinkUserNameSuggestion
from src.db.models.impl.url.suggestion.agency.user import UserUrlAgencySuggestion
from src.db.models.impl.url.suggestion.location.user.sqlalchemy import UserLocationSuggestion
from src.db.models.impl.url.suggestion.name.enums import NameSuggestionSource
from src.db.models.impl.url.suggestion.name.sqlalchemy import URLNameSuggestion
from src.db.models.impl.url.suggestion.record_type.user import UserRecordTypeSuggestion
from src.db.models.impl.url.suggestion.relevant.user import UserURLTypeSuggestion
from src.db.templates.requester import RequesterBase


class AddAllAnnotationsToURLRequester(RequesterBase):

Check warning on line 16 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L16 <101>

Missing docstring in public class
Raw output
./src/api/endpoints/annotate/all/post/requester.py:16:1: D101 Missing docstring in public class

def __init__(

Check warning on line 18 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L18 <107>

Missing docstring in __init__
Raw output
./src/api/endpoints/annotate/all/post/requester.py:18:1: D107 Missing docstring in __init__
self,
session: AsyncSession,
url_id: int,
user_id: int,
):
super().__init__(session=session)
self.url_id = url_id
self.user_id = user_id

def optionally_add_record_type(

Check warning on line 28 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L28 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/requester.py:28:1: D102 Missing docstring in public method
self,
rt: RecordType | None,
) -> None:
if rt is None:
return
record_type_suggestion = UserRecordTypeSuggestion(
url_id=self.url_id,
user_id=self.user_id,
record_type=rt.value
)
self.session.add(record_type_suggestion)

def add_relevant_annotation(

Check warning on line 41 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L41 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/requester.py:41:1: D102 Missing docstring in public method
self,
url_type: URLType,
) -> None:
relevant_suggestion = UserURLTypeSuggestion(
url_id=self.url_id,
user_id=self.user_id,
type=url_type
)
self.session.add(relevant_suggestion)

def add_agency_ids(self, agency_ids: list[int]) -> None:

Check warning on line 52 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L52 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/requester.py:52:1: D102 Missing docstring in public method
for agency_id in agency_ids:
agency_suggestion = UserUrlAgencySuggestion(
url_id=self.url_id,
user_id=self.user_id,
agency_id=agency_id,
)
self.session.add(agency_suggestion)

def add_location_ids(self, location_ids: list[int]) -> None:

Check warning on line 61 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L61 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/requester.py:61:1: D102 Missing docstring in public method
locations: list[UserLocationSuggestion] = []
for location_id in location_ids:
locations.append(UserLocationSuggestion(
url_id=self.url_id,
user_id=self.user_id,
location_id=location_id
))
self.session.add_all(locations)

async def optionally_add_name_suggestion(

Check warning on line 71 in src/api/endpoints/annotate/all/post/requester.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/api/endpoints/annotate/all/post/requester.py#L71 <102>

Missing docstring in public method
Raw output
./src/api/endpoints/annotate/all/post/requester.py:71:1: D102 Missing docstring in public method
self,
name_info: AnnotationPostNameInfo
) -> None:
if name_info.empty:
return
if name_info.existing_name_id is not None:
link = LinkUserNameSuggestion(
user_id=self.user_id,
suggestion_id=name_info.existing_name_id,
)
self.session.add(link)
return
name_suggestion = URLNameSuggestion(
url_id=self.url_id,
suggestion=name_info.new_name,
source=NameSuggestionSource.USER
)
self.session.add(name_suggestion)
await self.session.flush()
link = LinkUserNameSuggestion(
user_id=self.user_id,
suggestion_id=name_suggestion.id,
)
self.session.add(link)
5 changes: 1 addition & 4 deletions src/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

from fastapi import HTTPException
from pydantic import BaseModel
from sqlalchemy.exc import IntegrityError

from src.api.endpoints.annotate.agency.post.dto import URLAgencyAnnotationPostInfo
from src.api.endpoints.annotate.all.get.models.response import GetNextURLForAllAnnotationResponse
from src.api.endpoints.annotate.all.post.models.request import AllAnnotationPostInfo
from src.api.endpoints.annotate.all.post.query import AddAllAnnotationsToURLQueryBuilder
Expand Down Expand Up @@ -35,8 +33,7 @@
from src.api.endpoints.url.get.dto import GetURLsResponseInfo
from src.collectors.enums import CollectorType
from src.collectors.manager import AsyncCollectorManager
from src.core.enums import BatchStatus, RecordType, AnnotationType
from src.core.error_manager.core import ErrorManager
from src.core.enums import BatchStatus
from src.core.tasks.url.manager import TaskManager
from src.db.client.async_ import AsyncDatabaseClient
from src.db.enums import TaskType
Expand Down
5 changes: 5 additions & 0 deletions src/db/models/impl/url/core/sqlalchemy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sqlalchemy import Column, Text, String, JSON
from sqlalchemy.orm import relationship

from src.api.endpoints.annotate.all.get.models.name import NameAnnotationSuggestion

Check warning on line 4 in src/db/models/impl/url/core/sqlalchemy.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] src/db/models/impl/url/core/sqlalchemy.py#L4 <401>

'src.api.endpoints.annotate.all.get.models.name.NameAnnotationSuggestion' imported but unused
Raw output
./src/db/models/impl/url/core/sqlalchemy.py:4:1: F401 'src.api.endpoints.annotate.all.get.models.name.NameAnnotationSuggestion' imported but unused
from src.collectors.enums import URLStatus
from src.core.enums import RecordType
from src.db.models.helpers import enum_column
Expand All @@ -9,6 +10,7 @@
from src.db.models.impl.url.probed_for_404 import URLProbedFor404
from src.db.models.impl.url.record_type.sqlalchemy import URLRecordType
from src.db.models.impl.url.suggestion.location.auto.subtask.sqlalchemy import AutoLocationIDSubtask
from src.db.models.impl.url.suggestion.name.sqlalchemy import URLNameSuggestion
from src.db.models.mixins import UpdatedAtMixin, CreatedAtMixin
from src.db.models.templates_.with_id import WithIDBase

Expand Down Expand Up @@ -60,6 +62,9 @@
auto_location_subtasks = relationship(
AutoLocationIDSubtask
)
name_suggestions = relationship(
URLNameSuggestion
)
user_agency_suggestions = relationship(
"UserUrlAgencySuggestion", back_populates="url")
auto_record_type_suggestion = relationship(
Expand Down
3 changes: 2 additions & 1 deletion src/db/models/impl/url/suggestion/name/sqlalchemy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlalchemy import Column, String
from sqlalchemy.orm import Mapped

from src.db.models.helpers import enum_column
from src.db.models.impl.url.suggestion.location.auto.subtask.constants import MAX_SUGGESTION_LENGTH
Expand All @@ -16,7 +17,7 @@ class URLNameSuggestion(
__tablename__ = "url_name_suggestions"

suggestion = Column(String(MAX_SUGGESTION_LENGTH), nullable=False)
source = enum_column(
source: Mapped[NameSuggestionSource] = enum_column(
NameSuggestionSource,
name="suggestion_source_enum"
)
Loading