ccproxy-api 0.1.0__py3-none-any.whl
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.
- ccproxy/__init__.py +4 -0
- ccproxy/__main__.py +7 -0
- ccproxy/_version.py +21 -0
- ccproxy/adapters/__init__.py +11 -0
- ccproxy/adapters/base.py +80 -0
- ccproxy/adapters/openai/__init__.py +43 -0
- ccproxy/adapters/openai/adapter.py +915 -0
- ccproxy/adapters/openai/models.py +412 -0
- ccproxy/adapters/openai/streaming.py +449 -0
- ccproxy/api/__init__.py +28 -0
- ccproxy/api/app.py +225 -0
- ccproxy/api/dependencies.py +140 -0
- ccproxy/api/middleware/__init__.py +11 -0
- ccproxy/api/middleware/auth.py +0 -0
- ccproxy/api/middleware/cors.py +55 -0
- ccproxy/api/middleware/errors.py +703 -0
- ccproxy/api/middleware/headers.py +51 -0
- ccproxy/api/middleware/logging.py +175 -0
- ccproxy/api/middleware/request_id.py +69 -0
- ccproxy/api/middleware/server_header.py +62 -0
- ccproxy/api/responses.py +84 -0
- ccproxy/api/routes/__init__.py +16 -0
- ccproxy/api/routes/claude.py +181 -0
- ccproxy/api/routes/health.py +489 -0
- ccproxy/api/routes/metrics.py +1033 -0
- ccproxy/api/routes/proxy.py +238 -0
- ccproxy/auth/__init__.py +75 -0
- ccproxy/auth/bearer.py +68 -0
- ccproxy/auth/credentials_adapter.py +93 -0
- ccproxy/auth/dependencies.py +229 -0
- ccproxy/auth/exceptions.py +79 -0
- ccproxy/auth/manager.py +102 -0
- ccproxy/auth/models.py +118 -0
- ccproxy/auth/oauth/__init__.py +26 -0
- ccproxy/auth/oauth/models.py +49 -0
- ccproxy/auth/oauth/routes.py +396 -0
- ccproxy/auth/oauth/storage.py +0 -0
- ccproxy/auth/storage/__init__.py +12 -0
- ccproxy/auth/storage/base.py +57 -0
- ccproxy/auth/storage/json_file.py +159 -0
- ccproxy/auth/storage/keyring.py +192 -0
- ccproxy/claude_sdk/__init__.py +20 -0
- ccproxy/claude_sdk/client.py +169 -0
- ccproxy/claude_sdk/converter.py +331 -0
- ccproxy/claude_sdk/options.py +120 -0
- ccproxy/cli/__init__.py +14 -0
- ccproxy/cli/commands/__init__.py +8 -0
- ccproxy/cli/commands/auth.py +553 -0
- ccproxy/cli/commands/config/__init__.py +14 -0
- ccproxy/cli/commands/config/commands.py +766 -0
- ccproxy/cli/commands/config/schema_commands.py +119 -0
- ccproxy/cli/commands/serve.py +630 -0
- ccproxy/cli/docker/__init__.py +34 -0
- ccproxy/cli/docker/adapter_factory.py +157 -0
- ccproxy/cli/docker/params.py +278 -0
- ccproxy/cli/helpers.py +144 -0
- ccproxy/cli/main.py +193 -0
- ccproxy/cli/options/__init__.py +14 -0
- ccproxy/cli/options/claude_options.py +216 -0
- ccproxy/cli/options/core_options.py +40 -0
- ccproxy/cli/options/security_options.py +48 -0
- ccproxy/cli/options/server_options.py +117 -0
- ccproxy/config/__init__.py +40 -0
- ccproxy/config/auth.py +154 -0
- ccproxy/config/claude.py +124 -0
- ccproxy/config/cors.py +79 -0
- ccproxy/config/discovery.py +87 -0
- ccproxy/config/docker_settings.py +265 -0
- ccproxy/config/loader.py +108 -0
- ccproxy/config/observability.py +158 -0
- ccproxy/config/pricing.py +88 -0
- ccproxy/config/reverse_proxy.py +31 -0
- ccproxy/config/scheduler.py +89 -0
- ccproxy/config/security.py +14 -0
- ccproxy/config/server.py +81 -0
- ccproxy/config/settings.py +534 -0
- ccproxy/config/validators.py +231 -0
- ccproxy/core/__init__.py +274 -0
- ccproxy/core/async_utils.py +675 -0
- ccproxy/core/constants.py +97 -0
- ccproxy/core/errors.py +256 -0
- ccproxy/core/http.py +328 -0
- ccproxy/core/http_transformers.py +428 -0
- ccproxy/core/interfaces.py +247 -0
- ccproxy/core/logging.py +189 -0
- ccproxy/core/middleware.py +114 -0
- ccproxy/core/proxy.py +143 -0
- ccproxy/core/system.py +38 -0
- ccproxy/core/transformers.py +259 -0
- ccproxy/core/types.py +129 -0
- ccproxy/core/validators.py +288 -0
- ccproxy/docker/__init__.py +67 -0
- ccproxy/docker/adapter.py +588 -0
- ccproxy/docker/docker_path.py +207 -0
- ccproxy/docker/middleware.py +103 -0
- ccproxy/docker/models.py +228 -0
- ccproxy/docker/protocol.py +192 -0
- ccproxy/docker/stream_process.py +264 -0
- ccproxy/docker/validators.py +173 -0
- ccproxy/models/__init__.py +123 -0
- ccproxy/models/errors.py +42 -0
- ccproxy/models/messages.py +243 -0
- ccproxy/models/requests.py +85 -0
- ccproxy/models/responses.py +227 -0
- ccproxy/models/types.py +102 -0
- ccproxy/observability/__init__.py +51 -0
- ccproxy/observability/access_logger.py +400 -0
- ccproxy/observability/context.py +447 -0
- ccproxy/observability/metrics.py +539 -0
- ccproxy/observability/pushgateway.py +366 -0
- ccproxy/observability/sse_events.py +303 -0
- ccproxy/observability/stats_printer.py +755 -0
- ccproxy/observability/storage/__init__.py +1 -0
- ccproxy/observability/storage/duckdb_simple.py +665 -0
- ccproxy/observability/storage/models.py +55 -0
- ccproxy/pricing/__init__.py +19 -0
- ccproxy/pricing/cache.py +212 -0
- ccproxy/pricing/loader.py +267 -0
- ccproxy/pricing/models.py +106 -0
- ccproxy/pricing/updater.py +309 -0
- ccproxy/scheduler/__init__.py +39 -0
- ccproxy/scheduler/core.py +335 -0
- ccproxy/scheduler/exceptions.py +34 -0
- ccproxy/scheduler/manager.py +186 -0
- ccproxy/scheduler/registry.py +150 -0
- ccproxy/scheduler/tasks.py +484 -0
- ccproxy/services/__init__.py +10 -0
- ccproxy/services/claude_sdk_service.py +614 -0
- ccproxy/services/credentials/__init__.py +55 -0
- ccproxy/services/credentials/config.py +105 -0
- ccproxy/services/credentials/manager.py +562 -0
- ccproxy/services/credentials/oauth_client.py +482 -0
- ccproxy/services/proxy_service.py +1536 -0
- ccproxy/static/.keep +0 -0
- ccproxy/testing/__init__.py +34 -0
- ccproxy/testing/config.py +148 -0
- ccproxy/testing/content_generation.py +197 -0
- ccproxy/testing/mock_responses.py +262 -0
- ccproxy/testing/response_handlers.py +161 -0
- ccproxy/testing/scenarios.py +241 -0
- ccproxy/utils/__init__.py +6 -0
- ccproxy/utils/cost_calculator.py +210 -0
- ccproxy/utils/streaming_metrics.py +199 -0
- ccproxy_api-0.1.0.dist-info/METADATA +253 -0
- ccproxy_api-0.1.0.dist-info/RECORD +148 -0
- ccproxy_api-0.1.0.dist-info/WHEEL +4 -0
- ccproxy_api-0.1.0.dist-info/entry_points.txt +2 -0
- ccproxy_api-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""Response models for Claude Proxy API Server compatible with Anthropic's API format."""
|
|
2
|
+
|
|
3
|
+
from typing import Annotated, Any, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
from .requests import MessageContent, Usage
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ToolCall(BaseModel):
|
|
11
|
+
"""Tool call made by the model."""
|
|
12
|
+
|
|
13
|
+
id: Annotated[str, Field(description="Unique identifier for the tool call")]
|
|
14
|
+
type: Annotated[Literal["function"], Field(description="Tool call type")] = (
|
|
15
|
+
"function"
|
|
16
|
+
)
|
|
17
|
+
function: Annotated[
|
|
18
|
+
dict[str, Any],
|
|
19
|
+
Field(description="Function call details including name and arguments"),
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ToolUse(BaseModel):
|
|
24
|
+
"""Tool use content block."""
|
|
25
|
+
|
|
26
|
+
type: Annotated[Literal["tool_use"], Field(description="Content type")] = "tool_use"
|
|
27
|
+
id: Annotated[str, Field(description="Unique identifier for the tool use")]
|
|
28
|
+
name: Annotated[str, Field(description="Name of the tool being used")]
|
|
29
|
+
input: Annotated[dict[str, Any], Field(description="Input parameters for the tool")]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TextResponse(BaseModel):
|
|
33
|
+
"""Text response content block."""
|
|
34
|
+
|
|
35
|
+
type: Annotated[Literal["text"], Field(description="Content type")] = "text"
|
|
36
|
+
text: Annotated[str, Field(description="The generated text content")]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
ResponseContent = TextResponse | ToolUse
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Choice(BaseModel):
|
|
43
|
+
"""Individual choice in a non-streaming response."""
|
|
44
|
+
|
|
45
|
+
index: Annotated[int, Field(description="Index of the choice")]
|
|
46
|
+
message: Annotated[dict[str, Any], Field(description="The generated message")]
|
|
47
|
+
finish_reason: Annotated[
|
|
48
|
+
str | None, Field(description="Reason why the model stopped generating")
|
|
49
|
+
] = None
|
|
50
|
+
|
|
51
|
+
model_config = ConfigDict(extra="forbid")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class StreamingChoice(BaseModel):
|
|
55
|
+
"""Individual choice in a streaming response."""
|
|
56
|
+
|
|
57
|
+
index: Annotated[int, Field(description="Index of the choice")]
|
|
58
|
+
delta: Annotated[
|
|
59
|
+
dict[str, Any], Field(description="The incremental message content")
|
|
60
|
+
]
|
|
61
|
+
finish_reason: Annotated[
|
|
62
|
+
str | None, Field(description="Reason why the model stopped generating")
|
|
63
|
+
] = None
|
|
64
|
+
|
|
65
|
+
model_config = ConfigDict(extra="forbid")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ChatCompletionResponse(BaseModel):
|
|
69
|
+
"""Response model for Claude chat completions compatible with Anthropic's API."""
|
|
70
|
+
|
|
71
|
+
id: Annotated[str, Field(description="Unique identifier for the response")]
|
|
72
|
+
type: Annotated[Literal["message"], Field(description="Response type")] = "message"
|
|
73
|
+
role: Annotated[Literal["assistant"], Field(description="Message role")] = (
|
|
74
|
+
"assistant"
|
|
75
|
+
)
|
|
76
|
+
content: Annotated[
|
|
77
|
+
list[ResponseContent],
|
|
78
|
+
Field(description="Array of content blocks in the response"),
|
|
79
|
+
]
|
|
80
|
+
model: Annotated[str, Field(description="The model used for the response")]
|
|
81
|
+
stop_reason: Annotated[
|
|
82
|
+
str | None, Field(description="Reason why the model stopped generating")
|
|
83
|
+
] = None
|
|
84
|
+
stop_sequence: Annotated[
|
|
85
|
+
str | None,
|
|
86
|
+
Field(description="The stop sequence that triggered stopping (if applicable)"),
|
|
87
|
+
] = None
|
|
88
|
+
usage: Annotated[Usage, Field(description="Token usage information")]
|
|
89
|
+
|
|
90
|
+
model_config = ConfigDict(extra="forbid", validate_assignment=True)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class StreamingChatCompletionResponse(BaseModel):
|
|
94
|
+
"""Streaming response model for Claude chat completions."""
|
|
95
|
+
|
|
96
|
+
id: Annotated[str, Field(description="Unique identifier for the response")]
|
|
97
|
+
type: Annotated[
|
|
98
|
+
Literal[
|
|
99
|
+
"message_start",
|
|
100
|
+
"message_delta",
|
|
101
|
+
"message_stop",
|
|
102
|
+
"content_block_start",
|
|
103
|
+
"content_block_delta",
|
|
104
|
+
"content_block_stop",
|
|
105
|
+
"ping",
|
|
106
|
+
],
|
|
107
|
+
Field(description="Type of streaming event"),
|
|
108
|
+
]
|
|
109
|
+
message: Annotated[
|
|
110
|
+
dict[str, Any] | None, Field(description="Message data for message events")
|
|
111
|
+
] = None
|
|
112
|
+
index: Annotated[int | None, Field(description="Index of the content block")] = None
|
|
113
|
+
content_block: Annotated[
|
|
114
|
+
dict[str, Any] | None, Field(description="Content block data")
|
|
115
|
+
] = None
|
|
116
|
+
delta: Annotated[
|
|
117
|
+
dict[str, Any] | None, Field(description="Delta data for incremental updates")
|
|
118
|
+
] = None
|
|
119
|
+
usage: Annotated[Usage | None, Field(description="Token usage information")] = None
|
|
120
|
+
|
|
121
|
+
model_config = ConfigDict(extra="forbid", validate_assignment=True)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ErrorResponse(BaseModel):
|
|
125
|
+
"""Error response model."""
|
|
126
|
+
|
|
127
|
+
type: Annotated[Literal["error"], Field(description="Response type")] = "error"
|
|
128
|
+
error: Annotated[
|
|
129
|
+
dict[str, Any], Field(description="Error details including type and message")
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
model_config = ConfigDict(extra="forbid")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class APIError(BaseModel):
|
|
136
|
+
"""API error details."""
|
|
137
|
+
|
|
138
|
+
type: Annotated[str, Field(description="Error type")]
|
|
139
|
+
message: Annotated[str, Field(description="Error message")]
|
|
140
|
+
|
|
141
|
+
model_config = ConfigDict(
|
|
142
|
+
extra="forbid", validate_by_alias=True, validate_by_name=True
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class PermissionToolAllowResponse(BaseModel):
|
|
147
|
+
"""Response model for allowed permission tool requests."""
|
|
148
|
+
|
|
149
|
+
behavior: Annotated[Literal["allow"], Field(description="Permission behavior")] = (
|
|
150
|
+
"allow"
|
|
151
|
+
)
|
|
152
|
+
updated_input: Annotated[
|
|
153
|
+
dict[str, Any],
|
|
154
|
+
Field(
|
|
155
|
+
description="Updated input parameters for the tool, or original input if unchanged",
|
|
156
|
+
alias="updatedInput",
|
|
157
|
+
),
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class PermissionToolDenyResponse(BaseModel):
|
|
164
|
+
"""Response model for denied permission tool requests."""
|
|
165
|
+
|
|
166
|
+
behavior: Annotated[Literal["deny"], Field(description="Permission behavior")] = (
|
|
167
|
+
"deny"
|
|
168
|
+
)
|
|
169
|
+
message: Annotated[
|
|
170
|
+
str,
|
|
171
|
+
Field(
|
|
172
|
+
description="Human-readable explanation of why the permission was denied"
|
|
173
|
+
),
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
model_config = ConfigDict(extra="forbid")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
PermissionToolResponse = PermissionToolAllowResponse | PermissionToolDenyResponse
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class RateLimitError(APIError):
|
|
183
|
+
"""Rate limit error."""
|
|
184
|
+
|
|
185
|
+
type: Annotated[Literal["rate_limit_error"], Field(description="Error type")] = (
|
|
186
|
+
"rate_limit_error"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class InvalidRequestError(APIError):
|
|
191
|
+
"""Invalid request error."""
|
|
192
|
+
|
|
193
|
+
type: Annotated[
|
|
194
|
+
Literal["invalid_request_error"], Field(description="Error type")
|
|
195
|
+
] = "invalid_request_error"
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class AuthenticationError(APIError):
|
|
199
|
+
"""Authentication error."""
|
|
200
|
+
|
|
201
|
+
type: Annotated[
|
|
202
|
+
Literal["authentication_error"], Field(description="Error type")
|
|
203
|
+
] = "authentication_error"
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class NotFoundError(APIError):
|
|
207
|
+
"""Not found error."""
|
|
208
|
+
|
|
209
|
+
type: Annotated[Literal["not_found_error"], Field(description="Error type")] = (
|
|
210
|
+
"not_found_error"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class OverloadedError(APIError):
|
|
215
|
+
"""Overloaded error."""
|
|
216
|
+
|
|
217
|
+
type: Annotated[Literal["overloaded_error"], Field(description="Error type")] = (
|
|
218
|
+
"overloaded_error"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class InternalServerError(APIError):
|
|
223
|
+
"""Internal server error."""
|
|
224
|
+
|
|
225
|
+
type: Annotated[
|
|
226
|
+
Literal["internal_server_error"], Field(description="Error type")
|
|
227
|
+
] = "internal_server_error"
|
ccproxy/models/types.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Common type aliases used across the ccproxy models."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal, TypeAlias
|
|
4
|
+
|
|
5
|
+
from typing_extensions import TypedDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Message and content types
|
|
9
|
+
MessageRole: TypeAlias = Literal["user", "assistant", "system", "tool"]
|
|
10
|
+
OpenAIMessageRole: TypeAlias = Literal[
|
|
11
|
+
"system", "user", "assistant", "tool", "developer"
|
|
12
|
+
]
|
|
13
|
+
ContentBlockType: TypeAlias = Literal[
|
|
14
|
+
"text", "image", "image_url", "tool_use", "thinking"
|
|
15
|
+
]
|
|
16
|
+
OpenAIContentType: TypeAlias = Literal["text", "image_url"]
|
|
17
|
+
|
|
18
|
+
# Tool-related types
|
|
19
|
+
ToolChoiceType: TypeAlias = Literal["auto", "any", "tool", "none", "required"]
|
|
20
|
+
OpenAIToolChoiceType: TypeAlias = Literal["none", "auto", "required"]
|
|
21
|
+
ToolType: TypeAlias = Literal["function", "custom"]
|
|
22
|
+
|
|
23
|
+
# Response format types
|
|
24
|
+
ResponseFormatType: TypeAlias = Literal["text", "json_object", "json_schema"]
|
|
25
|
+
|
|
26
|
+
# Service tier types
|
|
27
|
+
ServiceTier: TypeAlias = Literal["auto", "standard_only"]
|
|
28
|
+
|
|
29
|
+
# Stop reasons (re-exported from messages for convenience)
|
|
30
|
+
StopReason: TypeAlias = Literal[
|
|
31
|
+
"end_turn",
|
|
32
|
+
"max_tokens",
|
|
33
|
+
"stop_sequence",
|
|
34
|
+
"tool_use",
|
|
35
|
+
"pause_turn",
|
|
36
|
+
"refusal",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
# OpenAI finish reasons
|
|
40
|
+
OpenAIFinishReason: TypeAlias = Literal[
|
|
41
|
+
"stop", "length", "tool_calls", "content_filter"
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# Error types
|
|
45
|
+
ErrorType: TypeAlias = Literal[
|
|
46
|
+
"error",
|
|
47
|
+
"rate_limit_error",
|
|
48
|
+
"invalid_request_error",
|
|
49
|
+
"authentication_error",
|
|
50
|
+
"not_found_error",
|
|
51
|
+
"overloaded_error",
|
|
52
|
+
"internal_server_error",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
# Stream event types
|
|
56
|
+
StreamEventType: TypeAlias = Literal[
|
|
57
|
+
"message_start",
|
|
58
|
+
"message_delta",
|
|
59
|
+
"message_stop",
|
|
60
|
+
"content_block_start",
|
|
61
|
+
"content_block_delta",
|
|
62
|
+
"content_block_stop",
|
|
63
|
+
"ping",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
# Image source types
|
|
67
|
+
ImageSourceType: TypeAlias = Literal["base64", "url"]
|
|
68
|
+
|
|
69
|
+
# Modality types
|
|
70
|
+
ModalityType: TypeAlias = Literal["text", "audio"]
|
|
71
|
+
|
|
72
|
+
# Reasoning effort types (OpenAI o1 models)
|
|
73
|
+
ReasoningEffort: TypeAlias = Literal["low", "medium", "high"]
|
|
74
|
+
|
|
75
|
+
# OpenAI object types
|
|
76
|
+
OpenAIObjectType: TypeAlias = Literal[
|
|
77
|
+
"chat.completion", "chat.completion.chunk", "model", "list"
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
# Permission behavior types
|
|
81
|
+
PermissionBehavior: TypeAlias = Literal["allow", "deny"]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Usage and streaming related types
|
|
85
|
+
class UsageData(TypedDict, total=False):
|
|
86
|
+
"""Token usage data extracted from streaming or non-streaming responses."""
|
|
87
|
+
|
|
88
|
+
input_tokens: int | None
|
|
89
|
+
output_tokens: int | None
|
|
90
|
+
cache_read_input_tokens: int | None
|
|
91
|
+
cache_creation_input_tokens: int | None
|
|
92
|
+
event_type: StreamEventType | None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class StreamingTokenMetrics(TypedDict, total=False):
|
|
96
|
+
"""Accumulated token metrics during streaming."""
|
|
97
|
+
|
|
98
|
+
tokens_input: int | None
|
|
99
|
+
tokens_output: int | None
|
|
100
|
+
cache_read_tokens: int | None
|
|
101
|
+
cache_write_tokens: int | None
|
|
102
|
+
cost_usd: float | None
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Observability module for the CCProxy API.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive observability capabilities including metrics collection,
|
|
5
|
+
structured logging, request context tracking, and observability pipeline management.
|
|
6
|
+
|
|
7
|
+
The observability system follows a hybrid architecture that combines:
|
|
8
|
+
- Real-time metrics collection and aggregation
|
|
9
|
+
- Structured logging with correlation IDs
|
|
10
|
+
- Request context propagation across service boundaries
|
|
11
|
+
- Pluggable pipeline for metrics export and alerting
|
|
12
|
+
|
|
13
|
+
Components:
|
|
14
|
+
- metrics: Core metrics collection, aggregation, and export functionality
|
|
15
|
+
- logging: Structured logging configuration and context-aware loggers
|
|
16
|
+
- context: Request context tracking and correlation across async operations
|
|
17
|
+
- pipeline: Observability data pipeline for metrics export and alerting
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .context import (
|
|
21
|
+
RequestContext,
|
|
22
|
+
get_context_tracker,
|
|
23
|
+
request_context,
|
|
24
|
+
timed_operation,
|
|
25
|
+
tracked_request_context,
|
|
26
|
+
)
|
|
27
|
+
from .metrics import PrometheusMetrics, get_metrics, reset_metrics
|
|
28
|
+
from .pushgateway import (
|
|
29
|
+
PushgatewayClient,
|
|
30
|
+
get_pushgateway_client,
|
|
31
|
+
reset_pushgateway_client,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Configuration
|
|
37
|
+
# Context management
|
|
38
|
+
"RequestContext",
|
|
39
|
+
"request_context",
|
|
40
|
+
"tracked_request_context",
|
|
41
|
+
"timed_operation",
|
|
42
|
+
"get_context_tracker",
|
|
43
|
+
# Prometheus metrics
|
|
44
|
+
"PrometheusMetrics",
|
|
45
|
+
"get_metrics",
|
|
46
|
+
"reset_metrics",
|
|
47
|
+
# Pushgateway
|
|
48
|
+
"PushgatewayClient",
|
|
49
|
+
"get_pushgateway_client",
|
|
50
|
+
"reset_pushgateway_client",
|
|
51
|
+
]
|