Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to the pyUSPTO package will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.2.2]

### Added

Expand Down
10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Operating System :: OS Independent",
"Development Status :: 2 - Pre-Alpha",
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries",
"Topic :: Scientific/Engineering :: Information Analysis",
Expand All @@ -34,12 +34,20 @@ dynamic = ["version"]
[project.urls]
GitHub = "https://github.com/DunlapCoddingPC/pyUSPTO"
issues = "https://github.com/DunlapCoddingPC/pyUSPTO/issues"
Documentation = "https://pyuspto.readthedocs.io/en/latest/"


[tool.setuptools_scm]

[tool.setuptools]
zip-safe = true

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
pyUSPTO = ["py.typed"]

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
Expand Down
12 changes: 8 additions & 4 deletions src/pyUSPTO/clients/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ def __init__(
# Handle config if provided
if config:
self.config = config
self.api_key = api_key or config.api_key
self._api_key = api_key or config.api_key
else:
# Backward compatibility: create minimal config
self.config = USPTOConfig(api_key=api_key)
self.api_key = api_key
self._api_key = api_key

self.base_url = base_url.rstrip("/")

Expand All @@ -91,9 +91,9 @@ def _create_session(self) -> requests.Session:
session = requests.Session()

# Set API key and default headers
if self.api_key:
if self._api_key:
session.headers.update(
{"X-API-KEY": self.api_key, "content-type": "application/json"}
{"X-API-KEY": self._api_key, "content-type": "application/json"}
)

# Apply custom headers from HTTP config
Expand Down Expand Up @@ -444,3 +444,7 @@ def _download_file(self, url: str, file_path: str, overwrite: bool = False) -> s
return self._save_response_to_file(
response=response, file_path=file_path, overwrite=overwrite
)

@property
def api_key(self) -> str:
return "********"
Empty file added src/pyUSPTO/py.typed
Empty file.
9 changes: 5 additions & 4 deletions tests/clients/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,15 @@ def test_init(self) -> None:
client: BaseUSPTOClient[Any] = BaseUSPTOClient(
api_key="test_key", base_url="https://api.test.com"
)
assert client.api_key == "test_key"
assert client._api_key == "test_key"
assert client.api_key == "********" # API key is masked
assert client.base_url == "https://api.test.com"
assert "X-API-KEY" in client.session.headers
assert client.session.headers["X-API-KEY"] == "test_key"

# Test without API key
client = BaseUSPTOClient(base_url="https://api.test.com")
assert client.api_key is None
assert client._api_key is None
assert client.base_url == "https://api.test.com"
assert "X-API-KEY" not in client.session.headers

Expand Down Expand Up @@ -651,7 +652,7 @@ def test_base_client_with_config_object(self) -> None:
)

# API key should come from config
assert client.api_key == "config_key"
assert client._api_key == "config_key"
assert client.config is config

def test_base_client_api_key_priority(self) -> None:
Expand All @@ -664,7 +665,7 @@ def test_base_client_api_key_priority(self) -> None:
)

# Explicit api_key should take precedence
assert client.api_key == "explicit_key"
assert client._api_key == "explicit_key"


class TestContentDispositionParsing:
Expand Down
6 changes: 3 additions & 3 deletions tests/clients/test_bulk_data_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class TestBulkDataClientInit:
def test_init_with_api_key(self) -> None:
"""Test initialization with direct API key."""
client = BulkDataClient(api_key="test_key")
assert client.api_key == "test_key"
assert client._api_key == "test_key"
assert client.base_url == "https://api.uspto.gov"
assert client.config is not None
assert client.config.api_key == "test_key"
Expand All @@ -230,7 +230,7 @@ def test_init_with_config(self) -> None:
bulk_data_base_url="https://config.api.test.com",
)
client = BulkDataClient(config=config)
assert client.api_key == "config_key"
assert client._api_key == "config_key"
assert client.base_url == "https://config.api.test.com"
assert client.config is config

Expand All @@ -241,7 +241,7 @@ def test_init_with_api_key_and_config(self) -> None:
bulk_data_base_url="https://config.api.test.com",
)
client = BulkDataClient(api_key="direct_key", config=config)
assert client.api_key == "direct_key"
assert client._api_key == "direct_key"
assert client.base_url == "https://config.api.test.com"


Expand Down
8 changes: 4 additions & 4 deletions tests/clients/test_patent_data_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ class TestPatentDataClientInit:
def test_init_with_api_key(self, api_key_fixture: str) -> None:
"""Test initialization with API key."""
client = PatentDataClient(api_key=api_key_fixture)
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
assert client.base_url == "https://api.uspto.gov"

def test_init_with_custom_base_url(self, api_key_fixture: str) -> None:
"""Test initialization with custom base URL."""
custom_url = "https://custom.api.test.com"
client = PatentDataClient(api_key=api_key_fixture, base_url=custom_url)
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
assert client.base_url == custom_url

def test_init_with_config(self) -> None:
Expand All @@ -265,7 +265,7 @@ def test_init_with_config(self) -> None:
config_url = "https://config.api.test.com"
config = USPTOConfig(api_key=config_key, patent_data_base_url=config_url)
client = PatentDataClient(config=config)
assert client.api_key == config_key
assert client._api_key == config_key
assert client.base_url == config_url
assert client.config is config

Expand All @@ -275,7 +275,7 @@ def test_init_with_api_key_and_config(self, api_key_fixture: str) -> None:
api_key="config_key", patent_data_base_url="https://config.api.test.com"
)
client = PatentDataClient(api_key=api_key_fixture, config=config)
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
assert client.base_url == "https://config.api.test.com"

custom_url = "https://custom.url.com"
Expand Down
8 changes: 4 additions & 4 deletions tests/clients/test_petition_decision_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class TestFinalPetitionDecisionsClientInit:
def test_init_with_api_key(self, api_key_fixture: str) -> None:
"""Test initialization with API key."""
client = FinalPetitionDecisionsClient(api_key=api_key_fixture)
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
assert client.base_url == "https://api.uspto.gov"

def test_init_with_custom_base_url(self, api_key_fixture: str) -> None:
Expand All @@ -108,7 +108,7 @@ def test_init_with_custom_base_url(self, api_key_fixture: str) -> None:
client = FinalPetitionDecisionsClient(
api_key=api_key_fixture, base_url=custom_url
)
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
assert client.base_url == custom_url

def test_init_with_config(self) -> None:
Expand All @@ -117,7 +117,7 @@ def test_init_with_config(self) -> None:
config_url = "https://config.api.test.com"
config = USPTOConfig(api_key=config_key, petition_decisions_base_url=config_url)
client = FinalPetitionDecisionsClient(config=config)
assert client.api_key == config_key
assert client._api_key == config_key
assert client.base_url == config_url
assert client.config is config

Expand All @@ -129,7 +129,7 @@ def test_init_with_api_key_and_config(self, api_key_fixture: str) -> None:
)
client = FinalPetitionDecisionsClient(api_key=api_key_fixture, config=config)
# API key parameter takes precedence
assert client.api_key == api_key_fixture
assert client._api_key == api_key_fixture
# But base_url comes from config
assert client.base_url == "https://config.api.test.com"

Expand Down
Loading