{"id":38063019,"url":"https://github.com/turing-complet/python-ouraring","last_synced_at":"2026-01-16T20:32:10.726Z","repository":{"id":46525270,"uuid":"163403246","full_name":"turing-complet/python-ouraring","owner":"turing-complet","description":"Oura ring API client for python","archived":false,"fork":false,"pushed_at":"2024-04-23T17:03:40.000Z","size":237,"stargazers_count":131,"open_issues_count":7,"forks_count":29,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-10-09T04:07:09.288Z","etag":null,"topics":["maintainer-wanted","oura","python"],"latest_commit_sha":null,"homepage":"https://python-ouraring.readthedocs.io/en/latest/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turing-complet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-28T11:32:48.000Z","updated_at":"2025-08-19T18:41:14.000Z","dependencies_parsed_at":"2023-01-25T19:30:16.663Z","dependency_job_id":"f6aeef22-066a-4c14-9be6-853792b0a4b4","html_url":"https://github.com/turing-complet/python-ouraring","commit_stats":{"total_commits":86,"total_committers":5,"mean_commits":17.2,"dds":"0.18604651162790697","last_synced_commit":"3924471788f23235d2dee0c4afcdd8e039e7cf7c"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/turing-complet/python-ouraring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turing-complet%2Fpython-ouraring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turing-complet%2Fpython-ouraring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turing-complet%2Fpython-ouraring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turing-complet%2Fpython-ouraring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turing-complet","download_url":"https://codeload.github.com/turing-complet/python-ouraring/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turing-complet%2Fpython-ouraring/sbom","scorecard":{"id":902693,"data":{"date":"2025-08-11","repo":{"name":"github.com/turing-complet/python-ouraring","commit":"35fd39c1b1adf62860b2e14059f6a908e1c85848"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":2,"reason":"Found 3/11 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/turing-complet/python-ouraring/test.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/lint.yml:13","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:15","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:24","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   3 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"40 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2024-230 / GHSA-248v-346w-9cwc","Warn: Project is vulnerable to: PYSEC-2022-42986 / GHSA-43fp-rhv2-5gv8","Warn: Project is vulnerable to: PYSEC-2023-135 / GHSA-xqr8-7jwr-rhp7","Warn: Project is vulnerable to: GHSA-39hc-v87j-747x","Warn: Project is vulnerable to: GHSA-3ww4-gg4f-jr7f","Warn: Project is vulnerable to: GHSA-5cpq-8wj7-hf2v","Warn: Project is vulnerable to: GHSA-9v9h-cgj8-h64p","Warn: Project is vulnerable to: GHSA-h4gh-qq45-vh27","Warn: Project is vulnerable to: PYSEC-2023-254 / GHSA-jfhm-5ghh-2f97","Warn: Project is vulnerable to: GHSA-jm77-qphf-c4w8","Warn: Project is vulnerable to: GHSA-v8gr-m533-ghj9","Warn: Project is vulnerable to: GHSA-w7pp-m8wf-vj6r","Warn: Project is vulnerable to: GHSA-x4qr-2fvf-3mr5","Warn: Project is vulnerable to: PYSEC-2023-62 / GHSA-m2qf-hxjv-5gpq","Warn: Project is vulnerable to: PYSEC-2024-60 / GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: GHSA-gmj6-6f8f-6699","Warn: Project is vulnerable to: GHSA-h5c8-rqwp-cp95","Warn: Project is vulnerable to: GHSA-h75v-3vvj-5mfj","Warn: Project is vulnerable to: GHSA-q2x7-8rv6-6q7h","Warn: Project is vulnerable to: PYSEC-2022-269 / GHSA-3pgj-pg6c-r5p7","Warn: Project is vulnerable to: PYSEC-2022-42969","Warn: Project is vulnerable to: PYSEC-2023-117 / GHSA-mrwq-x4v8-fh7p","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2023-74 / GHSA-j8r2-6x86-q33q","Warn: Project is vulnerable to: GHSA-34jh-p97f-mpxf","Warn: Project is vulnerable to: PYSEC-2023-212 / GHSA-g4mx-q9vg-27p4","Warn: Project is vulnerable to: GHSA-pq67-6m6q-mj2v","Warn: Project is vulnerable to: PYSEC-2023-192 / GHSA-v845-jxx5-vc9f","Warn: Project is vulnerable to: GHSA-2g68-c3qc-8985","Warn: Project is vulnerable to: GHSA-f9vj-2wh5-fj8j","Warn: Project is vulnerable to: PYSEC-2023-221 / GHSA-hrfv-mqp8-q5rw","Warn: Project is vulnerable to: PYSEC-2023-57 / GHSA-px8h-6qxv-m22q","Warn: Project is vulnerable to: GHSA-q34m-jh98-gwm2","Warn: Project is vulnerable to: PYSEC-2023-58 / GHSA-xg9f-g7g7-2323","Warn: Project is vulnerable to: GHSA-jfmj-5v4g-7637","Warn: Project is vulnerable to: PYSEC-2020-73","Warn: Project is vulnerable to: PYSEC-2018-66 / GHSA-562c-5r94-xh97","Warn: Project is vulnerable to: PYSEC-2019-179 / GHSA-5wv5-4vpf-pj6m"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T16:12:35.365Z","repository_id":46525270,"created_at":"2025-08-24T16:12:35.365Z","updated_at":"2025-08-24T16:12:35.365Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["maintainer-wanted","oura","python"],"created_at":"2026-01-16T20:32:10.073Z","updated_at":"2026-01-16T20:32:10.721Z","avatar_url":"https://github.com/turing-complet.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## Installation\n\nEasiest way is to get it from [PyPI](https://pypi.org/project/oura/):\n\n`pip install oura`\n\n## Project maintenance\nIf anyone is interested in taking over maintenance of this project, please contact me at\nturingcomplet@proton.me or submit an issue. Alternatively, feel free to simply fork this\nrepo or create a new one and publish the package under a new name. In that case, I will\nadd a link here. I still plan on doing what I can to keep this up to date, but don't\nfeel I can commit to maintaining a level of quality and responsiveness that you all\ndeserve.\n\n## Note about the v2 API\nAll sections in the readme should apply to the v2 API that is being rolled out, except that the\nmethods will differ, pandas support is less sophisticated, and I haven't tested the v2\nclients with the OAuth2 flow. The auth has been updated to pass tokens in the http\nheader, but the usage of the underlying `requests-oauthlib` library has not been\nchanged.\n\nEnjoy the latest clients as follows (and see\n[docs](https://cloud.ouraring.com/v2/docs)). All methods except `personal_info` take a\n`start_date`, `end_date`, and `next_token`.\n```\nfrom oura.v2 import OuraClientV2, OuraClientDataFrameV2\nv2 = OuraClientDataFrameV2(personal_access_token=\"MY_PAT\")\n\n# methods will be named after the url path (see docs linked above)\nv2.heartrate()\n\n# pandas methods end with _df\nv2.tags_df()\n```\n\n## Getting started\n\nBoth personal access tokens and oauth flows are supported by the API (and by\nthis library). For personal use, the simplest way to start is by getting\nyourself a PAT and supplying it to a client:\n\n```\nclient = OuraClient(personal_access_token=\"MY_TOKEN\")\n```\n\nIf you are using oauth, there are a few more steps. First, register an application\nThen 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).\n```\n./token-request.py \u003cclient-id\u003e \u003cclient-secret\u003e\n``` \n\nSome sample code is located in the [samples](samples) directory, maybe it will be useful for you. Maybe it will change your life for the better. Maybe it will cause you to rethink using this project at all. Let me know the outcome if you feel like it.\n\n\n## Business time\n\nIf you are writing a real application, use the following pattern. Basically, the work is done by the underlying oauthlib to use the refresh token whenever the access token has expired, and you supply the refresh callback to save the new tokens for next time. This seems to have worked fine for me, but I don't actually use this library that much\n```\nfrom oura import OuraClient, OuraOAuth2Client\n\nauth_client = OuraOAuth2Client(client_id='my_application', client_secret='random-string')\nurl = auth_client.authorize_endpoint(scope='defaults to all scopes', 'https://localhost/myendpoint')\n# user clicks url, auth happens, then redirect to given url\n```\n\nNow we handle the redirect by exchanging an auth code for a token\n\n```\n# save this somewhere, see below\ntoken_dict = auth_client.fetch_access_token(code='auth_code_from_query_string')\n```\n\nNow that's out of the way, you can call the api:\n```\n# supply all the params for auto refresh\noura = OuraClient(\u003cclient_id\u003e, \u003cclient_secret\u003e \u003caccess_token\u003e, \u003crefresh_token\u003e, \u003crefresh_callback\u003e)\n\n# or just these for make calls until token expires\noura = OuraClient(\u003cclient_id\u003e, \u003caccess_token\u003e)\n\n# make authenticated API calls\noura.user_info()\noura.sleep_summary(start='2018-12-05', end='2018-12-10')\noura.activity_summary(start='2018-12-25')\n```\n\n\nThe `refresh_callback` is a fuction that takes a token dict and saves it somewhere. It will look like:\n```\n{'token_type': 'bearer', 'refresh_token': \u003crefresh\u003e, 'access_token': \u003ctoken\u003e, 'expires_in': 86400, 'expires_at': 1546485086.3277025}\n```\n\n## Working with pandas\nYou can also make requests and have the data converted to pandas dataframes by\nusing the pandas client. Some customization is available but subject to\nfuture improvement.\n\n```\nclient = OuraClientDataFrame(...)\nbedtime = client.bedtime_df(start, end, convert=True)\n\nIn [3]: client.bedtime_df()\nOut[3]:\n              bedtime_window                   status\n  date\n  2020-03-17  {'start': -3600, 'end': 0} IDEAL_BEDTIME_AVAILABLE\n  2020-03-18  {'start': None, 'end': None} LOW_SLEEP_SCORES\n```\n\n\nLive your life.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturing-complet%2Fpython-ouraring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturing-complet%2Fpython-ouraring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturing-complet%2Fpython-ouraring/lists"}