Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
language: python
python:
- 3.6
- 3.7
- 3.8
install:
Expand Down
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ verify_ssl = true
requests-oauthlib = "*"
flask = "*"
twine = "*"
ipython = "*"
requests-mock = "*"
pytest = "*"
pandas = "*"
94 changes: 4 additions & 90 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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
11 changes: 8 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +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: Probably the best way to call the Oura API using python.
:synopsis: Extends the client by providing pandas functionality.
:members:

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

8 changes: 6 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 Down Expand Up @@ -34,7 +38,7 @@ 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
`OuraClient` instance and you'll be ready to go. See what I mean::
:class:`oura.OuraClient` instance and you'll be ready to go. See what I mean ::

import os
from oura import OuraClient
Expand Down
1 change: 0 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
sphinx
sphinx-rtd-theme
flask
pandas
pytest
requests-mock
Expand Down
10 changes: 5 additions & 5 deletions docs/summaries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Daily summaries
********************************

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 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.
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
3 changes: 2 additions & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import nox

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

Expand Down Expand Up @@ -44,4 +43,6 @@ def isort(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)
21 changes: 11 additions & 10 deletions oura/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(

def user_info(self):
"""
Returns information about the logged in user (who the access token was issued for).
Returns information about the current user.

See https://cloud.ouraring.com/docs/personal-info
"""
Expand Down Expand Up @@ -122,17 +122,18 @@ def _make_request(self, url):
return payload

def _build_summary_url(self, start, end, summary_type):
if start is None:
raise ValueError(
"Request for {} summary must include start date.".format(summary_type)
)
if not isinstance(start, str):
raise TypeError("start date must be of type str")

url = "{0}/v1/{1}?start={2}".format(self.API_ENDPOINT, summary_type, start)
url = "{0}/v1/{1}".format(self.API_ENDPOINT, summary_type)
params = {}
if start is not None:
if not isinstance(start, str):
raise TypeError("start date must be of type str")
params["start"] = start

if end is not None:
if not isinstance(end, str):
raise TypeError("end date must be of type str")
url = "{0}&end={1}".format(url, end)
params["end"] = end

qs = "&".join([f"{k}={v}" for k, v in params.items()])
url = f"{url}?{qs}"
return url
Loading