ogre-sdk 0.1.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.
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "Python SDK (3.13, uv)",
3
+
4
+ "dockerComposeFile": "../docker-compose.yml",
5
+ "service": "dev",
6
+
7
+ "workspaceFolder": "/workspace",
8
+
9
+ "remoteUser": "appuser",
10
+
11
+ "customizations": {
12
+ "vscode": {
13
+ "extensions": [
14
+ "ms-python.python",
15
+ "ms-python.vscode-pylance"
16
+ ]
17
+ }
18
+ },
19
+ "features": {
20
+ "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
21
+ }
22
+ }
@@ -0,0 +1,7 @@
1
+ .venv
2
+ __pycache__
3
+ .git
4
+ .devcontainer
5
+ dist
6
+ build
7
+ *.pyc
@@ -0,0 +1,29 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ publish:
11
+ name: Build and Publish
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ id-token: write
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v6
19
+
20
+ - name: Set up uv
21
+ uses: astral-sh/setup-uv@v8.1.0
22
+ with:
23
+ python-version: "3.13"
24
+
25
+ - name: Build package
26
+ run: uv build
27
+
28
+ - name: Publish to PyPI
29
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,30 @@
1
+ name: test
2
+
3
+ on: pull_request
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Check out repository
10
+ uses: actions/checkout@v6
11
+
12
+ - name: Set up uv
13
+ uses: astral-sh/setup-uv@v8.1.0
14
+ with:
15
+ python-version: "3.13"
16
+
17
+ - name: Install dependencies
18
+ run: uv sync --all-extras
19
+
20
+ # - name: Run tests
21
+ # run: uv run pytest
22
+
23
+ - name: Build package
24
+ run: uv build
25
+
26
+ - name: Upload build artifact
27
+ uses: actions/upload-artifact@v7
28
+ with:
29
+ name: ogre-sdk-dist
30
+ path: dist/
@@ -0,0 +1,24 @@
1
+ name: pre-commit
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [dev, prod, master]
7
+
8
+ jobs:
9
+ pre-commit:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v6
14
+
15
+ - name: Set up uv
16
+ uses: astral-sh/setup-uv@v8.1.0
17
+ with:
18
+ python-version: "3.13"
19
+
20
+ - name: Install dependencies
21
+ run: uv sync --all-extras
22
+
23
+ - name: Run pre-commit
24
+ run: uv run pre-commit run --all-files
@@ -0,0 +1,221 @@
1
+ # Claude Code
2
+ .claude/
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[codz]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py.cover
53
+ .hypothesis/
54
+ .pytest_cache/
55
+ cover/
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+ db.sqlite3
65
+ db.sqlite3-journal
66
+
67
+ # Flask stuff:
68
+ instance/
69
+ .webassets-cache
70
+
71
+ # Scrapy stuff:
72
+ .scrapy
73
+
74
+ # Sphinx documentation
75
+ docs/_build/
76
+
77
+ # PyBuilder
78
+ .pybuilder/
79
+ target/
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+
84
+ # IPython
85
+ profile_default/
86
+ ipython_config.py
87
+
88
+ # pyenv
89
+ # For a library or package, you might want to ignore these files since the code is
90
+ # intended to run in multiple environments; otherwise, check them in:
91
+ # .python-version
92
+
93
+ # pipenv
94
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
96
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
97
+ # install all needed dependencies.
98
+ # Pipfile.lock
99
+
100
+ # UV
101
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
102
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
103
+ # commonly ignored for libraries.
104
+ # uv.lock
105
+
106
+ # poetry
107
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
108
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
109
+ # commonly ignored for libraries.
110
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
111
+ # poetry.lock
112
+ # poetry.toml
113
+
114
+ # pdm
115
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
116
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
117
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
118
+ # pdm.lock
119
+ # pdm.toml
120
+ .pdm-python
121
+ .pdm-build/
122
+
123
+ # pixi
124
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
125
+ # pixi.lock
126
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
127
+ # in the .venv directory. It is recommended not to include this directory in version control.
128
+ .pixi
129
+
130
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
131
+ __pypackages__/
132
+
133
+ # Celery stuff
134
+ celerybeat-schedule
135
+ celerybeat.pid
136
+
137
+ # Redis
138
+ *.rdb
139
+ *.aof
140
+ *.pid
141
+
142
+ # RabbitMQ
143
+ mnesia/
144
+ rabbitmq/
145
+ rabbitmq-data/
146
+
147
+ # ActiveMQ
148
+ activemq-data/
149
+
150
+ # SageMath parsed files
151
+ *.sage.py
152
+
153
+ # Environments
154
+ .env
155
+ .envrc
156
+ .venv
157
+ env/
158
+ venv/
159
+ ENV/
160
+ env.bak/
161
+ venv.bak/
162
+
163
+ # Spyder project settings
164
+ .spyderproject
165
+ .spyproject
166
+
167
+ # Rope project settings
168
+ .ropeproject
169
+
170
+ # mkdocs documentation
171
+ /site
172
+
173
+ # mypy
174
+ .mypy_cache/
175
+ .dmypy.json
176
+ dmypy.json
177
+
178
+ # Pyre type checker
179
+ .pyre/
180
+
181
+ # pytype static type analyzer
182
+ .pytype/
183
+
184
+ # Cython debug symbols
185
+ cython_debug/
186
+
187
+ # PyCharm
188
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
189
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
190
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
191
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
192
+ # .idea/
193
+
194
+ # Abstra
195
+ # Abstra is an AI-powered process automation framework.
196
+ # Ignore directories containing user credentials, local state, and settings.
197
+ # Learn more at https://abstra.io/docs
198
+ .abstra/
199
+
200
+ # Visual Studio Code
201
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
202
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
203
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
204
+ # you could uncomment the following to ignore the entire vscode folder
205
+ # .vscode/
206
+ # Temporary file for partial code execution
207
+ tempCodeRunnerFile.py
208
+
209
+ # Ruff stuff:
210
+ .ruff_cache/
211
+
212
+ # PyPI configuration file
213
+ .pypirc
214
+
215
+ # Marimo
216
+ marimo/_static/
217
+ marimo/_lsp/
218
+ __marimo__/
219
+
220
+ # Streamlit
221
+ .streamlit/secrets.toml
@@ -0,0 +1,44 @@
1
+ repos:
2
+ - repo: 'https://github.com/pre-commit/pre-commit-hooks'
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: check-added-large-files
7
+ - id: check-ast
8
+ - id: check-builtin-literals
9
+ - id: check-case-conflict
10
+ - id: check-docstring-first
11
+ - id: check-json
12
+ - id: check-merge-conflict
13
+ - id: check-toml
14
+ - id: check-vcs-permalinks
15
+ - id: check-yaml
16
+ - id: debug-statements
17
+ - id: destroyed-symlinks
18
+ - id: detect-aws-credentials
19
+ args: [--allow-missing-credentials]
20
+ - id: detect-private-key
21
+ - id: end-of-file-fixer
22
+ - id: forbid-submodules
23
+ - id: mixed-line-ending
24
+ - id: name-tests-test
25
+ args: [--pytest-test-first]
26
+
27
+ - repo: local
28
+ hooks:
29
+ - id: ruff
30
+ name: ruff
31
+ entry: ruff check
32
+ language: system
33
+ types: [python]
34
+ args: [--fix, --exit-non-zero-on-fix]
35
+ - id: ruff-format
36
+ name: ruff-format
37
+ entry: ruff format
38
+ language: system
39
+ types: [python]
40
+ - id: mypy
41
+ name: mypy
42
+ entry: mypy ogre_sdk
43
+ language: system
44
+ pass_filenames: false
@@ -0,0 +1,7 @@
1
+ # CLAUDE.md
2
+
3
+ ## Memory
4
+
5
+ This project runs in a Docker container. The container home directory (`/home/appuser/`) is ephemeral and lost on rebuild.
6
+
7
+ **Always store memory in `/workspace/.claude/memory/`** — this directory is inside the volume mount and persists across rebuilds. Never use the default `/home/appuser/.claude/projects/` path for memory.
@@ -0,0 +1,45 @@
1
+ # ---------- base (shared by dev & CI) ----------
2
+ FROM python:3.13-slim
3
+
4
+ ENV DEBIAN_FRONTEND=noninteractive
5
+
6
+ RUN apt-get update && apt-get install -y \
7
+ bash \
8
+ curl \
9
+ git \
10
+ build-essential \
11
+ nodejs \
12
+ npm \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # Use bash for later RUN commands so devcontainer feature scripts that rely on bash work correctly
16
+ SHELL ["/bin/bash", "-lc"]
17
+
18
+ # install uv to a system-wide path so it's accessible to all users
19
+ RUN curl -Ls https://astral.sh/uv/install.sh | UV_INSTALL_DIR=/usr/local/bin sh
20
+
21
+ # create non-root user
22
+ ARG USERNAME=appuser
23
+ ARG USER_UID=1000
24
+ ARG USER_GID=1000
25
+
26
+ RUN groupadd --gid $USER_GID $USERNAME \
27
+ && useradd --shell /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME
28
+
29
+ WORKDIR /workspace
30
+
31
+ # dependency layer
32
+ COPY pyproject.toml uv.lock* ./
33
+
34
+ ENV UV_PROJECT_ENVIRONMENT=/workspace/.venv
35
+
36
+ RUN uv sync --frozen
37
+
38
+ RUN chown -R $USERNAME:$USERNAME /workspace
39
+
40
+ ENV PATH="/workspace/.venv/bin:$PATH"
41
+ ENV CLAUDE_CONFIG_DIR=/workspace/.claude
42
+
43
+ USER $USERNAME
44
+
45
+ CMD ["bash"]
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: ogre-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the ogre.ai API
5
+ Requires-Python: >=3.13
6
+ Requires-Dist: pydantic>=2.0
7
+ Requires-Dist: requests>=2.32
8
+ Provides-Extra: dev
9
+ Requires-Dist: jupyterlab>=4.0; extra == 'dev'
10
+ Requires-Dist: mypy; extra == 'dev'
11
+ Requires-Dist: pre-commit; extra == 'dev'
12
+ Requires-Dist: pytest; extra == 'dev'
13
+ Requires-Dist: ruff; extra == 'dev'
14
+ Requires-Dist: types-requests; extra == 'dev'
@@ -0,0 +1,21 @@
1
+ # ogre-sdk
2
+
3
+ Python SDK for the [ogre.ai](https://ogre.ai) API.
4
+
5
+ ## Development
6
+
7
+ ### Standard environment
8
+
9
+ ```bash
10
+ docker compose up
11
+ ```
12
+
13
+ Starts the container with `sleep infinity` — attach to it for a shell or use it with your IDE.
14
+
15
+ ### Jupyter environment
16
+
17
+ ```bash
18
+ docker compose -f docker-compose.yml -f docker-compose.dev.yml up
19
+ ```
20
+
21
+ Installs dev dependencies (`jupyterlab`, `pytest`, `ruff`, `mypy`) and starts Jupyter Lab at [http://localhost:8888](http://localhost:8888).
ogre_sdk-0.1.0/demo.py ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env python3
2
+ """End-to-end demand forecast pipeline using the ogre-sdk."""
3
+
4
+ import logging
5
+ from datetime import UTC, datetime
6
+ from pathlib import Path
7
+
8
+ from ogre_sdk import Ogre
9
+
10
+ API_KEY = "" # your Ogre API key
11
+ PROJECT_ID = "737f49b8-8b15-423c-adad-b1a8249a66d0"
12
+ DSO_ID = "7cefd274-f822-498c-ad7d-ccedb259d95b"
13
+ PROFILE_ID = "2c3c831f-8ade-497e-9c30-98e37aa26260"
14
+
15
+ CSV_PATH = Path("historical.csv")
16
+
17
+ TRAIN_START = datetime(2016, 1, 1, tzinfo=UTC)
18
+ TRAIN_END = datetime(2017, 12, 31, tzinfo=UTC)
19
+ FORECAST_START = datetime(2018, 1, 1, tzinfo=UTC)
20
+ FORECAST_END = datetime(2018, 2, 1, tzinfo=UTC)
21
+
22
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
23
+ log = logging.getLogger(__name__)
24
+
25
+ client = Ogre(api_key=API_KEY, project_id=PROJECT_ID)
26
+
27
+ sources = client.meteo_sources.list()
28
+ log.info("%d meteo source(s) available", len(sources))
29
+
30
+ consumer = client.consumers.create(
31
+ name="Demo Consumer",
32
+ latitude=53.350,
33
+ longitude=-6.260,
34
+ dso_id=DSO_ID,
35
+ profile_id=PROFILE_ID,
36
+ external_id="external-consumer-id",
37
+ )
38
+ log.info("Consumer id: %s", consumer.id)
39
+ log.info("Meteo location id: %s", consumer.meteo_location.id)
40
+ log.info("Forecast settings id: %s", consumer.forecast_settings.id)
41
+
42
+ consumer.import_historical(CSV_PATH, start_date=TRAIN_START, end_date=TRAIN_END).wait()
43
+
44
+ consumer.ingest_meteo(TRAIN_START, TRAIN_END).wait()
45
+
46
+ trained_model = consumer.train(TRAIN_START, TRAIN_END).wait()
47
+ log.info("Trained model id: %s", trained_model["id"])
48
+
49
+ if FORECAST_END > TRAIN_END:
50
+ consumer.ingest_meteo(FORECAST_START, FORECAST_END).wait()
51
+
52
+ result = consumer.run_forecast(FORECAST_START, FORECAST_END).wait()
53
+ log.info("Forecast records: %d", len(result))
@@ -0,0 +1,14 @@
1
+ version: "3.9"
2
+
3
+ services:
4
+ dev:
5
+ build:
6
+ args:
7
+ INSTALL_DEV: "true"
8
+
9
+ ports:
10
+ - "8888:8888"
11
+
12
+ command: >
13
+ bash -c "uv sync --frozen --extra dev &&
14
+ jupyter lab --ip=0.0.0.0 --port=8888 --no-browser"
@@ -0,0 +1,17 @@
1
+ version: "3.9"
2
+
3
+ services:
4
+ dev:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+
9
+ volumes:
10
+ - .:/workspace
11
+
12
+ working_dir: /workspace
13
+
14
+ environment:
15
+ - CLAUDE_CONFIG_DIR=/workspace/.claude
16
+
17
+ command: sleep infinity