BaseClient
핵심 HTTP 작업 및 페이지네이션 기능을 제공하는 모든 Synapse SDK 클라이언트의 기본 클래스입니다.
개요
BaseClient는 다른 모든 클라이언트에서 사용하는 HTTP 작업, 오류 처리, 요청 관리 및 페이지네이션을 위한 공통 기능을 제공합니다. 자동 파일 URL 변환 기능과 함께 효율적인 페이지네이션 처리를 구현합니다.
기능
- 재시도 로직이 있는 HTTP 요청 처리
- 자동 timeout 관리
- 제너레이터를 사용한 효율적인 페이지네이션
- 파일 URL을 로컬 경로로 자동 변환
- Pydantic 모델 유효성 검사
- 연결 풀링
핵심 HTTP 메서드
BaseClient는 모든 클라이언트 믹스인에서 내부적으로 사용하는 저수준 HTTP 메서드를 제공합니다:
_get()- 선택적 응답 모델 검증을 포함한 GET 요청_post()- 요청/응답 검증을 포함한 POST 요청_put()- 모델 검증을 포함한 PUT 요청_patch()- 모델 검증을 포함한 PATCH 요청_delete()- 모델 검증을 포함한 DELETE 요청
이러한 메서드는 일반적으로 직접 호출되지 않습니다. 대신 클라이언트 믹스인에서 제공하는 상위 수준 메서드를 사용하세요.
페이지네이션 메서드
_list(path, url_conversion=None, list_all=False, params=None, **kwargs)
선택적 자동 페이지네이션 및 파일 URL 변환 기능을 갖춘 페이지네이션 API 엔드포인트에서 리소스를 나열합니다.
매개변수:
path(str): 요청할 URL 경로url_conversion(dict, optional): 파일 URL을 로컬 경로로 변환하기 위한 설정- 구조:
{'files_fields': ['field1', 'field2'], 'is_list': True} - 자동으로 파일을 다운로드하고 URL을 로컬 경로로 대체
- 구조:
list_all(bool): True인 경우 제너레이터를 사용하여 모든 페이지의 모든 결과 반환params(dict, optional): 쿼리 매개변수 (필터, 정렬 등)**kwargs: 추가 요청 인자
반환값:
list_all=False인 경우:results,count,next,previous를 포함한 딕셔너리list_all=True인 경우:(generator, total_count)튜플
예제:
# 첫 페이지만 가져오기
response = client._list('api/tasks/')
tasks = response['results'] # 첫 페이지의 작업들
total = response['count'] # 전체 작업 수
# 제너레이터를 사용하여 모든 결과 가져오기 (메모리 효율적)
generator, total_count = client._list('api/tasks/', list_all=True)
all_tasks = list(generator) # 자동으로 모든 페이지 가져오기
# 필터와 함께 사용
params = {'status': 'pending', 'priority': 'high'}
response = client._list('api/tasks/', params=params)
# 파일 필드에 url_conversion 사용
url_conversion = {'files_fields': ['files'], 'is_list': True}
generator, count = client._list(
'api/data_units/',
url_conversion=url_conversion,
list_all=True,
params={'status': 'active'}
)
# 'files' 필드의 파일 URL이 자동으로 다운로드되어 로컬 경로로 변환됨
for unit in generator:
print(unit['files']) # URL이 아닌 로컬 파일 경로
_list_all(path, url_conversion=None, params=None, **kwargs)
페이지네이션된 API 엔드포인트에서 모든 결과를 생성하는 제너레이터입니다.
이 메서드는 list_all=True일 때 _list()에 의해 내부적으로 호출됩니다. next URL을 따라가며 자동으로 페이지네이션을 처리하고, 깊은 페이지네이션에서 스택 오버플로우를 방지하기 위해 재귀 대신 반복적 접근 방식(while 루프)을 사용합니다.
주요 개선사항 (SYN-5757):
-
page_size 중복 제거:
page_size매개변수는 첫 번째 요청에만 추가됩니다. 후속 요청은 이미 모든 필요한 매개변수를 포함하는nextURL을 직접 사용합니다. -
적절한 params 처리: 사용자가 지정한 쿼리 매개변수가 첫 번째 요청에 올바르게 전달되고
nextURL을 통해 페이지네이션 전체에 보존됩니다. -
모든 페이지에 url_conversion 적용: URL 변환이 첫 번째 페이지뿐만 아니라 모든 페이지에 적용됩니다.
-
재귀 대신 반복: 더 나은 메모리 효율성과 대용량 데이터셋에서 스택 오버플로우 방지를 위해 재귀 대신 while 루프를 사용합니다.
매개변수:
path(str): 초기 URL 경로url_conversion(dict, optional): 모든 페이지에 적용params(dict, optional): 첫 번째 요청에만 사용되는 쿼리 매개변수**kwargs: 추가 요청 인자
생성:
모든 페이지의 개별 결과 항목을 지연 방식으로 가져옵니다.
예제:
# 기본: 모든 작업 반복
for task in client._list_all('api/tasks/'):
process_task(task)
# 필터와 함께
params = {'status': 'pending'}
for task in client._list_all('api/tasks/', params=params):
print(task['id'])
# 중첩된 파일 필드에 url_conversion 사용
url_conversion = {'files_fields': ['data.files', 'metadata.attachments'], 'is_list': True}
for item in client._list_all('api/items/', url_conversion=url_conversion):
print(item['data']['files']) # 로컬 경로
# 모든 결과 수집 (대용량 데이터셋의 경우 메모리 집약적)
all_results = list(client._list_all('api/tasks/'))
파일 다운로드를 위한 URL 변환
url_conversion 매개변수는 API 응답에서 URL로 참조되는 파일의 자동 다운로드를 활성화합니다. 이는 파일 참조를 포함하는 데이터 유닛, 작업 또는 모든 리소스로 작업할 때 특히 유용합니다.
URL 변환 구조
url_conversion = {
'files_fields': ['files', 'images', 'data.attachments'], # 필드 경로
'is_list': True # 항목 목록을 처리하는지 여부
}
files_fields: 필드 경로 목록 (중첩 필드를 위한 점 표기법 지원)is_list: 페이지네이션된 목록 응답의 경우True로 설정
작동 방식
- API가 파일 URL이 포함된 응답 반환
url_conversion이 URL을 포함하는 필드 식별- 파일이 임시 디렉토리에 자동으로 다운로드됨
- URL이 로컬 파일 경로로 대체됨
- 코드가 URL 대신 로컬 경로가 포함된 응답 수신
예제
# 단순 파일 필드
url_conversion = {'files_fields': ['image_url'], 'is_list': True}
generator, count = client._list(
'api/photos/',
url_conversion=url_conversion,
list_all=True
)
for photo in generator:
# photo['image_url']은 이제 URL이 아닌 로컬 Path 객체
with open(photo['image_url'], 'rb') as f:
process_image(f)
# 여러 파일 필드
url_conversion = {
'files_fields': ['thumbnail', 'full_image', 'raw_data'],
'is_list': True
}
# 점 표기법을 사용한 중첩 필드
url_conversion = {
'files_fields': ['data.files', 'metadata.preview', 'annotations.image'],
'is_list': True
}
# 더 나은 성능을 위한 비동기 다운로드
from synapse_sdk.utils.file import files_url_to_path_from_objs
results = client._list('api/data_units/')['results']
files_url_to_path_from_objs(
results,
files_fields=['files'],
is_list=True,
is_async=True # 모든 파일 동시 다운로드
)
성능 고려사항
메모리 효율성
대용량 데이터셋으로 작업할 때는 모든 결과를 메모리에 로드하는 대신 제너레이터를 사용하세요:
# ❌ 메모리 집약적 - 모든 결과 로드
all_tasks = list(client._list('api/tasks/', list_all=True)[0])
# ✅ 메모리 효율적 - 한 번에 하나씩 처리
generator, _ = client._list('api/tasks/', list_all=True)
for task in generator:
process_task(task)
# 작업이 처리되고 가비지 컬렉션될 수 있음
페이지네이션 모범 사례
- 한 페이지보다 큰 데이터셋에는 list_all=True 사용
- 기본값(100)이 최적이 아닌 경우 params에서 적절한 page_size 설정
- 파일을 처리해야 할 때만 url_conversion 사용
- 항목당 여러 파일이 있는 경우 비동기 다운로드 고려
# 대용량 데이터셋을 위한 최적 페이지네이션
params = {'page_size': 50} # 더 빠른 첫 응답을 위한 작은 페이지
generator, total = client._list(
'api/large_dataset/',
list_all=True,
params=params
)
# 진행 상황 추적과 함께 처리
from tqdm import tqdm
for item in tqdm(generator, total=total):
process_item(item)
클라이언트 믹스인에서의 사용
BaseClient 페이지네이션 메서드는 모든 클라이언트 믹스인에서 내부적으로 사용됩니다:
# DataCollectionClientMixin
def list_data_units(self, params=None, url_conversion=None, list_all=False):
return self._list('data_units/', params=params,
url_conversion=url_conversion, list_all=list_all)
# AnnotationClientMixin
def list_tasks(self, params=None, url_conversion=None, list_all=False):
return self._list('sdk/tasks/', params=params,
url_conversion=url_conversion, list_all=list_all)
참고
- BackendClient - 메인 클라이언트 구현
- AgentClient - Agent 전용 작업
- DataCollectionClientMixin - 데이터 및 파일 작업
- AnnotationClientMixin - 작업 및 주석 관리