Skip to content
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ releases/
/HANDOFF.md
# Private launchers and the single manually maintained .env source.
/.ops/
/.ops.zip
*.zip
__MACOSX/
6 changes: 4 additions & 2 deletions api/app/api/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@


- YouTube 지표는 검색 결과 영상의 공개 지표입니다. 검색 국가 조건은 시청자 국적을 뜻하지 않습니다.
- Instagram과 Facebook 및 Reddit은 승인된 데이터가 없어 `unavailable`로 표시될 수 있습니다.
- Instagram과 Facebook 및 Reddit은 수집하지 않으며 `social_sources`에도 없습니다.
NAVER 검색 추세는 운영자가 저장 및 재제공 정책을 승인하고 자격 증명을 설정한 환경에서만
수집합니다. 현재 가용성과 마지막 성공 시각은 응답의 `meta.sources`를 확인하세요.
- X와 TikTok은 수집 대상이 아닙니다.
Expand Down Expand Up @@ -169,7 +169,9 @@
"area_code": (
"행정구역 코드 또는 EDEN 지역 ID. 요청 지역의 자료가 없으면 unavailable입니다."
),
"social_sources": ("선택 SNS만 조회합니다. 생략 시 youtube. 미승인 원천은 unavailable입니다."),
"social_sources": (
"트렌드는 youtube와 naver. 방한 시장은 youtube만. 생략 시 youtube입니다."
),
"period": "최신 확보 관측을 끝점으로 하는 조회 기간. 미수집 구간은 결측으로 표시합니다.",
"time_unit": ("트렌드 관측의 집계 간격. day/week/month이며 고유 영상 수를 뜻하지 않습니다."),
"limit": "반환 항목 수. 기본값과 최대값은 schema에 표시됩니다.",
Expand Down
14 changes: 2 additions & 12 deletions api/app/api/v1/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,8 @@
},
)
RepositoryDep = Annotated[ReadRepository, Depends(get_read_repository)]
TrendSocialSource = Literal[
"youtube",
"instagram",
"reddit",
"facebook",
]
InboundSocialSource = Literal[
"youtube",
"instagram",
"reddit",
"facebook",
]
TrendSocialSource = Literal["youtube", "naver"]
InboundSocialSource = Literal["youtube"]


def _resolve_area(repository: ReadRepository, identifier: str) -> str:
Expand Down
7 changes: 3 additions & 4 deletions api/app/operations/phase1_soak.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
)
from app.repositories.database import create_database_engine, create_session_factory
from app.repositories.models import Area, Country, PlaceSourceMap
from app.sources.social import REQUESTABLE_SOCIAL_SOURCES
from app.sources.social import INBOUND_SOCIAL_SOURCES, REQUESTABLE_SOCIAL_SOURCES

DEFAULT_EVIDENCE_PATH = Path("/opt/eden/phase1-evidence/soak.jsonl")
BASE_URL = "http://127.0.0.1:8000"
Expand Down Expand Up @@ -142,22 +142,21 @@ def probe_public_routes() -> list[dict[str, Any]]:
encoded_area = quote(area_code, safe="")
encoded_place = quote(place_id, safe="")
encoded_country = quote(country, safe="")
social_sources = sorted(REQUESTABLE_SOCIAL_SOURCES)
trend_query = urlencode(
[
("keyword", "phase1-soak"),
("period", "90d"),
("time_unit", "day"),
("limit", "100"),
*(("social_sources", source) for source in social_sources),
*(("social_sources", source) for source in sorted(REQUESTABLE_SOCIAL_SOURCES)),
]
)
inbound_query = urlencode(
[
("countries", country),
("period", "24m"),
("forecast_days", "7"),
*(("social_sources", source) for source in social_sources),
*(("social_sources", source) for source in sorted(INBOUND_SOCIAL_SOURCES)),
*(
("include", block)
for block in (
Expand Down
7 changes: 1 addition & 6 deletions api/app/products/forecast_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,7 @@ def covered(source_id: str, target: date) -> bool:
if complete_days == days
else (Availability.PARTIAL if available_days else Availability.UNAVAILABLE)
)
if availability == Availability.AVAILABLE:
reason = None
elif available_days < days:
reason = f"요청 {days}일 중 {available_days}일의 전망만 있습니다."
else:
reason = "일부 날짜에서 요청한 참고 원천이 없습니다."
reason = None
return (
{
"area_code": product["area_code"],
Expand Down
4 changes: 2 additions & 2 deletions api/app/products/inbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
TourismBalanceObservation,
)
from app.sources.kto_inbound import SOURCE_ID
from app.sources.social import REQUESTABLE_SOCIAL_SOURCES
from app.sources.social import INBOUND_SOCIAL_SOURCES

PERIOD_MONTHS = {"3m": 3, "6m": 6, "12m": 12, "24m": 24}
INBOUND_HISTORY_MONTHS = max(PERIOD_MONTHS.values()) * 2
SOCIAL_HISTORY_MONTHS = max(PERIOD_MONTHS.values())
MAX_AGE_SECONDS = 38 * 24 * 3600
SOCIAL_SOURCE_NAMES = {
source_id: source_name for source_name, source_id in REQUESTABLE_SOCIAL_SOURCES.items()
source_id: source_name for source_name, source_id in INBOUND_SOCIAL_SOURCES.items()
}
COUNTRY_PROXY_FLAGS = frozenset({"query_market_proxy", "query_language_market_proxy"})

Expand Down
6 changes: 2 additions & 4 deletions api/app/products/regional_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def build_region_insight_view(
if any(state != Availability.UNAVAILABLE for state in states)
else Availability.UNAVAILABLE
)
reason = None if availability == Availability.AVAILABLE else "일부 지역 데이터 블록이 없습니다."
reason = None
sources = []
if "visitors" in selected and area_visit_rows:
sources.append("SRC_KTO_REGIONAL_VISITORS")
Expand Down Expand Up @@ -479,7 +479,5 @@ def build_visitor_timeseries_view(
"sources": ["SRC_TOURISM_ADMISSION" if attraction else "SRC_KTO_REGIONAL_VISITORS"],
},
availability,
None if availability == Availability.AVAILABLE
else "요청한 방문자 유형의 관측이 없습니다." if availability == Availability.UNAVAILABLE
else "시계열의 일부 날짜가 없습니다.",
None,
)
8 changes: 2 additions & 6 deletions api/app/products/trend_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def build_trend_view(
if not source_rows:
source_availability[source_id] = {
"availability": "unavailable",
"reason": "요청 키워드 및 범위의 관측이 없습니다.",
"reason": None,
}
continue
score = source_scores.get(source_id)
Expand All @@ -310,8 +310,6 @@ def build_trend_view(
"아닌 재생 가능 지역입니다."
if source_id == "SRC_YOUTUBE"
else None
if score is not None
else "정규화 모집단이 부족합니다."
)
source_metrics.append(
{
Expand Down Expand Up @@ -369,9 +367,7 @@ def build_trend_view(
return (
data,
availability,
None
if availability == Availability.AVAILABLE
else "일부 social signal 원천 또는 정규화 점수를 제공할 수 없습니다.",
None,
)


Expand Down
Loading