Skip to content

Commit a32371f

Browse files
committed
initial commit
tind_client/ api.py fetch.py adapted from https://github.com/BerkeleyLibrary/willa claude-assisted
0 parents  commit a32371f

15 files changed

Lines changed: 1094 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["main"]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.13"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install ".[test,lint]"
28+
29+
- name: Lint with pylint
30+
run: pylint tind_client/
31+
32+
- name: Type-check with mypy
33+
run: mypy tind_client/
34+
35+
- name: Run tests
36+
run: pytest

.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# Distribution / packaging
7+
.eggs/
8+
dist/
9+
build/
10+
*.egg-info/
11+
*.egg
12+
13+
# Virtual environments
14+
.venv/
15+
venv/
16+
env/
17+
ENV/
18+
19+
# Installer logs
20+
pip-log.txt
21+
pip-delete-this-directory.txt
22+
23+
# Unit test / coverage reports
24+
.pytest_cache/
25+
.coverage
26+
htmlcov/
27+
.tox/
28+
29+
# Type checker caches
30+
.mypy_cache/
31+
.dmypy.json
32+
33+
# IDEs
34+
.vscode/
35+
.idea/
36+
*.swp
37+
*.swo
38+
39+
# macOS
40+
.DS_Store
41+
42+
# Env files
43+
.env
44+
.env.*

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
- Initial release
12+
- Basic project structure
13+
- Implemented TINDClient to wrap API interactions
14+
15+
### Changed
16+
- N/A
17+
18+
### Deprecated
19+
- N/A
20+
21+
### Removed
22+
- N/A
23+
24+
### Fixed
25+
- N/A
26+
27+
### Security
28+
- N/A

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 The Regents of the University of California
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# python-tind-client
2+
3+
Python library for interacting with the [TIND ILS](https://tind.io) API.
4+
5+
## Requirements
6+
7+
- Python 3.13+
8+
9+
## Installation
10+
11+
```bash
12+
pip install python-tind-client
13+
```
14+
15+
Install with optional development dependencies:
16+
17+
```bash
18+
pip install "python-tind-client[dev]" # test + lint + debug
19+
pip install "python-tind-client[test]" # pytest + requests-mock
20+
pip install "python-tind-client[lint]" # mypy + pydoclint + pylint
21+
pip install "python-tind-client[debug]" # debugpy
22+
```
23+
24+
## Configuration
25+
26+
Create a `TINDClient` with explicit configuration values:
27+
28+
- `api_key` (required): Your TIND API token
29+
- `api_url` (required): Base URL of the TIND instance (e.g. `https://tind.example.edu`)
30+
- `default_storage_dir` (optional): Default output directory for downloaded files
31+
32+
## Usage
33+
34+
```python
35+
from tind_client import TINDClient
36+
37+
client = TINDClient(
38+
api_key="your-token",
39+
api_url="https://tind.example.edu",
40+
default_storage_dir="/tmp",
41+
)
42+
43+
# Fetch MARC metadata for a record
44+
record = client.fetch_metadata("12345")
45+
print(record["245"]["a"]) # title
46+
47+
# Download a file
48+
path = client.fetch_file("https://tind.example.edu/files/12345/download")
49+
50+
# Search and retrieve PyMARC records
51+
records = client.search("title:python programming", result_format="pymarc")
52+
```
53+
54+
## Functional fetch API
55+
56+
The functions in `tind_client.fetch` are available for direct use and now accept
57+
explicit credentials instead of a client object.
58+
59+
```python
60+
from tind_client.fetch import fetch_metadata
61+
62+
record = fetch_metadata(
63+
"12345",
64+
api_key="your-token",
65+
api_url="https://tind.example.edu",
66+
)
67+
```
68+
69+
For most use cases, prefer `TINDClient` methods as the primary interface.
70+
71+
## Running tests
72+
73+
```bash
74+
pytest
75+
```
76+
77+
## License
78+
79+
MIT — © 2026 The Regents of the University of California

pyproject.toml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
[build-system]
2+
requires = ["setuptools>=80"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "python-tind-client"
7+
version = "0.1.0"
8+
description = "Python library for interacting with the TIND API"
9+
readme = "README.md"
10+
license = { file = "LICENSE" }
11+
authors = [
12+
{ name = "Jason Raitz", email = "raitz@berkeley.edu" },
13+
]
14+
requires-python = ">=3.13"
15+
dependencies = [
16+
"requests>=2.32",
17+
"pymarc>=5.2",
18+
]
19+
20+
[project.optional-dependencies]
21+
test = [
22+
"pytest>=8.3",
23+
"requests-mock>=1.12",
24+
]
25+
lint = [
26+
"mypy>=1.14",
27+
"pydoclint>=0.5",
28+
"pylint>=3.3",
29+
"types-requests>=2.32",
30+
]
31+
debug = [
32+
"debugpy>=1.8",
33+
]
34+
dev = [
35+
"python-tind-client[test,lint,debug]",
36+
]
37+
38+
[tool.setuptools.packages.find]
39+
where = ["."]
40+
include = ["tind_client*"]
41+
42+
[tool.pytest.ini_options]
43+
testpaths = ["tests"]
44+
45+
[tool.mypy]
46+
python_version = "3.13"
47+
strict = true
48+
49+
[tool.pylint.main]
50+
py-version = "3.13"
51+
52+
[tool.pylint.messages_control]
53+
disable = ["C0114"] # missing-module-docstring — already covered by file-level docstrings

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
Shared pytest fixtures for python-tind-client tests.
3+
"""
4+
5+
import pytest
6+
from tind_client import TINDClient
7+
8+
9+
SAMPLE_MARC_XML = """\
10+
<?xml version="1.0" encoding="UTF-8"?>
11+
<collection xmlns="http://www.loc.gov/MARC21/slim">
12+
<record>
13+
<leader>00000nam a2200000 i 4500</leader>
14+
<controlfield tag="001">12345</controlfield>
15+
<datafield tag="245" ind1="1" ind2="0">
16+
<subfield code="a">Sample Title</subfield>
17+
</datafield>
18+
</record>
19+
</collection>"""
20+
21+
22+
@pytest.fixture
23+
def tind_env(monkeypatch: pytest.MonkeyPatch) -> None:
24+
"""Set required TIND environment variables for a test."""
25+
monkeypatch.setenv("TIND_API_KEY", "test-api-key")
26+
monkeypatch.setenv("TIND_API_URL", "https://tind.example.edu")
27+
monkeypatch.setenv("DEFAULT_STORAGE_DIR", "/tmp")
28+
29+
30+
@pytest.fixture
31+
def sample_marc_xml() -> str:
32+
"""Return a minimal, valid MARC XML string containing one record."""
33+
return SAMPLE_MARC_XML
34+
35+
36+
@pytest.fixture
37+
def client() -> TINDClient:
38+
"""Return a configured TINDClient instance for tests."""
39+
return TINDClient(
40+
api_key="test-api-key",
41+
api_url="https://tind.example.edu",
42+
default_storage_dir="/tmp",
43+
)

0 commit comments

Comments
 (0)