fulcrumpro 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.
- fulcrumpro-0.1.0/PKG-INFO +82 -0
- fulcrumpro-0.1.0/README.md +74 -0
- fulcrumpro-0.1.0/fulcrumpro/__init__.py +3 -0
- fulcrumpro-0.1.0/fulcrumpro/client.py +54 -0
- fulcrumpro-0.1.0/fulcrumpro/endpoints/__init__.py +0 -0
- fulcrumpro-0.1.0/fulcrumpro/endpoints/jobs.py +21 -0
- fulcrumpro-0.1.0/fulcrumpro.egg-info/PKG-INFO +82 -0
- fulcrumpro-0.1.0/fulcrumpro.egg-info/SOURCES.txt +12 -0
- fulcrumpro-0.1.0/fulcrumpro.egg-info/dependency_links.txt +1 -0
- fulcrumpro-0.1.0/fulcrumpro.egg-info/requires.txt +1 -0
- fulcrumpro-0.1.0/fulcrumpro.egg-info/top_level.txt +1 -0
- fulcrumpro-0.1.0/pyproject.toml +64 -0
- fulcrumpro-0.1.0/setup.cfg +4 -0
- fulcrumpro-0.1.0/tests/test_client.py +103 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fulcrumpro
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight Python SDK for the Fulcrum Pro API, built with `httpx`.
|
|
5
|
+
Requires-Python: >=3.14
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: httpx>=0.28.1
|
|
8
|
+
|
|
9
|
+
# FulcrumPro
|
|
10
|
+
|
|
11
|
+
A lightweight Python SDK for the [Fulcrum Pro](https://fulcrumpro.com) API, built on [`httpx`](https://www.python-httpx.org/).
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install fulcrumpro
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or with `uv`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add fulcrumpro
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Python 3.14+
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from fulcrumpro import FulcrumPro
|
|
33
|
+
|
|
34
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
35
|
+
|
|
36
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
37
|
+
print(job["name"])
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Use as a context manager to ensure the underlying HTTP connection is closed:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
with FulcrumPro(api_token="your-api-token") as client:
|
|
44
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Authentication
|
|
48
|
+
|
|
49
|
+
All requests are authenticated with a Bearer token. Pass your API token when constructing the client:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Resources
|
|
56
|
+
|
|
57
|
+
### Jobs
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
# Get a job by ID
|
|
61
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Error Handling
|
|
65
|
+
|
|
66
|
+
All non-2xx responses raise a `FulcrumProError`:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from fulcrumpro import FulcrumPro, FulcrumProError
|
|
70
|
+
|
|
71
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
job = client.jobs.get("nonexistent-id")
|
|
75
|
+
except FulcrumProError as e:
|
|
76
|
+
print(e.status_code) # e.g. 404
|
|
77
|
+
print(str(e)) # "FulcrumPro API error 404: not found"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Version History
|
|
81
|
+
|
|
82
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# FulcrumPro
|
|
2
|
+
|
|
3
|
+
A lightweight Python SDK for the [Fulcrum Pro](https://fulcrumpro.com) API, built on [`httpx`](https://www.python-httpx.org/).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install fulcrumpro
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or with `uv`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv add fulcrumpro
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Python 3.14+
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from fulcrumpro import FulcrumPro
|
|
25
|
+
|
|
26
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
27
|
+
|
|
28
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
29
|
+
print(job["name"])
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use as a context manager to ensure the underlying HTTP connection is closed:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
with FulcrumPro(api_token="your-api-token") as client:
|
|
36
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Authentication
|
|
40
|
+
|
|
41
|
+
All requests are authenticated with a Bearer token. Pass your API token when constructing the client:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Resources
|
|
48
|
+
|
|
49
|
+
### Jobs
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
# Get a job by ID
|
|
53
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
|
|
58
|
+
All non-2xx responses raise a `FulcrumProError`:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from fulcrumpro import FulcrumPro, FulcrumProError
|
|
62
|
+
|
|
63
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
job = client.jobs.get("nonexistent-id")
|
|
67
|
+
except FulcrumProError as e:
|
|
68
|
+
print(e.status_code) # e.g. 404
|
|
69
|
+
print(str(e)) # "FulcrumPro API error 404: not found"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Version History
|
|
73
|
+
|
|
74
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from fulcrumpro.endpoints.jobs import Jobs
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FulcrumProError(Exception):
|
|
11
|
+
def __init__(self, status_code: int, message: str):
|
|
12
|
+
self.status_code = status_code
|
|
13
|
+
super().__init__(f"FulcrumPro API error {status_code}: {message}")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class FulcrumPro:
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
api_token: str,
|
|
20
|
+
):
|
|
21
|
+
base_url = "https://api.fulcrumpro.com/api"
|
|
22
|
+
self._client = httpx.Client(
|
|
23
|
+
base_url=base_url,
|
|
24
|
+
headers={
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
"Authorization": f"Bearer {api_token}",
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
self.jobs = Jobs(self)
|
|
30
|
+
|
|
31
|
+
def _request(self, method: str, path: str, **kwargs: Any) -> dict:
|
|
32
|
+
response = self._client.request(method, path, **kwargs)
|
|
33
|
+
if not response.is_success:
|
|
34
|
+
data = response.json()
|
|
35
|
+
raise FulcrumProError(response.status_code, data.get("errors"))
|
|
36
|
+
return response.json()
|
|
37
|
+
|
|
38
|
+
def get(self, path: str, **kwargs: Any) -> dict:
|
|
39
|
+
return self._request("GET", path, **kwargs)
|
|
40
|
+
|
|
41
|
+
def post(self, path: str, **kwargs: Any) -> dict:
|
|
42
|
+
return self._request("POST", path, **kwargs)
|
|
43
|
+
|
|
44
|
+
def patch(self, path: str, **kwargs: Any) -> dict:
|
|
45
|
+
return self._request("PATCH", path, **kwargs)
|
|
46
|
+
|
|
47
|
+
def delete(self, path: str, **kwargs: Any) -> dict:
|
|
48
|
+
return self._request("DELETE", path, **kwargs)
|
|
49
|
+
|
|
50
|
+
def __enter__(self) -> FulcrumPro:
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def __exit__(self, *_: Any) -> None:
|
|
54
|
+
self._client.close()
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from fulcrumpro.client import FulcrumPro
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Jobs:
|
|
10
|
+
def __init__(self, client: FulcrumPro):
|
|
11
|
+
self._client = client
|
|
12
|
+
|
|
13
|
+
def get(self, job_id: str) -> dict[str, Any]:
|
|
14
|
+
"""
|
|
15
|
+
Get a job by ID.
|
|
16
|
+
|
|
17
|
+
:param job_id: The ID of the job.
|
|
18
|
+
|
|
19
|
+
:return: The job data.
|
|
20
|
+
"""
|
|
21
|
+
return self._client.get(f"/jobs/{job_id}")
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fulcrumpro
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight Python SDK for the Fulcrum Pro API, built with `httpx`.
|
|
5
|
+
Requires-Python: >=3.14
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: httpx>=0.28.1
|
|
8
|
+
|
|
9
|
+
# FulcrumPro
|
|
10
|
+
|
|
11
|
+
A lightweight Python SDK for the [Fulcrum Pro](https://fulcrumpro.com) API, built on [`httpx`](https://www.python-httpx.org/).
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install fulcrumpro
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or with `uv`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add fulcrumpro
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Python 3.14+
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from fulcrumpro import FulcrumPro
|
|
33
|
+
|
|
34
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
35
|
+
|
|
36
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
37
|
+
print(job["name"])
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Use as a context manager to ensure the underlying HTTP connection is closed:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
with FulcrumPro(api_token="your-api-token") as client:
|
|
44
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Authentication
|
|
48
|
+
|
|
49
|
+
All requests are authenticated with a Bearer token. Pass your API token when constructing the client:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Resources
|
|
56
|
+
|
|
57
|
+
### Jobs
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
# Get a job by ID
|
|
61
|
+
job = client.jobs.get("6a0e5cad7c2e97225f8def9c")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Error Handling
|
|
65
|
+
|
|
66
|
+
All non-2xx responses raise a `FulcrumProError`:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from fulcrumpro import FulcrumPro, FulcrumProError
|
|
70
|
+
|
|
71
|
+
client = FulcrumPro(api_token="your-api-token")
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
job = client.jobs.get("nonexistent-id")
|
|
75
|
+
except FulcrumProError as e:
|
|
76
|
+
print(e.status_code) # e.g. 404
|
|
77
|
+
print(str(e)) # "FulcrumPro API error 404: not found"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Version History
|
|
81
|
+
|
|
82
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
fulcrumpro/__init__.py
|
|
4
|
+
fulcrumpro/client.py
|
|
5
|
+
fulcrumpro.egg-info/PKG-INFO
|
|
6
|
+
fulcrumpro.egg-info/SOURCES.txt
|
|
7
|
+
fulcrumpro.egg-info/dependency_links.txt
|
|
8
|
+
fulcrumpro.egg-info/requires.txt
|
|
9
|
+
fulcrumpro.egg-info/top_level.txt
|
|
10
|
+
fulcrumpro/endpoints/__init__.py
|
|
11
|
+
fulcrumpro/endpoints/jobs.py
|
|
12
|
+
tests/test_client.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
httpx>=0.28.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fulcrumpro
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fulcrumpro"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A lightweight Python SDK for the Fulcrum Pro API, built with `httpx`."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"httpx>=0.28.1",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[dependency-groups]
|
|
12
|
+
dev = [
|
|
13
|
+
"pytest>=9.0.3",
|
|
14
|
+
"pytest-cov>=7.1.0",
|
|
15
|
+
"rich>=15.0.0",
|
|
16
|
+
"ruff>=0.15.14",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.ruff]
|
|
20
|
+
line-length = 88
|
|
21
|
+
target-version = "py312"
|
|
22
|
+
src = ["infra"]
|
|
23
|
+
|
|
24
|
+
[tool.ruff.lint]
|
|
25
|
+
select = [
|
|
26
|
+
"E", # pycodestyle errors
|
|
27
|
+
"W", # pycodestyle warnings
|
|
28
|
+
"F", # pyflakes — unused imports, undefined names
|
|
29
|
+
"I", # isort — import ordering
|
|
30
|
+
"B", # flake8-bugbear — common bugs and design issues
|
|
31
|
+
"C4", # flake8-comprehensions — better list/dict/set comprehensions
|
|
32
|
+
"UP", # pyupgrade — modernize Python syntax
|
|
33
|
+
"SIM", # flake8-simplify — simplifiable code
|
|
34
|
+
"TCH", # flake8-type-checking — type hint import hygiene
|
|
35
|
+
"RUF", # ruff-specific rules
|
|
36
|
+
"N", # pep8-naming conventions
|
|
37
|
+
"S", # flake8-bandit — security issues
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
ignore = [
|
|
41
|
+
"S101", # assert statements — needed for pytest
|
|
42
|
+
"B008", # function calls in default arguments — CDK uses this pattern
|
|
43
|
+
"N802", # function name lowercase — CDK construct names are PascalCase
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint.per-file-ignores]
|
|
47
|
+
"tests/**" = [
|
|
48
|
+
"S101", # assert is fine in tests
|
|
49
|
+
"S105", # hardcoded passwords fine in tests
|
|
50
|
+
"S106",
|
|
51
|
+
]
|
|
52
|
+
"cdk/**" = [
|
|
53
|
+
"N803", # CDK uses PascalCase for some args
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.ruff.lint.isort]
|
|
57
|
+
force-sort-within-sections = true
|
|
58
|
+
|
|
59
|
+
[tool.ruff.format]
|
|
60
|
+
quote-style = "double"
|
|
61
|
+
indent-style = "space"
|
|
62
|
+
|
|
63
|
+
[tool.pytest.ini_options]
|
|
64
|
+
pythonpath = ["."]
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fulcrumpro.client import FulcrumPro, FulcrumProError
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from .conftest import make_response
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestInit:
|
|
10
|
+
def test_sets_auth_header(self, client: FulcrumPro):
|
|
11
|
+
headers = dict(client._client.headers)
|
|
12
|
+
assert headers["authorization"] == "Bearer test-token"
|
|
13
|
+
|
|
14
|
+
def test_sets_content_type_header(self, client: FulcrumPro):
|
|
15
|
+
headers = dict(client._client.headers)
|
|
16
|
+
assert headers["content-type"] == "application/json"
|
|
17
|
+
|
|
18
|
+
def test_exposes_jobs_resource(self, client: FulcrumPro):
|
|
19
|
+
from fulcrumpro.endpoints.jobs import Jobs
|
|
20
|
+
|
|
21
|
+
assert isinstance(client.jobs, Jobs)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TestRequest:
|
|
25
|
+
def test_returns_parsed_json_on_success(self, client: FulcrumPro):
|
|
26
|
+
client._client.request.return_value = make_response(200, {"id": "abc"})
|
|
27
|
+
result = client._request("GET", "/jobs/abc")
|
|
28
|
+
assert result == {"id": "abc"}
|
|
29
|
+
|
|
30
|
+
def test_calls_underlying_client_with_method_and_path(self, client: FulcrumPro):
|
|
31
|
+
client._client.request.return_value = make_response(200, {})
|
|
32
|
+
client._request("GET", "/jobs/abc")
|
|
33
|
+
client._client.request.assert_called_once_with("GET", "/jobs/abc")
|
|
34
|
+
|
|
35
|
+
def test_raises_fulcrumpro_error_on_4xx(self, client: FulcrumPro):
|
|
36
|
+
client._client.request.return_value = make_response(
|
|
37
|
+
404, {"errors": "not found"}
|
|
38
|
+
)
|
|
39
|
+
with pytest.raises(FulcrumProError) as exc_info:
|
|
40
|
+
client._request("GET", "/jobs/missing")
|
|
41
|
+
assert exc_info.value.status_code == 404
|
|
42
|
+
assert "not found" in str(exc_info.value)
|
|
43
|
+
|
|
44
|
+
def test_raises_fulcrumpro_error_on_5xx(self, client: FulcrumPro):
|
|
45
|
+
client._client.request.return_value = make_response(500, {"errors": "boom"})
|
|
46
|
+
with pytest.raises(FulcrumProError) as exc_info:
|
|
47
|
+
client._request("GET", "/jobs/abc")
|
|
48
|
+
assert exc_info.value.status_code == 500
|
|
49
|
+
|
|
50
|
+
def test_propagates_json_decode_error_on_non_json_response(
|
|
51
|
+
self, client: FulcrumPro
|
|
52
|
+
):
|
|
53
|
+
from json import JSONDecodeError
|
|
54
|
+
|
|
55
|
+
client._client.request.return_value = make_response(502, text="Bad Gateway")
|
|
56
|
+
with pytest.raises(JSONDecodeError):
|
|
57
|
+
client._request("GET", "/jobs/abc")
|
|
58
|
+
|
|
59
|
+
def test_passes_extra_kwargs_to_underlying_client(self, client: FulcrumPro):
|
|
60
|
+
client._client.request.return_value = make_response(200, {})
|
|
61
|
+
client._request("POST", "/jobs", json={"name": "test"})
|
|
62
|
+
client._client.request.assert_called_once_with(
|
|
63
|
+
"POST", "/jobs", json={"name": "test"}
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class TestHttpMethods:
|
|
68
|
+
def test_get_delegates_to_request(self, client: FulcrumPro):
|
|
69
|
+
client._client.request.return_value = make_response(200, {"ok": True})
|
|
70
|
+
result = client.get("/jobs/1")
|
|
71
|
+
client._client.request.assert_called_once_with("GET", "/jobs/1")
|
|
72
|
+
assert result == {"ok": True}
|
|
73
|
+
|
|
74
|
+
def test_post_delegates_to_request(self, client: FulcrumPro):
|
|
75
|
+
client._client.request.return_value = make_response(201, {"id": "new"})
|
|
76
|
+
result = client.post("/jobs", json={"name": "new job"})
|
|
77
|
+
client._client.request.assert_called_once_with(
|
|
78
|
+
"POST", "/jobs", json={"name": "new job"}
|
|
79
|
+
)
|
|
80
|
+
assert result == {"id": "new"}
|
|
81
|
+
|
|
82
|
+
def test_patch_delegates_to_request(self, client: FulcrumPro):
|
|
83
|
+
client._client.request.return_value = make_response(200, {"id": "1"})
|
|
84
|
+
result = client.patch("/jobs/1", json={"name": "updated"})
|
|
85
|
+
client._client.request.assert_called_once_with(
|
|
86
|
+
"PATCH", "/jobs/1", json={"name": "updated"}
|
|
87
|
+
)
|
|
88
|
+
assert result == {"id": "1"}
|
|
89
|
+
|
|
90
|
+
def test_delete_delegates_to_request(self, client: FulcrumPro):
|
|
91
|
+
client._client.request.return_value = make_response(200, {})
|
|
92
|
+
result = client.delete("/jobs/1")
|
|
93
|
+
client._client.request.assert_called_once_with("DELETE", "/jobs/1")
|
|
94
|
+
assert result == {}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestContextManager:
|
|
98
|
+
def test_enter_returns_client(self, client: FulcrumPro):
|
|
99
|
+
assert client.__enter__() is client
|
|
100
|
+
|
|
101
|
+
def test_exit_closes_underlying_httpx_client(self, client: FulcrumPro):
|
|
102
|
+
client.__exit__(None, None, None)
|
|
103
|
+
client._client.close.assert_called_once()
|