ccproxy-api 0.1.7__py3-none-any.whl → 0.2.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/api/__init__.py +1 -15
- ccproxy/api/app.py +434 -219
- ccproxy/api/bootstrap.py +30 -0
- ccproxy/api/decorators.py +85 -0
- ccproxy/api/dependencies.py +144 -168
- ccproxy/api/format_validation.py +54 -0
- ccproxy/api/middleware/cors.py +6 -3
- ccproxy/api/middleware/errors.py +388 -524
- ccproxy/api/middleware/hooks.py +563 -0
- ccproxy/api/middleware/normalize_headers.py +59 -0
- ccproxy/api/middleware/request_id.py +35 -16
- ccproxy/api/middleware/streaming_hooks.py +292 -0
- ccproxy/api/routes/__init__.py +5 -14
- ccproxy/api/routes/health.py +39 -672
- ccproxy/api/routes/plugins.py +277 -0
- ccproxy/auth/__init__.py +2 -19
- ccproxy/auth/bearer.py +25 -15
- ccproxy/auth/dependencies.py +123 -157
- ccproxy/auth/exceptions.py +0 -12
- ccproxy/auth/manager.py +35 -49
- ccproxy/auth/managers/__init__.py +10 -0
- ccproxy/auth/managers/base.py +523 -0
- ccproxy/auth/managers/base_enhanced.py +63 -0
- ccproxy/auth/managers/token_snapshot.py +77 -0
- ccproxy/auth/models/base.py +65 -0
- ccproxy/auth/models/credentials.py +40 -0
- ccproxy/auth/oauth/__init__.py +4 -18
- ccproxy/auth/oauth/base.py +533 -0
- ccproxy/auth/oauth/cli_errors.py +37 -0
- ccproxy/auth/oauth/flows.py +430 -0
- ccproxy/auth/oauth/protocol.py +366 -0
- ccproxy/auth/oauth/registry.py +408 -0
- ccproxy/auth/oauth/router.py +396 -0
- ccproxy/auth/oauth/routes.py +186 -113
- ccproxy/auth/oauth/session.py +151 -0
- ccproxy/auth/oauth/templates.py +342 -0
- ccproxy/auth/storage/__init__.py +2 -5
- ccproxy/auth/storage/base.py +279 -5
- ccproxy/auth/storage/generic.py +134 -0
- ccproxy/cli/__init__.py +1 -2
- ccproxy/cli/_settings_help.py +351 -0
- ccproxy/cli/commands/auth.py +1519 -793
- ccproxy/cli/commands/config/commands.py +209 -276
- ccproxy/cli/commands/plugins.py +669 -0
- ccproxy/cli/commands/serve.py +75 -810
- ccproxy/cli/commands/status.py +254 -0
- ccproxy/cli/decorators.py +83 -0
- ccproxy/cli/helpers.py +22 -60
- ccproxy/cli/main.py +359 -10
- ccproxy/cli/options/claude_options.py +0 -25
- ccproxy/config/__init__.py +7 -11
- ccproxy/config/core.py +227 -0
- ccproxy/config/env_generator.py +232 -0
- ccproxy/config/runtime.py +67 -0
- ccproxy/config/security.py +36 -3
- ccproxy/config/settings.py +382 -441
- ccproxy/config/toml_generator.py +299 -0
- ccproxy/config/utils.py +452 -0
- ccproxy/core/__init__.py +7 -271
- ccproxy/{_version.py → core/_version.py} +16 -3
- ccproxy/core/async_task_manager.py +516 -0
- ccproxy/core/async_utils.py +47 -14
- ccproxy/core/auth/__init__.py +6 -0
- ccproxy/core/constants.py +16 -50
- ccproxy/core/errors.py +53 -0
- ccproxy/core/id_utils.py +20 -0
- ccproxy/core/interfaces.py +16 -123
- ccproxy/core/logging.py +473 -18
- ccproxy/core/plugins/__init__.py +77 -0
- ccproxy/core/plugins/cli_discovery.py +211 -0
- ccproxy/core/plugins/declaration.py +455 -0
- ccproxy/core/plugins/discovery.py +604 -0
- ccproxy/core/plugins/factories.py +967 -0
- ccproxy/core/plugins/hooks/__init__.py +30 -0
- ccproxy/core/plugins/hooks/base.py +58 -0
- ccproxy/core/plugins/hooks/events.py +46 -0
- ccproxy/core/plugins/hooks/implementations/__init__.py +16 -0
- ccproxy/core/plugins/hooks/implementations/formatters/__init__.py +11 -0
- ccproxy/core/plugins/hooks/implementations/formatters/json.py +552 -0
- ccproxy/core/plugins/hooks/implementations/formatters/raw.py +370 -0
- ccproxy/core/plugins/hooks/implementations/http_tracer.py +431 -0
- ccproxy/core/plugins/hooks/layers.py +44 -0
- ccproxy/core/plugins/hooks/manager.py +186 -0
- ccproxy/core/plugins/hooks/registry.py +139 -0
- ccproxy/core/plugins/hooks/thread_manager.py +203 -0
- ccproxy/core/plugins/hooks/types.py +22 -0
- ccproxy/core/plugins/interfaces.py +416 -0
- ccproxy/core/plugins/loader.py +166 -0
- ccproxy/core/plugins/middleware.py +233 -0
- ccproxy/core/plugins/models.py +59 -0
- ccproxy/core/plugins/protocol.py +180 -0
- ccproxy/core/plugins/runtime.py +519 -0
- ccproxy/{observability/context.py → core/request_context.py} +137 -94
- ccproxy/core/status_report.py +211 -0
- ccproxy/core/transformers.py +13 -8
- ccproxy/data/claude_headers_fallback.json +540 -19
- ccproxy/data/codex_headers_fallback.json +114 -7
- ccproxy/http/__init__.py +30 -0
- ccproxy/http/base.py +95 -0
- ccproxy/http/client.py +323 -0
- ccproxy/http/hooks.py +642 -0
- ccproxy/http/pool.py +279 -0
- ccproxy/llms/formatters/__init__.py +7 -0
- ccproxy/llms/formatters/anthropic_to_openai/__init__.py +55 -0
- ccproxy/llms/formatters/anthropic_to_openai/errors.py +65 -0
- ccproxy/llms/formatters/anthropic_to_openai/requests.py +356 -0
- ccproxy/llms/formatters/anthropic_to_openai/responses.py +153 -0
- ccproxy/llms/formatters/anthropic_to_openai/streams.py +1546 -0
- ccproxy/llms/formatters/base.py +140 -0
- ccproxy/llms/formatters/base_model.py +33 -0
- ccproxy/llms/formatters/common/__init__.py +51 -0
- ccproxy/llms/formatters/common/identifiers.py +48 -0
- ccproxy/llms/formatters/common/streams.py +254 -0
- ccproxy/llms/formatters/common/thinking.py +74 -0
- ccproxy/llms/formatters/common/usage.py +135 -0
- ccproxy/llms/formatters/constants.py +55 -0
- ccproxy/llms/formatters/context.py +116 -0
- ccproxy/llms/formatters/mapping.py +33 -0
- ccproxy/llms/formatters/openai_to_anthropic/__init__.py +55 -0
- ccproxy/llms/formatters/openai_to_anthropic/_helpers.py +141 -0
- ccproxy/llms/formatters/openai_to_anthropic/errors.py +53 -0
- ccproxy/llms/formatters/openai_to_anthropic/requests.py +674 -0
- ccproxy/llms/formatters/openai_to_anthropic/responses.py +285 -0
- ccproxy/llms/formatters/openai_to_anthropic/streams.py +530 -0
- ccproxy/llms/formatters/openai_to_openai/__init__.py +53 -0
- ccproxy/llms/formatters/openai_to_openai/_helpers.py +325 -0
- ccproxy/llms/formatters/openai_to_openai/errors.py +6 -0
- ccproxy/llms/formatters/openai_to_openai/requests.py +388 -0
- ccproxy/llms/formatters/openai_to_openai/responses.py +594 -0
- ccproxy/llms/formatters/openai_to_openai/streams.py +1832 -0
- ccproxy/llms/formatters/utils.py +306 -0
- ccproxy/llms/models/__init__.py +9 -0
- ccproxy/llms/models/anthropic.py +619 -0
- ccproxy/llms/models/openai.py +844 -0
- ccproxy/llms/streaming/__init__.py +26 -0
- ccproxy/llms/streaming/accumulators.py +1074 -0
- ccproxy/llms/streaming/formatters.py +251 -0
- ccproxy/{adapters/openai/streaming.py → llms/streaming/processors.py} +193 -240
- ccproxy/models/__init__.py +8 -159
- ccproxy/models/detection.py +92 -193
- ccproxy/models/provider.py +75 -0
- ccproxy/plugins/access_log/README.md +32 -0
- ccproxy/plugins/access_log/__init__.py +20 -0
- ccproxy/plugins/access_log/config.py +33 -0
- ccproxy/plugins/access_log/formatter.py +126 -0
- ccproxy/plugins/access_log/hook.py +763 -0
- ccproxy/plugins/access_log/logger.py +254 -0
- ccproxy/plugins/access_log/plugin.py +137 -0
- ccproxy/plugins/access_log/writer.py +109 -0
- ccproxy/plugins/analytics/README.md +24 -0
- ccproxy/plugins/analytics/__init__.py +1 -0
- ccproxy/plugins/analytics/config.py +5 -0
- ccproxy/plugins/analytics/ingest.py +85 -0
- ccproxy/plugins/analytics/models.py +97 -0
- ccproxy/plugins/analytics/plugin.py +121 -0
- ccproxy/plugins/analytics/routes.py +163 -0
- ccproxy/plugins/analytics/service.py +284 -0
- ccproxy/plugins/claude_api/README.md +29 -0
- ccproxy/plugins/claude_api/__init__.py +10 -0
- ccproxy/plugins/claude_api/adapter.py +829 -0
- ccproxy/plugins/claude_api/config.py +52 -0
- ccproxy/plugins/claude_api/detection_service.py +461 -0
- ccproxy/plugins/claude_api/health.py +175 -0
- ccproxy/plugins/claude_api/hooks.py +284 -0
- ccproxy/plugins/claude_api/models.py +256 -0
- ccproxy/plugins/claude_api/plugin.py +298 -0
- ccproxy/plugins/claude_api/routes.py +118 -0
- ccproxy/plugins/claude_api/streaming_metrics.py +68 -0
- ccproxy/plugins/claude_api/tasks.py +84 -0
- ccproxy/plugins/claude_sdk/README.md +35 -0
- ccproxy/plugins/claude_sdk/__init__.py +80 -0
- ccproxy/plugins/claude_sdk/adapter.py +749 -0
- ccproxy/plugins/claude_sdk/auth.py +57 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/client.py +63 -39
- ccproxy/plugins/claude_sdk/config.py +210 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/converter.py +6 -6
- ccproxy/plugins/claude_sdk/detection_service.py +163 -0
- ccproxy/{services/claude_sdk_service.py → plugins/claude_sdk/handler.py} +123 -304
- ccproxy/plugins/claude_sdk/health.py +113 -0
- ccproxy/plugins/claude_sdk/hooks.py +115 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/manager.py +42 -32
- ccproxy/{claude_sdk → plugins/claude_sdk}/message_queue.py +8 -8
- ccproxy/{models/claude_sdk.py → plugins/claude_sdk/models.py} +64 -16
- ccproxy/plugins/claude_sdk/options.py +154 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/parser.py +23 -5
- ccproxy/plugins/claude_sdk/plugin.py +269 -0
- ccproxy/plugins/claude_sdk/routes.py +104 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/session_client.py +124 -12
- ccproxy/plugins/claude_sdk/session_pool.py +700 -0
- ccproxy/{claude_sdk → plugins/claude_sdk}/stream_handle.py +48 -43
- ccproxy/{claude_sdk → plugins/claude_sdk}/stream_worker.py +22 -18
- ccproxy/{claude_sdk → plugins/claude_sdk}/streaming.py +50 -16
- ccproxy/plugins/claude_sdk/tasks.py +97 -0
- ccproxy/plugins/claude_shared/README.md +18 -0
- ccproxy/plugins/claude_shared/__init__.py +12 -0
- ccproxy/plugins/claude_shared/model_defaults.py +171 -0
- ccproxy/plugins/codex/README.md +35 -0
- ccproxy/plugins/codex/__init__.py +6 -0
- ccproxy/plugins/codex/adapter.py +635 -0
- ccproxy/{config/codex.py → plugins/codex/config.py} +78 -12
- ccproxy/plugins/codex/detection_service.py +544 -0
- ccproxy/plugins/codex/health.py +162 -0
- ccproxy/plugins/codex/hooks.py +263 -0
- ccproxy/plugins/codex/model_defaults.py +39 -0
- ccproxy/plugins/codex/models.py +263 -0
- ccproxy/plugins/codex/plugin.py +275 -0
- ccproxy/plugins/codex/routes.py +129 -0
- ccproxy/plugins/codex/streaming_metrics.py +324 -0
- ccproxy/plugins/codex/tasks.py +106 -0
- ccproxy/plugins/codex/utils/__init__.py +1 -0
- ccproxy/plugins/codex/utils/sse_parser.py +106 -0
- ccproxy/plugins/command_replay/README.md +34 -0
- ccproxy/plugins/command_replay/__init__.py +17 -0
- ccproxy/plugins/command_replay/config.py +133 -0
- ccproxy/plugins/command_replay/formatter.py +432 -0
- ccproxy/plugins/command_replay/hook.py +294 -0
- ccproxy/plugins/command_replay/plugin.py +161 -0
- ccproxy/plugins/copilot/README.md +39 -0
- ccproxy/plugins/copilot/__init__.py +11 -0
- ccproxy/plugins/copilot/adapter.py +465 -0
- ccproxy/plugins/copilot/config.py +155 -0
- ccproxy/plugins/copilot/data/copilot_fallback.json +41 -0
- ccproxy/plugins/copilot/detection_service.py +255 -0
- ccproxy/plugins/copilot/manager.py +275 -0
- ccproxy/plugins/copilot/model_defaults.py +284 -0
- ccproxy/plugins/copilot/models.py +148 -0
- ccproxy/plugins/copilot/oauth/__init__.py +16 -0
- ccproxy/plugins/copilot/oauth/client.py +494 -0
- ccproxy/plugins/copilot/oauth/models.py +385 -0
- ccproxy/plugins/copilot/oauth/provider.py +602 -0
- ccproxy/plugins/copilot/oauth/storage.py +170 -0
- ccproxy/plugins/copilot/plugin.py +360 -0
- ccproxy/plugins/copilot/routes.py +294 -0
- ccproxy/plugins/credential_balancer/README.md +124 -0
- ccproxy/plugins/credential_balancer/__init__.py +6 -0
- ccproxy/plugins/credential_balancer/config.py +270 -0
- ccproxy/plugins/credential_balancer/factory.py +415 -0
- ccproxy/plugins/credential_balancer/hook.py +51 -0
- ccproxy/plugins/credential_balancer/manager.py +587 -0
- ccproxy/plugins/credential_balancer/plugin.py +146 -0
- ccproxy/plugins/dashboard/README.md +25 -0
- ccproxy/plugins/dashboard/__init__.py +1 -0
- ccproxy/plugins/dashboard/config.py +8 -0
- ccproxy/plugins/dashboard/plugin.py +71 -0
- ccproxy/plugins/dashboard/routes.py +67 -0
- ccproxy/plugins/docker/README.md +32 -0
- ccproxy/{docker → plugins/docker}/__init__.py +3 -0
- ccproxy/{docker → plugins/docker}/adapter.py +108 -10
- ccproxy/plugins/docker/config.py +82 -0
- ccproxy/{docker → plugins/docker}/docker_path.py +4 -3
- ccproxy/{docker → plugins/docker}/middleware.py +2 -2
- ccproxy/plugins/docker/plugin.py +198 -0
- ccproxy/{docker → plugins/docker}/stream_process.py +3 -3
- ccproxy/plugins/duckdb_storage/README.md +26 -0
- ccproxy/plugins/duckdb_storage/__init__.py +1 -0
- ccproxy/plugins/duckdb_storage/config.py +22 -0
- ccproxy/plugins/duckdb_storage/plugin.py +128 -0
- ccproxy/plugins/duckdb_storage/routes.py +51 -0
- ccproxy/plugins/duckdb_storage/storage.py +633 -0
- ccproxy/plugins/max_tokens/README.md +38 -0
- ccproxy/plugins/max_tokens/__init__.py +12 -0
- ccproxy/plugins/max_tokens/adapter.py +235 -0
- ccproxy/plugins/max_tokens/config.py +86 -0
- ccproxy/plugins/max_tokens/models.py +53 -0
- ccproxy/plugins/max_tokens/plugin.py +200 -0
- ccproxy/plugins/max_tokens/service.py +271 -0
- ccproxy/plugins/max_tokens/token_limits.json +54 -0
- ccproxy/plugins/metrics/README.md +35 -0
- ccproxy/plugins/metrics/__init__.py +10 -0
- ccproxy/{observability/metrics.py → plugins/metrics/collector.py} +20 -153
- ccproxy/plugins/metrics/config.py +85 -0
- ccproxy/plugins/metrics/grafana/dashboards/ccproxy-dashboard.json +1720 -0
- ccproxy/plugins/metrics/hook.py +403 -0
- ccproxy/plugins/metrics/plugin.py +268 -0
- ccproxy/{observability → plugins/metrics}/pushgateway.py +57 -59
- ccproxy/plugins/metrics/routes.py +107 -0
- ccproxy/plugins/metrics/tasks.py +117 -0
- ccproxy/plugins/oauth_claude/README.md +35 -0
- ccproxy/plugins/oauth_claude/__init__.py +14 -0
- ccproxy/plugins/oauth_claude/client.py +270 -0
- ccproxy/plugins/oauth_claude/config.py +84 -0
- ccproxy/plugins/oauth_claude/manager.py +482 -0
- ccproxy/plugins/oauth_claude/models.py +266 -0
- ccproxy/plugins/oauth_claude/plugin.py +149 -0
- ccproxy/plugins/oauth_claude/provider.py +571 -0
- ccproxy/plugins/oauth_claude/storage.py +212 -0
- ccproxy/plugins/oauth_codex/README.md +38 -0
- ccproxy/plugins/oauth_codex/__init__.py +14 -0
- ccproxy/plugins/oauth_codex/client.py +224 -0
- ccproxy/plugins/oauth_codex/config.py +95 -0
- ccproxy/plugins/oauth_codex/manager.py +256 -0
- ccproxy/plugins/oauth_codex/models.py +239 -0
- ccproxy/plugins/oauth_codex/plugin.py +146 -0
- ccproxy/plugins/oauth_codex/provider.py +574 -0
- ccproxy/plugins/oauth_codex/storage.py +92 -0
- ccproxy/plugins/permissions/README.md +28 -0
- ccproxy/plugins/permissions/__init__.py +22 -0
- ccproxy/plugins/permissions/config.py +28 -0
- ccproxy/{cli/commands/permission_handler.py → plugins/permissions/handlers/cli.py} +49 -25
- ccproxy/plugins/permissions/handlers/protocol.py +33 -0
- ccproxy/plugins/permissions/handlers/terminal.py +675 -0
- ccproxy/{api/routes → plugins/permissions}/mcp.py +34 -7
- ccproxy/{models/permissions.py → plugins/permissions/models.py} +65 -1
- ccproxy/plugins/permissions/plugin.py +153 -0
- ccproxy/{api/routes/permissions.py → plugins/permissions/routes.py} +20 -16
- ccproxy/{api/services/permission_service.py → plugins/permissions/service.py} +65 -11
- ccproxy/{api → plugins/permissions}/ui/permission_handler_protocol.py +1 -1
- ccproxy/{api → plugins/permissions}/ui/terminal_permission_handler.py +66 -10
- ccproxy/plugins/pricing/README.md +34 -0
- ccproxy/plugins/pricing/__init__.py +6 -0
- ccproxy/{pricing → plugins/pricing}/cache.py +7 -6
- ccproxy/{config/pricing.py → plugins/pricing/config.py} +32 -6
- ccproxy/plugins/pricing/exceptions.py +35 -0
- ccproxy/plugins/pricing/loader.py +440 -0
- ccproxy/{pricing → plugins/pricing}/models.py +13 -23
- ccproxy/plugins/pricing/plugin.py +169 -0
- ccproxy/plugins/pricing/service.py +191 -0
- ccproxy/plugins/pricing/tasks.py +300 -0
- ccproxy/{pricing → plugins/pricing}/updater.py +86 -72
- ccproxy/plugins/pricing/utils.py +99 -0
- ccproxy/plugins/request_tracer/README.md +40 -0
- ccproxy/plugins/request_tracer/__init__.py +7 -0
- ccproxy/plugins/request_tracer/config.py +120 -0
- ccproxy/plugins/request_tracer/hook.py +415 -0
- ccproxy/plugins/request_tracer/plugin.py +255 -0
- ccproxy/scheduler/__init__.py +2 -14
- ccproxy/scheduler/core.py +26 -41
- ccproxy/scheduler/manager.py +61 -105
- ccproxy/scheduler/registry.py +6 -32
- ccproxy/scheduler/tasks.py +268 -276
- ccproxy/services/__init__.py +0 -1
- ccproxy/services/adapters/__init__.py +11 -0
- ccproxy/services/adapters/base.py +123 -0
- ccproxy/services/adapters/chain_composer.py +88 -0
- ccproxy/services/adapters/chain_validation.py +44 -0
- ccproxy/services/adapters/chat_accumulator.py +200 -0
- ccproxy/services/adapters/delta_utils.py +142 -0
- ccproxy/services/adapters/format_adapter.py +136 -0
- ccproxy/services/adapters/format_context.py +11 -0
- ccproxy/services/adapters/format_registry.py +158 -0
- ccproxy/services/adapters/http_adapter.py +1045 -0
- ccproxy/services/adapters/mock_adapter.py +118 -0
- ccproxy/services/adapters/protocols.py +35 -0
- ccproxy/services/adapters/simple_converters.py +571 -0
- ccproxy/services/auth_registry.py +180 -0
- ccproxy/services/cache/__init__.py +6 -0
- ccproxy/services/cache/response_cache.py +261 -0
- ccproxy/services/cli_detection.py +437 -0
- ccproxy/services/config/__init__.py +6 -0
- ccproxy/services/config/proxy_configuration.py +111 -0
- ccproxy/services/container.py +256 -0
- ccproxy/services/factories.py +380 -0
- ccproxy/services/handler_config.py +76 -0
- ccproxy/services/interfaces.py +298 -0
- ccproxy/services/mocking/__init__.py +6 -0
- ccproxy/services/mocking/mock_handler.py +291 -0
- ccproxy/services/tracing/__init__.py +7 -0
- ccproxy/services/tracing/interfaces.py +61 -0
- ccproxy/services/tracing/null_tracer.py +57 -0
- ccproxy/streaming/__init__.py +23 -0
- ccproxy/streaming/buffer.py +1056 -0
- ccproxy/streaming/deferred.py +897 -0
- ccproxy/streaming/handler.py +117 -0
- ccproxy/streaming/interfaces.py +77 -0
- ccproxy/streaming/simple_adapter.py +39 -0
- ccproxy/streaming/sse.py +109 -0
- ccproxy/streaming/sse_parser.py +127 -0
- ccproxy/templates/__init__.py +6 -0
- ccproxy/templates/plugin_scaffold.py +695 -0
- ccproxy/testing/endpoints/__init__.py +33 -0
- ccproxy/testing/endpoints/cli.py +215 -0
- ccproxy/testing/endpoints/config.py +874 -0
- ccproxy/testing/endpoints/console.py +57 -0
- ccproxy/testing/endpoints/models.py +100 -0
- ccproxy/testing/endpoints/runner.py +1903 -0
- ccproxy/testing/endpoints/tools.py +308 -0
- ccproxy/testing/mock_responses.py +70 -1
- ccproxy/testing/response_handlers.py +20 -0
- ccproxy/utils/__init__.py +0 -6
- ccproxy/utils/binary_resolver.py +476 -0
- ccproxy/utils/caching.py +327 -0
- ccproxy/utils/cli_logging.py +101 -0
- ccproxy/utils/command_line.py +251 -0
- ccproxy/utils/headers.py +228 -0
- ccproxy/utils/model_mapper.py +120 -0
- ccproxy/utils/startup_helpers.py +68 -446
- ccproxy/utils/version_checker.py +273 -6
- ccproxy_api-0.2.0.dist-info/METADATA +212 -0
- ccproxy_api-0.2.0.dist-info/RECORD +417 -0
- {ccproxy_api-0.1.7.dist-info → ccproxy_api-0.2.0.dist-info}/WHEEL +1 -1
- ccproxy_api-0.2.0.dist-info/entry_points.txt +24 -0
- ccproxy/__init__.py +0 -4
- ccproxy/adapters/__init__.py +0 -11
- ccproxy/adapters/base.py +0 -80
- ccproxy/adapters/codex/__init__.py +0 -11
- ccproxy/adapters/openai/__init__.py +0 -42
- ccproxy/adapters/openai/adapter.py +0 -953
- ccproxy/adapters/openai/models.py +0 -412
- ccproxy/adapters/openai/response_adapter.py +0 -355
- ccproxy/adapters/openai/response_models.py +0 -178
- ccproxy/api/middleware/headers.py +0 -49
- ccproxy/api/middleware/logging.py +0 -180
- ccproxy/api/middleware/request_content_logging.py +0 -297
- ccproxy/api/middleware/server_header.py +0 -58
- ccproxy/api/responses.py +0 -89
- ccproxy/api/routes/claude.py +0 -371
- ccproxy/api/routes/codex.py +0 -1251
- ccproxy/api/routes/metrics.py +0 -1029
- ccproxy/api/routes/proxy.py +0 -211
- ccproxy/api/services/__init__.py +0 -6
- ccproxy/auth/conditional.py +0 -84
- ccproxy/auth/credentials_adapter.py +0 -93
- ccproxy/auth/models.py +0 -118
- ccproxy/auth/oauth/models.py +0 -48
- ccproxy/auth/openai/__init__.py +0 -13
- ccproxy/auth/openai/credentials.py +0 -166
- ccproxy/auth/openai/oauth_client.py +0 -334
- ccproxy/auth/openai/storage.py +0 -184
- ccproxy/auth/storage/json_file.py +0 -158
- ccproxy/auth/storage/keyring.py +0 -189
- ccproxy/claude_sdk/__init__.py +0 -18
- ccproxy/claude_sdk/options.py +0 -194
- ccproxy/claude_sdk/session_pool.py +0 -550
- ccproxy/cli/docker/__init__.py +0 -34
- ccproxy/cli/docker/adapter_factory.py +0 -157
- ccproxy/cli/docker/params.py +0 -274
- ccproxy/config/auth.py +0 -153
- ccproxy/config/claude.py +0 -348
- ccproxy/config/cors.py +0 -79
- ccproxy/config/discovery.py +0 -95
- ccproxy/config/docker_settings.py +0 -264
- ccproxy/config/observability.py +0 -158
- ccproxy/config/reverse_proxy.py +0 -31
- ccproxy/config/scheduler.py +0 -108
- ccproxy/config/server.py +0 -86
- ccproxy/config/validators.py +0 -231
- ccproxy/core/codex_transformers.py +0 -389
- ccproxy/core/http.py +0 -328
- ccproxy/core/http_transformers.py +0 -812
- ccproxy/core/proxy.py +0 -143
- ccproxy/core/validators.py +0 -288
- ccproxy/models/errors.py +0 -42
- ccproxy/models/messages.py +0 -269
- ccproxy/models/requests.py +0 -107
- ccproxy/models/responses.py +0 -270
- ccproxy/models/types.py +0 -102
- ccproxy/observability/__init__.py +0 -51
- ccproxy/observability/access_logger.py +0 -457
- ccproxy/observability/sse_events.py +0 -303
- ccproxy/observability/stats_printer.py +0 -753
- ccproxy/observability/storage/__init__.py +0 -1
- ccproxy/observability/storage/duckdb_simple.py +0 -677
- ccproxy/observability/storage/models.py +0 -70
- ccproxy/observability/streaming_response.py +0 -107
- ccproxy/pricing/__init__.py +0 -19
- ccproxy/pricing/loader.py +0 -251
- ccproxy/services/claude_detection_service.py +0 -243
- ccproxy/services/codex_detection_service.py +0 -252
- ccproxy/services/credentials/__init__.py +0 -55
- ccproxy/services/credentials/config.py +0 -105
- ccproxy/services/credentials/manager.py +0 -561
- ccproxy/services/credentials/oauth_client.py +0 -481
- ccproxy/services/proxy_service.py +0 -1827
- ccproxy/static/.keep +0 -0
- ccproxy/utils/cost_calculator.py +0 -210
- ccproxy/utils/disconnection_monitor.py +0 -83
- ccproxy/utils/model_mapping.py +0 -199
- ccproxy/utils/models_provider.py +0 -150
- ccproxy/utils/simple_request_logger.py +0 -284
- ccproxy/utils/streaming_metrics.py +0 -199
- ccproxy_api-0.1.7.dist-info/METADATA +0 -615
- ccproxy_api-0.1.7.dist-info/RECORD +0 -191
- ccproxy_api-0.1.7.dist-info/entry_points.txt +0 -4
- /ccproxy/{api/middleware/auth.py → auth/models/__init__.py} +0 -0
- /ccproxy/{claude_sdk → plugins/claude_sdk}/exceptions.py +0 -0
- /ccproxy/{docker → plugins/docker}/models.py +0 -0
- /ccproxy/{docker → plugins/docker}/protocol.py +0 -0
- /ccproxy/{docker → plugins/docker}/validators.py +0 -0
- /ccproxy/{auth/oauth/storage.py → plugins/permissions/handlers/__init__.py} +0 -0
- /ccproxy/{api → plugins/permissions}/ui/__init__.py +0 -0
- {ccproxy_api-0.1.7.dist-info → ccproxy_api-0.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
"""Docker adapter factory for CLI commands.
|
|
2
|
-
|
|
3
|
-
This module provides functions to create Docker adapters from CLI settings
|
|
4
|
-
and command-line arguments.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import getpass
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
from ccproxy.config.settings import Settings
|
|
12
|
-
from ccproxy.docker import (
|
|
13
|
-
DockerEnv,
|
|
14
|
-
DockerPath,
|
|
15
|
-
DockerUserContext,
|
|
16
|
-
DockerVolume,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _create_docker_adapter_from_settings(
|
|
21
|
-
settings: Settings,
|
|
22
|
-
docker_image: str | None = None,
|
|
23
|
-
docker_env: list[str] | None = None,
|
|
24
|
-
docker_volume: list[str] | None = None,
|
|
25
|
-
docker_arg: list[str] | None = None,
|
|
26
|
-
docker_home: str | None = None,
|
|
27
|
-
docker_workspace: str | None = None,
|
|
28
|
-
user_mapping_enabled: bool | None = None,
|
|
29
|
-
user_uid: int | None = None,
|
|
30
|
-
user_gid: int | None = None,
|
|
31
|
-
command: list[str] | None = None,
|
|
32
|
-
cmd_args: list[str] | None = None,
|
|
33
|
-
**kwargs: Any,
|
|
34
|
-
) -> tuple[
|
|
35
|
-
str,
|
|
36
|
-
list[DockerVolume],
|
|
37
|
-
DockerEnv,
|
|
38
|
-
list[str] | None,
|
|
39
|
-
DockerUserContext | None,
|
|
40
|
-
list[str],
|
|
41
|
-
]:
|
|
42
|
-
"""Convert settings and overrides to Docker adapter parameters.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
settings: Application settings
|
|
46
|
-
docker_image: Override Docker image
|
|
47
|
-
docker_env: Additional environment variables
|
|
48
|
-
docker_volume: Additional volume mappings
|
|
49
|
-
docker_arg: Additional Docker arguments
|
|
50
|
-
docker_home: Override home directory
|
|
51
|
-
docker_workspace: Override workspace directory
|
|
52
|
-
user_mapping_enabled: Override user mapping setting
|
|
53
|
-
user_uid: Override user ID
|
|
54
|
-
user_gid: Override group ID
|
|
55
|
-
command: Command to run in container
|
|
56
|
-
cmd_args: Arguments for the command
|
|
57
|
-
**kwargs: Additional keyword arguments (ignored)
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
Tuple of (image, volumes, environment, command, user_context, additional_args)
|
|
61
|
-
"""
|
|
62
|
-
docker_settings = settings.docker
|
|
63
|
-
|
|
64
|
-
# Determine effective image
|
|
65
|
-
image = docker_image or docker_settings.docker_image
|
|
66
|
-
|
|
67
|
-
# Process volumes
|
|
68
|
-
volumes: list[DockerVolume] = []
|
|
69
|
-
|
|
70
|
-
# Add home/workspace volumes with effective directories
|
|
71
|
-
home_dir = docker_home or docker_settings.docker_home_directory
|
|
72
|
-
workspace_dir = docker_workspace or docker_settings.docker_workspace_directory
|
|
73
|
-
|
|
74
|
-
if home_dir:
|
|
75
|
-
volumes.append((str(Path(home_dir)), "/data/home"))
|
|
76
|
-
if workspace_dir:
|
|
77
|
-
volumes.append((str(Path(workspace_dir)), "/data/workspace"))
|
|
78
|
-
|
|
79
|
-
# Add base volumes from settings
|
|
80
|
-
for vol_str in docker_settings.docker_volumes:
|
|
81
|
-
parts = vol_str.split(":", 2)
|
|
82
|
-
if len(parts) >= 2:
|
|
83
|
-
volumes.append((parts[0], parts[1]))
|
|
84
|
-
|
|
85
|
-
# Add CLI override volumes
|
|
86
|
-
if docker_volume:
|
|
87
|
-
for vol_str in docker_volume:
|
|
88
|
-
parts = vol_str.split(":", 2)
|
|
89
|
-
if len(parts) >= 2:
|
|
90
|
-
volumes.append((parts[0], parts[1]))
|
|
91
|
-
|
|
92
|
-
# Process environment
|
|
93
|
-
environment: DockerEnv = docker_settings.docker_environment.copy()
|
|
94
|
-
|
|
95
|
-
# Add home/workspace environment variables
|
|
96
|
-
if home_dir:
|
|
97
|
-
environment["CLAUDE_HOME"] = "/data/home"
|
|
98
|
-
if workspace_dir:
|
|
99
|
-
environment["CLAUDE_WORKSPACE"] = "/data/workspace"
|
|
100
|
-
|
|
101
|
-
# Add CLI override environment
|
|
102
|
-
if docker_env:
|
|
103
|
-
for env_var in docker_env:
|
|
104
|
-
if "=" in env_var:
|
|
105
|
-
key, value = env_var.split("=", 1)
|
|
106
|
-
environment[key] = value
|
|
107
|
-
|
|
108
|
-
# Create user context
|
|
109
|
-
user_context = None
|
|
110
|
-
effective_mapping_enabled = (
|
|
111
|
-
user_mapping_enabled
|
|
112
|
-
if user_mapping_enabled is not None
|
|
113
|
-
else docker_settings.user_mapping_enabled
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
if effective_mapping_enabled:
|
|
117
|
-
effective_uid = user_uid if user_uid is not None else docker_settings.user_uid
|
|
118
|
-
effective_gid = user_gid if user_gid is not None else docker_settings.user_gid
|
|
119
|
-
|
|
120
|
-
if effective_uid is not None and effective_gid is not None:
|
|
121
|
-
# Create DockerPath instances for user context
|
|
122
|
-
home_path = None
|
|
123
|
-
workspace_path = None
|
|
124
|
-
|
|
125
|
-
if home_dir:
|
|
126
|
-
home_path = DockerPath(
|
|
127
|
-
host_path=Path(home_dir), container_path="/data/home"
|
|
128
|
-
)
|
|
129
|
-
if workspace_dir:
|
|
130
|
-
workspace_path = DockerPath(
|
|
131
|
-
host_path=Path(workspace_dir), container_path="/data/workspace"
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
# Use a default username if not available
|
|
135
|
-
username = getpass.getuser()
|
|
136
|
-
|
|
137
|
-
user_context = DockerUserContext(
|
|
138
|
-
uid=effective_uid,
|
|
139
|
-
gid=effective_gid,
|
|
140
|
-
username=username,
|
|
141
|
-
home_path=home_path,
|
|
142
|
-
workspace_path=workspace_path,
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
# Build command
|
|
146
|
-
final_command = None
|
|
147
|
-
if command:
|
|
148
|
-
final_command = command.copy()
|
|
149
|
-
if cmd_args:
|
|
150
|
-
final_command.extend(cmd_args)
|
|
151
|
-
|
|
152
|
-
# Additional Docker arguments
|
|
153
|
-
additional_args = docker_settings.docker_additional_args.copy()
|
|
154
|
-
if docker_arg:
|
|
155
|
-
additional_args.extend(docker_arg)
|
|
156
|
-
|
|
157
|
-
return image, volumes, environment, final_command, user_context, additional_args
|
ccproxy/cli/docker/params.py
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
"""Shared Docker parameter definitions for Typer CLI commands.
|
|
2
|
-
|
|
3
|
-
This module provides reusable Typer Option definitions for Docker-related
|
|
4
|
-
parameters that are used across multiple CLI commands, eliminating duplication.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
import typer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# Docker parameter validation functions moved here to avoid utils dependency
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def parse_docker_env(
|
|
16
|
-
ctx: typer.Context, param: typer.CallbackParam, value: list[str] | None
|
|
17
|
-
) -> list[str]:
|
|
18
|
-
"""Parse Docker environment variable string."""
|
|
19
|
-
if not value:
|
|
20
|
-
return []
|
|
21
|
-
|
|
22
|
-
parsed = []
|
|
23
|
-
for env_str in value:
|
|
24
|
-
if not env_str or env_str == "[]":
|
|
25
|
-
raise typer.BadParameter(
|
|
26
|
-
f"Invalid env format: {env_str}. Expected KEY=VALUE"
|
|
27
|
-
)
|
|
28
|
-
if "=" not in env_str:
|
|
29
|
-
raise typer.BadParameter(
|
|
30
|
-
f"Invalid env format: {env_str}. Expected KEY=VALUE"
|
|
31
|
-
)
|
|
32
|
-
parsed.append(env_str)
|
|
33
|
-
|
|
34
|
-
return parsed
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def parse_docker_volume(
|
|
38
|
-
ctx: typer.Context, param: typer.CallbackParam, value: list[str] | None
|
|
39
|
-
) -> list[str]:
|
|
40
|
-
"""Parse Docker volume string."""
|
|
41
|
-
if not value:
|
|
42
|
-
return []
|
|
43
|
-
|
|
44
|
-
# Import the validation function from config
|
|
45
|
-
from ccproxy.config.docker_settings import validate_volume_format
|
|
46
|
-
|
|
47
|
-
parsed = []
|
|
48
|
-
for volume_str in value:
|
|
49
|
-
if not volume_str:
|
|
50
|
-
continue
|
|
51
|
-
try:
|
|
52
|
-
validated_volume = validate_volume_format(volume_str)
|
|
53
|
-
parsed.append(validated_volume)
|
|
54
|
-
except ValueError as e:
|
|
55
|
-
raise typer.BadParameter(str(e)) from e
|
|
56
|
-
|
|
57
|
-
return parsed
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def validate_docker_arg(
|
|
61
|
-
ctx: typer.Context, param: typer.CallbackParam, value: list[str] | None
|
|
62
|
-
) -> list[str]:
|
|
63
|
-
"""Validate Docker argument."""
|
|
64
|
-
if not value:
|
|
65
|
-
return []
|
|
66
|
-
|
|
67
|
-
# Basic validation - ensure arguments don't contain dangerous patterns
|
|
68
|
-
validated = []
|
|
69
|
-
for arg in value:
|
|
70
|
-
if not arg:
|
|
71
|
-
continue
|
|
72
|
-
# Basic validation - just return the arg for now
|
|
73
|
-
validated.append(arg)
|
|
74
|
-
|
|
75
|
-
return validated
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def validate_docker_home(
|
|
79
|
-
ctx: typer.Context, param: typer.CallbackParam, value: str | None
|
|
80
|
-
) -> str | None:
|
|
81
|
-
"""Validate Docker home directory."""
|
|
82
|
-
if value is None:
|
|
83
|
-
return None
|
|
84
|
-
|
|
85
|
-
from ccproxy.config.docker_settings import validate_host_path
|
|
86
|
-
|
|
87
|
-
try:
|
|
88
|
-
return validate_host_path(value)
|
|
89
|
-
except ValueError as e:
|
|
90
|
-
raise typer.BadParameter(str(e)) from e
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def validate_docker_image(
|
|
94
|
-
ctx: typer.Context, param: typer.CallbackParam, value: str | None
|
|
95
|
-
) -> str | None:
|
|
96
|
-
"""Validate Docker image name."""
|
|
97
|
-
if value is None:
|
|
98
|
-
return None
|
|
99
|
-
|
|
100
|
-
if not value:
|
|
101
|
-
raise typer.BadParameter("Docker image cannot be empty")
|
|
102
|
-
|
|
103
|
-
# Basic validation - no spaces allowed in image names
|
|
104
|
-
if " " in value:
|
|
105
|
-
raise typer.BadParameter(f"Docker image name cannot contain spaces: {value}")
|
|
106
|
-
|
|
107
|
-
return value
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def validate_docker_workspace(
|
|
111
|
-
ctx: typer.Context, param: typer.CallbackParam, value: str | None
|
|
112
|
-
) -> str | None:
|
|
113
|
-
"""Validate Docker workspace directory."""
|
|
114
|
-
if value is None:
|
|
115
|
-
return None
|
|
116
|
-
|
|
117
|
-
from ccproxy.config.docker_settings import validate_host_path
|
|
118
|
-
|
|
119
|
-
try:
|
|
120
|
-
return validate_host_path(value)
|
|
121
|
-
except ValueError as e:
|
|
122
|
-
raise typer.BadParameter(str(e)) from e
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def validate_user_gid(
|
|
126
|
-
ctx: typer.Context, param: typer.CallbackParam, value: int | None
|
|
127
|
-
) -> int | None:
|
|
128
|
-
"""Validate user GID."""
|
|
129
|
-
if value is None:
|
|
130
|
-
return None
|
|
131
|
-
|
|
132
|
-
if value < 0:
|
|
133
|
-
raise typer.BadParameter("GID must be non-negative")
|
|
134
|
-
|
|
135
|
-
return value
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def validate_user_uid(
|
|
139
|
-
ctx: typer.Context, param: typer.CallbackParam, value: int | None
|
|
140
|
-
) -> int | None:
|
|
141
|
-
"""Validate user UID."""
|
|
142
|
-
if value is None:
|
|
143
|
-
return None
|
|
144
|
-
|
|
145
|
-
if value < 0:
|
|
146
|
-
raise typer.BadParameter("UID must be non-negative")
|
|
147
|
-
|
|
148
|
-
return value
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def docker_image_option() -> Any:
|
|
152
|
-
"""Docker image parameter."""
|
|
153
|
-
return typer.Option(
|
|
154
|
-
None,
|
|
155
|
-
"--docker-image",
|
|
156
|
-
help="Docker image to use (overrides config)",
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def docker_env_option() -> Any:
|
|
161
|
-
"""Docker environment variables parameter."""
|
|
162
|
-
return typer.Option(
|
|
163
|
-
[],
|
|
164
|
-
"--docker-env",
|
|
165
|
-
help="Environment variables to pass to Docker (KEY=VALUE format, can be used multiple times)",
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def docker_volume_option() -> Any:
|
|
170
|
-
"""Docker volume mounts parameter."""
|
|
171
|
-
return typer.Option(
|
|
172
|
-
[],
|
|
173
|
-
"--docker-volume",
|
|
174
|
-
help="Volume mounts to add (host:container[:options] format, can be used multiple times)",
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def docker_arg_option() -> Any:
|
|
179
|
-
"""Docker arguments parameter."""
|
|
180
|
-
return typer.Option(
|
|
181
|
-
[],
|
|
182
|
-
"--docker-arg",
|
|
183
|
-
help="Additional Docker run arguments (can be used multiple times)",
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def docker_home_option() -> Any:
|
|
188
|
-
"""Docker home directory parameter."""
|
|
189
|
-
return typer.Option(
|
|
190
|
-
None,
|
|
191
|
-
"--docker-home",
|
|
192
|
-
help="Home directory inside Docker container (overrides config)",
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def docker_workspace_option() -> Any:
|
|
197
|
-
"""Docker workspace directory parameter."""
|
|
198
|
-
return typer.Option(
|
|
199
|
-
None,
|
|
200
|
-
"--docker-workspace",
|
|
201
|
-
help="Workspace directory inside Docker container (overrides config)",
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def user_mapping_option() -> Any:
|
|
206
|
-
"""User mapping parameter."""
|
|
207
|
-
return typer.Option(
|
|
208
|
-
None,
|
|
209
|
-
"--user-mapping/--no-user-mapping",
|
|
210
|
-
help="Enable/disable UID/GID mapping (overrides config)",
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
def user_uid_option() -> Any:
|
|
215
|
-
"""User UID parameter."""
|
|
216
|
-
return typer.Option(
|
|
217
|
-
None,
|
|
218
|
-
"--user-uid",
|
|
219
|
-
help="User ID to run container as (overrides config)",
|
|
220
|
-
min=0,
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
def user_gid_option() -> Any:
|
|
225
|
-
"""User GID parameter."""
|
|
226
|
-
return typer.Option(
|
|
227
|
-
None,
|
|
228
|
-
"--user-gid",
|
|
229
|
-
help="Group ID to run container as (overrides config)",
|
|
230
|
-
min=0,
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
class DockerOptions:
|
|
235
|
-
"""Container for all Docker-related Typer options.
|
|
236
|
-
|
|
237
|
-
This class provides a convenient way to include all Docker-related
|
|
238
|
-
options in a command using typed attributes.
|
|
239
|
-
"""
|
|
240
|
-
|
|
241
|
-
def __init__(
|
|
242
|
-
self,
|
|
243
|
-
docker_image: str | None = None,
|
|
244
|
-
docker_env: list[str] | None = None,
|
|
245
|
-
docker_volume: list[str] | None = None,
|
|
246
|
-
docker_arg: list[str] | None = None,
|
|
247
|
-
docker_home: str | None = None,
|
|
248
|
-
docker_workspace: str | None = None,
|
|
249
|
-
user_mapping_enabled: bool | None = None,
|
|
250
|
-
user_uid: int | None = None,
|
|
251
|
-
user_gid: int | None = None,
|
|
252
|
-
):
|
|
253
|
-
"""Initialize Docker options.
|
|
254
|
-
|
|
255
|
-
Args:
|
|
256
|
-
docker_image: Docker image to use
|
|
257
|
-
docker_env: Environment variables list
|
|
258
|
-
docker_volume: Volume mounts list
|
|
259
|
-
docker_arg: Additional Docker arguments
|
|
260
|
-
docker_home: Home directory path
|
|
261
|
-
docker_workspace: Workspace directory path
|
|
262
|
-
user_mapping_enabled: User mapping flag
|
|
263
|
-
user_uid: User ID
|
|
264
|
-
user_gid: Group ID
|
|
265
|
-
"""
|
|
266
|
-
self.docker_image = docker_image
|
|
267
|
-
self.docker_env = docker_env or []
|
|
268
|
-
self.docker_volume = docker_volume or []
|
|
269
|
-
self.docker_arg = docker_arg or []
|
|
270
|
-
self.docker_home = docker_home
|
|
271
|
-
self.docker_workspace = docker_workspace
|
|
272
|
-
self.user_mapping_enabled = user_mapping_enabled
|
|
273
|
-
self.user_uid = user_uid
|
|
274
|
-
self.user_gid = user_gid
|
ccproxy/config/auth.py
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
"""Authentication and credentials configuration."""
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Any
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel, Field, field_validator
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def _get_default_storage_paths() -> list[Path]:
|
|
10
|
-
"""Get default storage paths"""
|
|
11
|
-
return [
|
|
12
|
-
Path("~/.config/ccproxy/credentials.json"),
|
|
13
|
-
Path("~/.claude/.credentials.json"),
|
|
14
|
-
Path("~/.config/claude/.credentials.json"),
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class OAuthSettings(BaseModel):
|
|
19
|
-
"""OAuth-specific settings."""
|
|
20
|
-
|
|
21
|
-
base_url: str = Field(
|
|
22
|
-
default="https://console.anthropic.com",
|
|
23
|
-
description="Base URL for OAuth API endpoints",
|
|
24
|
-
)
|
|
25
|
-
beta_version: str = Field(
|
|
26
|
-
default="oauth-2025-04-20",
|
|
27
|
-
description="OAuth beta version header",
|
|
28
|
-
)
|
|
29
|
-
token_url: str = Field(
|
|
30
|
-
default="https://console.anthropic.com/v1/oauth/token",
|
|
31
|
-
description="OAuth token endpoint URL",
|
|
32
|
-
)
|
|
33
|
-
authorize_url: str = Field(
|
|
34
|
-
default="https://claude.ai/oauth/authorize",
|
|
35
|
-
description="OAuth authorization endpoint URL",
|
|
36
|
-
)
|
|
37
|
-
profile_url: str = Field(
|
|
38
|
-
default="https://api.anthropic.com/api/oauth/profile",
|
|
39
|
-
description="OAuth profile endpoint URL",
|
|
40
|
-
)
|
|
41
|
-
client_id: str = Field(
|
|
42
|
-
default="9d1c250a-e61b-44d9-88ed-5944d1962f5e",
|
|
43
|
-
description="OAuth client ID",
|
|
44
|
-
)
|
|
45
|
-
redirect_uri: str = Field(
|
|
46
|
-
default="http://localhost:54545/callback",
|
|
47
|
-
description="OAuth redirect URI",
|
|
48
|
-
)
|
|
49
|
-
scopes: list[str] = Field(
|
|
50
|
-
default_factory=lambda: [
|
|
51
|
-
"org:create_api_key",
|
|
52
|
-
"user:profile",
|
|
53
|
-
"user:inference",
|
|
54
|
-
],
|
|
55
|
-
description="OAuth scopes to request",
|
|
56
|
-
)
|
|
57
|
-
request_timeout: int = Field(
|
|
58
|
-
default=30,
|
|
59
|
-
description="Timeout in seconds for OAuth requests",
|
|
60
|
-
)
|
|
61
|
-
user_agent: str = Field(
|
|
62
|
-
default="Claude-Code/1.0.43",
|
|
63
|
-
description="User agent string for OAuth requests",
|
|
64
|
-
)
|
|
65
|
-
callback_timeout: int = Field(
|
|
66
|
-
default=300,
|
|
67
|
-
description="Timeout in seconds for OAuth callback",
|
|
68
|
-
ge=60,
|
|
69
|
-
le=600,
|
|
70
|
-
)
|
|
71
|
-
callback_port: int = Field(
|
|
72
|
-
default=54545,
|
|
73
|
-
description="Port for OAuth callback server",
|
|
74
|
-
ge=1024,
|
|
75
|
-
le=65535,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class CredentialStorageSettings(BaseModel):
|
|
80
|
-
"""Settings for credential storage locations."""
|
|
81
|
-
|
|
82
|
-
storage_paths: list[Path] = Field(
|
|
83
|
-
default_factory=lambda: _get_default_storage_paths(),
|
|
84
|
-
description="Paths to search for credentials files",
|
|
85
|
-
)
|
|
86
|
-
auto_refresh: bool = Field(
|
|
87
|
-
default=True,
|
|
88
|
-
description="Automatically refresh expired tokens",
|
|
89
|
-
)
|
|
90
|
-
refresh_buffer_seconds: int = Field(
|
|
91
|
-
default=300,
|
|
92
|
-
description="Refresh token this many seconds before expiry",
|
|
93
|
-
ge=0,
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class AuthSettings(BaseModel):
|
|
98
|
-
"""Combined authentication and credentials configuration."""
|
|
99
|
-
|
|
100
|
-
oauth: OAuthSettings = Field(
|
|
101
|
-
default_factory=OAuthSettings,
|
|
102
|
-
description="OAuth configuration",
|
|
103
|
-
)
|
|
104
|
-
storage: CredentialStorageSettings = Field(
|
|
105
|
-
default_factory=CredentialStorageSettings,
|
|
106
|
-
description="Credential storage configuration",
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
@field_validator("oauth", mode="before")
|
|
110
|
-
@classmethod
|
|
111
|
-
def validate_oauth(cls, v: Any) -> Any:
|
|
112
|
-
"""Validate and convert OAuth configuration."""
|
|
113
|
-
if v is None:
|
|
114
|
-
return OAuthSettings()
|
|
115
|
-
|
|
116
|
-
# If it's already an OAuthSettings instance, return as-is
|
|
117
|
-
if isinstance(v, OAuthSettings):
|
|
118
|
-
return v
|
|
119
|
-
|
|
120
|
-
# If it's a dict, create OAuthSettings from it
|
|
121
|
-
if isinstance(v, dict):
|
|
122
|
-
return OAuthSettings(**v)
|
|
123
|
-
|
|
124
|
-
# Try to convert to dict if possible
|
|
125
|
-
if hasattr(v, "model_dump"):
|
|
126
|
-
return OAuthSettings(**v.model_dump())
|
|
127
|
-
elif hasattr(v, "__dict__"):
|
|
128
|
-
return OAuthSettings(**v.__dict__)
|
|
129
|
-
|
|
130
|
-
return v
|
|
131
|
-
|
|
132
|
-
@field_validator("storage", mode="before")
|
|
133
|
-
@classmethod
|
|
134
|
-
def validate_storage(cls, v: Any) -> Any:
|
|
135
|
-
"""Validate and convert storage configuration."""
|
|
136
|
-
if v is None:
|
|
137
|
-
return CredentialStorageSettings()
|
|
138
|
-
|
|
139
|
-
# If it's already a CredentialStorageSettings instance, return as-is
|
|
140
|
-
if isinstance(v, CredentialStorageSettings):
|
|
141
|
-
return v
|
|
142
|
-
|
|
143
|
-
# If it's a dict, create CredentialStorageSettings from it
|
|
144
|
-
if isinstance(v, dict):
|
|
145
|
-
return CredentialStorageSettings(**v)
|
|
146
|
-
|
|
147
|
-
# Try to convert to dict if possible
|
|
148
|
-
if hasattr(v, "model_dump"):
|
|
149
|
-
return CredentialStorageSettings(**v.model_dump())
|
|
150
|
-
elif hasattr(v, "__dict__"):
|
|
151
|
-
return CredentialStorageSettings(**v.__dict__)
|
|
152
|
-
|
|
153
|
-
return v
|