Skip to content

Commit 19dc529

Browse files
author
Sergii Solonyna
committed
Initial commit: Python SDK for Astrology API v3
Typed client library with 16 category clients wrapping 150+ endpoints, built on httpx and pydantic v2. Includes full test suite with 100% branch coverage, CI workflows, and usage examples.
0 parents  commit 19dc529

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+9761
-0
lines changed

.github/workflows/ci.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
lint-and-type-check:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.10"
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install ruff mypy
26+
27+
- name: Lint with ruff
28+
run: ruff check src/ tests/
29+
30+
- name: Check formatting with ruff
31+
run: ruff format --check src/ tests/
32+
33+
- name: Type check with mypy
34+
run: |
35+
pip install httpx pydantic
36+
mypy src/astroapi
37+
38+
test:
39+
runs-on: ubuntu-latest
40+
strategy:
41+
matrix:
42+
python-version: ["3.10", "3.11", "3.12"]
43+
44+
steps:
45+
- uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0
48+
49+
- name: Set up Python ${{ matrix.python-version }}
50+
uses: actions/setup-python@v5
51+
with:
52+
python-version: ${{ matrix.python-version }}
53+
54+
- name: Install dependencies
55+
run: |
56+
python -m pip install --upgrade pip
57+
pip install -e ".[dev]"
58+
59+
- name: Run tests with coverage
60+
run: pytest --cov=src/astroapi --cov-report=xml --cov-report=term
61+
62+
- name: Upload coverage to Codecov
63+
if: matrix.python-version == '3.10'
64+
uses: codecov/codecov-action@v4
65+
with:
66+
file: ./coverage.xml
67+
fail_ci_if_error: true
68+
69+
build:
70+
runs-on: ubuntu-latest
71+
needs: [lint-and-type-check, test]
72+
steps:
73+
- uses: actions/checkout@v4
74+
with:
75+
fetch-depth: 0
76+
77+
- name: Set up Python
78+
uses: actions/setup-python@v5
79+
with:
80+
python-version: "3.10"
81+
82+
- name: Install build dependencies
83+
run: |
84+
python -m pip install --upgrade pip
85+
pip install build
86+
87+
- name: Build package
88+
run: python -m build
89+
90+
- name: Upload artifacts
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: dist
94+
path: dist/

.github/workflows/release.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
12+
jobs:
13+
build-and-publish:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.10"
24+
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install -e ".[dev]"
29+
pip install build
30+
31+
- name: Run full CI pipeline
32+
run: |
33+
ruff check src/ tests/
34+
ruff format --check src/ tests/
35+
mypy src/astroapi
36+
pytest --cov=src/astroapi --cov-fail-under=100
37+
38+
- name: Build package
39+
run: python -m build
40+
41+
- name: Publish to PyPI
42+
uses: pypa/gh-action-pypi-publish@release/v1
43+
44+
- name: Create GitHub Release
45+
uses: softprops/action-gh-release@v1
46+
with:
47+
files: dist/*
48+
generate_release_notes: true

.gitignore

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
share/python-wheels/
20+
*.egg-info/
21+
.installed.cfg
22+
*.egg
23+
MANIFEST
24+
25+
# Virtual environments
26+
venv/
27+
env/
28+
ENV/
29+
env.bak/
30+
venv.bak/
31+
.venv/
32+
33+
# Testing
34+
.pytest_cache/
35+
.coverage
36+
.coverage.*
37+
htmlcov/
38+
.tox/
39+
.nox/
40+
coverage.xml
41+
*.cover
42+
*.log
43+
44+
# Type checking
45+
.mypy_cache/
46+
.dmypy.json
47+
dmypy.json
48+
.pytype/
49+
50+
# IDEs
51+
.vscode/
52+
.idea/
53+
*.swp
54+
*.swo
55+
*~
56+
.DS_Store
57+
58+
# Documentation
59+
docs/_build/
60+
site/
61+
62+
# Environment
63+
.env
64+
.env.local
65+
.env.*.local
66+
67+
# Auto-generated version file (hatch-vcs)
68+
src/astroapi/_version.py
69+
70+
# Distribution
71+
*.whl
72+
*.tar.gz

CHANGELOG.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.0.0] - 2026-02-16
9+
10+
### Added
11+
- Initial release of astroapi-python
12+
- Full Astrology API v3 client implementation
13+
- 16 category clients with 150+ endpoint methods
14+
- Complete type safety with Pydantic models
15+
- Automatic retry logic with exponential backoff
16+
- Comprehensive validation for all request parameters
17+
- Context manager support for resource cleanup
18+
- 100% test coverage
19+
- GitHub Actions CI/CD pipeline
20+
- Comprehensive documentation and examples
21+
22+
### Category Clients
23+
- **DataClient**: Planetary positions, houses, aspects, midpoints, Arabic parts
24+
- **ChartsClient**: Natal, synastry, composite, transit, return, progression, direction charts
25+
- **HoroscopeClient**: Personalized and sun sign horoscopes (daily, weekly, monthly, yearly)
26+
- **AnalysisClient**: Natal, synastry, composite, transit reports and compatibility analysis
27+
- **GlossaryClient**: Reference data for cities, planets, signs, aspects, keywords
28+
- **ChineseClient**: BaZi (Four Pillars), Chinese zodiac, elements
29+
- **NumerologyClient**: Life path, expression, soul urge, personality numbers
30+
- **TarotClient**: Card draws and readings
31+
- **EclipsesClient**: Solar and lunar eclipse calculations
32+
- **LunarClient**: Moon phases, void of course, lunar mansions
33+
- **AstrocartographyClient**: Planetary lines and relocated charts
34+
- **TraditionalClient**: Dignities, receptions, almutens
35+
- **FixedStarsClient**: Fixed star positions and conjunctions
36+
- **InsightsClient**: Relationship, pet, wellness, financial, business insights
37+
- **SvgClient**: SVG chart rendering
38+
- **EnhancedClient**: Advanced calculations, patterns, dominants
39+
40+
### Features
41+
- Type-safe request and response models
42+
- Flexible configuration with environment variable support
43+
- Custom retry policies
44+
- Debug logging
45+
- HTTP client abstraction for testability
46+
- Comprehensive error handling with AstrologyError
47+
- Input validation before API calls
48+
- Response envelope unwrapping
49+
50+
[1.0.0]: https://github.com/procoders/astroapi-python/releases/tag/v1.0.0

CLAUDE.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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
6+
7+
Python client library (SDK) for the Astrology API v3. Provides typed wrappers around 150+ endpoints organized into 16 category clients. Built on `httpx` (sync HTTP) and `pydantic` v2 (request/response models). Requires Python 3.10+.
8+
9+
## Commands
10+
11+
```bash
12+
# Install (editable + dev deps)
13+
pip install -e ".[dev]"
14+
15+
# Run all tests (coverage is enforced at 100% branch via addopts)
16+
pytest
17+
18+
# Run a single test file
19+
pytest tests/unit/test_client.py
20+
21+
# Run a single test
22+
pytest tests/unit/test_client.py::TestAstrologyClient::test_client_creation_with_config
23+
24+
# Lint and format
25+
ruff check src/ tests/
26+
ruff format src/ tests/
27+
28+
# Type check (strict mode)
29+
mypy src/astroapi
30+
31+
# Pre-commit hooks
32+
pre-commit install
33+
```
34+
35+
## Architecture
36+
37+
**Entry point**: `AstrologyClient` ([client.py](src/astroapi/client.py)) — creates an `HttpClient` and instantiates all 16 category clients. Supports context manager protocol for cleanup.
38+
39+
**HTTP layer**: `HttpClient` ([utils/http_client.py](src/astroapi/utils/http_client.py)) wraps `httpx.Client` with Bearer auth, configurable retry logic (`RetryConfig`), and response envelope unwrapping (`data` or `result` keys). Categories depend on the `HttpHelper` ABC ([utils/http.py](src/astroapi/utils/http.py)), not `HttpClient` directly.
40+
41+
**Categories** ([categories/](src/astroapi/categories/)): 16 clients inheriting `BaseCategoryClient`. Each declares an `API_PREFIX` and builds URLs via `_build_url(*segments)`. `InsightsClient` is unique — it composes 5 sub-clients (relationship, pet, wellness, financial, business) as instance attributes.
42+
43+
**Types** ([types/](src/astroapi/types/)):
44+
- `config.py``AstrologyClientConfig`, `RetryConfig` dataclasses, type aliases, validation constants
45+
- `requests.py` — Pydantic request models with `ConfigDict(extra="forbid")`, serialized via `model_dump(exclude_none=True)`
46+
- `responses.py` — Pydantic response models with `extra="allow"` (tolerant of API additions)
47+
48+
**Validation**: Every category method validates inputs via functions in [utils/validators.py](src/astroapi/utils/validators.py) before making HTTP calls. All errors surface as `AstrologyError` ([errors.py](src/astroapi/errors.py)).
49+
50+
**Config**: API key resolved from `AstrologyClientConfig.api_key` or env var `ASTROLOGY_API_KEY`. Also reads `ASTROLOGY_API_BASE_URL` and `ASTROLOGY_DEBUG`.
51+
52+
## Versioning
53+
54+
Version is derived automatically from git tags via `hatch-vcs` (configured in `pyproject.toml`). There is no hardcoded version anywhere — `src/astroapi/_version.py` is generated at build/install time.
55+
56+
- Tag `v1.2.3` → package version `1.2.3`
57+
- Between tags → dev version like `1.2.4.dev3+g<hash>`
58+
- `_version.py` is in `.gitignore` — never commit it
59+
60+
**Release flow**: create and push a tag, [release.yml](.github/workflows/release.yml) handles the rest:
61+
```bash
62+
git tag v1.2.0
63+
git push origin v1.2.0
64+
```
65+
66+
CI workflows use `fetch-depth: 0` in checkout so git tags are always available for version resolution.
67+
68+
## Conventions
69+
70+
- Every source file uses `from __future__ import annotations`
71+
- Line length: 100 chars
72+
- Double quotes, space indent
73+
- All request models forbid extra fields; all response models allow them
74+
- Tests mock HTTP via `pytest-httpx` (`httpx_mock` fixture). Shared fixtures in [tests/conftest.py](tests/conftest.py), mock payloads in [tests/mocks/responses.py](tests/mocks/responses.py)
75+
- Coverage excludes `__init__.py` re-export files and `TYPE_CHECKING` blocks

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 Procoders
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.

0 commit comments

Comments
 (0)