Skip to content

Commit 3cacd2d

Browse files
authored
Merge pull request #9 from jrherskovic-mda/claude/fix-github-actions-011CUoMpdaBxuXgMa7nzp3YG
Claude/fix GitHub actions and update dependencies
2 parents da2cfa3 + 0e5da28 commit 3cacd2d

File tree

14 files changed

+865
-427
lines changed

14 files changed

+865
-427
lines changed

.github/workflows/greetings.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ jobs:
99
issues: write
1010
pull-requests: write
1111
steps:
12-
- uses: actions/first-interaction@v1
12+
- uses: actions/first-interaction@v1.3.0
1313
with:
1414
repo-token: ${{ secrets.GITHUB_TOKEN }}
15-
issue-message: "Thanks for contributing! Please follow the guidelines.' first issue"
15+
issue-message: "Thanks for contributing! Please follow the guidelines."
1616
pr-message: "Thanks for contributing! Please follow the guidelines."

.github/workflows/tests.yml

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,24 @@ jobs:
2121
python-version: ["3.9", "3.10", "3.11"]
2222

2323
steps:
24-
- uses: actions/checkout@v3
24+
- uses: actions/checkout@v4
2525
- name: Set up Python ${{ matrix.python-version }}
26-
uses: actions/setup-python@v3
26+
uses: actions/setup-python@v5
2727
with:
2828
python-version: ${{ matrix.python-version }}
29-
- name: Install dependencies
29+
- name: Install poetry
3030
run: |
31-
python -m pip install --upgrade pip
32-
pip install -r requirements.txt
33-
python -m pip install flake8 pytest
31+
curl -sSL https://install.python-poetry.org | python3 -
32+
echo "$HOME/.local/bin" >> $GITHUB_PATH
3433
35-
# - name: Install poetry
36-
# run: |
37-
# curl -sSL https://install.python-poetry.org | python -
38-
39-
# - name: Install project dependencies
40-
# run: |
41-
# poetry install
34+
- name: Install project dependencies
35+
run: |
36+
poetry install --with dev
4237
- name: Lint with flake8
4338
run: |
4439
# stop the build if there are Python syntax errors or undefined names
45-
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
40+
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
4641
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
47-
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
48-
- name: Run Tests
49-
run: python -m unittest tests/test_orcid.py
42+
poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
43+
- name: Run Tests
44+
run: poetry run python -m unittest tests/test_orcid.py

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

33
All notable changes to this project will be documented in this file.
4+
## [1.2.1] - 11/03/2025
5+
6+
### Changed
7+
- Dependencies updated; xmltojson removed in favor of xmltodict for broader compatibility. Now using an up-to-date certifi.
8+
- Moved dependency management to Poetry to better suit our needs.
9+
- Refactored using Claude to standardize linting, comments, add logging, and type hints.
410

511
## [1.2.0] - 05/17/2024
612

CLAUDE.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
PyOrcid is a Python library and API client for interacting with the ORCID API. ORCID (Open Researcher and Contributor ID) provides unique identifiers to researchers. This library enables developers to access and manage ORCID profile data, including publications, employment, education, and other research activities.
8+
9+
## Development Commands
10+
11+
### Package Management
12+
The project uses Poetry for dependency management:
13+
```bash
14+
# Install dependencies
15+
poetry install
16+
17+
# Add a dependency
18+
poetry add <package-name>
19+
20+
# Add a dev dependency
21+
poetry add --group dev <package-name>
22+
```
23+
24+
### Testing
25+
```bash
26+
# Run all tests
27+
python -m unittest tests/test_orcid.py
28+
29+
# Run tests with pytest (if installed)
30+
pytest tests/
31+
32+
# Run a single test
33+
python -m unittest tests.test_orcid.TestOrcid.test_access_token_valid
34+
```
35+
36+
### Linting
37+
```bash
38+
# Check for Python syntax errors and undefined names
39+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
40+
41+
# Full linting with warnings
42+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
43+
```
44+
45+
### Building
46+
```bash
47+
# Build the package using Poetry
48+
poetry build
49+
```
50+
51+
## Architecture
52+
53+
### Core Classes
54+
55+
The library is organized into four main classes in `src/pyorcid/`:
56+
57+
1. **`Orcid` (orcid.py)** - The main API wrapper class
58+
- Handles both Public and Member API access
59+
- Requires an ORCID ID and access token
60+
- Supports sandbox mode for testing
61+
- Methods map to ORCID API v3.0 endpoints (e.g., `/works`, `/person`, `/educations`)
62+
- Returns tuples: `(processed_data, raw_api_response)` for most section methods
63+
- Key methods: `record()`, `works()`, `educations()`, `employments()`, `fundings()`, `person()`
64+
- Helper: `generate_markdown_file()` creates formatted reports
65+
66+
2. **`OrcidAuthentication` (orcid_authentication.py)** - Handles OAuth 2.0 authentication
67+
- `get_public_access_token()` - For reading public data (/read-public scope), no user auth required
68+
- `get_private_access_token()` - For Member API or limited-access data, requires user authorization
69+
- Supports both production and sandbox environments
70+
- Manages redirect URIs and authorization codes
71+
72+
3. **`OrcidScrapper` (orcid_scrapper.py)** - Alternative data access via web scraping
73+
- Inherits from `Orcid` class
74+
- Scrapes public ORCID profiles without authentication
75+
- Converts XML responses to JSON and reformats to match API structure
76+
- Only works with public profiles
77+
- Overrides `__read_section()` to use web scraping instead of API calls
78+
79+
4. **`OrcidSearch` (orcid_search.py)** - Wrapper for ORCID Search API
80+
- `search(query, start, rows, search_mode, columns)` - Searches ORCID registry
81+
- Supports three search modes: "expanded-search", "search", "csv-search"
82+
- Handles query encoding and pagination
83+
- Requires access token for authentication
84+
85+
### API Modes
86+
87+
The library supports two ORCID API modes:
88+
- **Public API** (`state="public"`): Read-only access to public profiles, uses `pub.orcid.org`
89+
- **Member API** (`state="member"`): Read/write access for ORCID members, uses `api.orcid.org`
90+
91+
Both modes support sandbox environments for testing (`sandbox=True` parameter).
92+
93+
### Data Processing Pipeline
94+
95+
1. **Token validation**: All classes except `OrcidScrapper` validate tokens on initialization
96+
2. **API requests**: Made via `__read_section(section)` private method
97+
3. **Data extraction**: Helper methods like `__get_value_from_keys()` navigate nested JSON safely
98+
4. **Formatting**: Methods like `get_formatted_date()` convert API data to user-friendly formats
99+
5. **Unicode handling**: `__deunicode_string()` removes non-ASCII characters for compatibility
100+
101+
### Testing Approach
102+
103+
Tests use mocked HTTP requests (unittest.mock) to avoid live API calls. The main `Orcid` class includes special `__test_*` methods that pull credentials from environment variables (`ORCID_ACCESS_TOKEN`) for CI/CD integration with GitHub Actions.
104+
105+
## Important Patterns
106+
107+
- **Private methods**: Methods prefixed with `__` (double underscore) are internal-only
108+
- **Error handling**: Token validation occurs in `__init__()` for early failure detection
109+
- **Return tuples**: Section methods typically return `(simplified_data, raw_data)` to provide both convenience and full access
110+
- **Safe navigation**: `__get_value_from_keys()` prevents KeyError on missing nested keys
111+
- **Inheritance**: `OrcidScrapper` extends `Orcid` to reuse data processing logic while changing the data source
112+
113+
## Dependencies
114+
115+
Core dependencies:
116+
- `requests` - HTTP client for API calls
117+
- `python-dotenv` - Environment variable management
118+
- `urllib3` - URL handling and encoding
119+
- `xmltojson` - XML to JSON conversion (for scraping)
120+
121+
Development dependencies:
122+
- `pytest` - Testing framework
123+
- `flake8` - Linting (used in CI/CD)

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ orcid.__dir__()
118118
```python
119119
# Get the information of user's works from their ORCID profile
120120
works_data = orcid.works()[0]
121-
for key, value in works_data.items():
122-
print(key, value)
121+
for work in works_data:
122+
for key, value in work.items():
123+
print(key, value)
123124
```
124125
```python
125126

0 commit comments

Comments
 (0)