Skip to content

Commit

Permalink
Merge pull request #83 from AartGoossens/feature/tcx_metadata
Browse files Browse the repository at this point in the history
Finishes metadata loading for read_tcx()
  • Loading branch information
AartGoossens authored Apr 22, 2021
2 parents 23f7ea6 + 42509ac commit 13e61b0
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9, '3.10.0-alpha.7']
steps:
- uses: actions/checkout@master
- name: Set up Python ${{ matrix.python-version }}
Expand Down
12 changes: 10 additions & 2 deletions docker/Dockerfile.jupyter
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ FROM python

RUN pip install jupyter

RUN mkdir /build
WORKDIR /build
COPY pyproject.toml poetry.lock README.md ./
RUN mkdir /sweat
COPY sweat ./sweat

RUN pip install .

RUN mkdir /src/
WORKDIR /src/
WORKDIR /src/docs/docs

CMD pip install . && cd docs/docs/ && jupyter notebook --ip=0.0.0.0 --port=8888 --allow-root --NotebookApp.token='' --NotebookApp.password=''
CMD jupyter notebook --ip=0.0.0.0 --port=8888 --allow-root --NotebookApp.token='' --NotebookApp.password=''
2 changes: 2 additions & 0 deletions docker/Dockerfile.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ ENV PYTHONUNBUFFERED=1
RUN apt update
RUN apt install -y software-properties-common
RUN add-apt-repository -y ppa:deadsnakes/ppa
RUN apt update
RUN apt install -y \
curl \
python3.6-dev \
python3.7-dev \
python3.8-dev \
python3.9-dev \
python3.10-dev \
python3-pip
RUN pip3 install --upgrade pip

Expand Down
2 changes: 2 additions & 0 deletions docker/docker-compose.docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ services:
build:
context: ..
dockerfile: docker/Dockerfile.jupyter
environment:
- PYTHONPATH=/src:${PYTHONPATH}
ports:
- "8889:8888"
volumes:
Expand Down
5 changes: 5 additions & 0 deletions docs/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Types of changes:
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## [Unreleased] - {yyyy-mm-dd}
### Added
- Adds testing for Python 3.10
- `read_tcx()` now supports a metadata=True kwarg that will return device data.

## [0.20.3] - 2021-04-20
### Fixed
- `sweat.read_fit()` now supports integer column names.
Expand Down
14 changes: 14 additions & 0 deletions docs/docs/features/data_loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ example_tcx = sweat.examples(path="3173437224.tcx")
data = sweat.read_tcx(example_tcx.path)
```

### Metadata
The `read_tcx()` function accepts a `metadata=True` parameter.
When set to `True` (default is `False`) a dictionairy is returned, with the dataframe in the "data" key, and in the key "device" a `Device` object that has the attributes `name`, `product_id`, `serial_number`, `sensors` and `metadata`:

```python
import sweat


data = sweat.read_tcx("path_to.tcx", metadata=True)

data["device"]
-> Device(name='Garmin Edge 1000', product_id='1836', serial_number='3907354759', metadata={'creator_xml': ...}, sensors=[])
```

## Strava
The `sweat.read_strava()` function can be used to pull data from Strava.
Sweat assumes you already have an API access token. Read more about that [here](http://developers.strava.com/docs/authentication/).
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ openpyxl = "^3.0.7"
legacy_tox_ini = """
[tox]
isolated_build = true
envlist = py36,py37,py38,py39
envlist = py36,py37,py38,py39,py3.10
[testenv]
whitelist_externals = poetry
Expand Down
6 changes: 5 additions & 1 deletion sweat/io/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@

def process_location_columns(df, columns=None):
if columns is None:
columns = [c for c in df.columns if isinstance(c, str) and (c.endswith("_lat") or c.endswith("_long"))]
columns = [
c
for c in df.columns
if isinstance(c, str) and (c.endswith("_lat") or c.endswith("_long"))
]
else:
columns = [c for c in columns if c in df.columns]

Expand Down
13 changes: 6 additions & 7 deletions sweat/io/tcx.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,16 @@ def read_tcx(
if metadata:
creator = activity.find("default:Creator", NAMESPACES)
device_name = xml_find_value_or_none(creator, "default:Name", NAMESPACES)
device_unit_id = xml_find_value_or_none(
creator, "default:UnitId", NAMESPACES
)
device_product_id = xml_find_value_or_none(
creator, "default:ProductId", NAMESPACES
unit_id = xml_find_value_or_none(creator, "default:UnitId", NAMESPACES)
product_id = xml_find_value_or_none(
creator, "default:ProductID", NAMESPACES
)

device = Device(
name=device_name,
serial_number=device_unit_id,
metadata={},
product_id=product_id,
serial_number=unit_id,
metadata={"creator_xml": creator},
)

tcx_df = pd.DataFrame(records)
Expand Down
22 changes: 12 additions & 10 deletions sweat/io/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import List

import pandas as pd
Expand Down Expand Up @@ -50,15 +50,17 @@ def create_empty_dataframe():


@dataclass
class BaseDevice:
class Sensor:
name: str
serial_number: str
metadata: dict
product_id: str = None
serial_number: str = None
metadata: dict = field(default_factory=dict)


class Sensor(BaseDevice):
pass


class Device(BaseDevice):
sensors: List[Sensor]
@dataclass
class Device:
name: str
product_id: str = None
serial_number: str = None
metadata: dict = field(default_factory=dict)
sensors: List[Sensor] = field(default_factory=list)
13 changes: 9 additions & 4 deletions tests/io/test_tcx.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ def test_read_tcx(example):
assert activity["session"].max() == example.sessions - 1


@pytest.mark.parametrize(
"example", [(i) for i in sweat.examples(file_type=FileTypeEnum.tcx)]
)
def test_read_tcx_metadata(example):
def test_read_tcx_metadata():
example = sweat.examples(path="activity_4078723797.tcx")
activity = tcx.read_tcx(example.path, metadata=True)

assert isinstance(activity, dict)
Expand All @@ -46,3 +44,10 @@ def test_read_tcx_metadata(example):

assert "session" in data.columns
assert data["session"].max() == example.sessions - 1

device = activity["device"]
assert device.name == "Garmin Edge 1000"
assert device.product_id is not None
assert device.serial_number is not None
assert device.sensors == []
assert "creator_xml" in device.metadata

0 comments on commit 13e61b0

Please sign in to comment.