관리자 API¶
관리자 엔드포인트는 /api/v1/admin 아래에 있습니다.
인증 방식:
- 브라우저 관리자 콘솔: /api/v1/admin/auth/login으로 시작하는 쿠키 기반 관리자 세션
- 직접 관리자 API를 호출하는 클라이언트: HTTP Basic 인증
브라우저 관리자 세션 엔드포인트:
- POST /api/v1/admin/auth/login
- GET /api/v1/admin/auth/session
- POST /api/v1/admin/auth/logout
GET /api/v1/admin/stats¶
전체 통계를 반환합니다. 스토리지 기반 모드가 필요하며, FACE_API_STORAGE_ENABLED=false이면 501을 반환합니다.
- 요청 형식: 없음
- 응답 형식: JSON (
StatsResponse)
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/stats",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.json())
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/stats", {
headers: { Authorization: `Basic ${basic}` },
});
console.log(await response.json());
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/stats");
Console.WriteLine(await response.Content.ReadAsStringAsync());
{
"total_images": 1250,
"total_jobs": 3420,
"total_faces_detected": 8910,
"avg_inference_ms": 14.52,
"storage_used_bytes": 524288000,
"jobs_by_type": { "detect": 2100, "mask": 1320 },
"jobs_by_method": { "gaussian": 800, "pixelate": 400, "solid": 120 }
}
이미지¶
GET /api/v1/admin/images¶
저장된 이미지 목록을 반환합니다. 비공개 원본 다운로드 URL과, 있으면 가장 최근 처리 결과 URL도 함께 반환합니다. 스토리지 기반 모드가 필요하며, FACE_API_STORAGE_ENABLED=false이면 501을 반환합니다.
- 요청 형식: 없음(쿼리 문자열만 사용)
- 응답 형식: JSON (
PaginatedResponse[StoredImageResponse])
아직 처리 결과가 없으면 processed_url 값은 null입니다.
FACE_API_S3_PUBLIC_ENDPOINT가 설정되어 있으면 processed_url은 공개 처리 자산 호스트를 가리킬 수 있습니다.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
page |
int | 1 | 페이지 번호 |
per_page |
int | 20 | 페이지당 항목 수 (1-100) |
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/images?page=1&per_page=10",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.json())
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/images?page=1&per_page=10", {
headers: { Authorization: `Basic ${basic}` },
});
console.log(await response.json());
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/images?page=1&per_page=10");
Console.WriteLine(await response.Content.ReadAsStringAsync());
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "photo.jpg",
"content_type": "image/jpeg",
"size_bytes": 245760,
"width": 1920,
"height": 1080,
"original_url": "https://signed.example.com/originals/...",
"processed_url": "https://static.face-api.xylolabs.com/face-api/processed/...",
"job_count": 3,
"created_at": "2026-04-06T10:30:00+00:00"
}
],
"total": 1250, "page": 1, "per_page": 10, "pages": 125
}
signed.example.com은 비공개 서명 원본 다운로드 URL 예시를 보여 주기 위한 자리표시자입니다.
static.face-api.xylolabs.com은 FACE_API_S3_PUBLIC_ENDPOINT가 설정된 경우의 공개 처리 자산 호스트 예시입니다.
GET /api/v1/admin/images/{image_id}¶
이미지 상세 정보와 관련 작업 목록을 반환합니다.
- 요청 형식: 없음
- 응답 형식: JSON (
StoredImageDetailResponse)
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.json())
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...", {
headers: { Authorization: `Basic ${basic}` },
});
console.log(await response.json());
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...");
Console.WriteLine(await response.Content.ReadAsStringAsync());
DELETE /api/v1/admin/images/{image_id}¶
이미지와 관련 작업, S3 객체를 모두 삭제합니다. 성공 시 204를 반환합니다.
- 요청 형식: 없음
- 응답 형식: 빈 바디 (
204 No Content)
import requests
from requests.auth import HTTPBasicAuth
response = requests.delete(
"https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.status_code)
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...", {
method: "DELETE",
headers: { Authorization: `Basic ${basic}` },
});
console.log(response.status);
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.DeleteAsync("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-...");
Console.WriteLine(response.StatusCode);
GET /api/v1/admin/images/{image_id}/download¶
원본 이미지 다운로드 URL로 리다이렉트(302)합니다.
- 요청 형식: 없음
- 응답 형식: 리다이렉트 (
302 Found)
curl -u admin:password -L https://face-api.xylolabs.com/api/v1/admin/images/550e8400-.../download -o original.jpg
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/images/550e8400-.../download",
auth=HTTPBasicAuth("admin", "password"),
allow_redirects=True,
)
with open("original.jpg", "wb") as f:
f.write(response.content)
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-.../download", {
headers: { Authorization: `Basic ${basic}` },
});
const blob = await response.blob();
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/images/550e8400-.../download");
await using var output = File.Create("original.jpg");
await response.Content.CopyToAsync(output);
작업¶
GET /api/v1/admin/jobs¶
작업 목록을 반환합니다(페이지네이션, 필터 지원). 스토리지 기반 모드가 필요하며, FACE_API_STORAGE_ENABLED=false이면 501을 반환합니다.
- 요청 형식: 없음(쿼리 문자열만 사용)
- 응답 형식: JSON (
PaginatedResponse[JobResponse])
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
page |
int | 1 | 페이지 번호 |
per_page |
int | 20 | 페이지당 항목 수 (1-100) |
job_type |
string | — | detect 또는 mask |
method |
string | — | 블러 방식으로 필터 |
curl -u admin:password "https://face-api.xylolabs.com/api/v1/admin/jobs?job_type=mask&method=gaussian"
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/jobs?job_type=mask&method=gaussian",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.json())
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/jobs?job_type=mask&method=gaussian", {
headers: { Authorization: `Basic ${basic}` },
});
console.log(await response.json());
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/jobs?job_type=mask&method=gaussian");
Console.WriteLine(await response.Content.ReadAsStringAsync());
GET /api/v1/admin/jobs/{job_id}¶
작업 상세 정보를 반환합니다(감지 데이터 포함).
- 요청 형식: 없음
- 응답 형식: JSON (
JobDetailResponse)
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-...",
auth=HTTPBasicAuth("admin", "password"),
)
print(response.json())
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-...", {
headers: { Authorization: `Basic ${basic}` },
});
console.log(await response.json());
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-...");
Console.WriteLine(await response.Content.ReadAsStringAsync());
GET /api/v1/admin/jobs/{job_id}/download¶
처리된 이미지 URL로 리다이렉트(302)합니다.
- 요청 형식: 없음
- 응답 형식: 리다이렉트 (
302 Found)
curl -u admin:password -L https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-.../download -o processed.jpg
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-.../download",
auth=HTTPBasicAuth("admin", "password"),
allow_redirects=True,
)
with open("processed.jpg", "wb") as f:
f.write(response.content)
const basic = btoa("admin:password");
const response = await fetch("https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-.../download", {
headers: { Authorization: `Basic ${basic}` },
});
const blob = await response.blob();
using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes("admin:password"))
);
var response = await client.GetAsync("https://face-api.xylolabs.com/api/v1/admin/jobs/550e8400-.../download");
await using var output = File.Create("processed.jpg");
await response.Content.CopyToAsync(output);
API 키¶
모든 /api/v1/admin/api-keys* 엔드포인트는 데이터베이스 기반 모드가 필요하며, DB 계층이 비활성화되어 있으면 501을 반환합니다.