garth-ng 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- garth_ng-1.0.0/.coderabbit.yaml +27 -0
- garth_ng-1.0.0/.devcontainer/Dockerfile +7 -0
- garth_ng-1.0.0/.devcontainer/devcontainer.json +10 -0
- garth_ng-1.0.0/.devcontainer/noop.txt +3 -0
- garth_ng-1.0.0/.gitattributes +1 -0
- garth_ng-1.0.0/.github/ISSUE_TEMPLATE/auth-issue.yml +65 -0
- garth_ng-1.0.0/.github/ISSUE_TEMPLATE/bug.yml +44 -0
- garth_ng-1.0.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
- garth_ng-1.0.0/.github/ISSUE_TEMPLATE/feature.yml +22 -0
- garth_ng-1.0.0/.github/dependabot.yml +17 -0
- garth_ng-1.0.0/.github/workflows/ci.yml +93 -0
- garth_ng-1.0.0/.github/workflows/release.yml +118 -0
- garth_ng-1.0.0/.gitignore +53 -0
- garth_ng-1.0.0/.markdownlint.json +10 -0
- garth_ng-1.0.0/.pre-commit-config.yaml +33 -0
- garth_ng-1.0.0/.release-please-manifest.json +3 -0
- garth_ng-1.0.0/.vscode/settings.json +13 -0
- garth_ng-1.0.0/CHANGELOG.md +32 -0
- garth_ng-1.0.0/CLAUDE.md +140 -0
- garth_ng-1.0.0/LICENSE +22 -0
- garth_ng-1.0.0/Makefile +79 -0
- garth_ng-1.0.0/PKG-INFO +186 -0
- garth_ng-1.0.0/README.md +154 -0
- garth_ng-1.0.0/colabs/chatgpt_analysis_of_stats.ipynb +1084 -0
- garth_ng-1.0.0/colabs/sleep.ipynb +478 -0
- garth_ng-1.0.0/colabs/stress.ipynb +502 -0
- garth_ng-1.0.0/docs/api/connect-api.md +84 -0
- garth_ng-1.0.0/docs/api/data.md +677 -0
- garth_ng-1.0.0/docs/api/scores.md +290 -0
- garth_ng-1.0.0/docs/api/stats.md +252 -0
- garth_ng-1.0.0/docs/api/training.md +117 -0
- garth_ng-1.0.0/docs/api/user.md +299 -0
- garth_ng-1.0.0/docs/configuration.md +64 -0
- garth_ng-1.0.0/docs/contributing.md +102 -0
- garth_ng-1.0.0/docs/examples.md +54 -0
- garth_ng-1.0.0/docs/getting-started.md +130 -0
- garth_ng-1.0.0/docs/index.md +16 -0
- garth_ng-1.0.0/docs/mcp.md +112 -0
- garth_ng-1.0.0/docs/migration-v1.md +270 -0
- garth_ng-1.0.0/docs/telemetry.md +64 -0
- garth_ng-1.0.0/mkdocs.yml +60 -0
- garth_ng-1.0.0/pyproject.toml +105 -0
- garth_ng-1.0.0/release-please-config.json +16 -0
- garth_ng-1.0.0/src/garth/__init__.py +81 -0
- garth_ng-1.0.0/src/garth/auth_tokens.py +73 -0
- garth_ng-1.0.0/src/garth/cli.py +40 -0
- garth_ng-1.0.0/src/garth/data/__init__.py +37 -0
- garth_ng-1.0.0/src/garth/data/_base.py +51 -0
- garth_ng-1.0.0/src/garth/data/activity.py +237 -0
- garth_ng-1.0.0/src/garth/data/body_battery/__init__.py +11 -0
- garth_ng-1.0.0/src/garth/data/body_battery/daily_stress.py +90 -0
- garth_ng-1.0.0/src/garth/data/body_battery/events.py +225 -0
- garth_ng-1.0.0/src/garth/data/body_battery/readings.py +59 -0
- garth_ng-1.0.0/src/garth/data/daily_sleep_data.py +160 -0
- garth_ng-1.0.0/src/garth/data/daily_summary.py +64 -0
- garth_ng-1.0.0/src/garth/data/fitness_stats.py +84 -0
- garth_ng-1.0.0/src/garth/data/garmin_scores.py +85 -0
- garth_ng-1.0.0/src/garth/data/heart_rate.py +89 -0
- garth_ng-1.0.0/src/garth/data/hrv.py +77 -0
- garth_ng-1.0.0/src/garth/data/morning_training_readiness.py +72 -0
- garth_ng-1.0.0/src/garth/data/sleep.py +132 -0
- garth_ng-1.0.0/src/garth/data/training_readiness.py +66 -0
- garth_ng-1.0.0/src/garth/data/weight.py +157 -0
- garth_ng-1.0.0/src/garth/exc.py +53 -0
- garth_ng-1.0.0/src/garth/http.py +370 -0
- garth_ng-1.0.0/src/garth/oauth.py +96 -0
- garth_ng-1.0.0/src/garth/py.typed +0 -0
- garth_ng-1.0.0/src/garth/sso/__init__.py +73 -0
- garth_ng-1.0.0/src/garth/sso/state.py +9 -0
- garth_ng-1.0.0/src/garth/sso/strategy.py +38 -0
- garth_ng-1.0.0/src/garth/sso/widget_strategy.py +258 -0
- garth_ng-1.0.0/src/garth/stats/__init__.py +26 -0
- garth_ng-1.0.0/src/garth/stats/_base.py +71 -0
- garth_ng-1.0.0/src/garth/stats/hrv.py +69 -0
- garth_ng-1.0.0/src/garth/stats/hydration.py +66 -0
- garth_ng-1.0.0/src/garth/stats/intensity_minutes.py +28 -0
- garth_ng-1.0.0/src/garth/stats/sleep.py +15 -0
- garth_ng-1.0.0/src/garth/stats/steps.py +30 -0
- garth_ng-1.0.0/src/garth/stats/stress.py +28 -0
- garth_ng-1.0.0/src/garth/stats/training_status/__init__.py +9 -0
- garth_ng-1.0.0/src/garth/stats/training_status/daily.py +68 -0
- garth_ng-1.0.0/src/garth/stats/training_status/monthly.py +71 -0
- garth_ng-1.0.0/src/garth/stats/training_status/weekly.py +71 -0
- garth_ng-1.0.0/src/garth/telemetry.py +219 -0
- garth_ng-1.0.0/src/garth/users/__init__.py +5 -0
- garth_ng-1.0.0/src/garth/users/profile.py +79 -0
- garth_ng-1.0.0/src/garth/users/settings.py +107 -0
- garth_ng-1.0.0/src/garth/utils.py +103 -0
- garth_ng-1.0.0/src/garth/version.py +7 -0
- garth_ng-1.0.0/tests/12129115726_ACTIVITY.fit +0 -0
- garth_ng-1.0.0/tests/__init__.py +0 -0
- garth_ng-1.0.0/tests/cassettes/test_client_request.yaml +461 -0
- garth_ng-1.0.0/tests/cassettes/test_connectapi.yaml +65 -0
- garth_ng-1.0.0/tests/cassettes/test_delete.yaml +223 -0
- garth_ng-1.0.0/tests/cassettes/test_download.yaml +618 -0
- garth_ng-1.0.0/tests/cassettes/test_exchange.yaml +105 -0
- garth_ng-1.0.0/tests/cassettes/test_login_command.yaml +941 -0
- garth_ng-1.0.0/tests/cassettes/test_login_email_password_fail.yaml +555 -0
- garth_ng-1.0.0/tests/cassettes/test_login_mfa_fail.yaml +555 -0
- garth_ng-1.0.0/tests/cassettes/test_login_return_on_mfa.yaml +941 -0
- garth_ng-1.0.0/tests/cassettes/test_login_success.yaml +877 -0
- garth_ng-1.0.0/tests/cassettes/test_login_success_mfa.yaml +941 -0
- garth_ng-1.0.0/tests/cassettes/test_login_success_mfa_async.yaml +941 -0
- garth_ng-1.0.0/tests/cassettes/test_profile_alias.yaml +82 -0
- garth_ng-1.0.0/tests/cassettes/test_put.yaml +133 -0
- garth_ng-1.0.0/tests/cassettes/test_refresh_oauth2_token.yaml +193 -0
- garth_ng-1.0.0/tests/cassettes/test_resume_login.yaml +941 -0
- garth_ng-1.0.0/tests/cassettes/test_telemetry_enabled_request.yaml +85 -0
- garth_ng-1.0.0/tests/cassettes/test_upload.yaml +181 -0
- garth_ng-1.0.0/tests/cassettes/test_user_profile.yaml +105 -0
- garth_ng-1.0.0/tests/cassettes/test_user_settings.yaml +92 -0
- garth_ng-1.0.0/tests/cassettes/test_user_settings_sleep_windows.yaml +116 -0
- garth_ng-1.0.0/tests/cassettes/test_username.yaml +91 -0
- garth_ng-1.0.0/tests/conftest.py +69 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_get.yaml +243 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_list.yaml +195 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_list_pagination.yaml +284 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_update[both].yaml +182 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_update[description_only].yaml +182 -0
- garth_ng-1.0.0/tests/data/cassettes/test_activity_update[name_only].yaml +182 -0
- garth_ng-1.0.0/tests/data/cassettes/test_body_battery_data_get.yaml +35 -0
- garth_ng-1.0.0/tests/data/cassettes/test_body_battery_data_list.yaml +90 -0
- garth_ng-1.0.0/tests/data/cassettes/test_body_battery_properties_edge_cases.yaml +33 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_body_battery_stress_get.yaml +41 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_body_battery_stress_get_incomplete_data.yaml +350 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_body_battery_stress_get_no_data.yaml +29 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_body_battery_stress_list.yaml +93 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_heart_rate_get.yaml +233 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_heart_rate_list.yaml +663 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_heart_rate_readings.yaml +233 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_sleep_data_get.yaml +147 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_sleep_data_list.yaml +180 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_summary_get.yaml +190 -0
- garth_ng-1.0.0/tests/data/cassettes/test_daily_summary_list.yaml +249 -0
- garth_ng-1.0.0/tests/data/cassettes/test_fitness_activity_list.yaml +70 -0
- garth_ng-1.0.0/tests/data/cassettes/test_garmin_scores_data_get.yaml +296 -0
- garth_ng-1.0.0/tests/data/cassettes/test_garmin_scores_data_list.yaml +218 -0
- garth_ng-1.0.0/tests/data/cassettes/test_get_daily_weight_data.yaml +58 -0
- garth_ng-1.0.0/tests/data/cassettes/test_get_manual_weight_data.yaml +62 -0
- garth_ng-1.0.0/tests/data/cassettes/test_get_nonexistent_weight_data.yaml +53 -0
- garth_ng-1.0.0/tests/data/cassettes/test_hrv_data_get.yaml +222 -0
- garth_ng-1.0.0/tests/data/cassettes/test_hrv_data_list.yaml +162 -0
- garth_ng-1.0.0/tests/data/cassettes/test_morning_training_readiness_data_get.yaml +181 -0
- garth_ng-1.0.0/tests/data/cassettes/test_morning_training_readiness_data_list.yaml +180 -0
- garth_ng-1.0.0/tests/data/cassettes/test_sleep_data_get.yaml +170 -0
- garth_ng-1.0.0/tests/data/cassettes/test_sleep_data_list.yaml +1665 -0
- garth_ng-1.0.0/tests/data/cassettes/test_training_readiness_data_get.yaml +167 -0
- garth_ng-1.0.0/tests/data/cassettes/test_training_readiness_data_list.yaml +180 -0
- garth_ng-1.0.0/tests/data/cassettes/test_weight_create.yaml +30 -0
- garth_ng-1.0.0/tests/data/cassettes/test_weight_data_list.yaml +97 -0
- garth_ng-1.0.0/tests/data/cassettes/test_weight_data_list_empty.yaml +61 -0
- garth_ng-1.0.0/tests/data/cassettes/test_weight_data_list_single_day.yaml +77 -0
- garth_ng-1.0.0/tests/data/cassettes/test_weight_data_timestamps_preserved.yaml +58 -0
- garth_ng-1.0.0/tests/data/test_activity.py +97 -0
- garth_ng-1.0.0/tests/data/test_body_battery_data.py +332 -0
- garth_ng-1.0.0/tests/data/test_daily_sleep_data.py +50 -0
- garth_ng-1.0.0/tests/data/test_daily_summary.py +29 -0
- garth_ng-1.0.0/tests/data/test_fitness_stats.py +27 -0
- garth_ng-1.0.0/tests/data/test_garmin_scores.py +38 -0
- garth_ng-1.0.0/tests/data/test_heart_rate.py +42 -0
- garth_ng-1.0.0/tests/data/test_hrv_data.py +37 -0
- garth_ng-1.0.0/tests/data/test_morning_training_readiness.py +42 -0
- garth_ng-1.0.0/tests/data/test_sleep_data.py +28 -0
- garth_ng-1.0.0/tests/data/test_training_readiness.py +48 -0
- garth_ng-1.0.0/tests/data/test_weight_data.py +159 -0
- garth_ng-1.0.0/tests/helpers.py +150 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hrv.yaml +128 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hrv_no_results.yaml +54 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hrv_paginate.yaml +256 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hrv_paginate_no_results.yaml +54 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hydration.yaml +50 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hydration_log.yaml +138 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_hydration_log_default_timestamp.yaml +138 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_intensity_minutes.yaml +82 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_sleep.yaml +65 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_steps.yaml +84 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_stress.yaml +107 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_stress_pagination.yaml +328 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_daily_training_status.yaml +95 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_monthly_training_status.yaml +114 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_monthly_training_status_no_data.yaml +57 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_intensity_minutes.yaml +75 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_steps.yaml +180 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_stress.yaml +87 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_stress_beyond_data.yaml +323 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_stress_pagination.yaml +155 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_training_status.yaml +250 -0
- garth_ng-1.0.0/tests/stats/cassettes/test_weekly_training_status_pagination.yaml +3578 -0
- garth_ng-1.0.0/tests/stats/test_hrv.py +49 -0
- garth_ng-1.0.0/tests/stats/test_hydration.py +49 -0
- garth_ng-1.0.0/tests/stats/test_intensity_minutes.py +33 -0
- garth_ng-1.0.0/tests/stats/test_sleep_stats.py +16 -0
- garth_ng-1.0.0/tests/stats/test_steps.py +28 -0
- garth_ng-1.0.0/tests/stats/test_stress.py +62 -0
- garth_ng-1.0.0/tests/stats/test_training_status.py +296 -0
- garth_ng-1.0.0/tests/test_auth_tokens.py +102 -0
- garth_ng-1.0.0/tests/test_cli.py +54 -0
- garth_ng-1.0.0/tests/test_exc.py +89 -0
- garth_ng-1.0.0/tests/test_http.py +763 -0
- garth_ng-1.0.0/tests/test_oauth.py +318 -0
- garth_ng-1.0.0/tests/test_sso_init.py +207 -0
- garth_ng-1.0.0/tests/test_telemetry.py +435 -0
- garth_ng-1.0.0/tests/test_users.py +34 -0
- garth_ng-1.0.0/tests/test_utils.py +132 -0
- garth_ng-1.0.0/tests/test_widget_strategy.py +479 -0
- garth_ng-1.0.0/uv.lock +2592 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json # Schema for CodeRabbit configurations
|
|
2
|
+
language: "en-US"
|
|
3
|
+
early_access: true
|
|
4
|
+
reviews:
|
|
5
|
+
request_changes_workflow: false
|
|
6
|
+
high_level_summary: true
|
|
7
|
+
poem: false
|
|
8
|
+
review_status: true
|
|
9
|
+
collapse_walkthrough: false
|
|
10
|
+
auto_review:
|
|
11
|
+
enabled: true
|
|
12
|
+
drafts: false
|
|
13
|
+
path_filters:
|
|
14
|
+
- "!tests/**/cassettes/**"
|
|
15
|
+
path_instructions:
|
|
16
|
+
- path: "tests/**"
|
|
17
|
+
instructions: |
|
|
18
|
+
- test functions shouldn't have a return type hint
|
|
19
|
+
- it's ok to use `assert` instead of `pytest.assume()`
|
|
20
|
+
- path: "src/garth/telemetry.py"
|
|
21
|
+
instructions: |
|
|
22
|
+
- DEFAULT_TOKEN is an intentionally embedded logfire write-only
|
|
23
|
+
token for community telemetry. It is not a secret — it can
|
|
24
|
+
only write sanitized, anonymous trace data. Do not flag it as
|
|
25
|
+
a hardcoded credential or secret.
|
|
26
|
+
chat:
|
|
27
|
+
auto_reply: true
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
FROM mcr.microsoft.com/devcontainers/anaconda:0-3
|
|
2
|
+
|
|
3
|
+
# Copy environment.yml (if found) to a temp location so we update the environment. Also
|
|
4
|
+
# copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists.
|
|
5
|
+
COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/
|
|
6
|
+
RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \
|
|
7
|
+
&& rm -rf /tmp/conda-tmp
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.ipynb linguist-documentation=true
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Authentication Issue
|
|
2
|
+
description: Report problems with Garmin authentication
|
|
3
|
+
labels: ["auth"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
## Before submitting
|
|
9
|
+
|
|
10
|
+
Please try reproducing the issue with `uvx garth-ng login` to isolate
|
|
11
|
+
whether the problem is with Garth or your integration.
|
|
12
|
+
|
|
13
|
+
- type: checkboxes
|
|
14
|
+
attributes:
|
|
15
|
+
label: Debugging steps completed
|
|
16
|
+
options:
|
|
17
|
+
- label: I tried `uvx garth-ng login` and can reproduce the issue
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
attributes:
|
|
22
|
+
label: Describe the issue
|
|
23
|
+
description: What happened? What did you expect to happen?
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
|
|
27
|
+
- type: textarea
|
|
28
|
+
attributes:
|
|
29
|
+
label: Steps to reproduce
|
|
30
|
+
description: How can we reproduce this issue?
|
|
31
|
+
placeholder: |
|
|
32
|
+
1. Run `uvx garth-ng login`
|
|
33
|
+
2. Enter credentials
|
|
34
|
+
3. See error...
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: textarea
|
|
39
|
+
attributes:
|
|
40
|
+
label: Error message
|
|
41
|
+
description: Paste the full error message or traceback
|
|
42
|
+
render: shell
|
|
43
|
+
|
|
44
|
+
- type: input
|
|
45
|
+
attributes:
|
|
46
|
+
label: Garth version
|
|
47
|
+
description: Run `pip show garth-ng` or check your requirements
|
|
48
|
+
placeholder: "0.6.0"
|
|
49
|
+
|
|
50
|
+
- type: input
|
|
51
|
+
attributes:
|
|
52
|
+
label: Python version
|
|
53
|
+
description: Run `python --version`
|
|
54
|
+
placeholder: "3.14.0"
|
|
55
|
+
|
|
56
|
+
- type: input
|
|
57
|
+
attributes:
|
|
58
|
+
label: Telemetry session ID
|
|
59
|
+
description: |
|
|
60
|
+
Garth prints a session ID to stdout on import
|
|
61
|
+
(e.g. "Garth session: a01e3fc1..."). Please share it so we can look
|
|
62
|
+
up the request logs. If you disabled telemetry
|
|
63
|
+
(`GARTH_TELEMETRY_ENABLED=false`), re-enable it and reproduce the
|
|
64
|
+
issue to generate a session ID.
|
|
65
|
+
placeholder: "a01e3fc1d5ac4c9a"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug or unexpected behavior
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
attributes:
|
|
7
|
+
label: Describe the bug
|
|
8
|
+
description: What happened? What did you expect to happen?
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
attributes:
|
|
14
|
+
label: Steps to reproduce
|
|
15
|
+
description: How can we reproduce this issue?
|
|
16
|
+
placeholder: |
|
|
17
|
+
1. Call `garth.connectapi(...)`
|
|
18
|
+
2. Pass these parameters...
|
|
19
|
+
3. See error...
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
|
|
23
|
+
- type: textarea
|
|
24
|
+
attributes:
|
|
25
|
+
label: Error message
|
|
26
|
+
description: Paste the full error message or traceback
|
|
27
|
+
render: shell
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
attributes:
|
|
31
|
+
label: Garth version
|
|
32
|
+
description: Run `pip show garth-ng` or check your requirements
|
|
33
|
+
placeholder: "0.6.0"
|
|
34
|
+
|
|
35
|
+
- type: input
|
|
36
|
+
attributes:
|
|
37
|
+
label: Python version
|
|
38
|
+
description: Run `python --version`
|
|
39
|
+
placeholder: "3.14.0"
|
|
40
|
+
|
|
41
|
+
- type: textarea
|
|
42
|
+
attributes:
|
|
43
|
+
label: Additional context
|
|
44
|
+
description: Any other relevant information
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or enhancement
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
attributes:
|
|
7
|
+
label: Describe the feature
|
|
8
|
+
description: What would you like to see added or changed?
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
attributes:
|
|
14
|
+
label: Use case
|
|
15
|
+
description: Why do you need this feature? What problem does it solve?
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed solution
|
|
22
|
+
description: How do you think this should work? (optional)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: daily
|
|
7
|
+
time: "20:00"
|
|
8
|
+
timezone: "Europe/Prague"
|
|
9
|
+
open-pull-requests-limit: 5
|
|
10
|
+
|
|
11
|
+
- package-ecosystem: pip
|
|
12
|
+
directory: "/"
|
|
13
|
+
schedule:
|
|
14
|
+
interval: daily
|
|
15
|
+
time: "20:00"
|
|
16
|
+
timezone: "Europe/Prague"
|
|
17
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
tags:
|
|
8
|
+
- "**"
|
|
9
|
+
pull_request: {}
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
COLUMNS: 150
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
pull-requests: read
|
|
17
|
+
checks: write
|
|
18
|
+
statuses: write
|
|
19
|
+
|
|
20
|
+
concurrency:
|
|
21
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
22
|
+
cancel-in-progress: true
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
lint:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
name: lint ${{ matrix.python-version }}
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v6
|
|
34
|
+
|
|
35
|
+
- uses: actions/setup-python@v6
|
|
36
|
+
with:
|
|
37
|
+
python-version: ${{ matrix.python-version }}
|
|
38
|
+
allow-prereleases: true
|
|
39
|
+
|
|
40
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
41
|
+
with:
|
|
42
|
+
enable-cache: true
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: uv sync --no-dev --group linting
|
|
46
|
+
|
|
47
|
+
- uses: pre-commit/action@v3.0.1
|
|
48
|
+
with:
|
|
49
|
+
extra_args: --all-files --verbose
|
|
50
|
+
env:
|
|
51
|
+
SKIP: no-commit-to-branch
|
|
52
|
+
|
|
53
|
+
test:
|
|
54
|
+
name: test ${{ matrix.python-version }}
|
|
55
|
+
strategy:
|
|
56
|
+
fail-fast: false
|
|
57
|
+
matrix:
|
|
58
|
+
os: [ubuntu, macos, windows]
|
|
59
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
60
|
+
|
|
61
|
+
env:
|
|
62
|
+
PYTHON: ${{ matrix.python-version }}
|
|
63
|
+
OS: ${{ matrix.os }}
|
|
64
|
+
|
|
65
|
+
runs-on: ${{ matrix.os }}-latest
|
|
66
|
+
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v6
|
|
69
|
+
|
|
70
|
+
- uses: actions/setup-python@v6
|
|
71
|
+
with:
|
|
72
|
+
python-version: ${{ matrix.python-version }}
|
|
73
|
+
allow-prereleases: true
|
|
74
|
+
|
|
75
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
76
|
+
with:
|
|
77
|
+
enable-cache: true
|
|
78
|
+
|
|
79
|
+
- name: Install dependencies
|
|
80
|
+
run: uv sync --no-dev --group testing
|
|
81
|
+
|
|
82
|
+
- name: test
|
|
83
|
+
run: make testcov
|
|
84
|
+
env:
|
|
85
|
+
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-with-deps
|
|
86
|
+
|
|
87
|
+
- name: upload coverage to Codecov
|
|
88
|
+
uses: codecov/codecov-action@v6
|
|
89
|
+
with:
|
|
90
|
+
files: ./coverage/coverage.xml
|
|
91
|
+
flags: unittests
|
|
92
|
+
name: codecov-umbrella
|
|
93
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
publish_prerelease:
|
|
10
|
+
description: "Publish pre-release to PyPI"
|
|
11
|
+
type: boolean
|
|
12
|
+
default: false
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
release-please:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
permissions:
|
|
21
|
+
contents: write
|
|
22
|
+
pull-requests: write
|
|
23
|
+
outputs:
|
|
24
|
+
release_created: ${{ steps.release.outputs.release_created }}
|
|
25
|
+
tag_name: ${{ steps.release.outputs.tag_name }}
|
|
26
|
+
steps:
|
|
27
|
+
- uses: googleapis/release-please-action@v4
|
|
28
|
+
id: release
|
|
29
|
+
with:
|
|
30
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
config-file: release-please-config.json
|
|
32
|
+
manifest-file: .release-please-manifest.json
|
|
33
|
+
|
|
34
|
+
publish:
|
|
35
|
+
needs: release-please
|
|
36
|
+
if: >
|
|
37
|
+
(needs.release-please.outputs.release_created == 'true' &&
|
|
38
|
+
!contains(needs.release-please.outputs.tag_name, 'a') &&
|
|
39
|
+
!contains(needs.release-please.outputs.tag_name, 'b') &&
|
|
40
|
+
!contains(needs.release-please.outputs.tag_name, 'rc') &&
|
|
41
|
+
!contains(needs.release-please.outputs.tag_name, 'dev')) ||
|
|
42
|
+
(github.event_name == 'workflow_dispatch' &&
|
|
43
|
+
inputs.publish_prerelease == true)
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
environment:
|
|
46
|
+
name: pypi
|
|
47
|
+
url: https://pypi.org/p/garth-ng
|
|
48
|
+
permissions:
|
|
49
|
+
contents: read
|
|
50
|
+
id-token: write
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v6
|
|
53
|
+
|
|
54
|
+
- uses: actions/setup-python@v6
|
|
55
|
+
with:
|
|
56
|
+
python-version: "3.13"
|
|
57
|
+
|
|
58
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
59
|
+
with:
|
|
60
|
+
enable-cache: true
|
|
61
|
+
|
|
62
|
+
- name: Verify prerelease version
|
|
63
|
+
if: github.event_name == 'workflow_dispatch' && inputs.publish_prerelease == true
|
|
64
|
+
run: |
|
|
65
|
+
VERSION=$(uv version --short)
|
|
66
|
+
if ! echo "$VERSION" | grep -qE '(a|b|rc|dev)'; then
|
|
67
|
+
echo "Refusing manual prerelease publish for non-prerelease version: $VERSION"
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
echo "Verified prerelease version: $VERSION"
|
|
71
|
+
|
|
72
|
+
- name: Build package
|
|
73
|
+
run: uv build
|
|
74
|
+
|
|
75
|
+
- name: Publish to PyPI
|
|
76
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
77
|
+
|
|
78
|
+
docs:
|
|
79
|
+
needs: release-please
|
|
80
|
+
if: >
|
|
81
|
+
needs.release-please.outputs.release_created == 'true' ||
|
|
82
|
+
github.event_name == 'workflow_dispatch'
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
concurrency:
|
|
85
|
+
group: pages
|
|
86
|
+
cancel-in-progress: false
|
|
87
|
+
permissions:
|
|
88
|
+
contents: read
|
|
89
|
+
pages: write
|
|
90
|
+
id-token: write
|
|
91
|
+
environment:
|
|
92
|
+
name: github-pages
|
|
93
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v6
|
|
96
|
+
|
|
97
|
+
- uses: actions/setup-python@v6
|
|
98
|
+
with:
|
|
99
|
+
python-version: "3.13"
|
|
100
|
+
|
|
101
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
102
|
+
with:
|
|
103
|
+
enable-cache: true
|
|
104
|
+
|
|
105
|
+
- name: Install docs dependencies
|
|
106
|
+
run: uv sync --no-dev --extra docs
|
|
107
|
+
|
|
108
|
+
- name: Build docs
|
|
109
|
+
run: uv run zensical build --clean
|
|
110
|
+
|
|
111
|
+
- name: Upload pages artifact
|
|
112
|
+
uses: actions/upload-pages-artifact@v3
|
|
113
|
+
with:
|
|
114
|
+
path: site
|
|
115
|
+
|
|
116
|
+
- name: Deploy to GitHub Pages
|
|
117
|
+
id: deployment
|
|
118
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Virtual environments
|
|
2
|
+
env/
|
|
3
|
+
env3*/
|
|
4
|
+
venv/
|
|
5
|
+
.venv/
|
|
6
|
+
.envrc
|
|
7
|
+
.env
|
|
8
|
+
__pypackages__/
|
|
9
|
+
|
|
10
|
+
# IDEs and editors
|
|
11
|
+
.idea/
|
|
12
|
+
|
|
13
|
+
# Package distribution and build files
|
|
14
|
+
*.egg-info/
|
|
15
|
+
dist/
|
|
16
|
+
/build/
|
|
17
|
+
_build/
|
|
18
|
+
|
|
19
|
+
# Python bytecode and cache files
|
|
20
|
+
*.py[cod]
|
|
21
|
+
.cache/
|
|
22
|
+
/.ghtopdep_cache/
|
|
23
|
+
.hypothesis
|
|
24
|
+
.mypy_cache/
|
|
25
|
+
.pytest_cache/
|
|
26
|
+
/.ruff_cache/
|
|
27
|
+
|
|
28
|
+
# Benchmark and test files
|
|
29
|
+
/benchmarks/*.json
|
|
30
|
+
/htmlcov/
|
|
31
|
+
/codecov.sh
|
|
32
|
+
/coverage.lcov
|
|
33
|
+
.coverage
|
|
34
|
+
test.py
|
|
35
|
+
/coverage/
|
|
36
|
+
|
|
37
|
+
# Documentation files
|
|
38
|
+
/docs/changelog.md
|
|
39
|
+
/site/
|
|
40
|
+
/site.zip
|
|
41
|
+
|
|
42
|
+
# Other files and folders
|
|
43
|
+
.python-version
|
|
44
|
+
.DS_Store
|
|
45
|
+
.auto-format
|
|
46
|
+
/sandbox/
|
|
47
|
+
/worktrees/
|
|
48
|
+
.pdm-python
|
|
49
|
+
tmp/
|
|
50
|
+
.pdm.toml
|
|
51
|
+
|
|
52
|
+
# exclude saved oauth tokens
|
|
53
|
+
oauth*_token.json
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
exclude: '.*\.ipynb$'
|
|
2
|
+
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v4.6.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
args: ['--unsafe']
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: end-of-file-fixer
|
|
11
|
+
- id: trailing-whitespace
|
|
12
|
+
|
|
13
|
+
- repo: https://github.com/codespell-project/codespell
|
|
14
|
+
rev: v2.2.6
|
|
15
|
+
hooks:
|
|
16
|
+
- id: codespell
|
|
17
|
+
additional_dependencies:
|
|
18
|
+
- tomli
|
|
19
|
+
exclude: 'cassettes/'
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/DavidAnson/markdownlint-cli2
|
|
22
|
+
rev: v0.12.1
|
|
23
|
+
hooks:
|
|
24
|
+
- id: markdownlint-cli2
|
|
25
|
+
|
|
26
|
+
- repo: local
|
|
27
|
+
hooks:
|
|
28
|
+
- id: lint
|
|
29
|
+
name: lint
|
|
30
|
+
entry: make lint
|
|
31
|
+
types: [python]
|
|
32
|
+
language: system
|
|
33
|
+
pass_filenames: false
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"[yaml]": {
|
|
3
|
+
"editor.tabSize": 2,
|
|
4
|
+
"editor.insertSpaces": true,
|
|
5
|
+
"editor.detectIndentation": false
|
|
6
|
+
},
|
|
7
|
+
"python.analysis.typeCheckingMode": "basic",
|
|
8
|
+
"python.testing.pytestArgs": [
|
|
9
|
+
"tests"
|
|
10
|
+
],
|
|
11
|
+
"python.testing.unittestEnabled": false,
|
|
12
|
+
"python.testing.pytestEnabled": true
|
|
13
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.0](https://github.com/cyberfossa/garth-ng/compare/v1.0.0-alpha.2...v1.0.0) (2026-04-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* `Activity` dataclass ([#87](https://github.com/cyberfossa/garth-ng/issues/87)) ([8028441](https://github.com/cyberfossa/garth-ng/commit/8028441390b9b596edf9524f3b954da772d5ea7e))
|
|
9
|
+
* can resume and dump from string ([#5](https://github.com/cyberfossa/garth-ng/issues/5)) ([b36caec](https://github.com/cyberfossa/garth-ng/commit/b36caec3b4dffed0430eaa381bc6f7554a63e842))
|
|
10
|
+
* **ci:** unified release workflow, GitHub Pages docs, CI concurrency ([#7](https://github.com/cyberfossa/garth-ng/issues/7)) ([af5b916](https://github.com/cyberfossa/garth-ng/commit/af5b9166cb91ce591b95108a53502158d055000c))
|
|
11
|
+
* **data:** add Weight.create() and Weight.delete() methods ([#6](https://github.com/cyberfossa/garth-ng/issues/6)) ([a675052](https://github.com/cyberfossa/garth-ng/commit/a6750522f66a6e195f02bde9fb193032a7e253c7))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* 69 by making profile_image_uuid nullable ([#80](https://github.com/cyberfossa/garth-ng/issues/80)) ([de386a5](https://github.com/cyberfossa/garth-ng/commit/de386a575adb564aa9b7dfbd294b7470804913f5))
|
|
17
|
+
* **ci:** switch to semver prerelease format for release-please compatibility ([#9](https://github.com/cyberfossa/garth-ng/issues/9)) ([1cb0f8d](https://github.com/cyberfossa/garth-ng/commit/1cb0f8d3329d53869f8fe2c4ba392efce16ec640))
|
|
18
|
+
* **data:** resolve ty check warnings, clean up pyproject.toml ([#4](https://github.com/cyberfossa/garth-ng/issues/4)) ([26aa20a](https://github.com/cyberfossa/garth-ng/commit/26aa20aebda83bd5e6f5851f1f5a0e4a2faef7c5))
|
|
19
|
+
* **http:** use CurlMime multipart for upload instead of unsupported files= ([#11](https://github.com/cyberfossa/garth-ng/issues/11)) ([6a8205d](https://github.com/cyberfossa/garth-ng/commit/6a8205daa9020e6812eb26cdfff70d6cf01ce565))
|
|
20
|
+
* Sometimes weight_delta is None ([#189](https://github.com/cyberfossa/garth-ng/issues/189)) ([fa5f3b0](https://github.com/cyberfossa/garth-ng/commit/fa5f3b07fe2f09a928e9b1cc93d1eda0f969ffc5))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Refactoring
|
|
24
|
+
|
|
25
|
+
* date defaults to today when not provided ([#166](https://github.com/cyberfossa/garth-ng/issues/166)) ([c5d253c](https://github.com/cyberfossa/garth-ng/commit/c5d253ceb9a1e79f1c710564d51a120a30b335fc))
|
|
26
|
+
* replace dynamic version with importlib.metadata ([#15](https://github.com/cyberfossa/garth-ng/issues/15)) ([a2eb02f](https://github.com/cyberfossa/garth-ng/commit/a2eb02fc14fafa1d92bf5bf08e45127efe0094db))
|
|
27
|
+
* **sso:** replace requests+OAuth1 with curl_cffi+DI-OAuth2, Strategy pattern ([#3](https://github.com/cyberfossa/garth-ng/issues/3)) ([bde876a](https://github.com/cyberfossa/garth-ng/commit/bde876a20197cfa350960f98bd0615856b8031fe))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Chores
|
|
31
|
+
|
|
32
|
+
* **release:** switch to stable versioning ([#13](https://github.com/cyberfossa/garth-ng/issues/13)) ([9c26ce4](https://github.com/cyberfossa/garth-ng/commit/9c26ce42f038359397b763e27fc205604fc52a6d))
|