Skip to content

Commit 0527637

Browse files
committed
Refactor code structure for improved readability and maintainability
1 parent ae9adee commit 0527637

File tree

13 files changed

+1148
-215
lines changed

13 files changed

+1148
-215
lines changed

.github/dependabot.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
version: 2
77
updates:
8-
- package-ecosystem: "pip" # See documentation for possible values
8+
- package-ecosystem: "uv" # See documentation for possible values
99
directory: "/" # Location of package manifests
1010
schedule:
11-
interval: "daily"
11+
interval: "weekly"

.github/workflows/lint.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
workflow_dispatch: # Allows manual triggering
9+
10+
jobs:
11+
lint:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
python-version: ["3.10", "3.11", "3.12"]
17+
18+
steps:
19+
- uses: actions/checkout@main
20+
21+
- name: Install the latest version of uv
22+
uses: astral-sh/setup-uv@v5
23+
with:
24+
enable-cache: true
25+
python-version: ${{ matrix.python-version }}
26+
27+
- name: Lint with ruff
28+
run: |
29+
uvx --with cryptography ruff check
30+
31+
- name: Type check with mypy
32+
run: |
33+
uvx --with cryptography mypy httpx_pkcs12

.github/workflows/publish.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Deploy to PyPI
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
deploy:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
13+
- name: Install the latest version of uv
14+
uses: astral-sh/setup-uv@v5
15+
with:
16+
enable-cache: true
17+
18+
- name: Build
19+
run: |
20+
uv build
21+
22+
- name: Publish
23+
run: |
24+
uv publish

.github/workflows/python-publish.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

.github/workflows/test.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
workflow_dispatch: # Allows manual triggering
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
python-version: ["3.10", "3.11", "3.12"]
17+
18+
steps:
19+
- uses: actions/checkout@main
20+
21+
- name: Install the latest version of uv
22+
uses: astral-sh/setup-uv@v5
23+
with:
24+
enable-cache: true
25+
python-version: ${{ matrix.python-version }}
26+
27+
- name: Install dependencies
28+
run: |
29+
uv sync --frozen --extra dev
30+
31+
- name: Test with pytest
32+
run: |
33+
pytest --cov=httpx_pkcs12 --cov-report=xml
34+
35+
- name: Upload coverage to Codecov
36+
uses: codecov/codecov-action@v3
37+
with:
38+
file: ./coverage.xml
39+
fail_ci_if_error: false

.gitignore

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
.vscode
22
.idea
3-
dist
3+
dist
4+
.venv
5+
__pycache__
6+
.pytest_cache
7+
.ruff_cache
8+
*.egg-info
9+
*.egg
10+
*.pdb
11+
*.log
12+
*.coverage
13+
*.cover
14+
*.hypothesis

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12

README.md

Lines changed: 111 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,119 @@
1-
## httpx-pkcs12
1+
# httpx-pkcs12
22

3-
Addon which activates PKCS12 certificates usage with HTTPX client.
3+
Enhanced PKCS12 (PFX/P12) certificate support for the HTTPX Python client. This package allows you to easily use PKCS12 certificates with HTTPX for client certificate authentication.
4+
5+
## Features
6+
7+
- Simple API for loading PKCS12 certificates
8+
- Support for certificate validation
9+
- Extract certificate information
10+
- Works with both file paths and certificate data
11+
- Accepts passwords as strings or bytes
12+
- Proper cleanup of temporary certificate files
13+
- Comprehensive type hints
14+
15+
## Installation
16+
17+
```bash
18+
pip install httpx-pkcs12
19+
```
20+
21+
Or with uv:
22+
23+
```bash
24+
uv add httpx-pkcs12
25+
```
426

527
## Usage
28+
29+
### Basic Usage
30+
631
```python
7-
with open('path/to/your/cert', 'rb') as f:
8-
cert_contents = f.read()
9-
password = 'your-secret-password'
32+
import httpx
33+
from httpx_pkcs12 import create_ssl_context
1034

11-
context = create_ssl_context(cert_contents, password)
35+
# Load certificate from file
36+
context = create_ssl_context(
37+
'path/to/your/cert.p12',
38+
password='your-secret-password'
39+
)
1240

13-
# async version
41+
# With async client
1442
async with httpx.AsyncClient(verify=context) as client:
15-
response = ...
43+
response = await client.get('https://api.example.com')
44+
45+
# With sync client
46+
with httpx.Client(verify=context) as client:
47+
response = client.get('https://api.example.com')
48+
49+
# Or for a one-off request
50+
response = httpx.get('https://api.example.com', verify=context)
51+
```
52+
53+
### Advanced Usage
54+
55+
```python
56+
from httpx_pkcs12 import create_ssl_context, get_certificate_info
57+
58+
# Load certificate directly from bytes
59+
with open('path/to/cert.p12', 'rb') as f:
60+
cert_data = f.read()
61+
62+
# Create context without validation (for expired certs)
63+
context = create_ssl_context(
64+
cert_data,
65+
password='your-password',
66+
validate=False
67+
)
68+
69+
# Get certificate information
70+
not_before, not_after, common_name, alt_names = get_certificate_info(
71+
'path/to/cert.p12',
72+
password='your-password'
73+
)
74+
75+
print(f"Certificate: {common_name}")
76+
print(f"Valid from: {not_before}")
77+
print(f"Valid until: {not_after}")
78+
print(f"Alternative names: {', '.join(alt_names)}")
79+
```
80+
81+
## API Reference
82+
83+
### `create_ssl_context(pkcs12_data, password=None, validate=True)`
84+
85+
Creates an SSL context from PKCS12 data.
86+
87+
- **pkcs12_data**: The PKCS12 certificate data as bytes or a path to the file
88+
- **password**: Password to decrypt the PKCS12 data (string or bytes)
89+
- **validate**: Whether to validate certificate expiration
90+
- **Returns**: An SSLContext object configured with the certificate
91+
92+
### `load_pkcs12_from_file(certificate_path, password=None, validate=True)`
93+
94+
Convenience function to create an SSL context from a PKCS12 certificate file.
95+
96+
- **certificate_path**: Path to the PKCS12 certificate file
97+
- **password**: Password to decrypt the PKCS12 data
98+
- **validate**: Whether to validate certificate expiration
99+
- **Returns**: An SSLContext object configured with the certificate
100+
101+
### `get_certificate_info(pkcs12_data, password=None)`
102+
103+
Extracts and returns information about the certificate.
104+
105+
- **pkcs12_data**: The PKCS12 certificate data or file path
106+
- **password**: Password to decrypt the PKCS12 data
107+
- **Returns**: Tuple with (not_valid_before, not_valid_after, common_name, alt_names)
108+
109+
## Error Handling
110+
111+
The package raises the following exceptions:
112+
113+
- `CertificateError`: For certificate validation issues
114+
- `ValueError`: For invalid input data
115+
- `IOError`: For file operation failures
116+
117+
## License
16118

17-
# or sync version
18-
response = httpx.get(..., verify=context)
19-
```
119+
MIT

0 commit comments

Comments
 (0)