hirundo 0.1.3__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.
- hirundo-0.1.3/LICENSE +9 -0
- hirundo-0.1.3/PKG-INFO +114 -0
- hirundo-0.1.3/README.md +55 -0
- hirundo-0.1.3/hirundo/__init__.py +35 -0
- hirundo-0.1.3/hirundo/__main__.py +3 -0
- hirundo-0.1.3/hirundo/_constraints.py +21 -0
- hirundo-0.1.3/hirundo/_env.py +12 -0
- hirundo-0.1.3/hirundo/_headers.py +9 -0
- hirundo-0.1.3/hirundo/_iter_sse_retrying.py +97 -0
- hirundo-0.1.3/hirundo/_timeouts.py +2 -0
- hirundo-0.1.3/hirundo/cli.py +132 -0
- hirundo-0.1.3/hirundo/dataset_optimization.py +383 -0
- hirundo-0.1.3/hirundo/enum.py +20 -0
- hirundo-0.1.3/hirundo/git.py +158 -0
- hirundo-0.1.3/hirundo/storage.py +260 -0
- hirundo-0.1.3/hirundo.egg-info/PKG-INFO +114 -0
- hirundo-0.1.3/hirundo.egg-info/SOURCES.txt +21 -0
- hirundo-0.1.3/hirundo.egg-info/dependency_links.txt +1 -0
- hirundo-0.1.3/hirundo.egg-info/entry_points.txt +2 -0
- hirundo-0.1.3/hirundo.egg-info/requires.txt +37 -0
- hirundo-0.1.3/hirundo.egg-info/top_level.txt +1 -0
- hirundo-0.1.3/pyproject.toml +160 -0
- hirundo-0.1.3/setup.cfg +4 -0
hirundo-0.1.3/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Hirundo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
hirundo-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: hirundo
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: This package is used to interface with Hirundo's platform. It provides a simple API to optimize your ML datasets.
|
|
5
|
+
Author-email: Hirundo <dev@hirundo.io>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024, Hirundo
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
15
|
+
|
|
16
|
+
Project-URL: Homepage, https://github.com/Hirundo-io/hirundo-client
|
|
17
|
+
Keywords: dataset,machine learning,data science,data engineering
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
25
|
+
Requires-Dist: types-PyYAML>=6.0.12
|
|
26
|
+
Requires-Dist: pydantic>=2.7.1
|
|
27
|
+
Requires-Dist: twine>=5.0.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
29
|
+
Requires-Dist: types-requests>=2.31.0
|
|
30
|
+
Requires-Dist: typer>=0.12.3
|
|
31
|
+
Requires-Dist: httpx>=0.27.0
|
|
32
|
+
Requires-Dist: stamina>=24.2.0
|
|
33
|
+
Requires-Dist: httpx-sse>=0.4.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pyyaml>=6.0.1; extra == "dev"
|
|
36
|
+
Requires-Dist: types-PyYAML>=6.0.12; extra == "dev"
|
|
37
|
+
Requires-Dist: pydantic>=2.7.1; extra == "dev"
|
|
38
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
39
|
+
Requires-Dist: python-dotenv>=1.0.1; extra == "dev"
|
|
40
|
+
Requires-Dist: types-requests>=2.31.0; extra == "dev"
|
|
41
|
+
Requires-Dist: types-setuptools>=69.5.0; extra == "dev"
|
|
42
|
+
Requires-Dist: typer>=0.12.3; extra == "dev"
|
|
43
|
+
Requires-Dist: httpx>=0.27.0; extra == "dev"
|
|
44
|
+
Requires-Dist: stamina>=24.2.0; extra == "dev"
|
|
45
|
+
Requires-Dist: httpx-sse>=0.4.0; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest>=8.2.0; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest-asyncio>=0.23.6; extra == "dev"
|
|
48
|
+
Requires-Dist: uv; extra == "dev"
|
|
49
|
+
Requires-Dist: pre-commit>=3.7.1; extra == "dev"
|
|
50
|
+
Requires-Dist: ruff; extra == "dev"
|
|
51
|
+
Requires-Dist: bumpver; extra == "dev"
|
|
52
|
+
Provides-Extra: docs
|
|
53
|
+
Requires-Dist: sphinx>=7.4.7; extra == "docs"
|
|
54
|
+
Requires-Dist: sphinx-autobuild>=2024.4.16; extra == "docs"
|
|
55
|
+
Requires-Dist: sphinx-click>=5.0.1; extra == "docs"
|
|
56
|
+
Requires-Dist: autodoc_pydantic>=2.2.0; extra == "docs"
|
|
57
|
+
Requires-Dist: furo; extra == "docs"
|
|
58
|
+
Requires-Dist: sphinx-multiversion; extra == "docs"
|
|
59
|
+
|
|
60
|
+
# Hirundo client
|
|
61
|
+
|
|
62
|
+
This repo contains the source code for the Hirundo client library
|
|
63
|
+
|
|
64
|
+
## Usage:
|
|
65
|
+
|
|
66
|
+
To learn about how to use this library, please visit the [http://docs.hirundo.io/](documentation) or see the Google Colab examples.
|
|
67
|
+
|
|
68
|
+
## Development:
|
|
69
|
+
|
|
70
|
+
### Install dev dependencies
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install -r dev-requirements.txt
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Note: You can install and use `uv` as a faster drop-in replacement for `pip`. We have it as part of our dev dependencies for this reason.
|
|
77
|
+
|
|
78
|
+
### Install `git` hooks (optional)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pre-commit install
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Check lint and apply formatting with Ruff (optional; pre-commit hooks run this automatically)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
ruff check
|
|
88
|
+
ruff format
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Change packages
|
|
92
|
+
|
|
93
|
+
#### Update `requirements.txt` files
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
uv pip compile pyproject.toml
|
|
97
|
+
uv pip compile --extra dev -o dev-requirements.txt -c requirements.txt pyproject.toml
|
|
98
|
+
uv pip compile --extra docs -o docs-requirements.txt -c requirements.txt pyproject.toml
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Sync installed packages
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
uv pip sync dev-requirements.txt
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Build process
|
|
108
|
+
|
|
109
|
+
To build the package, run:
|
|
110
|
+
`python -m build`
|
|
111
|
+
|
|
112
|
+
### Publish documentation & releases
|
|
113
|
+
|
|
114
|
+
Documentation & releases are published via GitHub Actions on merges to `main`.
|
hirundo-0.1.3/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Hirundo client
|
|
2
|
+
|
|
3
|
+
This repo contains the source code for the Hirundo client library
|
|
4
|
+
|
|
5
|
+
## Usage:
|
|
6
|
+
|
|
7
|
+
To learn about how to use this library, please visit the [http://docs.hirundo.io/](documentation) or see the Google Colab examples.
|
|
8
|
+
|
|
9
|
+
## Development:
|
|
10
|
+
|
|
11
|
+
### Install dev dependencies
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install -r dev-requirements.txt
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Note: You can install and use `uv` as a faster drop-in replacement for `pip`. We have it as part of our dev dependencies for this reason.
|
|
18
|
+
|
|
19
|
+
### Install `git` hooks (optional)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pre-commit install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Check lint and apply formatting with Ruff (optional; pre-commit hooks run this automatically)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ruff check
|
|
29
|
+
ruff format
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Change packages
|
|
33
|
+
|
|
34
|
+
#### Update `requirements.txt` files
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv pip compile pyproject.toml
|
|
38
|
+
uv pip compile --extra dev -o dev-requirements.txt -c requirements.txt pyproject.toml
|
|
39
|
+
uv pip compile --extra docs -o docs-requirements.txt -c requirements.txt pyproject.toml
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Sync installed packages
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uv pip sync dev-requirements.txt
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Build process
|
|
49
|
+
|
|
50
|
+
To build the package, run:
|
|
51
|
+
`python -m build`
|
|
52
|
+
|
|
53
|
+
### Publish documentation & releases
|
|
54
|
+
|
|
55
|
+
Documentation & releases are published via GitHub Actions on merges to `main`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from .dataset_optimization import (
|
|
2
|
+
HirundoError,
|
|
3
|
+
OptimizationDataset,
|
|
4
|
+
)
|
|
5
|
+
from .enum import (
|
|
6
|
+
DatasetMetadataType,
|
|
7
|
+
LabellingType,
|
|
8
|
+
)
|
|
9
|
+
from .git import GitRepo
|
|
10
|
+
from .storage import (
|
|
11
|
+
StorageGCP,
|
|
12
|
+
# StorageAzure, TODO: Azure storage integration is coming soon
|
|
13
|
+
StorageGit,
|
|
14
|
+
StorageIntegration,
|
|
15
|
+
StorageLink,
|
|
16
|
+
StorageS3,
|
|
17
|
+
StorageTypes,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"HirundoError",
|
|
22
|
+
"OptimizationDataset",
|
|
23
|
+
"LabellingType",
|
|
24
|
+
"DatasetMetadataType",
|
|
25
|
+
"GitRepo",
|
|
26
|
+
"StorageLink",
|
|
27
|
+
"StorageTypes",
|
|
28
|
+
"StorageS3",
|
|
29
|
+
"StorageGCP",
|
|
30
|
+
# "StorageAzure", TODO: Azure storage integration is coming soon
|
|
31
|
+
"StorageGit",
|
|
32
|
+
"StorageIntegration",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
__version__ = "0.1.3"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from pydantic import StringConstraints
|
|
4
|
+
|
|
5
|
+
S3BucketUrl = Annotated[
|
|
6
|
+
str,
|
|
7
|
+
StringConstraints(
|
|
8
|
+
min_length=8,
|
|
9
|
+
max_length=1023,
|
|
10
|
+
pattern=r"s3?://[a-z0-9.-]{3,64}[/]?", # Only allow real S3 bucket URLs
|
|
11
|
+
),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
StorageIntegrationName = Annotated[
|
|
15
|
+
str,
|
|
16
|
+
StringConstraints(
|
|
17
|
+
min_length=1,
|
|
18
|
+
max_length=255,
|
|
19
|
+
pattern=r"^[a-zA-Z0-9-_]+$",
|
|
20
|
+
),
|
|
21
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
|
|
5
|
+
load_dotenv()
|
|
6
|
+
|
|
7
|
+
API_HOST = os.getenv("API_HOST", "https://api.hirundo.io")
|
|
8
|
+
API_KEY = os.getenv("API_KEY")
|
|
9
|
+
if not API_KEY:
|
|
10
|
+
raise ValueError(
|
|
11
|
+
"API_KEY is not set. Please run `hirundo setup` to set the API key"
|
|
12
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import time
|
|
3
|
+
from collections.abc import AsyncGenerator, Generator
|
|
4
|
+
from typing import Union
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
from httpx_sse import ServerSentEvent, aconnect_sse, connect_sse
|
|
8
|
+
from stamina import retry
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Credit: https://github.com/florimondmanca/httpx-sse/blob/master/README.md#handling-reconnections
|
|
12
|
+
def iter_sse_retrying(
|
|
13
|
+
client: httpx.Client,
|
|
14
|
+
method: str,
|
|
15
|
+
url: str,
|
|
16
|
+
headers: Union[dict[str, str], None] = None,
|
|
17
|
+
) -> Generator[ServerSentEvent, None, None]:
|
|
18
|
+
if headers is None:
|
|
19
|
+
headers = {}
|
|
20
|
+
last_event_id = ""
|
|
21
|
+
reconnection_delay = 0.0
|
|
22
|
+
|
|
23
|
+
# `stamina` will apply jitter and exponential backoff on top of
|
|
24
|
+
# the `retry` reconnection delay sent by the server.
|
|
25
|
+
# httpx.ReadError is thrown when there is a network error.
|
|
26
|
+
# Some network errors may be temporary, hence the retries.
|
|
27
|
+
# httpx.RemoteProtocolError is thrown when the server closes the connection.
|
|
28
|
+
# This may happen when the server is overloaded and closes the connection or
|
|
29
|
+
# when Kubernetes restarts / replaces a pod.
|
|
30
|
+
# Likewise, this will likely be temporary, hence the retries.
|
|
31
|
+
@retry(on=(httpx.ReadError, httpx.RemoteProtocolError))
|
|
32
|
+
def _iter_sse():
|
|
33
|
+
nonlocal last_event_id, reconnection_delay
|
|
34
|
+
|
|
35
|
+
time.sleep(reconnection_delay)
|
|
36
|
+
|
|
37
|
+
connect_headers = {
|
|
38
|
+
**headers,
|
|
39
|
+
"Accept": "text/event-stream",
|
|
40
|
+
"X-Accel-Buffering": "no",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if last_event_id:
|
|
44
|
+
connect_headers["Last-Event-ID"] = last_event_id
|
|
45
|
+
|
|
46
|
+
with connect_sse(client, method, url, headers=connect_headers) as event_source:
|
|
47
|
+
for sse in event_source.iter_sse():
|
|
48
|
+
last_event_id = sse.id
|
|
49
|
+
|
|
50
|
+
if sse.retry is not None:
|
|
51
|
+
reconnection_delay = sse.retry / 1000
|
|
52
|
+
|
|
53
|
+
yield sse
|
|
54
|
+
|
|
55
|
+
return _iter_sse()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def aiter_sse_retrying(
|
|
59
|
+
client: httpx.AsyncClient,
|
|
60
|
+
method: str,
|
|
61
|
+
url: str,
|
|
62
|
+
headers: dict[str, str],
|
|
63
|
+
) -> AsyncGenerator[ServerSentEvent, None]:
|
|
64
|
+
last_event_id = ""
|
|
65
|
+
reconnection_delay = 0.0
|
|
66
|
+
|
|
67
|
+
# `stamina` will apply jitter and exponential backoff on top of
|
|
68
|
+
# the `retry` reconnection delay sent by the server.
|
|
69
|
+
# httpx.ReadError is thrown when there is a network error.
|
|
70
|
+
# Some network errors may be temporary, hence the retries.
|
|
71
|
+
# httpx.RemoteProtocolError is thrown when the server closes the connection.
|
|
72
|
+
# This may happen when the server is overloaded and closes the connection or
|
|
73
|
+
# when Kubernetes restarts / replaces a pod.
|
|
74
|
+
# Likewise, this will likely be temporary, hence the retries.
|
|
75
|
+
@retry(on=(httpx.ReadError, httpx.RemoteProtocolError))
|
|
76
|
+
async def _iter_sse() -> AsyncGenerator[ServerSentEvent, None]:
|
|
77
|
+
nonlocal last_event_id, reconnection_delay
|
|
78
|
+
|
|
79
|
+
await asyncio.sleep(reconnection_delay)
|
|
80
|
+
|
|
81
|
+
connect_headers = {**headers, "Accept": "text/event-stream"}
|
|
82
|
+
|
|
83
|
+
if last_event_id:
|
|
84
|
+
connect_headers["Last-Event-ID"] = last_event_id
|
|
85
|
+
|
|
86
|
+
async with aconnect_sse(
|
|
87
|
+
client, method, url, headers=connect_headers
|
|
88
|
+
) as event_source:
|
|
89
|
+
async for sse in event_source.aiter_sse():
|
|
90
|
+
last_event_id = sse.id
|
|
91
|
+
|
|
92
|
+
if sse.retry is not None:
|
|
93
|
+
reconnection_delay = sse.retry / 1000
|
|
94
|
+
|
|
95
|
+
yield sse
|
|
96
|
+
|
|
97
|
+
return _iter_sse()
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
|
+
from hirundo._env import API_HOST
|
|
9
|
+
|
|
10
|
+
docs = "sphinx" in sys.modules
|
|
11
|
+
hirundo_epilog = (
|
|
12
|
+
None
|
|
13
|
+
if docs
|
|
14
|
+
else "Made with ❤️ by Hirundo. Visit https://www.hirundo.io for more information."
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
app = typer.Typer(
|
|
18
|
+
name="hirundo", no_args_is_help=True, rich_markup_mode="rich", epilog=hirundo_epilog
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upsert_env(var_name: str, var_value: str):
|
|
23
|
+
"""
|
|
24
|
+
Change an environment variable in the .env file.
|
|
25
|
+
If the variable does not exist, it will be added.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
var_name: The name of the environment variable to change.
|
|
29
|
+
var_value: The new value of the environment variable.
|
|
30
|
+
"""
|
|
31
|
+
dotenv = "./.env"
|
|
32
|
+
regex = re.compile(rf"^{var_name}=.*$")
|
|
33
|
+
with open(dotenv) as f:
|
|
34
|
+
lines = f.readlines()
|
|
35
|
+
|
|
36
|
+
with open(dotenv, "w") as f:
|
|
37
|
+
f.writelines(line for line in lines if not regex.search(line) and line != "\n")
|
|
38
|
+
|
|
39
|
+
with open(dotenv, "a") as f:
|
|
40
|
+
f.writelines(f"\n{var_name}={var_value}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def fix_api_host(api_host: str):
|
|
44
|
+
if not api_host.startswith("http") and not api_host.startswith("https"):
|
|
45
|
+
api_host = f"https://{api_host}"
|
|
46
|
+
print(
|
|
47
|
+
"API host must start with 'http://' or 'https://'. Automatically added 'https://'."
|
|
48
|
+
)
|
|
49
|
+
if (url := urlparse(api_host)) and url.path != "":
|
|
50
|
+
print("API host should not contain a path. Removing path.")
|
|
51
|
+
api_host = f"{url.scheme}://{url.hostname}"
|
|
52
|
+
return api_host
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@app.command("set-api-key", epilog=hirundo_epilog)
|
|
56
|
+
def setup_api_key(
|
|
57
|
+
api_key: Annotated[
|
|
58
|
+
str,
|
|
59
|
+
typer.Option(
|
|
60
|
+
prompt="Please enter the API key value",
|
|
61
|
+
help=""
|
|
62
|
+
if docs
|
|
63
|
+
else f"Visit '{API_HOST}/api-key' to generate your API key.",
|
|
64
|
+
),
|
|
65
|
+
],
|
|
66
|
+
):
|
|
67
|
+
"""
|
|
68
|
+
Setup the API key for the Hirundo client library.
|
|
69
|
+
Values are saved to a .env file in the current directory for use by the library in requests.
|
|
70
|
+
"""
|
|
71
|
+
upsert_env("API_KEY", api_key)
|
|
72
|
+
print("API key saved to .env for future use. Please do not share the .env file")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@app.command("change-remote", epilog=hirundo_epilog)
|
|
76
|
+
def change_api_remote(
|
|
77
|
+
api_host: Annotated[
|
|
78
|
+
str, # TODO: Change to HttpUrl when https://github.com/tiangolo/typer/pull/723 is merged
|
|
79
|
+
typer.Option(
|
|
80
|
+
prompt="Please enter the API server address",
|
|
81
|
+
help=""
|
|
82
|
+
if docs
|
|
83
|
+
else f"Current API server address: '{API_HOST}'. This is the same address where you access the Hirundo web interface.",
|
|
84
|
+
),
|
|
85
|
+
],
|
|
86
|
+
):
|
|
87
|
+
"""
|
|
88
|
+
Change the API server address for the Hirundo client library.
|
|
89
|
+
This is the same address where you access the Hirundo web interface.
|
|
90
|
+
"""
|
|
91
|
+
api_host = fix_api_host(api_host)
|
|
92
|
+
|
|
93
|
+
upsert_env("API_HOST", api_host)
|
|
94
|
+
print("API host saved to .env for future use. Please do not share this file")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@app.command("setup", epilog=hirundo_epilog)
|
|
98
|
+
def setup(
|
|
99
|
+
api_key: Annotated[
|
|
100
|
+
str,
|
|
101
|
+
typer.Option(
|
|
102
|
+
prompt="Please enter the API key value",
|
|
103
|
+
help=""
|
|
104
|
+
if docs
|
|
105
|
+
else f"Visit '{API_HOST}/api-key' to generate your API key.",
|
|
106
|
+
),
|
|
107
|
+
],
|
|
108
|
+
api_host: Annotated[
|
|
109
|
+
str, # TODO: Change to HttpUrl as above
|
|
110
|
+
typer.Option(
|
|
111
|
+
prompt="Please enter the API server address",
|
|
112
|
+
help=""
|
|
113
|
+
if docs
|
|
114
|
+
else f"Current API server address: '{API_HOST}'. This is the same address where you access the Hirundo web interface.",
|
|
115
|
+
),
|
|
116
|
+
],
|
|
117
|
+
):
|
|
118
|
+
"""
|
|
119
|
+
Setup the Hirundo client library.
|
|
120
|
+
"""
|
|
121
|
+
api_host = fix_api_host(api_host)
|
|
122
|
+
upsert_env("API_HOST", api_host)
|
|
123
|
+
upsert_env("API_KEY", api_key)
|
|
124
|
+
print(
|
|
125
|
+
"API host and API key saved to .env for future use. Please do not share this file"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
typer_click_object = typer.main.get_command(app)
|
|
130
|
+
|
|
131
|
+
if __name__ == "__main__":
|
|
132
|
+
app()
|