Skip to content

Commit e2ac5cc

Browse files
committed
Merge branch 'feature/lint-format' into develop
2 parents d43ab0e + faa138e commit e2ac5cc

File tree

74 files changed

+5255
-4448
lines changed

Some content is hidden

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

74 files changed

+5255
-4448
lines changed

app/api/v1/admin.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
from app.api.v1.utils import create_response, sanitize_for_json
99
from app.services.admin_service import (
1010
AdminService,
11-
CacheManagementService,
12-
ReindexingService,
13-
ResourceProcessingService,
1411
CacheManagementError,
12+
CacheManagementService,
1513
ReindexingError,
14+
ReindexingService,
15+
ResourceNotFoundError,
1616
ResourceProcessingError,
17-
ResourceNotFoundError
17+
ResourceProcessingService,
1818
)
1919

2020
logger = logging.getLogger(__name__)
@@ -31,12 +31,16 @@ def get_admin_service() -> AdminService:
3131
return AdminService(cache_management_service, reindexing_service, resource_processing_service)
3232

3333

34+
# Module-level singleton for dependency injection
35+
_admin_service_dependency = Depends(get_admin_service)
36+
37+
3438
@router.post("/cache/clear")
3539
async def clear_cache(
3640
cache_type: Optional[str] = Query(
3741
None, description="Type of cache to clear (search, item, suggest, all)"
3842
),
39-
service: AdminService = Depends(get_admin_service),
43+
service: AdminService = _admin_service_dependency,
4044
):
4145
"""Clear specified cache or all cache if not specified."""
4246
try:
@@ -53,26 +57,30 @@ async def clear_cache(
5357
@router.post("/reindex")
5458
async def reindex(
5559
callback: Optional[str] = Query(None, description="JSONP callback name"),
56-
service: AdminService = Depends(get_admin_service),
60+
service: AdminService = _admin_service_dependency,
5761
):
5862
"""Trigger reindexing of all items in Elasticsearch."""
5963
try:
6064
result = await service.reindex_resources()
6165
return create_response(result, callback)
6266
except ReindexingError as e:
6367
logger.error(f"Reindexing error: {str(e)}")
64-
raise HTTPException(status_code=500, detail={"message": "Reindexing failed", "error": str(e)}) from e
68+
raise HTTPException(
69+
status_code=500, detail={"message": "Reindexing failed", "error": str(e)}
70+
) from e
6571
except Exception as e:
6672
logger.error(f"Unexpected error during reindexing: {str(e)}")
67-
raise HTTPException(status_code=500, detail={"message": "Reindexing failed", "error": str(e)}) from e
73+
raise HTTPException(
74+
status_code=500, detail={"message": "Reindexing failed", "error": str(e)}
75+
) from e
6876

6977

7078
@router.post("/resources/{id}/summarize")
7179
async def summarize_resource(
7280
id: str,
7381
background_tasks: BackgroundTasks,
7482
callback: Optional[str] = Query(None, description="JSONP callback name"),
75-
service: AdminService = Depends(get_admin_service),
83+
service: AdminService = _admin_service_dependency,
7684
):
7785
"""
7886
Trigger the generation of a summary for a resource.
@@ -84,7 +92,7 @@ async def summarize_resource(
8492
"""
8593
try:
8694
result = await service.summarize_resource(id)
87-
95+
8896
# Sanitize the response data before returning
8997
sanitized_response = sanitize_for_json(result)
9098
return create_response(sanitized_response, callback)
@@ -104,7 +112,7 @@ async def identify_geo_entities(
104112
id: str,
105113
background_tasks: BackgroundTasks,
106114
callback: Optional[str] = Query(None, description="JSONP callback name"),
107-
service: AdminService = Depends(get_admin_service),
115+
service: AdminService = _admin_service_dependency,
108116
):
109117
"""
110118
Trigger the identification of geographic entities in a resource.
@@ -123,5 +131,8 @@ async def identify_geo_entities(
123131
logger.error(f"Resource processing error: {str(e)}")
124132
raise HTTPException(status_code=500, detail=str(e)) from e
125133
except Exception as e:
126-
logger.error(f"Unexpected error triggering geographic entity identification for resource {id}: {str(e)}")
127-
raise HTTPException(status_code=500, detail=str(e)) from e
134+
logger.error(
135+
f"Unexpected error triggering geographic entity identification "
136+
f"for resource {id}: {str(e)}"
137+
)
138+
raise HTTPException(status_code=500, detail=str(e)) from e

app/api/v1/endpoint_modules/admin.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
from app.api.v1.utils import create_response, sanitize_for_json
99
from app.services.admin_service import (
1010
AdminService,
11-
CacheManagementService,
12-
ReindexingService,
13-
ResourceProcessingService,
1411
CacheManagementError,
12+
CacheManagementService,
1513
ReindexingError,
14+
ReindexingService,
15+
ResourceNotFoundError,
1616
ResourceProcessingError,
17-
ResourceNotFoundError
17+
ResourceProcessingService,
1818
)
1919

2020
logger = logging.getLogger(__name__)
@@ -31,12 +31,16 @@ def get_admin_service() -> AdminService:
3131
return AdminService(cache_management_service, reindexing_service, resource_processing_service)
3232

3333

34+
# Module-level singleton for dependency injection
35+
_admin_service_dependency = Depends(get_admin_service)
36+
37+
3438
@router.post("/cache/clear")
3539
async def clear_cache(
3640
cache_type: Optional[str] = Query(
3741
None, description="Type of cache to clear (search, item, suggest, all)"
3842
),
39-
service: AdminService = Depends(get_admin_service),
43+
service: AdminService = _admin_service_dependency,
4044
):
4145
"""Clear specified cache or all cache if not specified."""
4246
try:
@@ -53,26 +57,30 @@ async def clear_cache(
5357
@router.post("/reindex")
5458
async def reindex(
5559
callback: Optional[str] = Query(None, description="JSONP callback name"),
56-
service: AdminService = Depends(get_admin_service),
60+
service: AdminService = _admin_service_dependency,
5761
):
5862
"""Trigger reindexing of all items in Elasticsearch."""
5963
try:
6064
result = await service.reindex_resources()
6165
return create_response(result, callback)
6266
except ReindexingError as e:
6367
logger.error(f"Reindexing error: {str(e)}")
64-
raise HTTPException(status_code=500, detail={"message": "Reindexing failed", "error": str(e)}) from e
68+
raise HTTPException(
69+
status_code=500, detail={"message": "Reindexing failed", "error": str(e)}
70+
) from e
6571
except Exception as e:
6672
logger.error(f"Unexpected error during reindexing: {str(e)}")
67-
raise HTTPException(status_code=500, detail={"message": "Reindexing failed", "error": str(e)}) from e
73+
raise HTTPException(
74+
status_code=500, detail={"message": "Reindexing failed", "error": str(e)}
75+
) from e
6876

6977

7078
@router.post("/resources/{id}/summarize")
7179
async def summarize_resource(
7280
id: str,
7381
background_tasks: BackgroundTasks,
7482
callback: Optional[str] = Query(None, description="JSONP callback name"),
75-
service: AdminService = Depends(get_admin_service),
83+
service: AdminService = _admin_service_dependency,
7684
):
7785
"""
7886
Trigger the generation of a summary for a resource.
@@ -84,7 +92,7 @@ async def summarize_resource(
8492
"""
8593
try:
8694
result = await service.summarize_resource(id)
87-
95+
8896
# Sanitize the response data before returning
8997
sanitized_response = sanitize_for_json(result)
9098
return create_response(sanitized_response, callback)
@@ -104,7 +112,7 @@ async def identify_geo_entities(
104112
id: str,
105113
background_tasks: BackgroundTasks,
106114
callback: Optional[str] = Query(None, description="JSONP callback name"),
107-
service: AdminService = Depends(get_admin_service),
115+
service: AdminService = _admin_service_dependency,
108116
):
109117
"""
110118
Trigger the identification of geographic entities in a resource.
@@ -123,5 +131,8 @@ async def identify_geo_entities(
123131
logger.error(f"Resource processing error: {str(e)}")
124132
raise HTTPException(status_code=500, detail=str(e)) from e
125133
except Exception as e:
126-
logger.error(f"Unexpected error triggering geographic entity identification for resource {id}: {str(e)}")
127-
raise HTTPException(status_code=500, detail=str(e)) from e
134+
logger.error(
135+
f"Unexpected error triggering geographic entity identification "
136+
f"for resource {id}: {str(e)}"
137+
)
138+
raise HTTPException(status_code=500, detail=str(e)) from e

app/api/v1/endpoint_modules/resources.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -304,41 +304,35 @@ async def get_resource_spatial_facets(
304304
query = select(resources.c.id, resources.c.dcat_bbox).where(resources.c.id == id)
305305
result = await session.execute(query)
306306
row = result.fetchone()
307-
307+
308308
if not row:
309309
# Return empty response for nonexistent resource
310-
response_data = {
311-
"id": id,
312-
"type": "spatial_facets",
313-
"attributes": {}
314-
}
310+
response_data = {"id": id, "type": "spatial_facets", "attributes": {}}
315311
request_url = str(request.url) if request else None
316312
return create_jsonapi_response(response_data, request_url, callback)
317-
313+
318314
# Convert to dict
319315
resource_dict = dict(row._mapping)
320-
316+
321317
# Get spatial facets using the SpatialFacetService with the resource data
322318
service = SpatialFacetService(resource_dict)
323319
spatial_facets = await service.get_spatial_facets_with_wof_ids(session, debug=debug)
324-
320+
325321
# Prepare attributes with dcat_bbox first, then spatial facets
326322
attributes = {}
327323
if resource_dict.get("dcat_bbox"):
328324
attributes["dcat_bbox"] = resource_dict["dcat_bbox"]
329325
# Add spatial facets after dcat_bbox
330326
attributes.update(spatial_facets)
331-
327+
332328
# Create JSON:API compliant response
333-
response_data = {
334-
"id": id,
335-
"type": "spatial_facets",
336-
"attributes": attributes
337-
}
338-
329+
response_data = {"id": id, "type": "spatial_facets", "attributes": attributes}
330+
339331
request_url = str(request.url) if request else None
340332
return create_jsonapi_response(response_data, request_url, callback)
341-
333+
342334
except Exception as e:
343335
logger.error(f"Error getting spatial facets for resource {id}: {str(e)}", exc_info=True)
344-
raise HTTPException(status_code=500, detail=f"Error retrieving spatial facets: {str(e)}")
336+
raise HTTPException(
337+
status_code=500, detail=f"Error retrieving spatial facets: {str(e)}"
338+
) from e

app/api/v1/endpoint_modules/shapefiles.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
from app.api.v1.utils import create_response
99
from app.services.shapefile_service import (
10-
ShapefileService,
11-
DefaultDownloadService,
10+
DefaultDownloadService,
1211
DefaultDuckDBService,
1312
DuckDBConnectionError,
13+
ShapefileDownloadError,
1414
ShapefileProcessingError,
15-
ShapefileDownloadError
15+
ShapefileService,
1616
)
1717

1818
# Load environment variables
@@ -35,12 +35,16 @@ def get_shapefile_service() -> ShapefileService:
3535
return ShapefileService(download_service, duckdb_service)
3636

3737

38+
# Module-level singleton for dependency injection
39+
_shapefile_service_dependency = Depends(get_shapefile_service)
40+
41+
3842
@router.get("/shapefiles/query")
3943
async def query_endpoint(
4044
s3_uri: str = Query(..., description="S3 URI or URL of the shapefile"),
4145
sql: str = Query(..., description="SQL WHERE clause to filter the data"),
4246
callback: Optional[str] = Query(None, description="JSONP callback name"),
43-
service: ShapefileService = Depends(get_shapefile_service),
47+
service: ShapefileService = _shapefile_service_dependency,
4448
):
4549
"""Query a shapefile using SQL WHERE clauses."""
4650
try:
@@ -50,23 +54,23 @@ async def query_endpoint(
5054

5155
except DuckDBConnectionError as e:
5256
logger.error(f"DuckDB connection error: {str(e)}")
53-
raise HTTPException(status_code=503, detail=str(e))
57+
raise HTTPException(status_code=503, detail=str(e)) from e
5458
except ShapefileDownloadError as e:
5559
logger.error(f"Shapefile download error: {str(e)}")
56-
raise HTTPException(status_code=400, detail=str(e))
60+
raise HTTPException(status_code=400, detail=str(e)) from e
5761
except ShapefileProcessingError as e:
5862
logger.error(f"Shapefile processing error: {str(e)}")
59-
raise HTTPException(status_code=500, detail=str(e))
63+
raise HTTPException(status_code=500, detail=str(e)) from e
6064
except Exception as e:
6165
logger.error(f"Unexpected error querying shapefile: {str(e)}", exc_info=True)
62-
raise HTTPException(status_code=500, detail=f"Error querying shapefile: {str(e)}")
66+
raise HTTPException(status_code=500, detail=f"Error querying shapefile: {str(e)}") from e
6367

6468

6569
@router.get("/shapefiles/schema")
6670
async def schema_endpoint(
6771
s3_uri: str = Query(..., description="S3 URI or URL of the shapefile"),
6872
callback: Optional[str] = Query(None, description="JSONP callback name"),
69-
service: ShapefileService = Depends(get_shapefile_service),
73+
service: ShapefileService = _shapefile_service_dependency,
7074
):
7175
"""Get the schema of a shapefile."""
7276
try:
@@ -76,24 +80,26 @@ async def schema_endpoint(
7680

7781
except DuckDBConnectionError as e:
7882
logger.error(f"DuckDB connection error: {str(e)}")
79-
raise HTTPException(status_code=503, detail=str(e))
83+
raise HTTPException(status_code=503, detail=str(e)) from e
8084
except ShapefileDownloadError as e:
8185
logger.error(f"Shapefile download error: {str(e)}")
82-
raise HTTPException(status_code=400, detail=str(e))
86+
raise HTTPException(status_code=400, detail=str(e)) from e
8387
except ShapefileProcessingError as e:
8488
logger.error(f"Shapefile processing error: {str(e)}")
85-
raise HTTPException(status_code=500, detail=str(e))
89+
raise HTTPException(status_code=500, detail=str(e)) from e
8690
except Exception as e:
8791
logger.error(f"Unexpected error getting shapefile schema: {str(e)}", exc_info=True)
88-
raise HTTPException(status_code=500, detail=f"Error getting shapefile schema: {str(e)}")
92+
raise HTTPException(
93+
status_code=500, detail=f"Error getting shapefile schema: {str(e)}"
94+
) from e
8995

9096

9197
@router.get("/shapefiles/preview")
9298
async def preview_endpoint(
9399
s3_uri: str = Query(..., description="S3 URI or URL of the shapefile"),
94100
limit: int = Query(10, description="Maximum number of rows to return", ge=1, le=1000),
95101
callback: Optional[str] = Query(None, description="JSONP callback name"),
96-
service: ShapefileService = Depends(get_shapefile_service),
102+
service: ShapefileService = _shapefile_service_dependency,
97103
):
98104
"""Preview a shapefile with a limited number of rows."""
99105
try:
@@ -103,13 +109,13 @@ async def preview_endpoint(
103109

104110
except DuckDBConnectionError as e:
105111
logger.error(f"DuckDB connection error: {str(e)}")
106-
raise HTTPException(status_code=503, detail=str(e))
112+
raise HTTPException(status_code=503, detail=str(e)) from e
107113
except ShapefileDownloadError as e:
108114
logger.error(f"Shapefile download error: {str(e)}")
109-
raise HTTPException(status_code=400, detail=str(e))
115+
raise HTTPException(status_code=400, detail=str(e)) from e
110116
except ShapefileProcessingError as e:
111117
logger.error(f"Shapefile processing error: {str(e)}")
112-
raise HTTPException(status_code=500, detail=str(e))
118+
raise HTTPException(status_code=500, detail=str(e)) from e
113119
except Exception as e:
114120
logger.error(f"Unexpected error previewing shapefile: {str(e)}", exc_info=True)
115-
raise HTTPException(status_code=500, detail=f"Error previewing shapefile: {str(e)}")
121+
raise HTTPException(status_code=500, detail=f"Error previewing shapefile: {str(e)}") from e

app/api/v1/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ def sanitize_for_json(obj: Any) -> Any:
1919
return obj.isoformat()
2020
elif hasattr(obj, "__dict__"): # Handle objects with __dict__
2121
return sanitize_for_json(obj.__dict__)
22+
elif isinstance(obj, bool): # Handle boolean objects (before float conversion)
23+
return obj
2224
# Handle Decimal objects from database
2325
elif hasattr(obj, "__float__"):
2426
return float(obj)

0 commit comments

Comments
 (0)