-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathpyproject.toml
More file actions
267 lines (236 loc) · 6.86 KB
/
pyproject.toml
File metadata and controls
267 lines (236 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[project]
name = "trends-earth-api"
version = "1.0.0"
description = "API for managing Scripts, Users, and Executions in Trends.Earth"
authors = [
{ name = "Alex Zvoleff", email = "azvoleff@conservation.org" }
]
readme = "README.md"
requires-python = ">=3.11,<3.14"
dynamic = ["dependencies"]
[tool.poetry]
packages = [{ include = "gefapi" }]
[tool.poetry.dependencies]
python = ">=3.11,<3.14"
flask = ">=3.0.0"
flask-cors = "*"
flask-compress = "*"
flask-jwt-extended = "*"
flask-limiter = ">=3.13"
flask-migrate = "*"
flask-sqlalchemy = "*"
psycopg2 = ">=2.9.11"
celery = "*"
redis = "*"
rollbar = "*"
sqlalchemy = ">=2.0.44"
werkzeug = "*"
psutil = "*"
boto3 = "*"
docker = "*"
sparkpost = "*"
python-slugify = "*"
gunicorn = "*"
gevent = "*"
# Google Groups integration dependencies
google-auth = ">=2.0.0"
google-auth-oauthlib = ">=0.5.0"
google-auth-httplib2 = ">=0.1.0"
google-api-python-client = ">=2.0.0"
# Google Earth Engine API
earthengine-api = ">=1.0.0"
# Cryptography for secure credential storage - updated for security patches
cryptography = ">=46.0.2"
# GeoAlchemy2 for PostGIS spatial database support
geoalchemy2 = ">=0.14.0"
# Shapely for geometry manipulation
shapely = ">=2.0.0"
# TopoJSON for converting TopoJSON to GeoJSON
topojson = ">=1.0"
brotlicffi = "^1.2.0.0"
# Markdown to HTML conversion for news items
markdown = ">=3.0"
[tool.poetry.group.dev.dependencies]
pytest = "*"
pytest-cov = "*"
pytest-timeout = "*"
pytest-html = "*"
ruff = "*"
mypy = "*"
types-redis = "*"
[tool.setuptools]
packages = ["gefapi"]
[tool.ruff]
# Same as Black's default line length
line-length = 88
indent-width = 4
# Assume Python 3.11+ (updated for better compatibility)
target-version = "py311"
# Exclude files/directories from linting
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
"migrations/versions/*.py", # Skip auto-generated migration files
]
[tool.ruff.lint]
# Enable additional rules beyond the default
extend-select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"UP", # pyupgrade
"B", # flake8-bugbear
"SIM", # flake8-simplify
"I", # isort
"N", # pep8-naming
"S", # flake8-bandit (security)
"C4", # flake8-comprehensions
"PIE", # flake8-pie
"T20", # flake8-print (discourage print statements)
"RET", # flake8-return
"TCH", # flake8-type-checking
]
# Disable specific rules that might conflict with Flask/API patterns
ignore = [
"S101", # Use of assert (common in tests)
"S104", # Binding to all interfaces (0.0.0.0 in main.py)
"S105", # Possible hardcoded password (often false positives)
"S106", # Possible hardcoded password (often false positives)
"S107", # Possible hardcoded password (often false positives)
"S602", # subprocess call with shell=True (used in utility scripts)
"T201", # print found (allow for debugging)
"B008", # Do not perform function calls in argument defaults (Flask patterns)
"N818", # Exception name should be named with an Error suffix
"RET504", # Unnecessary variable assignment before `return` statement
"SIM108", # Use ternary operator instead of if-else block (readability preference)
]
[tool.ruff.format]
# Use double quotes for strings (consistent with Black)
quote-style = "double"
# Indent with spaces
indent-style = "space"
# Respect magic trailing commas
skip-magic-trailing-comma = false
# Automatically detect line endings
line-ending = "auto"
[tool.ruff.lint.isort]
# Import sorting configuration (replacing isort)
known-first-party = ["gefapi"]
force-sort-within-sections = true
split-on-trailing-comma = true
# Group imports
section-order = [
"future",
"standard-library",
"third-party",
"first-party",
"local-folder"
]
[tool.ruff.lint.per-file-ignores]
# Allow specific ignores for test files
"tests/*.py" = [
"S101", # Use of assert (expected in tests)
"S105", # Hardcoded password (test fixtures)
"S106", # Hardcoded password (test fixtures)
"S107", # Hardcoded password (test fixtures)
"S110", # try-except-pass (acceptable in tests)
"T201", # print statements (debugging in tests)
"B017", # assertRaises(Exception) (acceptable in tests)
"B007", # Loop variable not used (acceptable in tests)
]
# Models use mixedCase to match external API field names exactly
"gefapi/models/boundary.py" = [
"N815", # mixedCase variable names (matching geoBoundaries API fields)
]
# Allow print statements and specific patterns in debug scripts
"debug_*.py" = [
"T201", # print statements
"S101", # assert statements
"E402", # Module import not at top (setup scripts)
"E501", # Line too long (utility script output)
"SIM118", # Use key in dict (readability in debug)
]
# Utility scripts can have relaxed rules
"*_code.py" = [
"E501", # Line too long
"T201", # print statements
]
# Test utility scripts
"test_*.py" = [
"T201", # print statements
"S101", # assert statements
"E402", # Module import not at top (setup scripts)
"E501", # Line too long (utility script output)
"SIM118", # Use key in dict (readability in debug)
"PIE790", # Unnecessary pass statement
"RET505", # Unnecessary else after return
"F541", # f-string without placeholders
]
# Script files
"generate_*.py" = [
"E501", # Line too long (generated content)
"T201", # print statements
]
# Allow specific patterns in migration files
"migrations/versions/*.py" = [
"E501", # Line too long (auto-generated content)
"F401", # Unused imports (auto-generated)
]
# Config files can have different patterns
"gefapi/config/*.py" = [
"S105", # Hardcoded password (config values)
"S106", # Hardcoded password (config values)
"S108", # Hardcoded temporary file (config values)
]
# Services can have specific patterns
"gefapi/services/*.py" = [
"S311", # Standard pseudo-random (acceptable for non-crypto use)
"S202", # tarfile.extractall (controlled usage)
]
# Allow specific patterns in services/__init__.py for circular dependency handling
"gefapi/services/__init__.py" = [
"E402", # Module import not at top (intentional for setup)
]
[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"
[tool.ruff.lint.mccabe]
# Maximum complexity
max-complexity = 10
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false
ignore_missing_imports = true
strict_optional = false
# Exclude specific paths
exclude = [
"migrations/",
"build/",
"dist/",
]
[[tool.mypy.overrides]]
module = "tests.*"
ignore_errors = true