Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5d82976
adding a pandas wrapper
Oct 19, 2020
7f0c2ba
Merge pull request #28 from jjjchens235/master
turing-complet Oct 22, 2020
9dbb0d0
initial reworking of ci and package updates
turing-complet Oct 23, 2020
66bb513
run black
turing-complet Oct 23, 2020
30d603b
sort imports and get linting to pass
turing-complet Oct 23, 2020
696110b
update travis config
turing-complet Oct 24, 2020
8681926
Merge pull request #29 from turing-complet/jon/dev
turing-complet Oct 25, 2020
3bb356c
allow personal access token auth and wrapper for bedtime summary
turing-complet Oct 25, 2020
e6c9c6e
move auth to own module
turing-complet Oct 25, 2020
f61c602
add mock client for tests
turing-complet Oct 26, 2020
5e6e804
fix mock structure, update tests
turing-complet Oct 26, 2020
e171705
better docstrings and validation
turing-complet Oct 30, 2020
7f4fbdf
nox for docs
turing-complet Oct 31, 2020
a7134a5
cleanup packages
turing-complet Oct 31, 2020
5c05adc
Merge pull request #30 from turing-complet/jon/dev
turing-complet Oct 31, 2020
50405f4
separate files for writing output and converters, flatten bedtime jso…
turing-complet Nov 1, 2020
f12e365
drop ipython dependency
turing-complet Nov 1, 2020
3c996a6
start date optional, some docs cleanup
turing-complet Nov 2, 2020
ad869f7
Merge pull request #31 from turing-complet/jon/dev
turing-complet Nov 6, 2020
db6dd63
remove unused code and simplify pandas interface
turing-complet Nov 9, 2020
89ed8f7
handle bedtime date key and add converter
turing-complet Nov 12, 2020
d1bf64b
add new features to readme
turing-complet Nov 12, 2020
3d98ea3
Merge pull request #32 from turing-complet/jon/dev
turing-complet Nov 12, 2020
439e7e6
add hypnogram converter and allow column level override
turing-complet Nov 16, 2020
815d594
bump version and format setup.py
turing-complet Nov 16, 2020
8057ca3
update docstrings for pandas client
turing-complet Nov 16, 2020
c69aa3d
Merge pull request #33 from turing-complet/jon/dev
turing-complet Nov 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# .flake8
[flake8]
select = BLK,C,E,F,I,W
ignore = E203,W503,E501,F401,E731
max-line-length = 88
max-complexity = 10
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ __pycache__
build
*.egg-info
.tox
.nox
docs/_build/
data
data
test_token.json
19 changes: 13 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
language: python
python:
- "3.5"
- "3.6"
- "3.7-dev"
- 3.6
- 3.7
- 3.8
install:
- pip install pipenv
- pipenv install
script: pytest
- pip install nox
env:
- SESSION=tests
jobs:
include:
- python: 3.8
env: SESSION=lint
- python: 3.8
env: SESSION=docs
script: nox -s $SESSION
5 changes: 1 addition & 4 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ verify_ssl = true

[packages]
requests-oauthlib = "*"
sphinx = "*"
sphinx-rtd-theme = "*"
flask = "*"
twine = "*"
wheel = "*"
ipython = "*"
requests-mock = "*"
pytest = "*"
pandas = "*"
535 changes: 272 additions & 263 deletions Pipfile.lock

Large diffs are not rendered by default.

34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@

## Installation

Package is on pypi, so install as follows, or clone the repo and install dependencies using pipenv.
Easiest way is to get it from PyPI:

`pip install oura` or `pipenv install oura`
`pip install oura`

## Getting started

Once you register an application, you can use this sample script to authorize access to your own data or some test account data. It will follow the auth code flow and print out the token response. Make sure to add localhost:3030 to the redirect uris for your app (the port can be changed in the script).
Both personal access tokens and oauth flows are supported by the API (and by
this library). For personal use, the simplest way to start is by getting
yourself a PAT and supplying it to a client:

```
client = OuraClient(personal_access_token="MY_TOKEN")
```

If you are using oauth, there are a few more steps. First, register an application
Then you can use this sample script to authorize access to your own data or some test account data. It will follow the auth code flow and print out the token response. Make sure to add localhost:3030 to the redirect uris for your app (the port can be changed in the script).
```
./token-request.py <client-id> <client-secret>
```
Expand Down Expand Up @@ -45,7 +54,6 @@ oura = OuraClient(<client_id>, <access_token>)
oura.user_info()
oura.sleep_summary(start='2018-12-05', end='2018-12-10')
oura.activity_summary(start='2018-12-25')
oura.readiness_summary() # throws exception since start is None
```


Expand All @@ -54,4 +62,22 @@ The `refresh_callback` is a fuction that takes a token dict and saves it somewhe
{'token_type': 'bearer', 'refresh_token': <refresh>, 'access_token': <token>, 'expires_in': 86400, 'expires_at': 1546485086.3277025}
```

## Working with pandas
You can also make requests and have the data converted to pandas dataframes by
using the pandas client. Some customization is available but subject to
future improvement.

```
client = OuraClientDataFrame(...)
bedtime = client.bedtime_df(start, end, convert=True)

In [3]: client.bedtime_df()
Out[3]:
bedtime_window status
date
2020-03-17 {'start': -3600, 'end': 0} IDEAL_BEDTIME_AVAILABLE
2020-03-18 {'start': None, 'end': None} LOW_SLEEP_SCORES
```


Live your life.
5 changes: 4 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

clean:
rm -rf _build
12 changes: 10 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ API
Purpose
================

Reference for full api surface.
Reference for api surface.

Client
Module Index
================

.. automodule:: oura.client
:synopsis: Probably the best way to call the Oura API using python.
:members:

.. automodule:: oura.client_pandas
:synopsis: Extends the client by providing pandas functionality.
:members:

.. automodule:: oura.writers
:synopsis: Various ways to export data (excel, console, etc).
:members:

23 changes: 21 additions & 2 deletions docs/auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
Authentication and Authorization
********************************

Oura uses OAuth2 to allow a user to grant access to their data.
There are two choices for auth:

* oauth2 for making requests on behalf of other users
* personal access tokens, which are unsurprisingly for personal use


See the `official documentation <https://cloud.ouraring.com/docs/authentication>`_

Expand All @@ -26,4 +30,19 @@ In following the standard flow, you would have some code under your `/callback`
token_response = auth_client.fetch_access_token(code=code)


Now you are ready to make authenticated API requests. Please use this power responsibly.
Now you are ready to make authenticated API requests. Please use this power responsibly.

Personal Access Token
=====================

You can also access your own data using a personal_access_token - get one from
the cloud portal and save the value somewhere, like an environment variable. Or
somewhere else, it's your token anyway. Then just pass it to a new
:class:`oura.OuraClient` instance and you'll be ready to go. See what I mean ::

import os
from oura import OuraClient
my_token = os.getenv('MY_TOKEN')
client = OuraClient(personal_access_token=my_token)
who_am_i = client.user_info()

2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------

project = 'python-oura'
copyright = '2019, Jon Hagg'
copyright = '2020, Jon Hagg'
author = 'Jon Hagg'

# The short X.Y version
Expand Down
32 changes: 6 additions & 26 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
alabaster==0.7.12
Babel==2.6.0
certifi==2018.11.29
chardet==3.0.4
Click==7.0
docutils==0.14
Flask==1.0.2
idna==2.8
imagesize==1.1.0
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.0
oauthlib==2.1.0
packaging==18.0
Pygments==2.3.1
pyparsing==2.3.0
pytz==2018.7
requests==2.21.0
requests-oauthlib==1.0.0
six==1.12.0
snowballstemmer==1.2.1
Sphinx==1.8.3
sphinx-rtd-theme==0.4.2
sphinxcontrib-websupport==1.1.0
urllib3==1.24.2
Werkzeug==0.15.3
sphinx
sphinx-rtd-theme
pandas
pytest
requests-mock
requests-oauthlib
12 changes: 6 additions & 6 deletions docs/summaries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
Daily summaries
********************************

Oura's API is based on the idea of daily summaries. For each kind of data (sleep, activity, readiness)
there is an endpoint which will return summaries for one or more day. They take a start and end date in the query string,
but if you only supply the start date you'll get back data for just that day.
Oura's API is based on the idea of daily summaries. For each kind of data (sleep, activity, readiness, bedtime)
there is an endpoint which will return summaries for one or more day. They each
take an optional start date and end date (YYYY-MM-DD).

See the `official documentation <https://cloud.ouraring.com/docs/daily-summaries>`_
See the `official documentation <https://cloud.ouraring.com/docs/daily-summaries>`_ for behavior regarding the dates.

Usage
========================

If you just want to make some requests, it's fairly easy. Just do this::
If you just want to make some requests, it's fairly easy. Just do this ::

from oura import OuraClient
oura = OuraClient(client_id=MY_CLIENT_ID, access_token=ACCESS_TOKEN)
Expand All @@ -34,7 +34,7 @@ For example::
client = OuraClient(client_id=MY_CLIENT_ID, client_secret=MY_CLIENT_SECRET, access_token, refresh_token, refresh_callback=save_token_to_db)


Now you are ready to get all the data, provided the user has granted you the required scopes.::
Now you are ready to get all the data, provided the user has granted you the required scopes. ::

from datetime import date
today = str(date.today()) # 2019-01-06, e,g, YYYY-MM-DD, or use whatever start/end date you want
Expand Down
48 changes: 48 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import nox

nox.options.sessions = "lint", "tests"
locations = ["oura", "tests", "samples"]


@nox.session
def tests(session):
args = session.posargs
session.install("pipenv")
session.run("pipenv", "sync")
session.run("pipenv", "run", "pytest", *args)


@nox.session
def lint(session):
args = session.posargs or locations
session.install("flake8", "black", "isort")
session.run("flake8", *args)
session.run("black", "--check", "--diff", *args)
session.run("isort", "-m", "3", "--tc", "--check", "--diff", *args)


@nox.session
def format(session):
black(session)
isort(session)


def black(session):
args = session.posargs or locations
session.install("black")
session.run("black", *args)


def isort(session):
args = session.posargs or locations
session.install("isort")
session.run("isort", "-m", "3", "--tc", *args)


@nox.session
def docs(session):
session.chdir("docs")
session.install("-r", "requirements.txt")
# session.run("sphinx-apidoc", "-f", "-o", "source", "../oura")
# session.run("make", "clean", external=True)
session.run("make", "html", external=True)
10 changes: 8 additions & 2 deletions oura/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@

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

It's a description for __init__.py, innit.
Welcome to the python oura library!

For more information, please check the github:
https://github.com/turing-complet/python-ouraring


"""
from .client import OuraClient, OuraOAuth2Client
from .auth import OAuthRequestHandler, OuraOAuth2Client, PersonalRequestHandler
from .client import OuraClient
from .client_pandas import OuraClientDataFrame
Loading