# GSC Storage


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L47"
target="_blank" style="float:right; font-size:smaller">source</a>

### filter_exclude_pages

``` python

def filter_exclude_pages(
    query, # SQLModel query
    exclude_pages:list, # Page path substrings to exclude
):

```

*Exclude rows where page contains any of the given substrings.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L39"
target="_blank" style="float:right; font-size:smaller">source</a>

### filter_dimension

``` python

def filter_dimension(
    query, # SQLModel query
    dimension:str, # GSCAnalytics field name
    value:str, # Value to match
):

```

*Filter query by a specific dimension value.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L31"
target="_blank" style="float:right; font-size:smaller">source</a>

### filter_dates

``` python

def filter_dates(
    query, # SQLModel query
    start:str, # Start date (YYYY-MM-DD)
    end:str, # End date (YYYY-MM-DD)
):

```

*Filter query by date range.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L24"
target="_blank" style="float:right; font-size:smaller">source</a>

### filter_site

``` python

def filter_site(
    query, # SQLModel query
    site_url:str, # GSC property URL
):

```

*Filter query by site URL.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L58"
target="_blank" style="float:right; font-size:smaller">source</a>

### AnalyticsSummary

``` python

def AnalyticsSummary(
    __pydantic_self__, data:Any
)->None:

```

*!!! abstract “Usage Documentation”* [Models](../concepts/models.md)

A base class for creating Pydantic models.

Attributes: **class_vars**: The names of the class variables defined on
the model. **private_attributes**: Metadata about the private attributes
of the model. **signature**: The synthesized `__init__`
\[`Signature`\]\[inspect.Signature\] of the model.

    __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
    __pydantic_core_schema__: The core schema of the model.
    __pydantic_custom_init__: Whether the model has a custom `__init__` function.
    __pydantic_decorators__: Metadata containing the decorators defined on the model.
        This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
    __pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
        __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
    __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
    __pydantic_post_init__: The name of the post-init method for the model, if defined.
    __pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
    __pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
    __pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.

    __pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
    __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

    __pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
        is set to `'allow'`.
    __pydantic_fields_set__: The names of fields explicitly set during instantiation.
    __pydantic_private__: Values of private attributes set on the model instance.

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L67"
target="_blank" style="float:right; font-size:smaller">source</a>

### normalize_url

``` python

def normalize_url(
    url:str
)->str:

```

*Normalize URL by decoding percent-encoding and standardizing
separators*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L75"
target="_blank" style="float:right; font-size:smaller">source</a>

### parse_gsc_row

``` python

def parse_gsc_row(
    row:dict, # Raw GSC API row
    site_url:str, # GSC property URL
    date:str, # Date of the row (YYYY-MM-DD)
)->GSCAnalytics:

```

*Parse a raw GSC API row into a GSCAnalytics instance.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L91"
target="_blank" style="float:right; font-size:smaller">source</a>

### store_gsc_data

``` python

def store_gsc_data(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    date:str, # Date of the data (YYYY-MM-DD)
    rows:list, # Raw GSC API rows
)->None:

```

*Store GSC rows with upsert (update on conflict).*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L110"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_top_queries

``` python

def get_top_queries(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
    country:str | None=None, # Filter by country code
    page_path:str | None=None, # Filter by page path substring
    limit:int=10, # Max rows to return
    sort_by:str='clicks', # Sort by 'clicks' or 'impressions'
)->list:

```

*Get top performing queries, optionally filtered by country and page.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L139"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_top_pages

``` python

def get_top_pages(
    session:Session, site_url:str, start_date:str, end_date:str, country:str | None=None, limit:int=20,
    sort_by:str='clicks'
)->list:

```

*Get top performing pages by clicks or impressions.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L160"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_wins

``` python

def get_wins(
    session:Session, site_url:str, start_date:str, end_date:str, min_impressions:int=100, min_position:float=10.0,
    max_position:float=50.0, country:str | None=None, page_url:str | None=None, limit:int=20
)->list:

```

*Get high-impression, low-ranking keyword opportunities.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L187"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_top_queries_excluding_pages

``` python

def get_top_queries_excluding_pages(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
    exclude_pages:list, # Page substrings to exclude
    country:str | None=None, # Filter by country code
    limit:int=10, # Max rows to return
)->list:

```

*Get top queries excluding specific pages.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L212"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_page_analytics

``` python

def get_page_analytics(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    page_path:str, # Partial page path to match
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
)->dict:

```

*Get aggregated analytics and top queries for a specific page.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L249"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_analytics_by_date_range

``` python

def get_analytics_by_date_range(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
)->list:

```

*Get all raw GSC analytics rows for a date range.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L263"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_trends

``` python

def get_trends(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
    dimension:str | None=None, # Optional dimension to group by
)->list:

```

*Get click/impression trends over time, optionally grouped by a
dimension.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L289"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_analytics_by

``` python

def get_analytics_by(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
    dimension:str, # GSCAnalytics field to filter by
    value:str, # Value to match
)->list:

```

*Get query-level analytics filtered by a specific dimension value.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L312"
target="_blank" style="float:right; font-size:smaller">source</a>

### store_single_date

``` python

def store_single_date(
    session:Session, # Active database session
    auth:GSCAuth, # Authenticated GSCAuth instance
    site_url:str, # GSC property URL
    date:str, # Date to fetch and store (YYYY-MM-DD)
)->int:

```

*Fetch and store GSC data for a single date. Returns number of records
stored.*

``` python
# Check what's actually stored
stored = session.exec(select(GSCAnalytics).limit(1)).first()
print(f"Query: {stored.query}")
print(f"Clicks: {stored.clicks}")
print(f"Date: {stored.date}")
test_eq(stored.site_url, "sc-domain:kareemai.com")
```

    Query: أنواع السباكة
    Clicks: 0
    Date: 2024-11-11

    AssertionError: ==:
    sc-domain:awazly.com
    sc-domain:kareemai.com
    [31m---------------------------------------------------------------------------[39m
    [31mAssertionError[39m                            Traceback (most recent call last)
    [36mCell[39m[36m [39m[32mIn[31][39m[32m, line 8[39m
    [32m      6[39m [38;5;28mprint[39m([33mf[39m[33m"[39m[33mClicks: [39m[38;5;132;01m{[39;00mstored.clicks[38;5;132;01m}[39;00m[33m"[39m)
    [32m      7[39m [38;5;28mprint[39m([33mf[39m[33m"[39m[33mDate: [39m[38;5;132;01m{[39;00mstored.date[38;5;132;01m}[39;00m[33m"[39m)
    [32m----> [39m[32m8[39m [43mtest_eq[49m[43m([49m[43mstored[49m[43m.[49m[43msite_url[49m[43m,[49m[43m [49m[33;43m"[39;49m[33;43msc-domain:kareemai.com[39;49m[33;43m"[39;49m[43m)[49m

    [36mFile [39m[32m~/Desktop/seo_rat/.venv/lib/python3.13/site-packages/fastcore/test.py:40[39m, in [36mtest_eq[39m[34m(a, b)[39m
    [32m     38[39m [38;5;28;01mdef[39;00m[38;5;250m [39m[34mtest_eq[39m(a,b):
    [32m     39[39m     [33m"[39m[33m`test` that `a==b`[39m[33m"[39m
    [32m---> [39m[32m40[39m     [43mtest[49m[43m([49m[43ma[49m[43m,[49m[43mb[49m[43m,[49m[43mequals[49m[43m,[49m[43m [49m[43mcname[49m[43m=[49m[33;43m'[39;49m[33;43m==[39;49m[33;43m'[39;49m[43m)[49m

    [36mFile [39m[32m~/Desktop/seo_rat/.venv/lib/python3.13/site-packages/fastcore/test.py:30[39m, in [36mtest[39m[34m(a, b, cmp, cname)[39m
    [32m     28[39m [33m"[39m[33m`assert` that `cmp(a,b)`; display inputs and `cname or cmp.__name__` if it fails[39m[33m"[39m
    [32m     29[39m [38;5;28;01mif[39;00m cname [38;5;129;01mis[39;00m [38;5;28;01mNone[39;00m: cname=cmp.[34m__name__[39m
    [32m---> [39m[32m30[39m [38;5;28;01massert[39;00m cmp(a,b),[33mf[39m[33m"[39m[38;5;132;01m{[39;00mcname[38;5;132;01m}[39;00m[33m:[39m[38;5;130;01m\n[39;00m[38;5;132;01m{[39;00ma[38;5;132;01m}[39;00m[38;5;130;01m\n[39;00m[38;5;132;01m{[39;00mb[38;5;132;01m}[39;00m[33m"[39m

    [31mAssertionError[39m: ==:
    sc-domain:awazly.com
    sc-domain:kareemai.com

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L344"
target="_blank" style="float:right; font-size:smaller">source</a>

### store_date_range

``` python

def store_date_range(
    session:Session, auth:GSCAuth, site_url:str, start_date:str, end_date:str
)->dict:

```

*Fetch and store GSC data for all dates in range.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L365"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_missing_dates

``` python

def get_missing_dates(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
)->list:

```

*Return dates in range that have no stored GSC data.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L354"
target="_blank" style="float:right; font-size:smaller">source</a>

### iter_dates

``` python

def iter_dates(
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
)->list:

```

*Generate all dates between start and end inclusive.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L380"
target="_blank" style="float:right; font-size:smaller">source</a>

### sync_missing_dates

``` python

def sync_missing_dates(
    session:Session, auth:GSCAuth, site_url:str, start_date:str, end_date:str
)->dict:

```

*Fetch and store GSC data for missing dates only.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L385"
target="_blank" style="float:right; font-size:smaller">source</a>

### daily_sync

``` python

def daily_sync(
    session:Session, # Active database session
    auth:GSCAuth, # Authenticated GSCAuth instance
    sites:list, # List of GSC property URLs to sync
)->dict:

```

*Sync missing GSC data for all sites up to today.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L397"
target="_blank" style="float:right; font-size:smaller">source</a>

### compare_date_ranges

``` python

def compare_date_ranges(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start1:str, # First period start date (YYYY-MM-DD)
    end1:str, # First period end date (YYYY-MM-DD)
    start2:str, # Second period start date (YYYY-MM-DD)
    end2:str, # Second period end date (YYYY-MM-DD)
    page_url:str | None=None, # Optional specific page to compare
)->dict:

```

*Compare GSC metrics between two date ranges, optionally for a specific
page.*

------------------------------------------------------------------------

<a
href="https://github.com/abdelkareemkobo/seo_rat/blob/main/seo_rat/gsc_storage.py#L445"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_country_breakdown

``` python

def get_country_breakdown(
    session:Session, # Active database session
    site_url:str, # GSC property URL
    start_date:str, # Start date (YYYY-MM-DD)
    end_date:str, # End date (YYYY-MM-DD)
    page_url:str | None=None, # Optional specific page to filter
    limit:int=20, # Max number of countries to return
)->list:

```

*Get traffic metrics grouped by country, optionally for a specific
page.*
