### Initialize Client with catalog Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Example of initializing the Client class and fetching data using the get method. ```python >>> client = Client(catalog="catalog.yaml") >>> df = client.get(["GDP_US", "CPI_EU"], start="2020-01-01", end="2024-12-31") ``` -------------------------------- ### Installation and Usage Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md Commands for installing the fork in development mode and verifying the import. ```bash pip install -e /path/to/myfork ``` ```python # Import from myfork, not original_pkg from myfork import Client, CustomFeature client = Client() ``` ```powershell # Install in development mode pip install -e . # Verify import works python -c "from myfork import Client; print('OK')" ``` -------------------------------- ### Making a Forked Package Installable Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md After initial setup, modify `pyproject.toml` to reflect your fork's name and version scheme. Create the necessary package structure and install it in editable mode. ```powershell # === MAKE INSTALLABLE (after setup) === # Edit pyproject.toml: name = "myfork", version = "1.0.0+fork.1" mkdir src/myfork # Create src/myfork/__init__.py with re-exports pip install -e . ``` -------------------------------- ### Install Metapyle with Bloomberg Support Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-25-metapyle-design.md Command to install Metapyle along with the optional Bloomberg data source integration. ```bash pip install metapyle[bloomberg] # With Bloomberg support ``` -------------------------------- ### Install Metapyle from PyPI Source Distribution Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-smoke-test-implementation.md Alternative installation method for environments where GitHub access is restricted. ```bash pip download metapyle --no-binary :all: tar -xzf metapyle-*.tar.gz cd metapyle-* pip install -e ".[dev]" # or: uv sync --group dev ``` -------------------------------- ### Clone and Install Metapyle for Development Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-smoke-test-implementation.md Commands to clone the repository and install dependencies for running the full test suite. ```bash git clone https://github.com/stabilefrisur/metapyle.git cd metapyle uv sync --group dev # or: pip install -e ".[dev]" ``` -------------------------------- ### Install xbbg Library Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-14-reuters-api-research.md Use this command to install the xbbg library for Bloomberg data access. ```bash pip install xbbg ``` -------------------------------- ### Install lseg-data Library Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-14-reuters-api-research.md Use this command to install the lseg-data library for LSEG data access. ```bash pip install lseg-data ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/user-guide.md Commands to set up the development environment from GitHub or PyPI source distributions. ```bash git clone https://github.com/stabilefrisur/metapyle.git cd metapyle uv sync --group dev # or: pip install -e ".[dev]" ``` ```bash pip download metapyle --no-binary :all: tar -xzf metapyle-*.tar.gz cd metapyle-* pip install -e ".[dev]" # or: uv sync --group dev ``` -------------------------------- ### Install Metapyle Source: https://github.com/stabilefrisur/metapyle/blob/master/README.md Installation commands for common Python package managers. ```bash uv add metapyle ``` ```bash pip install metapyle ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/stabilefrisur/metapyle/blob/master/CLAUDE.md Installs project dependencies using the uv package manager. Ensure uv is installed and configured. ```bash # Install dependencies (uses uv) uv sync ``` -------------------------------- ### Catalog Entry Example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-gsquant-source-design.md Example configuration for a gs-quant data source entry in YAML format. ```yaml - my_name: eurusd_3m_vol source: gsquant symbol: EURUSD field: FXIMPLIEDVOL::impliedVolatility params: tenor: 3m deltaStrike: DN location: NYC ``` -------------------------------- ### Usage examples for unified_options Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-01-unified-options-design.md Demonstrates how to use the new unified_options parameter for server-side and client-side alignment. ```python from macrobond_data_api.common.enums import SeriesFrequency df = client.get( ["us_gdp", "eu_gdp"], start="2020-01-01", unified=True, unified_options={"frequency": SeriesFrequency.MONTHLY, "currency": "EUR"}, ) ``` ```python df = client.get( ["us_gdp", "sp500_close"], # macrobond + bloomberg start="2020-01-01", unified=True, unified_options={"frequency": SeriesFrequency.MONTHLY}, frequency="ME", # client-side alignment for final merge ) ``` ```python df = client.get( ["us_gdp", "eu_gdp"], start="2020-01-01", unified=True, unified_options={"frequency": SeriesFrequency.QUARTERLY}, frequency="ME", # additional client-side resampling ) ``` -------------------------------- ### Install Metapyle Core Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-25-metapyle-design.md Command to install the core Metapyle package without optional features. ```bash pip install metapyle # Core only ``` -------------------------------- ### Running Integration Tests Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-integration-tests-design.md Command line examples for executing the test suite with different markers and flags. ```bash # All integration tests (requires both Bloomberg and Macrobond) pytest -m integration # Single source pytest -m bloomberg pytest -m macrobond # Include private series tests pytest -m integration --run-private ``` -------------------------------- ### Frequency Alignment Example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/user-guide.md This example demonstrates fetching daily and quarterly data, aligning them to a month-end frequency. The output shows how downsampling (daily to monthly) takes the last value, and upsampling (quarterly to monthly) forward-fills values. ```python # sp500_close: daily data, us_gdp: quarterly data df = client.get( ["sp500_close", "us_gdp"], start="2024-01-01", end="2024-06-30", frequency="ME" # month-end ) print(df) # sp500_close us_gdp # 2024-01-31 4845.65 27956.0 # Q1 GDP forward-filled # 2024-02-29 5096.27 27956.0 # 2024-03-31 5254.35 27956.0 # Q1 GDP (actual release month) # 2024-04-30 5035.69 28279.0 # Q2 GDP forward-filled # ... ``` -------------------------------- ### Commit User Guide Documentation Changes Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-01-unified-series-implementation.md Command to stage and commit the updated user guide Markdown file. ```bash git add docs/user-guide.md git commit -m "docs: add unified series section to user guide" ``` -------------------------------- ### Example Conflict Resolution Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md This example shows a merge conflict in `client.py`, analyzes the changes from both your fork and upstream, and proposes a resolution that combines both improvements. ```diff <<<<<<< HEAD (your fork) for attempt in range(self.max_retries): try: return self._send(request) except ConnectionError: if attempt == self.max_retries - 1: raise time.sleep(self.retry_delay) ======= for attempt in range(max_retries): try: return self._send(request) except (ConnectionError, TimeoutError): # NEW: also catch TimeoutError if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # NEW: exponential backoff >>>>>>> upstream ``` ```python for attempt in range(self.max_retries): try: return self._send(request) except (ConnectionError, TimeoutError): if attempt == self.max_retries - 1: raise time.sleep(self.retry_delay * (2 ** attempt)) ``` -------------------------------- ### Configure Multi-source Catalogs Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-25-metapyle-design.md Example showing how to define unique names for the same underlying security across different sources. ```yaml # bloomberg_catalog.yaml - my_name: SPX source: bloomberg symbol: SPX Index # local_catalog.yaml - must use different name - my_name: SPX_LOCAL source: localfile symbol: /data/spx.parquet ``` -------------------------------- ### Verify Metapyle Installation Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-smoke-test-implementation.md A simple script to confirm that the metapyle package is correctly installed in the environment. ```python from metapyle import Client print("metapyle installed successfully") ``` -------------------------------- ### Usage examples for unified series Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-01-unified-series-design.md Demonstrates basic usage with defaults and advanced usage with enum overrides. ```python # Simple case - uses hardcoded defaults (most users) client.get(["gdp_us", "cpi_eu"], start, end, unified=True) # Power user - imports macrobond enums directly from macrobond_data_api.common.enums import SeriesFrequency client.get(["gdp_us"], start, end, unified=True, frequency=SeriesFrequency.WEEKLY, currency="EUR") ``` -------------------------------- ### Define Absolute Import Guidelines Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md Example configuration for enforcing absolute imports in copilot-instructions.md. ```markdown ## Imports Use `collections.abc` for abstract types (`Callable`, `Iterator`, `Mapping`, `Sequence`). ### Absolute Imports Throughout Package ```python # ✅ Correct - Absolute imports from metapyle.catalog import Catalog, CatalogEntry from metapyle.exceptions import FetchError from metapyle.sources import BaseSource # ❌ Avoid - Relative imports (harder to refactor) from .catalog import Catalog from ..sources import BaseSource ``` ``` -------------------------------- ### Breaking change migration example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-01-unified-options-design.md Comparison of the old **kwargs approach versus the new unified_options dictionary approach. ```python # Before: df = client.get( ["us_gdp"], unified=True, frequency=SeriesFrequency.MONTHLY, currency="EUR", ) ``` ```python # After: df = client.get( ["us_gdp"], unified=True, unified_options={ "frequency": SeriesFrequency.MONTHLY, "currency": "EUR", }, ) ``` -------------------------------- ### Stage Documentation Changes Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-integration-tests-implementation.md Stage the updated user guide markdown file for commit. ```bash git add docs/user-guide.md ``` -------------------------------- ### Catalog YAML Configuration Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-27-column-naming-design.md Example YAML configuration for catalog entries using the updated schema. ```yaml - my_name: gdp_us source: localfile symbol: GDP_US path: /data/macro.csv description: US Gross Domestic Product - my_name: spx_close source: bloomberg symbol: SPX Index field: PX_LAST description: S&P 500 closing price ``` -------------------------------- ### Commit Documentation Updates Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md Stage and commit changes to the user guide documentation file. ```bash git add docs/user-guide.md git commit -m "docs: add multiple options for setting METAPYLE_CACHE_PATH" ``` -------------------------------- ### Test SourceRegistry Initialization Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Ensures that a new SourceRegistry instance starts empty, with no sources registered. ```python def test_source_registry_starts_empty() -> None: """SourceRegistry should start with no registered sources.""" from metapyle.sources.base import SourceRegistry registry = SourceRegistry() assert registry.list_sources() == [] ``` -------------------------------- ### Query Financial Data Source: https://github.com/stabilefrisur/metapyle/blob/master/README.md Initialize the client with a catalog file and retrieve data using the unified get method. ```python from metapyle import Client with Client(catalog="catalog.yaml") as client: # end defaults to today df = client.get(["sp500_close", "us_gdp"], start="2024-01-01") ``` -------------------------------- ### Example Error Messages for Source Validation Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-02-source-attribute-validation-design.md Illustrative error messages that provide actionable feedback to users when source attribute validation fails. These messages identify the specific entry, the problematic attribute, and the source, guiding the user on how to correct the issue. ```text Macrobond entry 'us_gdp' has 'field' set, but macrobond does not use field. Remove it. Localfile entry 'sp500' requires 'path' but none provided. Bloomberg entry 'spx' has 'path' set, but bloomberg does not use path. Remove it. ``` -------------------------------- ### Initialize Metapyle Client Source: https://context7.com/stabilefrisur/metapyle/llms.txt Demonstrates various ways to initialize the Client, including using multiple catalogs, custom cache paths, or context managers. ```python from metapyle import Client # Basic initialization with a single catalog file client = Client(catalog="catalog.yaml") # Initialize with multiple catalog files client = Client(catalog=[ "catalogs/equities.yaml", "catalogs/macro.yaml", ]) # Initialize with custom cache path client = Client( catalog="catalog.yaml", cache_path="/path/to/my_cache.db" ) # Initialize with caching disabled client = Client(catalog="catalog.yaml", cache_enabled=False) # Always close when done client.close() # Or use as context manager (recommended) with Client(catalog="catalog.yaml") as client: df = client.get(["sp500_close"], start="2024-01-01") # Client automatically closes when exiting the block ``` -------------------------------- ### Initialize and Query with Metapyle Client Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-25-metapyle-design.md Demonstrates client initialization, data retrieval, and cache management operations. ```python from metapyle import Client # Initialize with catalog(s) client = Client(catalog="catalogs/financial.yaml") client = Client(catalog=["catalogs/equities.yaml", "catalogs/macro.yaml"]) # With custom cache path client = Client(catalog="catalogs/financial.yaml", cache_path="//server/shared/cache") # Disable caching entirely client = Client(catalog="catalogs/financial.yaml", cache_enabled=False) # Query by catalog names df = client.get(["GDP_US", "CPI_EU"], start="2020-01-01", end="2024-12-31") # With explicit frequency alignment df = client.get(["GDP_US", "SPX_CLOSE"], start="2020-01-01", frequency="daily") # Bypass catalog for ad-hoc queries df = client.get_raw(source="bloomberg", symbol="SPX Index", field="PX_LAST", start="2020-01-01", end="2024-12-31") # Force fresh fetch (bypass cache) df = client.get(["GDP_US"], start="2020-01-01", end="2024-12-31", use_cache=False) # Retrieve metadata meta = client.get_metadata("GDP_US") # Cache management client.clear_cache() # Clear entire cache client.clear_cache(symbol="GDP_US") # Clear specific symbol ``` -------------------------------- ### Initialize Metapyle Client Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-gsquant-source-design.md Demonstrates session initialization and data retrieval using the Metapyle client. ```python from gs_quant.session import GsSession, Environment # User initializes session externally GsSession.use(Environment.PROD, client_id='...', client_secret='...') # Then use metapyle normally from metapyle import Client client = Client(catalog="gsquant_catalog.yaml") df = client.get(["eurusd_3m_vol", "usdjpy_3m_vol"], start="2024-01-01", end="2024-12-31") ``` -------------------------------- ### Initial Setup for Forking a Package Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md This sequence initializes a Git repository, checks out an orphan branch for the upstream code, downloads the package, extracts it, commits it as the upstream version, tags it, and then creates a main branch. ```powershell # === INITIAL SETUP === git init && git checkout --orphan upstream pip download --no-deps --no-binary :all: pkg==1.0.0 tar -xzf pkg-1.0.0.tar.gz --strip-components=1 git add -A && git commit -m "upstream: import pkg v1.0.0" git tag upstream/v1.0.0 git checkout -b main # create main from upstream ``` -------------------------------- ### Register and Get Source Instance Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Demonstrates how to register a source class with the registry and then retrieve an instance of it. Subsequent calls for the same source name return the same instance, ensuring a singleton pattern for adapters. ```python registry.register("test", TestSource) source1 = registry.get("test") source2 = registry.get("test") assert source1 is source2 ``` -------------------------------- ### Test Client Initialization Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Verify client behavior under different catalog and cache configurations. ```python def test_client_initialization(catalog_yaml: Path, cache_path: str) -> None: """Client initializes with catalog path and cache settings.""" client = Client(catalog=str(catalog_yaml), cache_path=cache_path) assert client._catalog is not None assert len(client._catalog) == 3 assert client._cache is not None assert client._cache._enabled is True ``` ```python def test_client_initialization_cache_disabled(catalog_yaml: Path) -> None: """Client can be initialized with cache disabled.""" client = Client(catalog=str(catalog_yaml), cache_enabled=False) assert client._cache._enabled is False ``` ```python def test_client_multiple_catalog_files( catalog_yaml: Path, catalog_yaml_2: Path, cache_path: str, ) -> None: """Client can load multiple catalog files.""" client = Client( catalog=[str(catalog_yaml), str(catalog_yaml_2)], cache_path=cache_path, ) assert len(client._catalog) == 4 assert "TEST_DAILY" in client._catalog assert "TEST_DAILY_3" in client._catalog ``` -------------------------------- ### Package Initialization and Exports Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Configuration for the package entry point to expose the Client and core exceptions. ```python """Metapyle - Unified interface for financial time-series data.""" from metapyle.client import Client from metapyle.exceptions import ( CatalogError, CatalogValidationError, DuplicateNameError, FetchError, FrequencyMismatchError, MetapyleError, NoDataError, SymbolNotFoundError, UnknownSourceError, ) from metapyle.sources import BaseSource, register_source __all__ = [ "Client", "BaseSource", "register_source", "MetapyleError", "CatalogError", "CatalogValidationError", "DuplicateNameError", "FetchError", "FrequencyMismatchError", "NoDataError", "SymbolNotFoundError", "UnknownSourceError", ] ``` -------------------------------- ### Smoke Test Failure Output Example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/smoke-test.md Example console output indicating connection failures for specific data sources. ```text ✗ Bloomberg: cannot find Bloomberg API (blpapi) ✗ Macrobond: Failed to connect to Macrobond ``` -------------------------------- ### Test Client Initialization Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Verifies that the Metapyle Client can be successfully initialized with a catalog path. ```python def test_client_initialization(mock_catalog, mock_source) -> None: """Client can be initialized with a catalog path.""" from metapyle import Client client = Client(catalog=mock_catalog) assert client is not None ``` -------------------------------- ### Update Client Get Method Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Implementation of the get method in the client to support frequency alignment using the align_to_frequency utility. ```python def get( self, symbols: list[str], start: str, end: str, *, frequency: str | None = None, use_cache: bool = True, ) -> pd.DataFrame: """ Fetch time-series data for multiple symbols. Parameters ---------- symbols : list[str] List of catalog names to fetch. start : str Start date in ISO format (YYYY-MM-DD). end : str End date in ISO format (YYYY-MM-DD). frequency : str | None, optional Alignment frequency. If omitted, all symbols must have the same native frequency. use_cache : bool, optional If False, bypass cache and fetch fresh data. Default True. Returns ------- pd.DataFrame Wide DataFrame with datetime index and columns named by catalog names. Raises ------ SymbolNotFoundError If any symbol is not in the catalog. FrequencyMismatchError If symbols have different frequencies and no alignment frequency specified. FetchError If data retrieval fails for any symbol. """ from metapyle.processing import align_to_frequency # Resolve catalog entries entries = [self._catalog.get(name) for name in symbols] # Check frequency compatibility (if no alignment requested) if frequency is None: self._check_frequency_compatibility(entries) # Fetch each symbol dfs: dict[str, pd.DataFrame] = {} for entry in entries: df = self._fetch_symbol(entry, start, end, use_cache) # Apply frequency alignment if requested if frequency is not None: df = align_to_frequency(df, frequency) dfs[entry.my_name] = df # Assemble into wide DataFrame result = self._assemble_dataframe(dfs) logger.info( "get_complete: symbols=%d, rows=%d, start=%s, end=%s", len(symbols), len(result), start, end, ) return result ``` -------------------------------- ### Smoke Test Success Output Example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/smoke-test.md Example console output indicating successful data retrieval from Bloomberg and Macrobond sources. ```text Testing metapyle connections (2021-12-29 to 2024-12-29) ================================================== ✓ bloomberg: 756 rows bloomberg 2021-12-29 4778.73 2021-12-30 4778.73 2021-12-31 4766.18 ... bloomberg 2024-12-26 5974.65 2024-12-27 5970.84 2024-12-29 5906.94 ✓ macrobond: 12 rows macrobond 2022-03-31 24740 2022-06-30 25249 2022-09-30 25724 ... macrobond 2024-03-31 28278 2024-06-30 28631 2024-09-30 29349 ================================================== Smoke test complete ``` -------------------------------- ### Initialize Cache Database Schema Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-27-column-naming-implementation.md Sets up the SQLite database, performs schema migration if the 'path' column is missing, and creates the necessary tables. ```python def _initialize_database(self) -> None: """Create database and tables if they don't exist.""" # Ensure parent directory exists db_path = Path(self._path) db_path.parent.mkdir(parents=True, exist_ok=True) self._conn = sqlite3.connect(self._path) # Check if we need to migrate (old schema without path column) cursor = self._conn.execute("PRAGMA table_info(cache_entries)") columns = [row[1] for row in cursor.fetchall()] if columns and "path" not in columns: # Old schema - drop tables and recreate logger.info("cache_schema_migration: dropping old tables") self._conn.execute("DROP TABLE IF EXISTS cache_data") self._conn.execute("DROP TABLE IF EXISTS cache_entries") # Create cache_entries table for metadata self._conn.execute(""" CREATE TABLE IF NOT EXISTS cache_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT NOT NULL, symbol TEXT NOT NULL, field TEXT, path TEXT, start_date TEXT NOT NULL, end_date TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(source, symbol, field, path, start_date, end_date) ) """) # Create cache_data table for storing DataFrame as blob self._conn.execute(""" CREATE TABLE IF NOT EXISTS cache_data ( entry_id INTEGER PRIMARY KEY, data BLOB NOT NULL, FOREIGN KEY(entry_id) REFERENCES cache_entries(id) ) """) ``` -------------------------------- ### Test FetchError when xbbg is not installed Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-batch-fetch-implementation.md Checks that a FetchError is raised when the 'xbbg' library is not installed, indicating a missing dependency for Bloomberg data retrieval. ```python def test_xbbg_not_available(self, source: BloombergSource) -> None: """Raise FetchError when xbbg not installed.""" with patch( "metapyle.sources.bloomberg._get_blp", return_value=None ): requests = [FetchRequest(symbol="SPX Index", field="PX_LAST")] with pytest.raises(FetchError, match="xbbg"): source.fetch(requests, "2024-01-01", "2024-01-02") ``` -------------------------------- ### Update Metapyle get() Method Call Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md This change updates the call to `_assemble_dataframe` within the `get()` method to pass the `symbols` list, ensuring that the symbol order is correctly utilized for DataFrame assembly. ```python # Assemble into wide DataFrame return self._assemble_dataframe(dfs, symbols) ``` -------------------------------- ### Add GsSession Initialization in raw-api-examples.md Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md This code block demonstrates the necessary session initialization for GS Quant examples in `raw-api-examples.md`. It imports `GsSession` and `Environment`, then calls `GsSession.use()` with production environment credentials. ```python from gs_quant.session import GsSession, Environment # Initialize session (required before any API calls) GsSession.use(Environment.PROD, client_id="YOUR_ID", client_secret="YOUR_SECRET") ``` -------------------------------- ### GET /catalog/names Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Lists all available catalog entry names. ```APIDOC ## GET /catalog/names ### Description Returns a list of all names currently present in the catalog. ### Method GET ### Endpoint /catalog/names ### Response #### Success Response (200) - **names** (list[string]) - A list of all catalog entry names. ``` -------------------------------- ### Initialize Fork Repository Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md Sets up a new local Git repository for your package fork. Configure your Git user name and email. ```powershell # Create project directory mkdir my-package-fork cd my-package-fork git init # Configure (use your details) git config user.name "Your Name" git config user.email "your.email@company.com" ``` -------------------------------- ### GET /catalog/{name} Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Retrieves a specific catalog entry by its name. ```APIDOC ## GET /catalog/{name} ### Description Retrieves a specific catalog entry by its name. If the name does not exist in the catalog, a SymbolNotFoundError is raised. ### Method GET ### Endpoint /catalog/{name} ### Parameters #### Path Parameters - **name** (string) - Required - The unique name of the catalog entry to retrieve. ### Response #### Success Response (200) - **my_name** (string) - The name of the entry - **source** (string) - The source of the entry - **symbol** (string) - The symbol associated with the entry - **field** (string) - Optional field value - **description** (string) - Optional description - **unit** (string) - Optional unit of measurement ``` -------------------------------- ### Get Catalog Size Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Returns the total number of entries in the catalog. ```python def __len__(self) -> int: """Return the number of entries in the catalog.""" return len(self._entries) ``` -------------------------------- ### Initialize Metapyle Client Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Initializes the Metapyle Client with catalog files and cache settings. Supports multiple catalog paths and cache enablement. ```python from metapyle import Client client = Client(catalog=mock_catalog, cache_path=str(cache_path)) ``` ```python client = Client(catalog=[str(file1), str(file2)], cache_enabled=False) ``` -------------------------------- ### Query Data with Client Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/user-guide.md Initialize the client and fetch data series. Ensure the client is closed after operations are complete. ```python from metapyle import Client # Initialize client with your catalog client = Client(catalog="catalog.yaml") # Fetch a single series (end defaults to today) df = client.get(["sp500_close"], start="2024-01-01") print(df.head()) # sp500_close # 2024-01-02 4742.83 # 2024-01-03 4704.81 # ... # Fetch multiple series with explicit end date df = client.get( ["sp500_close", "nasdaq_close"], start="2024-01-01", end="2024-12-31" ) # Always close the client when done (or use context manager) client.close() ``` -------------------------------- ### Catalog Entry Before Redesign Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-design.md Example of a catalog entry with the 'frequency' field before the redesign. ```yaml - my_name: GDP_US source: bloomberg symbol: GDP CURY Index frequency: quarterly field: PX_LAST ``` -------------------------------- ### Commit documentation changes Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-catalog-csv-tools-implementation.md Stages and commits the updated user guide to the repository. ```bash git add docs/user-guide.md git commit -m "docs: add catalog CSV tools to user guide" ``` -------------------------------- ### Update Client.get() Signature Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md Adds the output_format parameter to the get method signature. ```python def get( self, symbols: list[str], start: str, end: str | None = None, *, frequency: str | None = None, output_format: str = "wide", use_cache: bool = True, ) -> pd.DataFrame: ``` -------------------------------- ### Verify BloombergSource Import Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-31-user-testing-fixes-implementation.md Execute a command-line check to confirm the class is correctly exposed. ```bash python -c "from metapyle.sources import BloombergSource; print(BloombergSource)" ``` -------------------------------- ### Update sources/__init__.py exports Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-batch-fetch-implementation.md Adds FetchRequest and make_column_name to the __all__ list in src/metapyle/sources/__init__.py. ```python from metapyle.sources.base import FetchRequest, make_column_name __all__ = [ "BaseSource", "FetchRequest", "make_column_name", "register_source", "BloombergSource", "LocalFileSource", "MacrobondSource", ] ``` -------------------------------- ### Conflicting frequency parameter usage Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2026-01-01-unified-options-design.md Example of the problematic API usage where frequency is ambiguous. ```python df = client.get( ["us_gdp"], start="2020-01-01", unified=True, frequency=SeriesFrequency.MONTHLY, ) ``` -------------------------------- ### Catalog Entry After Redesign Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-design.md Example of a catalog entry after the redesign, with the 'frequency' field removed. ```yaml - my_name: GDP_US source: bloomberg symbol: GDP CURY Index field: PX_LAST ``` -------------------------------- ### Client Initialization Source: https://context7.com/stabilefrisur/metapyle/llms.txt The Client class is the main entry point for interacting with the Metapyle library, handling catalog loading, source validation, and cache management. ```APIDOC ## Client Initialization ### Description Initializes the Metapyle client to manage data fetching, catalog loading, and caching configurations. ### Parameters #### Request Body - **catalog** (str or list) - Required - Path to a single YAML/CSV catalog file or a list of paths. - **cache_path** (str) - Optional - Custom file path for the SQLite cache database. - **cache_enabled** (bool) - Optional - Toggle for enabling or disabling automatic caching (default: True). ``` -------------------------------- ### Register a New Source Adapter Source: https://github.com/stabilefrisur/metapyle/blob/master/CLAUDE.md Example of creating a new source adapter by subclassing `BaseSource` and using the `@register_source` decorator. Implement `fetch` and `get_metadata` methods. ```python from metapyle.sources.base import BaseSource, FetchRequest, make_column_name, register_source @register_source("newsource") class NewSource(BaseSource): def fetch(self, requests: Sequence[FetchRequest], start: str, end: str, **kwargs) -> pd.DataFrame: # Return DataFrame with DatetimeIndex, columns named via make_column_name() ... def get_metadata(self, symbol: str) -> dict[str, Any]: ... ``` -------------------------------- ### Get Local File Metadata Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Retrieves metadata information about a specified local file. ```APIDOC ## GET /api/localfile/metadata ### Description Retrieves metadata for a local file, including its absolute path, existence status, and file suffix. ### Method GET ### Endpoint /api/localfile/metadata ### Parameters #### Query Parameters - **symbol** (str) - Required - Path to the file. ### Response #### Success Response (200) - **metadata** (dict) - Dictionary containing file metadata. - **path** (str) - The absolute path of the file. - **exists** (bool) - Boolean indicating if the file exists. - **suffix** (str) - The file extension (e.g., '.csv', '.parquet'). #### Response Example ```json { "metadata": { "path": "/absolute/path/to/your/data.csv", "exists": true, "suffix": ".csv" } } ``` ``` -------------------------------- ### GET /client/get Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/user-guide.md Fetches data series defined in the catalog for a specified date range. ```APIDOC ## GET /client/get ### Description Retrieves historical data for one or more series defined in the catalog. ### Parameters #### Query Parameters - **series** (list) - Required - List of 'my_name' identifiers from the catalog. - **start** (string) - Required - Start date in YYYY-MM-DD format. - **end** (string) - Optional - End date in YYYY-MM-DD format (defaults to today). ### Request Example client.get(["sp500_close"], start="2024-01-01", end="2024-12-31") ### Response #### Success Response (200) - **data** (pandas.DataFrame) - A DataFrame containing the requested series indexed by date. ``` -------------------------------- ### Update Source Adapters Initialization Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-29-gsquant-source-implementation.md The updated __init__.py file including the GSQuantSource import and export. ```python """Source adapters for metapyle.""" from metapyle.sources.base import ( BaseSource, FetchRequest, make_column_name, register_source, ) from metapyle.sources.bloomberg import BloombergSource from metapyle.sources.gsquant import GSQuantSource from metapyle.sources.localfile import LocalFileSource from metapyle.sources.macrobond import MacrobondSource __all__ = [ "BaseSource", "BloombergSource", "FetchRequest", "GSQuantSource", "LocalFileSource", "MacrobondSource", "make_column_name", "register_source", ] ``` -------------------------------- ### Client get() Flow for Batch Fetching Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-batch-fetch-design.md Describes the client-side flow for the `get()` method when utilizing batch fetching. It includes resolving catalog entries, checking cache, grouping by source, building requests, calling source fetch, splitting results, caching, aligning frequency, renaming columns, and assembling the final DataFrame. ```python 1. Resolve catalog entries for all requested symbols 2. Check cache per-entry, separate cached vs uncached 3. Group uncached entries by source 4. For each source group: - Build `FetchRequest` list from entries - Call `source.fetch(requests, start, end)` - Split result DataFrame into single-column DataFrames - Cache each individually 5. Apply frequency alignment if requested 6. Rename all columns to `my_name` 7. Assemble final wide DataFrame ``` -------------------------------- ### Configure CLI Entry Points Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md Update the package configuration to point to the new fork entry point. ```toml myfork-cli = "myfork:main" # Changed from "original-cli" ``` -------------------------------- ### Catalog Validation Example Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-frequency-redesign-implementation.md Demonstrates how the Catalog class validates registered and unregistered sources against a SourceRegistry. ```APIDOC ## Catalog Validation ### Description This example shows how `Catalog.validate_sources` works with registered and unregistered sources. ### Test Case 1: Unknown Source #### Code ```python from metapyle.catalog import Catalog, CatalogEntry from metapyle.sources import SourceRegistry from metapyle.exceptions import UnknownSourceError import pytest entry = CatalogEntry( my_name="GDP_US", source="unknown_source", symbol="GDP CUR$ Index", ) catalog = Catalog({"GDP_US": entry}) registry = SourceRegistry() registry.register("bloomberg", type) with pytest.raises(UnknownSourceError, match="unknown_source"): catalog.validate_sources(registry) ``` ### Test Case 2: Successful Validation #### Code ```python from metapyle.catalog import Catalog, CatalogEntry from metapyle.sources import SourceRegistry entry1 = CatalogEntry( my_name="GDP_US", source="bloomberg", symbol="GDP CUR$ Index", ) entry2 = CatalogEntry( my_name="LOCAL_DATA", source="localfile", symbol="/data/local.csv", ) catalog = Catalog({"GDP_US": entry1, "LOCAL_DATA": entry2}) registry = SourceRegistry() registry.register("bloomberg", type) registry.register("localfile", type) catalog.validate_sources(registry) ``` ``` -------------------------------- ### Set Up Main Branch for Development Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/managing-upstream-tarballs.md Creates the 'main' branch from the current state of the 'upstream' branch and makes an initial empty commit to establish the fork's development history. ```powershell # Create main branch from current upstream state git checkout -b main # Create your first fork commit (even if no changes yet) git commit --allow-empty -m "fork: initialize fork from upstream v1.0.0" ``` -------------------------------- ### Initialize Database Schema Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Creates the cache_entries and cache_data tables if they do not exist and enables foreign key support. ```python def _init_schema(self) -> None: """Create database schema if not exists.""" if self._conn is None: return self._conn.executescript(""" CREATE TABLE IF NOT EXISTS cache_entries ( id INTEGER PRIMARY KEY, source TEXT NOT NULL, symbol TEXT NOT NULL, field TEXT, start_date TEXT NOT NULL, end_date TEXT NOT NULL, cached_at TEXT NOT NULL, UNIQUE(source, symbol, field, start_date, end_date) ); CREATE TABLE IF NOT EXISTS cache_data ( entry_id INTEGER NOT NULL, date TEXT NOT NULL, value REAL NOT NULL, FOREIGN KEY (entry_id) REFERENCES cache_entries(id) ON DELETE CASCADE, PRIMARY KEY (entry_id, date) ); CREATE INDEX IF NOT EXISTS idx_cache_lookup ON cache_entries(source, symbol, field); """) self._conn.execute("PRAGMA foreign_keys = ON") self._conn.commit() ``` -------------------------------- ### Get Bloomberg Symbol Metadata Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Retrieves metadata information for a specified Bloomberg ticker symbol. ```APIDOC ## Get Metadata ### Description Returns a dictionary containing metadata for the provided Bloomberg ticker symbol. ### Parameters #### Query Parameters - **symbol** (str) - Required - Bloomberg ticker. ### Response #### Success Response (200) - **dict** - Metadata dictionary containing the symbol and source name. ``` -------------------------------- ### Test Concrete Source Instantiation Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Confirms that a concrete subclass implementing both 'fetch' and 'get_metadata' can be successfully instantiated. ```python def test_concrete_source_can_be_instantiated() -> None: """Concrete subclass with both methods can be instantiated.""" from metapyle.sources.base import BaseSource class ConcreteSource(BaseSource): def fetch( self, symbol: str, start: str, end: str, **kwargs ) -> pd.DataFrame: return pd.DataFrame({"value": [1, 2, 3]}) def get_metadata(self, symbol: str) -> dict: return {"description": "test"} source = ConcreteSource() assert source is not None ``` -------------------------------- ### Get Metadata Method Signature Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-27-macrobond-source-design.md Defines the method signature for retrieving metadata for a specific symbol. ```python def get_metadata(self, symbol: str) -> dict[str, Any]: ``` -------------------------------- ### Run Integration Tests Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-27-column-naming-implementation.md Execute the full project test suite. ```bash python -m pytest tests/ -v ``` -------------------------------- ### GET /cache Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Retrieves time-series data from the cache if the requested date range is a subset of a cached range. ```APIDOC ## GET /cache ### Description Retrieves time-series data from the cache. Returns data if the requested date range is a subset of a cached range. ### Method GET ### Endpoint /cache ### Parameters #### Query Parameters - **source** (string) - Required - Source adapter name. - **symbol** (string) - Required - Source-specific symbol. - **field** (string | null) - Optional - Source-specific field. - **start_date** (string) - Required - Start date in ISO format. - **end_date** (string) - Required - End date in ISO format. ### Response #### Success Response (200) - **data** (pd.DataFrame | null) - Cached data if found, null otherwise. The DataFrame will have a DatetimeIndex and a 'value' column. #### Response Example ```json { "data": { "2023-01-01": {"value": 100.5}, "2023-01-02": {"value": 101.2} } } ``` ``` -------------------------------- ### GET Macrobond Time-Series Data Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-27-macrobond-source-implementation.md Fetches time-series data from Macrobond for a specified symbol and date range. ```APIDOC ## GET /fetch ### Description Fetches time-series data from Macrobond. Supports both raw series retrieval and unified series retrieval based on the unified parameter. ### Method GET ### Parameters #### Query Parameters - **symbol** (str) - Required - Macrobond series name (e.g., "usgdp", "gbcpi"). - **start** (str) - Required - Start date in ISO format (YYYY-MM-DD). - **end** (str) - Required - End date in ISO format (YYYY-MM-DD). - **unified** (bool) - Optional - If True, use get_unified_series. If False (default), use get_one_series. - **kwargs** (Any) - Optional - Additional parameters passed to get_unified_series when unified=True. ### Response #### Success Response (200) - **pd.DataFrame** - DataFrame with DatetimeIndex and single column named by symbol. #### Errors - **FetchError** - Raised if macrobond_data_api is not available or API call fails. - **NoDataError** - Raised if no data is returned for the symbol or within the specified date range. ``` -------------------------------- ### Initialize Source Adapters Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-26-metapyle-implementation.md Initializes the source adapters for metapyle by importing necessary modules to register them. This ensures that all available data source adapters are available for use. ```python """Source adapters for metapyle. This module provides the base interface for data sources and a registry for managing source adapters. """ from metapyle.sources.base import BaseSource, SourceRegistry, register_source # Import adapters to register them from metapyle.sources import localfile # noqa: F401 __all__ = ["BaseSource", "SourceRegistry", "register_source"] ``` -------------------------------- ### Define a Catalog Entry Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/user-guide.md Example of a YAML catalog entry mapping a human-readable name to a Bloomberg data source. ```yaml - my_name: sp500_close source: bloomberg symbol: SPX Index field: PX_LAST ``` -------------------------------- ### Project File Structure Source: https://github.com/stabilefrisur/metapyle/blob/master/docs/plans/2025-12-28-integration-tests-design.md The directory layout for integration tests, fixtures, and configuration files. ```text tests/integration/ ├── fixtures/ │ ├── bloomberg.yaml # Bloomberg catalog entries │ ├── macrobond.yaml # Macrobond catalog entries │ └── combined.yaml # Both sources for cross-source tests ├── conftest.py # Shared fixtures and pytest hooks ├── test_bloomberg.py # Bloomberg feature tests ├── test_macrobond.py # Macrobond feature tests └── test_cross_source.py # Cross-source tests ```