Skip to content

Commit 7c590cc

Browse files
author
aman
committed
Merge branch 'aman/add-first-content'
2 parents 2e1c5c1 + 48a57e9 commit 7c590cc

304 files changed

Lines changed: 46031 additions & 13 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,10 @@ htmlcov/
3939
# OS
4040
.DS_Store
4141
Thumbs.db
42+
43+
## API generator
44+
.ruff_cache/
45+
openapi.json
46+
openapi.codegen.json
47+
48+
.env

README.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Python SDK for the BodyLoop API for seamless ecosystem integration
44

55
The URL of the source repository <https://github.com/bodyloop/bodyloop-sdk-python> has suffix `python` to enable adding SDKs for other lanuages such as JavaScript/TypeScript, C/C++, Rust, etc.
66

7-
The distribution name (install) of the Python Package name is `bodyloop-sdk` and is available in the global Package Index PyPi at <https://pypi.org/project/bodyloop-sdk>. It omits the suffix since PyPi already tells us that we are in the Python ecosystem.
7+
The distribution name (install) of the Python Package name is `bodyloop-sdk` and is available in the global Package Index PyPi at <https://pypi.org/project/bodyloop-sdk>. It omits the suffix since PyPi already tells us that we are in the Python ecosystem.
88

99
Examples how to get the package are:
1010

@@ -27,7 +27,7 @@ Usage:
2727
```python
2828
import bodyloop
2929
from bodyloop import Viatar, Proband
30-
from bodyloop import System as BodyLoopSystem
30+
from bodyloop import ScanUnit
3131
```
3232

3333
## Contribute
@@ -42,3 +42,33 @@ uv sync
4242
uv run pytest
4343
uv build
4444
```
45+
46+
The release / publish workflow is defined as:
47+
48+
- Push to the `main` branch
49+
- Create a new tag `vYYYY.MM.DD.r` where `YYYY.MM.DD` is the current date and `r` is the sequential release number we increment over all releases, independent of the date and push the tag as well.
50+
- Create a new GitHub release based on that tag, baptize the release identical to the tag and add release notes.
51+
- Triggered by the release creation the GitHub Action `publish.yml` will build the package and publish it to PyPi.
52+
53+
Update the API client
54+
55+
The API generator <https://pypi.org/project/openapi-python-client/> is used.
56+
57+
```bash
58+
./generate_api_client.sh <ip_or_hostname_of_my_bodyloop_instance>
59+
```
60+
61+
Use the experiments to get your feet wet:
62+
63+
```bash
64+
touch .env
65+
echo "BODYLOOP_BASE_URL='https://bodyloop-control-pc'" >> .env
66+
echo "BODYLOOP_API_TOKEN='your_api_token_here'" >> .env
67+
68+
uv run experiments/a_create_client.py
69+
uv run experiments/b_load_probands.py
70+
```
71+
72+
## License
73+
74+
See [LICENSE](LICENSE)

experiments/a_create_client.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
from pathlib import Path
6+
from dotenv import load_dotenv
7+
8+
# Load environment variables from .env file
9+
load_dotenv()
10+
11+
# Add the src directory (src-layout project) so `bodyloop_sdk` can be imported
12+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
13+
14+
from bodyloop_sdk.client import AuthenticatedClient
15+
16+
base_url = os.getenv("BODYLOOP_BASE_URL")
17+
api_token = os.getenv("BODYLOOP_API_TOKEN")
18+
19+
# Create a client with SSL verification disabled for local IP
20+
# Note: In production, you should use proper SSL certificates
21+
client = AuthenticatedClient(
22+
base_url=base_url,
23+
verify_ssl=False,
24+
token=api_token,
25+
timeout=10.0
26+
)
27+
28+
print(f"Client configured for: {base_url}")

experiments/b_load_probands.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
from pathlib import Path
6+
from dotenv import load_dotenv
7+
8+
# Load environment variables from .env file
9+
load_dotenv()
10+
11+
# Add the src directory (src-layout project) so `bodyloop_sdk` can be imported
12+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
13+
14+
from bodyloop_sdk.client import AuthenticatedClient
15+
16+
base_url = os.getenv("BODYLOOP_BASE_URL")
17+
api_token = os.getenv("BODYLOOP_API_TOKEN")
18+
19+
# (a) Create a client with SSL verification disabled for local IP)
20+
client = AuthenticatedClient(
21+
base_url=base_url,
22+
verify_ssl=False,
23+
token=api_token,
24+
timeout=10.0
25+
)
26+
27+
print(f"Client configured for: {base_url}")
28+
29+
30+
# (b) Load probands
31+
from functools import partial
32+
from bodyloop_sdk.client.api.probands import get_probands_api_v2_probands_get
33+
34+
get_probands = partial(get_probands_api_v2_probands_get.sync, client=client)
35+
36+
probands = get_probands() or []
37+
print(f"Total probands: {len(probands)}\n")
38+
39+
# Print first and last proband for sanity check
40+
if probands:
41+
print("First proband:")
42+
print(probands[0])
43+
print("\nLast proband:")
44+
print(probands[-1])
45+
46+
import json
47+
if probands:
48+
print("First proband:")
49+
print(json.dumps(probands[0].to_dict(), indent=2))
50+
print("\nLast proband:")
51+
print(json.dumps(probands[-1].to_dict(), indent=2))

generate-api-client.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
HOSTNAME=${1:-bodyloop-control-pc}
4+
5+
curl -kO https://${HOSTNAME}/api/v2/openapi.json
6+
7+
# Optionally beautify the JSON file with jq
8+
mv openapi.json openapi_tmp.json && jq . openapi_tmp.json > openapi.json && rm openapi_tmp.json
9+
10+
# Generate the API client code
11+
mkdir -p src/bodyloop_sdk/api
12+
13+
# Normalize OpenAPI for openapi-python-client compatibility
14+
uv run python scripts/prepare_openapi_for_codegen.py --input openapi.json --output openapi.codegen.json
15+
16+
uv run --with openapi-python-client python -m openapi_python_client generate --overwrite --config generate-api-client.yml --path openapi.codegen.json --output-path src/bodyloop_sdk
17+
18+
mv src/bodyloop_sdk/README.md src/bodyloop_sdk/client/
19+
20+
rm src/bodyloop_sdk/.gitignore
21+
rm src/bodyloop_sdk/pyproject.toml
22+
rm -rf src/bodyloop_sdk/client/.ruff_cache/

generate-api-client.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
project_name_override: client
2+
package_name_override: client
3+
class_overrides:
4+
_PrivateInternalLongName:
5+
class_name: ShortName
6+
module_name: short_name
7+
docstrings_on_attributes: true
8+
literal_enums: true
9+
generate_all_tags: true

0 commit comments

Comments
 (0)