compytroller 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- compytroller-0.1.0/CHANGELOG.md +79 -0
- compytroller-0.1.0/LICENSE +21 -0
- compytroller-0.1.0/MANIFEST.in +26 -0
- compytroller-0.1.0/PKG-INFO +237 -0
- compytroller-0.1.0/README.md +194 -0
- compytroller-0.1.0/pyproject.toml +155 -0
- compytroller-0.1.0/requirements.txt +13 -0
- compytroller-0.1.0/setup.cfg +4 -0
- compytroller-0.1.0/setup.py +11 -0
- compytroller-0.1.0/src/compytroller/__init__.py +46 -0
- compytroller-0.1.0/src/compytroller/client.py +78 -0
- compytroller-0.1.0/src/compytroller/exceptions.py +79 -0
- compytroller-0.1.0/src/compytroller/fields/__init__.py +55 -0
- compytroller-0.1.0/src/compytroller/fields/_base.py +19 -0
- compytroller-0.1.0/src/compytroller/fields/franchise_tax.py +49 -0
- compytroller-0.1.0/src/compytroller/fields/mixed_beverage.py +35 -0
- compytroller-0.1.0/src/compytroller/fields/sales_tax.py +214 -0
- compytroller-0.1.0/src/compytroller/py.typed +0 -0
- compytroller-0.1.0/src/compytroller/resources/__init__.py +7 -0
- compytroller-0.1.0/src/compytroller/resources/resources.py +282 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/__init__.py +0 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/active_permits.py +199 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/allocation_history.py +180 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/allocation_payment_detail.py +136 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/city_county_comparison_summary.py +126 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/county_spd_mta_allocations.py +126 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/direct_pay.py +135 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/marketplace_provider.py +138 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/marketplace_provider_allocations.py +156 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/permitted_locations.py +204 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/quarterly_sales_history.py +259 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/rates.py +149 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/single_local_allocations.py +210 -0
- compytroller-0.1.0/src/compytroller/resources/sales_tax/single_local_tax_rates.py +138 -0
- compytroller-0.1.0/src/compytroller/responses/__init__.py +41 -0
- compytroller-0.1.0/src/compytroller/responses/franchise_tax.py +91 -0
- compytroller-0.1.0/src/compytroller/responses/mixed_beverage_tax.py +125 -0
- compytroller-0.1.0/src/compytroller/responses/sales_tax.py +853 -0
- compytroller-0.1.0/src/compytroller/socrata.py +55 -0
- compytroller-0.1.0/src/compytroller/utils.py +49 -0
- compytroller-0.1.0/src/compytroller.egg-info/PKG-INFO +237 -0
- compytroller-0.1.0/src/compytroller.egg-info/SOURCES.txt +43 -0
- compytroller-0.1.0/src/compytroller.egg-info/dependency_links.txt +1 -0
- compytroller-0.1.0/src/compytroller.egg-info/requires.txt +17 -0
- compytroller-0.1.0/src/compytroller.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
## [0.1.0] - 2026-04-03
|
|
9
|
+
|
|
10
|
+
Initial public release.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- ComptrollerClient for accessing Texas Comptroller data
|
|
14
|
+
- Sales tax data resources:
|
|
15
|
+
- Active permits
|
|
16
|
+
- Tax rates
|
|
17
|
+
- Allocation history
|
|
18
|
+
- Payment details
|
|
19
|
+
- Single local allocations
|
|
20
|
+
- Marketplace provider data
|
|
21
|
+
- Permitted locations
|
|
22
|
+
- Direct pay taxpayers
|
|
23
|
+
- Quarterly sales history
|
|
24
|
+
- Single local tax rates
|
|
25
|
+
- City/county comparison summaries
|
|
26
|
+
- County/SPD/MTA allocations
|
|
27
|
+
- Franchise tax resources:
|
|
28
|
+
- Active permit holders
|
|
29
|
+
- Mixed beverage tax resources:
|
|
30
|
+
- Gross receipts
|
|
31
|
+
- Allocation history
|
|
32
|
+
- Fluent query builder API with method chaining
|
|
33
|
+
- Type-safe response models using dataclasses
|
|
34
|
+
- Type-safe field enums for all dataset resources (`ActivePermitField`, `SalesTaxRateField`, `FranchiseTaxPermitHolderField`, `MixedBeverageGrossReceiptsField`, etc.)
|
|
35
|
+
- Categorical enums for filter values (`AuthorityType`, `RightToTransactCode`, `SalesTaxRateType`)
|
|
36
|
+
- Union type hints (`str | FieldEnum`) on `sort_by()` and categorical filter methods for IDE discoverability
|
|
37
|
+
- Custom exception hierarchy (HttpError, InvalidRequest)
|
|
38
|
+
- Multiple data source support (Socrata API, web scraping, CSV downloads)
|
|
39
|
+
- Comprehensive documentation
|
|
40
|
+
- Full test coverage (99%)
|
|
41
|
+
- CONTRIBUTING.md with import path conventions
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Release Notes
|
|
46
|
+
|
|
47
|
+
### Version 0.1.0
|
|
48
|
+
|
|
49
|
+
This is the first public release of Compytroller, a comprehensive Python library for accessing Texas Comptroller of Public Accounts data. The library provides:
|
|
50
|
+
|
|
51
|
+
**Key Features:**
|
|
52
|
+
- **16 sales tax data resources** covering rates, permits, allocations, and historical data
|
|
53
|
+
- **Franchise and mixed beverage tax support** with dedicated resource classes
|
|
54
|
+
- **Fluent API** with method chaining for intuitive query construction
|
|
55
|
+
- **Type-safe responses** using Python dataclasses with full type hints
|
|
56
|
+
- **Type-safe field enums** for IDE discoverability on `sort_by()` and categorical filters
|
|
57
|
+
- **Multiple data sources** including Socrata API, web scraping, and CSV downloads
|
|
58
|
+
- **Comprehensive error handling** with custom exception types
|
|
59
|
+
- **99% test coverage** ensuring reliability and stability
|
|
60
|
+
|
|
61
|
+
**Python Support:**
|
|
62
|
+
- Python 3.10+
|
|
63
|
+
- Type hints throughout the codebase
|
|
64
|
+
- Fully tested on Python 3.10-3.12
|
|
65
|
+
|
|
66
|
+
**Dependencies:**
|
|
67
|
+
- httpx (HTTP client)
|
|
68
|
+
- pandas (data processing)
|
|
69
|
+
- selectolax (HTML parsing)
|
|
70
|
+
|
|
71
|
+
For detailed API documentation, see the [API reference](docs/API.md).
|
|
72
|
+
|
|
73
|
+
<<<<<<< Updated upstream
|
|
74
|
+
[0.1.0]: https://github.com/TeamZac/compytroller/releases/tag/v0.1.0
|
|
75
|
+
=======
|
|
76
|
+
[Unreleased]: https://github.com/zactax/compytroller/compare/v0.1.0...HEAD
|
|
77
|
+
[0.1.0]: https://github.com/zactax/compytroller/releases/tag/v0.1.0
|
|
78
|
+
[0.0.1]: https://github.com/zactax/compytroller/releases/tag/v0.0.1
|
|
79
|
+
>>>>>>> Stashed changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ZacTax
|
|
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,0 +1,26 @@
|
|
|
1
|
+
# Include documentation
|
|
2
|
+
include README.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include CHANGELOG.md
|
|
5
|
+
|
|
6
|
+
# Include configuration files
|
|
7
|
+
include pyproject.toml
|
|
8
|
+
include requirements.txt
|
|
9
|
+
|
|
10
|
+
# Include type hints
|
|
11
|
+
recursive-include src/compytroller py.typed *.pyi
|
|
12
|
+
|
|
13
|
+
# Exclude development files
|
|
14
|
+
exclude .gitignore
|
|
15
|
+
exclude .pre-commit-config.yaml
|
|
16
|
+
recursive-exclude tests *
|
|
17
|
+
recursive-exclude docs *
|
|
18
|
+
recursive-exclude htmlcov *
|
|
19
|
+
recursive-exclude .pytest_cache *
|
|
20
|
+
recursive-exclude __pycache__ *
|
|
21
|
+
recursive-exclude * *.py[cod]
|
|
22
|
+
recursive-exclude * *.so
|
|
23
|
+
recursive-exclude * *.dylib
|
|
24
|
+
recursive-exclude * .DS_Store
|
|
25
|
+
exclude .coverage
|
|
26
|
+
exclude example_usage.ipynb
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: compytroller
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python library for accessing Texas Comptroller of Public Accounts tax and financial data
|
|
5
|
+
Author-email: ZacTax <gavin@zactax.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/zactax/compytroller
|
|
8
|
+
Project-URL: Documentation, https://github.com/zactax/compytroller/blob/main/README.md
|
|
9
|
+
Project-URL: Repository, https://github.com/zactax/compytroller
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/zactax/compytroller/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/zactax/compytroller/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: texas,comptroller,tax,sales-tax,franchise-tax,mixed-beverage-tax,socrata,open-data,government-data
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: httpx>=0.24.0
|
|
28
|
+
Requires-Dist: pandas>=1.5.0
|
|
29
|
+
Requires-Dist: selectolax>=0.3.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
34
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
38
|
+
Provides-Extra: docs
|
|
39
|
+
Requires-Dist: mkdocs>=1.4.0; extra == "docs"
|
|
40
|
+
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
|
|
41
|
+
Requires-Dist: mkdocstrings[python]>=0.20.0; extra == "docs"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# Compytroller
|
|
45
|
+
|
|
46
|
+
A Python library for accessing Texas Comptroller of Public Accounts tax and financial data.
|
|
47
|
+
|
|
48
|
+
## Overview
|
|
49
|
+
|
|
50
|
+
Compytroller provides a clean, type-safe interface to Texas Comptroller data from multiple sources:
|
|
51
|
+
- Socrata Open Data API (data.texas.gov)
|
|
52
|
+
- Texas Comptroller web forms
|
|
53
|
+
- CSV data exports
|
|
54
|
+
|
|
55
|
+
The library supports:
|
|
56
|
+
- Sales tax data (rates, permits, allocations, quarterly sales)
|
|
57
|
+
- Franchise tax data (permit holders)
|
|
58
|
+
- Mixed beverage tax data (receipts, allocations)
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
### From PyPI (Recommended)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install compytroller
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### From Source
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git clone https://github.com/zactax/compytroller.git
|
|
72
|
+
cd compytroller
|
|
73
|
+
pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Development Installation
|
|
77
|
+
|
|
78
|
+
To install with development dependencies:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install -e ".[dev]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Quick Start
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from compytroller import ComptrollerClient
|
|
88
|
+
|
|
89
|
+
# Initialize the client with your Socrata app token
|
|
90
|
+
client = ComptrollerClient(app_token="your-app-token-here")
|
|
91
|
+
|
|
92
|
+
# Get sales tax rates for a specific city
|
|
93
|
+
rates = (client.sales_tax()
|
|
94
|
+
.rates()
|
|
95
|
+
.for_city("Austin")
|
|
96
|
+
.get())
|
|
97
|
+
|
|
98
|
+
# Get active permits for a taxpayer
|
|
99
|
+
permits = (client.sales_tax()
|
|
100
|
+
.active_permits()
|
|
101
|
+
.for_taxpayer("12345678")
|
|
102
|
+
.get())
|
|
103
|
+
|
|
104
|
+
# Get franchise tax permit holders
|
|
105
|
+
franchise = (client.franchise_tax()
|
|
106
|
+
.active_permit_holders()
|
|
107
|
+
.for_taxpayer("12345678")
|
|
108
|
+
.get())
|
|
109
|
+
|
|
110
|
+
# Get mixed beverage gross receipts
|
|
111
|
+
receipts = (client.mixed_beverage_tax()
|
|
112
|
+
.gross_receipts()
|
|
113
|
+
.for_year(2024)
|
|
114
|
+
.get())
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Features
|
|
118
|
+
|
|
119
|
+
### Fluent Query Builder API
|
|
120
|
+
All data sources support method chaining for intuitive query construction:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
results = (client.sales_tax()
|
|
124
|
+
.active_permits()
|
|
125
|
+
.for_city("Houston")
|
|
126
|
+
.in_county("Harris")
|
|
127
|
+
.issued_after("2024-01-01")
|
|
128
|
+
.sort_by("outlet_city", desc=True)
|
|
129
|
+
.limit(100)
|
|
130
|
+
.get())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Field Enums
|
|
134
|
+
Optional enums for `sort_by()` fields and categorical filters provide IDE autocompletion and eliminate magic strings:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from compytroller.fields import ActivePermitField, AuthorityType
|
|
138
|
+
|
|
139
|
+
# Sort by field enum instead of a raw string
|
|
140
|
+
permits = (client.sales_tax()
|
|
141
|
+
.active_permits()
|
|
142
|
+
.sort_by(ActivePermitField.OUTLET_CITY)
|
|
143
|
+
.limit(100)
|
|
144
|
+
.get())
|
|
145
|
+
|
|
146
|
+
# Categorical enum for filter values
|
|
147
|
+
allocations = (client.sales_tax()
|
|
148
|
+
.county_spd_mta_allocations()
|
|
149
|
+
.for_type(AuthorityType.COUNTY)
|
|
150
|
+
.get())
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
All enums inherit from `str`, so raw strings continue to work everywhere.
|
|
154
|
+
|
|
155
|
+
### Type-Safe Responses
|
|
156
|
+
All responses are returned as Python dataclasses with full type hints:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from compytroller.responses.sales_tax import ActivePermitData
|
|
160
|
+
|
|
161
|
+
permits: list[ActivePermitData] = client.sales_tax().active_permits().get()
|
|
162
|
+
for permit in permits:
|
|
163
|
+
print(f"{permit.taxpayer_name} - {permit.outlet_city}")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Multiple Data Sources
|
|
167
|
+
- **Socrata API**: Primary source for most datasets
|
|
168
|
+
- **Web Scraping**: Historical allocation data via state forms
|
|
169
|
+
- **CSV Downloads**: Marketplace provider lists
|
|
170
|
+
|
|
171
|
+
### Comprehensive Error Handling
|
|
172
|
+
Custom exceptions for clear error messages:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from compytroller.exceptions import HttpError, InvalidRequest
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
results = client.sales_tax().rates().get()
|
|
179
|
+
except HttpError as e:
|
|
180
|
+
print(f"HTTP Error {e.status_code}: {e.url}")
|
|
181
|
+
except InvalidRequest as e:
|
|
182
|
+
print(f"Invalid request: {e}")
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Available Data Sources
|
|
186
|
+
|
|
187
|
+
### Sales Tax
|
|
188
|
+
- `active_permits()` - Active sales tax permits
|
|
189
|
+
- `rates()` - Sales tax rate changes
|
|
190
|
+
- `allocation_history()` - Historical allocation data
|
|
191
|
+
- `allocation_payment_details()` - Detailed payment breakdowns
|
|
192
|
+
- `single_local_allocations()` - Single local jurisdiction allocations
|
|
193
|
+
- `marketplace_provider_allocations()` - Marketplace provider allocations
|
|
194
|
+
- `marketplace_provider()` - Marketplace provider registry
|
|
195
|
+
- `permitted_locations()` - Permitted location details
|
|
196
|
+
- `direct_pay_taxpayers()` - Direct pay taxpayer list
|
|
197
|
+
- `quarterly_sales_history()` - Quarterly sales by jurisdiction/industry
|
|
198
|
+
- `single_local_tax_rates()` - Single local tax rates
|
|
199
|
+
- `city_county_comparison_summary()` - City/county payment comparisons
|
|
200
|
+
- `county_spd_mta_allocations()` - County/SPD/MTA allocations
|
|
201
|
+
|
|
202
|
+
### Franchise Tax
|
|
203
|
+
- `active_permit_holders()` - Active franchise tax permit holders
|
|
204
|
+
|
|
205
|
+
### Mixed Beverage Tax
|
|
206
|
+
- `gross_receipts()` - Gross receipts by beverage type
|
|
207
|
+
- `history()` - Historical allocation data
|
|
208
|
+
|
|
209
|
+
## Documentation
|
|
210
|
+
|
|
211
|
+
- [API Reference](docs/API.md) - Complete API documentation
|
|
212
|
+
- [Usage Examples](docs/EXAMPLES.md) - Common usage patterns
|
|
213
|
+
- [Data Sources](docs/DATA_SOURCES.md) - Detailed data source reference
|
|
214
|
+
- [Development Guide](docs/DEVELOPMENT.md) - Contributing and development setup
|
|
215
|
+
|
|
216
|
+
## Authentication
|
|
217
|
+
|
|
218
|
+
Most data sources require a Socrata app token. Get yours by creating an account on https://data.texas.gov and then navigating to https://data.texas.gov/profile/edit/developer_settings.
|
|
219
|
+
|
|
220
|
+
## Requirements
|
|
221
|
+
|
|
222
|
+
- Python 3.10+
|
|
223
|
+
- httpx
|
|
224
|
+
- pandas
|
|
225
|
+
- selectolax
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
See LICENSE file for details.
|
|
230
|
+
|
|
231
|
+
## Contributing
|
|
232
|
+
|
|
233
|
+
Contributions are welcome! See [DEVELOPMENT.md](docs/DEVELOPMENT.md) for development setup and guidelines.
|
|
234
|
+
|
|
235
|
+
## Support
|
|
236
|
+
|
|
237
|
+
For issues and feature requests, please use the GitHub issue tracker.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Compytroller
|
|
2
|
+
|
|
3
|
+
A Python library for accessing Texas Comptroller of Public Accounts tax and financial data.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Compytroller provides a clean, type-safe interface to Texas Comptroller data from multiple sources:
|
|
8
|
+
- Socrata Open Data API (data.texas.gov)
|
|
9
|
+
- Texas Comptroller web forms
|
|
10
|
+
- CSV data exports
|
|
11
|
+
|
|
12
|
+
The library supports:
|
|
13
|
+
- Sales tax data (rates, permits, allocations, quarterly sales)
|
|
14
|
+
- Franchise tax data (permit holders)
|
|
15
|
+
- Mixed beverage tax data (receipts, allocations)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### From PyPI (Recommended)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install compytroller
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### From Source
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/zactax/compytroller.git
|
|
29
|
+
cd compytroller
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Development Installation
|
|
34
|
+
|
|
35
|
+
To install with development dependencies:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install -e ".[dev]"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from compytroller import ComptrollerClient
|
|
45
|
+
|
|
46
|
+
# Initialize the client with your Socrata app token
|
|
47
|
+
client = ComptrollerClient(app_token="your-app-token-here")
|
|
48
|
+
|
|
49
|
+
# Get sales tax rates for a specific city
|
|
50
|
+
rates = (client.sales_tax()
|
|
51
|
+
.rates()
|
|
52
|
+
.for_city("Austin")
|
|
53
|
+
.get())
|
|
54
|
+
|
|
55
|
+
# Get active permits for a taxpayer
|
|
56
|
+
permits = (client.sales_tax()
|
|
57
|
+
.active_permits()
|
|
58
|
+
.for_taxpayer("12345678")
|
|
59
|
+
.get())
|
|
60
|
+
|
|
61
|
+
# Get franchise tax permit holders
|
|
62
|
+
franchise = (client.franchise_tax()
|
|
63
|
+
.active_permit_holders()
|
|
64
|
+
.for_taxpayer("12345678")
|
|
65
|
+
.get())
|
|
66
|
+
|
|
67
|
+
# Get mixed beverage gross receipts
|
|
68
|
+
receipts = (client.mixed_beverage_tax()
|
|
69
|
+
.gross_receipts()
|
|
70
|
+
.for_year(2024)
|
|
71
|
+
.get())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Features
|
|
75
|
+
|
|
76
|
+
### Fluent Query Builder API
|
|
77
|
+
All data sources support method chaining for intuitive query construction:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
results = (client.sales_tax()
|
|
81
|
+
.active_permits()
|
|
82
|
+
.for_city("Houston")
|
|
83
|
+
.in_county("Harris")
|
|
84
|
+
.issued_after("2024-01-01")
|
|
85
|
+
.sort_by("outlet_city", desc=True)
|
|
86
|
+
.limit(100)
|
|
87
|
+
.get())
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Field Enums
|
|
91
|
+
Optional enums for `sort_by()` fields and categorical filters provide IDE autocompletion and eliminate magic strings:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from compytroller.fields import ActivePermitField, AuthorityType
|
|
95
|
+
|
|
96
|
+
# Sort by field enum instead of a raw string
|
|
97
|
+
permits = (client.sales_tax()
|
|
98
|
+
.active_permits()
|
|
99
|
+
.sort_by(ActivePermitField.OUTLET_CITY)
|
|
100
|
+
.limit(100)
|
|
101
|
+
.get())
|
|
102
|
+
|
|
103
|
+
# Categorical enum for filter values
|
|
104
|
+
allocations = (client.sales_tax()
|
|
105
|
+
.county_spd_mta_allocations()
|
|
106
|
+
.for_type(AuthorityType.COUNTY)
|
|
107
|
+
.get())
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
All enums inherit from `str`, so raw strings continue to work everywhere.
|
|
111
|
+
|
|
112
|
+
### Type-Safe Responses
|
|
113
|
+
All responses are returned as Python dataclasses with full type hints:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from compytroller.responses.sales_tax import ActivePermitData
|
|
117
|
+
|
|
118
|
+
permits: list[ActivePermitData] = client.sales_tax().active_permits().get()
|
|
119
|
+
for permit in permits:
|
|
120
|
+
print(f"{permit.taxpayer_name} - {permit.outlet_city}")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Multiple Data Sources
|
|
124
|
+
- **Socrata API**: Primary source for most datasets
|
|
125
|
+
- **Web Scraping**: Historical allocation data via state forms
|
|
126
|
+
- **CSV Downloads**: Marketplace provider lists
|
|
127
|
+
|
|
128
|
+
### Comprehensive Error Handling
|
|
129
|
+
Custom exceptions for clear error messages:
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from compytroller.exceptions import HttpError, InvalidRequest
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
results = client.sales_tax().rates().get()
|
|
136
|
+
except HttpError as e:
|
|
137
|
+
print(f"HTTP Error {e.status_code}: {e.url}")
|
|
138
|
+
except InvalidRequest as e:
|
|
139
|
+
print(f"Invalid request: {e}")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Available Data Sources
|
|
143
|
+
|
|
144
|
+
### Sales Tax
|
|
145
|
+
- `active_permits()` - Active sales tax permits
|
|
146
|
+
- `rates()` - Sales tax rate changes
|
|
147
|
+
- `allocation_history()` - Historical allocation data
|
|
148
|
+
- `allocation_payment_details()` - Detailed payment breakdowns
|
|
149
|
+
- `single_local_allocations()` - Single local jurisdiction allocations
|
|
150
|
+
- `marketplace_provider_allocations()` - Marketplace provider allocations
|
|
151
|
+
- `marketplace_provider()` - Marketplace provider registry
|
|
152
|
+
- `permitted_locations()` - Permitted location details
|
|
153
|
+
- `direct_pay_taxpayers()` - Direct pay taxpayer list
|
|
154
|
+
- `quarterly_sales_history()` - Quarterly sales by jurisdiction/industry
|
|
155
|
+
- `single_local_tax_rates()` - Single local tax rates
|
|
156
|
+
- `city_county_comparison_summary()` - City/county payment comparisons
|
|
157
|
+
- `county_spd_mta_allocations()` - County/SPD/MTA allocations
|
|
158
|
+
|
|
159
|
+
### Franchise Tax
|
|
160
|
+
- `active_permit_holders()` - Active franchise tax permit holders
|
|
161
|
+
|
|
162
|
+
### Mixed Beverage Tax
|
|
163
|
+
- `gross_receipts()` - Gross receipts by beverage type
|
|
164
|
+
- `history()` - Historical allocation data
|
|
165
|
+
|
|
166
|
+
## Documentation
|
|
167
|
+
|
|
168
|
+
- [API Reference](docs/API.md) - Complete API documentation
|
|
169
|
+
- [Usage Examples](docs/EXAMPLES.md) - Common usage patterns
|
|
170
|
+
- [Data Sources](docs/DATA_SOURCES.md) - Detailed data source reference
|
|
171
|
+
- [Development Guide](docs/DEVELOPMENT.md) - Contributing and development setup
|
|
172
|
+
|
|
173
|
+
## Authentication
|
|
174
|
+
|
|
175
|
+
Most data sources require a Socrata app token. Get yours by creating an account on https://data.texas.gov and then navigating to https://data.texas.gov/profile/edit/developer_settings.
|
|
176
|
+
|
|
177
|
+
## Requirements
|
|
178
|
+
|
|
179
|
+
- Python 3.10+
|
|
180
|
+
- httpx
|
|
181
|
+
- pandas
|
|
182
|
+
- selectolax
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
See LICENSE file for details.
|
|
187
|
+
|
|
188
|
+
## Contributing
|
|
189
|
+
|
|
190
|
+
Contributions are welcome! See [DEVELOPMENT.md](docs/DEVELOPMENT.md) for development setup and guidelines.
|
|
191
|
+
|
|
192
|
+
## Support
|
|
193
|
+
|
|
194
|
+
For issues and feature requests, please use the GitHub issue tracker.
|