sendgo-fastapi 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sendgo_fastapi-1.0.0/LICENSE +21 -0
- sendgo_fastapi-1.0.0/PKG-INFO +423 -0
- sendgo_fastapi-1.0.0/README.md +397 -0
- sendgo_fastapi-1.0.0/pyproject.toml +37 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi/__init__.py +26 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi/dependencies.py +75 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi/settings.py +32 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi.egg-info/PKG-INFO +423 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi.egg-info/SOURCES.txt +11 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi.egg-info/dependency_links.txt +1 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi.egg-info/requires.txt +3 -0
- sendgo_fastapi-1.0.0/sendgo_fastapi.egg-info/top_level.txt +1 -0
- sendgo_fastapi-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sendgo <dev@sendgo.io>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sendgo-fastapi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Sendgo FastAPI 확장 — 카카오 알림톡/친구톡, SMS/LMS/MMS
|
|
5
|
+
Author-email: Sendgo <dev@sendgo.io>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://sendgo.io
|
|
8
|
+
Project-URL: Repository, https://github.com/send-go/fastapi
|
|
9
|
+
Keywords: sendgo,fastapi,kakao,alimtalk,sms,notification,korea
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Web Environment
|
|
12
|
+
Classifier: Framework :: FastAPI
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: sendgo-python>=1.0
|
|
23
|
+
Requires-Dist: fastapi>=0.110
|
|
24
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# sendgo-fastapi
|
|
28
|
+
|
|
29
|
+
> **FastAPI에서 카카오 알림톡, 친구톡, SMS를 가장 쉽게 발송하는 공식 FastAPI 확장 패키지**
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/sendgo-fastapi/)
|
|
32
|
+
[](https://python.org)
|
|
33
|
+
[](https://fastapi.tiangolo.com)
|
|
34
|
+
[](LICENSE)
|
|
35
|
+
|
|
36
|
+
`sendgo-fastapi`는 [`sendgo-python`](https://github.com/send-go/python) 코어를 확장한 **FastAPI 전용 패키지**입니다.
|
|
37
|
+
환경변수 기반 설정 로딩(pydantic-settings), 의존성 주입(`Depends`), lifespan 초기화 등 FastAPI 통합을 완벽하게 제공합니다.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 목차
|
|
42
|
+
|
|
43
|
+
- [설치](#설치)
|
|
44
|
+
- [빠른 시작](#빠른-시작)
|
|
45
|
+
- [의존성 주입 사용법](#의존성-주입-사용법)
|
|
46
|
+
- [lifespan 초기화](#lifespan-초기화)
|
|
47
|
+
- [상세 사용법](#상세-사용법)
|
|
48
|
+
- [알림톡](#알림톡)
|
|
49
|
+
- [친구톡](#친구톡)
|
|
50
|
+
- [SMS / LMS / MMS](#sms--lms--mms)
|
|
51
|
+
- [서비스 클래스 패턴](#서비스-클래스-패턴)
|
|
52
|
+
- [백그라운드 태스크 비동기 발송](#백그라운드-태스크-비동기-발송)
|
|
53
|
+
- [예외 처리](#예외-처리)
|
|
54
|
+
- [설정 옵션](#설정-옵션)
|
|
55
|
+
- [자주 묻는 질문](#자주-묻는-질문-faq)
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 설치
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install sendgo-fastapi
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
코어 패키지 `sendgo-python`은 의존성으로 자동 설치됩니다.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 빠른 시작
|
|
70
|
+
|
|
71
|
+
### 1단계 — 환경변수 설정 (`.env` 또는 셸 환경)
|
|
72
|
+
|
|
73
|
+
모든 환경변수는 `SENDGO_` 접두사를 사용하며, `SendgoSettings`가 자동으로 바인딩합니다.
|
|
74
|
+
|
|
75
|
+
```env
|
|
76
|
+
SENDGO_ACCESS_KEY=your_access_key
|
|
77
|
+
SENDGO_SECRET_KEY=your_secret_key
|
|
78
|
+
SENDGO_KAKAO_SENDER_KEY=your_kakao_key
|
|
79
|
+
SENDGO_SMS_SENDER_KEY=your_sms_key
|
|
80
|
+
SENDGO_API_VERSION=v2
|
|
81
|
+
SENDGO_BASE_URL=https://sendgo.io
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2단계 — 알림톡 전송
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from fastapi import FastAPI
|
|
88
|
+
from sendgo_fastapi import SendgoDep
|
|
89
|
+
|
|
90
|
+
app = FastAPI()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@app.post("/notify")
|
|
94
|
+
async def notify(sendgo: SendgoDep):
|
|
95
|
+
sendgo.alimtalk.send(
|
|
96
|
+
template_code="ORDER_CONFIRM_001",
|
|
97
|
+
contacts=[
|
|
98
|
+
{"contact": "01012345678", "name": "홍길동", "var1": "ORD-001", "var2": "29,000원"},
|
|
99
|
+
],
|
|
100
|
+
)
|
|
101
|
+
return {"success": True}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`SendgoDep`은 `Annotated[Sendgo, Depends(get_sendgo)]`의 별칭으로, 라우트 인자에
|
|
105
|
+
타입힌트만 추가하면 Sendgo 클라이언트가 자동으로 주입됩니다.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 의존성 주입 사용법
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from fastapi import FastAPI
|
|
113
|
+
from sendgo_fastapi import SendgoDep
|
|
114
|
+
|
|
115
|
+
app = FastAPI()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@app.post("/verify")
|
|
119
|
+
async def send_verification(sendgo: SendgoDep):
|
|
120
|
+
# SMS 발송
|
|
121
|
+
sendgo.sms.send_sms(
|
|
122
|
+
content="[인증] 인증번호: 123456 (5분 이내 입력)",
|
|
123
|
+
contacts=[{"contact": "01012345678"}],
|
|
124
|
+
)
|
|
125
|
+
return {"success": True}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
환경변수 기반 클라이언트는 최초 요청 시 한 번만 생성되어 메모이즈됩니다.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## lifespan 초기화
|
|
133
|
+
|
|
134
|
+
애플리케이션 시작 시점에 클라이언트를 미리 생성해 `app.state.sendgo`에
|
|
135
|
+
저장하려면 `init_sendgo(app)`을 lifespan에서 호출하세요. 이 경우
|
|
136
|
+
`SendgoDep`/`get_sendgo`는 저장된 인스턴스를 우선 사용합니다.
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from contextlib import asynccontextmanager
|
|
140
|
+
|
|
141
|
+
from fastapi import FastAPI
|
|
142
|
+
from sendgo_fastapi import SendgoDep, init_sendgo
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@asynccontextmanager
|
|
146
|
+
async def lifespan(app: FastAPI):
|
|
147
|
+
# 시작 시점에 환경변수 기반 클라이언트를 생성해 app.state.sendgo 에 저장
|
|
148
|
+
init_sendgo(app)
|
|
149
|
+
yield
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
app = FastAPI(lifespan=lifespan)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@app.post("/notify")
|
|
156
|
+
async def notify(sendgo: SendgoDep):
|
|
157
|
+
sendgo.alimtalk.send(
|
|
158
|
+
template_code="ORDER_CONFIRM_001",
|
|
159
|
+
contacts=[{"contact": "01012345678", "var1": "ORD-001"}],
|
|
160
|
+
)
|
|
161
|
+
return {"success": True}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
커스텀 설정을 직접 주입할 수도 있습니다.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from sendgo_fastapi import SendgoSettings, init_sendgo
|
|
168
|
+
|
|
169
|
+
init_sendgo(app, SendgoSettings(access_key="...", secret_key="..."))
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 상세 사용법
|
|
175
|
+
|
|
176
|
+
### 알림톡
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from sendgo_fastapi import SendgoDep
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@app.post("/orders/{order_id}/confirm")
|
|
183
|
+
async def confirm(order_id: str, sendgo: SendgoDep):
|
|
184
|
+
# 다건 발송
|
|
185
|
+
sendgo.alimtalk.send(
|
|
186
|
+
template_code="ORDER_CONFIRM_001",
|
|
187
|
+
contacts=[
|
|
188
|
+
{"contact": "01011111111", "name": "홍길동", "var1": "ORD-001", "var2": "29,000원"},
|
|
189
|
+
{"contact": "01022222222", "name": "김철수", "var1": "ORD-002", "var2": "15,000원"},
|
|
190
|
+
],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# 예약 발송
|
|
194
|
+
sendgo.alimtalk.send(
|
|
195
|
+
template_code="PROMO_SUMMER_2026",
|
|
196
|
+
schedule_type="SCHEDULED",
|
|
197
|
+
at="2026-07-28 09:00:00",
|
|
198
|
+
contacts=[{"contact": "01012345678", "var1": "여름 한정 50% 할인"}],
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# SMS 자동 대체 발송
|
|
202
|
+
sendgo.alimtalk.send(
|
|
203
|
+
template_code="DELIVERY_START_001",
|
|
204
|
+
replace_sms="Y",
|
|
205
|
+
sms_subject="[배송 시작 안내]",
|
|
206
|
+
sms_content="주문하신 상품이 출고되었습니다.\n송장번호: 1234567890",
|
|
207
|
+
contacts=[{"contact": "01012345678", "var1": "ORD-001", "var2": "1234567890"}],
|
|
208
|
+
)
|
|
209
|
+
return {"success": True}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 친구톡
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
# 텍스트형
|
|
216
|
+
sendgo.friendtalk.send(
|
|
217
|
+
content="안녕하세요! 7월 한정 특가 이벤트를 확인해보세요.",
|
|
218
|
+
contacts=[{"contact": "01012345678"}],
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# 이미지형
|
|
222
|
+
sendgo.friendtalk.send(
|
|
223
|
+
message_type="FI",
|
|
224
|
+
content="이번 주 특가 상품을 확인하세요!",
|
|
225
|
+
image_url="https://cdn.example.com/banner.jpg",
|
|
226
|
+
image_link="https://example.com/event",
|
|
227
|
+
contacts=[{"contact": "01012345678"}],
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# 버튼 포함
|
|
231
|
+
sendgo.friendtalk.send(
|
|
232
|
+
content="7월 쿠폰이 도착했습니다! 지금 바로 사용하세요.",
|
|
233
|
+
buttons=[
|
|
234
|
+
{"name": "쿠폰 받기", "type": "WL", "linkMo": "https://example.com/coupon"},
|
|
235
|
+
{"name": "고객센터", "type": "WL", "linkMo": "https://example.com/cs"},
|
|
236
|
+
],
|
|
237
|
+
contacts=[{"contact": "01012345678"}],
|
|
238
|
+
)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### SMS / LMS / MMS
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# SMS (90자 이하)
|
|
245
|
+
sendgo.sms.send_sms(
|
|
246
|
+
content="[Sendgo] 인증번호: 123456 (5분 이내 입력)",
|
|
247
|
+
contacts=[{"contact": "01012345678"}],
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
# LMS (장문, 2,000자 이하)
|
|
251
|
+
sendgo.sms.send_lms(
|
|
252
|
+
subject="[중요] 서비스 점검 안내",
|
|
253
|
+
content="안녕하세요. 서비스 점검이 예정되어 있습니다.\n\n■ 일시: 2026-07-25 02:00 ~ 06:00",
|
|
254
|
+
contacts=[{"contact": "01012345678"}],
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# MMS (이미지 포함)
|
|
258
|
+
sendgo.sms.send_mms(
|
|
259
|
+
subject="[이벤트] 7월 특가",
|
|
260
|
+
content="이번 달 특가 상품을 확인하세요!",
|
|
261
|
+
contacts=[{"contact": "01011111111"}, {"contact": "01022222222"}],
|
|
262
|
+
)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 서비스 클래스 패턴
|
|
268
|
+
|
|
269
|
+
라우트에서 직접 발송하는 대신, 재사용 가능한 서비스 클래스로 분리할 수 있습니다.
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
# app/services/notification.py
|
|
273
|
+
from sendgo import Sendgo
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class NotificationService:
|
|
277
|
+
def __init__(self, sendgo: Sendgo) -> None:
|
|
278
|
+
self._sendgo = sendgo
|
|
279
|
+
|
|
280
|
+
def send_order_confirm(self, phone: str, order_no: str, amount: int) -> None:
|
|
281
|
+
self._sendgo.alimtalk.send(
|
|
282
|
+
template_code="ORDER_CONFIRM_001",
|
|
283
|
+
contacts=[{"contact": phone, "var1": order_no, "var2": f"{amount:,}원"}],
|
|
284
|
+
)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
# app/main.py
|
|
289
|
+
from typing import Annotated
|
|
290
|
+
|
|
291
|
+
from fastapi import Depends, FastAPI
|
|
292
|
+
from sendgo_fastapi import SendgoDep
|
|
293
|
+
|
|
294
|
+
from app.services.notification import NotificationService
|
|
295
|
+
|
|
296
|
+
app = FastAPI()
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def get_notification_service(sendgo: SendgoDep) -> NotificationService:
|
|
300
|
+
return NotificationService(sendgo)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
NotificationDep = Annotated[NotificationService, Depends(get_notification_service)]
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@app.post("/orders/{order_id}/confirm")
|
|
307
|
+
async def confirm(order_id: str, service: NotificationDep):
|
|
308
|
+
service.send_order_confirm("01012345678", order_id, 29000)
|
|
309
|
+
return {"success": True}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## 백그라운드 태스크 비동기 발송
|
|
315
|
+
|
|
316
|
+
발송을 요청 응답과 분리하려면 FastAPI의 `BackgroundTasks`를 사용하세요.
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
from fastapi import BackgroundTasks, FastAPI
|
|
320
|
+
from sendgo_fastapi import SendgoDep
|
|
321
|
+
|
|
322
|
+
app = FastAPI()
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
@app.post("/notify")
|
|
326
|
+
async def notify(sendgo: SendgoDep, background_tasks: BackgroundTasks):
|
|
327
|
+
background_tasks.add_task(
|
|
328
|
+
sendgo.alimtalk.send,
|
|
329
|
+
template_code="ORDER_CONFIRM_001",
|
|
330
|
+
contacts=[{"contact": "01012345678", "var1": "ORD-001"}],
|
|
331
|
+
)
|
|
332
|
+
return {"success": True, "queued": True}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 예외 처리
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
from fastapi import FastAPI, HTTPException
|
|
341
|
+
from sendgo import SendgoError
|
|
342
|
+
from sendgo_fastapi import SendgoDep
|
|
343
|
+
|
|
344
|
+
app = FastAPI()
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@app.post("/notify")
|
|
348
|
+
async def notify(sendgo: SendgoDep):
|
|
349
|
+
try:
|
|
350
|
+
sendgo.alimtalk.send(
|
|
351
|
+
template_code="ORDER_CONFIRM_001",
|
|
352
|
+
contacts=[{"contact": "01012345678", "var1": "ORD-001"}],
|
|
353
|
+
)
|
|
354
|
+
except SendgoError as e:
|
|
355
|
+
raise HTTPException(status_code=502, detail=f"Sendgo 발송 실패: {e}")
|
|
356
|
+
return {"success": True}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
전역 예외 핸들러로 처리할 수도 있습니다.
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
from fastapi import Request
|
|
363
|
+
from fastapi.responses import JSONResponse
|
|
364
|
+
from sendgo import SendgoError
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
@app.exception_handler(SendgoError)
|
|
368
|
+
async def sendgo_exception_handler(request: Request, exc: SendgoError):
|
|
369
|
+
return JSONResponse(status_code=502, content={"detail": str(exc)})
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## 설정 옵션
|
|
375
|
+
|
|
376
|
+
`SendgoSettings`(pydantic-settings)가 `SENDGO_` 접두사 환경변수를 자동으로 읽습니다.
|
|
377
|
+
|
|
378
|
+
| 필드 | 환경변수 | 기본값 | 설명 |
|
|
379
|
+
|------|---------|--------|------|
|
|
380
|
+
| `access_key` | `SENDGO_ACCESS_KEY` | — | Sendgo 액세스 키 (필수) |
|
|
381
|
+
| `secret_key` | `SENDGO_SECRET_KEY` | — | Sendgo 시크릿 키 (필수) |
|
|
382
|
+
| `kakao_sender_key` | `SENDGO_KAKAO_SENDER_KEY` | `None` | 카카오 발신프로필 키 |
|
|
383
|
+
| `sms_sender_key` | `SENDGO_SMS_SENDER_KEY` | `None` | SMS 발신자 키 |
|
|
384
|
+
| `api_version` | `SENDGO_API_VERSION` | `"v2"` | API 버전 |
|
|
385
|
+
| `base_url` | `SENDGO_BASE_URL` | `"https://sendgo.io"` | API 기본 URL |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 자주 묻는 질문 (FAQ)
|
|
390
|
+
|
|
391
|
+
**Q. `sendgo-python`과의 차이는 무엇인가요?**
|
|
392
|
+
A. `sendgo-python`은 프레임워크 독립적인 순수 Python 코어 패키지입니다. `sendgo-fastapi`는 이를 확장해 pydantic-settings 기반 환경변수 로딩, `Depends` 의존성 주입, lifespan 초기화 등 FastAPI 통합을 추가합니다.
|
|
393
|
+
|
|
394
|
+
**Q. 환경변수 없이 설정을 직접 지정할 수 있나요?**
|
|
395
|
+
A. 네, `init_sendgo(app, SendgoSettings(access_key="...", secret_key="..."))`처럼 설정 객체를 직접 주입할 수 있습니다.
|
|
396
|
+
|
|
397
|
+
**Q. `get_sendgo`는 요청마다 새 클라이언트를 만드나요?**
|
|
398
|
+
A. 아니요. 환경변수 기반 싱글턴 또는 `app.state.sendgo`에 저장된 인스턴스를 재사용합니다.
|
|
399
|
+
|
|
400
|
+
**Q. 테스트 시 Sendgo를 Mock 처리하려면?**
|
|
401
|
+
A. `app.dependency_overrides[get_sendgo] = lambda: mock_client`로 의존성을 교체하면 됩니다.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 관련 패키지
|
|
406
|
+
|
|
407
|
+
| 언어/프레임워크 | 패키지 | GitHub |
|
|
408
|
+
|----------------|--------|--------|
|
|
409
|
+
| Python (순수) | `sendgo-python` | [python](https://github.com/send-go/python) |
|
|
410
|
+
| Django | `sendgo-django` | [django](https://github.com/send-go/django) |
|
|
411
|
+
| PHP (순수) | `sendgo/php` | [php](https://github.com/send-go/php) |
|
|
412
|
+
| Laravel | `sendgo/laravel` | [laravel](https://github.com/send-go/laravel) |
|
|
413
|
+
| 전체 목록 | — | [send-go GitHub 조직](https://github.com/send-go) |
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## 라이선스
|
|
418
|
+
|
|
419
|
+
MIT License © 2026 [Sendgo](https://sendgo.io)
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
*키워드: 카카오 알림톡 FastAPI, 카카오 친구톡 FastAPI, SMS 발송 FastAPI, 알림톡 FastAPI 패키지, FastAPI 카카오 API 연동, FastAPI 의존성 주입, Sendgo FastAPI SDK*
|