fmp-data 2.3.0__tar.gz → 2.3.1__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.
- {fmp_data-2.3.0 → fmp_data-2.3.1}/PKG-INFO +1 -1
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/base.py +4 -4
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_base.py +42 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/.gitignore +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/LICENSE +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/NOTICE +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/README.md +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/alternative/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/_csv_utils.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/batch/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/base.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/config.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/file.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/memory.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/cache/redis_backend.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/hints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/company/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/config.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/economics/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/exceptions.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/fundamental/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/helpers.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/index/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/institutional/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/intelligence/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/investment/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/config.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/embedding.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/hints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/registry.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/utils.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/validation.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/lc/vector_store.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/logger.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/hints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/market/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/__main__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/cli.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/discovery.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/server.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/setup.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/tool_loader.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/tools_manifest.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/mcp/utils.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/py.typed +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/rate_limit.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/sec/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/technical/schema.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/async_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/endpoints.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/fmp_data/transcripts/models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/pyproject.toml +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/examples/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/examples/test_examples_smoke.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/base.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/conftest.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_alternative.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_batch.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_company.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_economics.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_fundamental.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_index.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_institutional.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_intelligence.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_investment.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_lc.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_market.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_sec.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_technical.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/integration/test_transcripts.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/conftest.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/__init__.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/conftest.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_config.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_embedding.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_endpoint_based_rules.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_imports.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_mapping.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_utils.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_validation_registry.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/lc/test_vector_store.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_alternative.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_alternative_coverage.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_async_clients.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_base_async.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_base_coverage.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_batch.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_cache_backends.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_cache_integration.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_cassette_contracts.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_client.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_company.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_company_coverage.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_config.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_economics.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_exceptions.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_fundamental.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_helpers.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_index.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_institutional.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_intelligence.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_investment.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_logger.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_market.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_mcp.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_mcp_cli.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_models.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_rate_limit.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_rate_limit_async.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_rate_limit_coverage.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_sec.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_technical.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_technical_coverage.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_transcripts.py +0 -0
- {fmp_data-2.3.0 → fmp_data-2.3.1}/tests/unit/test_vcr_sanitization.py +0 -0
|
@@ -564,27 +564,27 @@ class BaseClient:
|
|
|
564
564
|
status_code=429,
|
|
565
565
|
response=error_details,
|
|
566
566
|
retry_after=wait_time,
|
|
567
|
-
) from
|
|
567
|
+
) from None
|
|
568
568
|
|
|
569
569
|
if status_code == 401:
|
|
570
570
|
raise AuthenticationError(
|
|
571
571
|
"Invalid API key or authentication failed",
|
|
572
572
|
status_code=401,
|
|
573
573
|
response=error_details,
|
|
574
|
-
) from
|
|
574
|
+
) from None
|
|
575
575
|
|
|
576
576
|
if status_code == 400:
|
|
577
577
|
raise ValidationError(
|
|
578
578
|
f"Invalid request parameters: {error_details}",
|
|
579
579
|
status_code=400,
|
|
580
580
|
response=error_details,
|
|
581
|
-
) from
|
|
581
|
+
) from None
|
|
582
582
|
|
|
583
583
|
raise FMPError(
|
|
584
584
|
f"HTTP {status_code} error occurred: {error_details}",
|
|
585
585
|
status_code=status_code,
|
|
586
586
|
response=error_details,
|
|
587
|
-
) from
|
|
587
|
+
) from None
|
|
588
588
|
|
|
589
589
|
@staticmethod
|
|
590
590
|
def _check_error_response(data: dict[str, Any]) -> None:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import traceback
|
|
2
3
|
from unittest.mock import MagicMock, Mock, patch
|
|
3
4
|
|
|
4
5
|
import httpx
|
|
@@ -273,6 +274,47 @@ def test_handle_http_status_error_uses_retry_after_header(base_client):
|
|
|
273
274
|
assert exc_info.value.retry_after == 12.0
|
|
274
275
|
|
|
275
276
|
|
|
277
|
+
@pytest.mark.parametrize(
|
|
278
|
+
("status_code", "expected_exception"),
|
|
279
|
+
[
|
|
280
|
+
(429, RateLimitError),
|
|
281
|
+
(401, AuthenticationError),
|
|
282
|
+
(400, ValidationError),
|
|
283
|
+
(500, FMPError),
|
|
284
|
+
],
|
|
285
|
+
)
|
|
286
|
+
def test_handle_http_status_error_redacts_chained_apikey_traceback(
|
|
287
|
+
base_client: BaseClient,
|
|
288
|
+
status_code: int,
|
|
289
|
+
expected_exception: type[FMPError],
|
|
290
|
+
) -> None:
|
|
291
|
+
"""Test HTTP error tracebacks do not expose the API key query parameter."""
|
|
292
|
+
marker = "TRACEBACK_REDACTION_SENTINEL"
|
|
293
|
+
request = httpx.Request(
|
|
294
|
+
"GET",
|
|
295
|
+
f"https://financialmodelingprep.com/stable/quote?symbol=AAPL&apikey={marker}",
|
|
296
|
+
)
|
|
297
|
+
response = httpx.Response(
|
|
298
|
+
status_code,
|
|
299
|
+
request=request,
|
|
300
|
+
json={"message": "Rate limit exceeded"},
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
try:
|
|
304
|
+
base_client.handle_response(response)
|
|
305
|
+
except FMPError as exc:
|
|
306
|
+
assert isinstance(exc, expected_exception)
|
|
307
|
+
formatted_traceback = traceback.format_exc()
|
|
308
|
+
assert "apikey=" not in formatted_traceback
|
|
309
|
+
assert marker not in formatted_traceback
|
|
310
|
+
assert "apikey=" not in str(exc)
|
|
311
|
+
assert marker not in str(exc)
|
|
312
|
+
assert exc.__cause__ is None
|
|
313
|
+
assert exc.__suppress_context__ is True
|
|
314
|
+
else:
|
|
315
|
+
pytest.fail(f"Expected {expected_exception.__name__}")
|
|
316
|
+
|
|
317
|
+
|
|
276
318
|
@pytest.mark.parametrize(
|
|
277
319
|
"payload",
|
|
278
320
|
[
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|