Skip to content

Commit

Permalink
Merge pull request #1 from anaconda/testing-ci
Browse files Browse the repository at this point in the history
Testing and CI
  • Loading branch information
AlbertDeFusco authored Sep 23, 2021
2 parents 57f226d + ad4761e commit d267d72
Show file tree
Hide file tree
Showing 9 changed files with 548 additions and 33 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build and test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
package:
name: Build package
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
activate-environment: build-intake-ga
environment-file: etc/build-environment.yml
python-version: 3.8
auto-activate-base: false
- name: Conda Build
shell: bash -l {0}
run: |
conda build conda.recipe --no-test
mv $CONDA_PREFIX/conda-bld .
- name: Upload conda-bld directory
uses: actions/upload-artifact@v2
with:
name: package-${{ github.sha }}
path: ./conda-bld
test:
name: Test (${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python-version: ["3.7", "3.8", "3.9"]
steps:
- uses: actions/checkout@v2
- uses: conda-incubator/setup-miniconda@v2
with:
miniconda-version: "latest"
python-version: ${{ matrix.python-version }}
activate-environment: test-intake-ga
environment-file: etc/test-environment.yml
- name: Download the build artifact
uses: actions/download-artifact@v2
with:
name: package-${{ github.sha }}
path: ~/.conda/conda-bld
- name: py.test
shell: bash -l {0}
run: |
conda install -n test-intake-ga --use-local ~/.conda/conda-bld/noarch/intake-google-analytics-*.tar.bz2
py.test -xv
- name: Codecov
uses: codecov/codecov-action@v1
with:
file: ./cov.xml
env_vars: OS,PYTHON
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ nosetests.xml
coverage.xml
*,cover
.hypothesis/
junit.xml
cov.xml

# Translations
*.mo
Expand Down
4 changes: 3 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ dependencies:
- pandas
- intake
- flake8
- pytest
- pytest-cov
channels:
- defaults
- conda-forge
- conda-forge
5 changes: 5 additions & 0 deletions etc/build-environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: build-intake-ga
dependencies:
- conda
- conda-build
- conda-verify
12 changes: 12 additions & 0 deletions etc/test-environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: test-intake-ga
dependencies:
- google-api-python-client
- google-auth-oauthlib
- pandas
- intake
- flake8
- pytest
- pytest-cov
channels:
- defaults
- conda-forge
79 changes: 47 additions & 32 deletions intake_google_analytics/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"INTEGER": int,
"TIME": float,
"PERCENT": float,
"STRING": str,
"FLOAT": float,
"CURRENCY": float
}

Expand Down Expand Up @@ -90,51 +90,39 @@ def to_dask(self):
raise NotImplementedError()

def _close(self):
self._dataframe = None
self._df = None


class GoogleAnalyticsAPI(object):
def __init__(self, credentials_path=None):
credentials = None

if credentials_path:
credentials = Credentials.from_service_account_file(credentials_path)
def __init__(self, credentials_path):
self._credentials_path = credentials_path
self.client = self.create_client()

self.client = discovery.build('analyticsreporting', 'v4',
credentials=credentials,
cache_discovery=False).reports()
def create_client(self):
credentials = Credentials.from_service_account_file(self._credentials_path)
c = discovery.build('analyticsreporting', 'v4',
credentials=credentials,
cache_discovery=False).reports()
return c

def query(self, view_id: str, start_date: DateTypes, end_date: DateTypes, metrics: list,
dimensions: list = None, filters: list = None):
def query(self, view_id: str, start_date: DateTypes, end_date: DateTypes,
metrics: list, dimensions: list = None, filters: list = None):
result = self._query(
view_id=view_id, start_date=start_date, end_date=end_date,
metrics=metrics, dimensions=dimensions, filters=filters
)

df = self._to_dataframe(result)

return df

def _query(self, view_id: str, start_date: DateTypes, end_date: DateTypes, metrics: list,
def _build_body(self, view_id: str, start_date: DateTypes, end_date: DateTypes, metrics: list,
dimensions: list = None, filters: list = None):

date_range = {'startDate': start_date, 'endDate': end_date}
for key, value in date_range.items():
if is_dt(value):
date_range[key] = as_day(value)
elif value.lower() in ['yesterday', 'today']:
date_range[key] = value.lower()
elif re.match(YYYY_MM_DD, value):
pass
elif re.match(r'\d+DaysAgo', value):
pass
else:
raise ValueError(f'{key}={value} is not a supported date.\n'
f'Please use a date/datetime object.')

body = {
'reportRequests': []
date_range = {
'startDate': self._parse_date(start_date),
'endDate': self._parse_date(end_date)
}

request = {
'viewId': view_id,
'dateRanges': [date_range],
Expand All @@ -151,11 +139,23 @@ def _query(self, view_id: str, start_date: DateTypes, end_date: DateTypes, metri
if filters:
request['filtersExpression'] = filters

body['reportRequests'].append(request)
body = {'reportRequests': [request]}
return body

def _query(self, view_id: str, start_date: DateTypes, end_date: DateTypes, metrics: list,
dimensions: list = None, filters: list = None):

body = self._build_body(
view_id=view_id, start_date=start_date, end_date=end_date,
metrics=metrics, dimensions=dimensions, filters=filters
)

result = self.client.batchGet(body=body).execute()

report = result['reports'][0]
expected_rows = report['data']['rowCount']
expected_rows = report['data'].get('rowCount', 0)
if expected_rows == 0:
return report

while result['reports'][0].get('nextPageToken'):
body['reportRequests'][0]['pageToken'] = result['reports'][0].get('nextPageToken')
Expand Down Expand Up @@ -238,3 +238,18 @@ def _parse_fields(fields, style):
raise ValueError('\n'.join(errors))

return parsed

@staticmethod
def _parse_date(value):
if is_dt(value):
return as_day(value)
elif value in ['yesterday', 'today']:
return value
elif re.match(YYYY_MM_DD, value):
return value
elif re.match(r'\d+DaysAgo', value):
return value
else:
raise ValueError(f'{value} is not a supported date.\n'
f'Please use a date/datetime object or string of the following formats:\n'
f'"yesterday", "today", "NDaysAgo", "YYYY-MM-DD"')
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ addopts =
--junitxml=junit.xml
--ignore setup.py
--ignore run_test.py
--cov=intake_google_analytics
--cov-report=xml:cov.xml
--cov-report term-missing
--tb native
--strict-markers
Expand Down
Loading

0 comments on commit d267d72

Please sign in to comment.