Skip to content

Commit cff90ee

Browse files
move GIS check to Python agent (#29)
1 parent b993e35 commit cff90ee

File tree

12 files changed

+80
-102
lines changed

12 files changed

+80
-102
lines changed

crates/djls-django/src/apps.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use djls_ipc::v1::*;
2-
use djls_ipc::{ProcessError, PythonProcess};
31
use std::fmt;
42

53
#[derive(Debug)]
@@ -36,24 +34,6 @@ impl Apps {
3634
pub fn iter(&self) -> impl Iterator<Item = &App> {
3735
self.apps().iter()
3836
}
39-
40-
pub fn check_installed(python: &mut PythonProcess, app: &str) -> Result<bool, ProcessError> {
41-
let request = messages::Request {
42-
command: Some(messages::request::Command::CheckAppInstalled(
43-
check::AppInstalledRequest {
44-
app_name: app.to_string(),
45-
},
46-
)),
47-
};
48-
49-
let response = python.send(request).map_err(ProcessError::Transport)?;
50-
51-
match response.result {
52-
Some(messages::response::Result::CheckAppInstalled(response)) => Ok(response.passed),
53-
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message)),
54-
_ => Err(ProcessError::Response),
55-
}
56-
}
5737
}
5838

5939
impl fmt::Display for Apps {

crates/djls-django/src/django.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::gis::{check_gis_setup, GISError};
21
use djls_ipc::v1::*;
32
use djls_ipc::IpcCommand;
43
use djls_ipc::{ProcessError, PythonProcess, TransportError};
@@ -24,16 +23,24 @@ impl DjangoProject {
2423
pub fn setup(mut python: PythonProcess) -> Result<Self, ProjectError> {
2524
let py = Python::setup(&mut python)?;
2625

27-
if !check_gis_setup(&mut python)? {
28-
eprintln!("Warning: GeoDjango detected but GDAL is not available.");
29-
eprintln!("Django initialization will be skipped. Some features may be limited.");
30-
eprintln!("To enable full functionality, please install GDAL and other GeoDjango prerequisites.");
26+
match check::GeoDjangoPrereqsRequest::execute(&mut python)?.result {
27+
Some(messages::response::Result::CheckGeodjangoPrereqs(response)) => {
28+
if !response.passed {
29+
eprintln!("Warning: GeoDjango detected but GDAL is not available.");
30+
eprintln!(
31+
"Django initialization will be skipped. Some features may be limited."
32+
);
33+
eprintln!("To enable full functionality, please install GDAL and other GeoDjango prerequisites.");
3134

32-
return Ok(Self {
33-
py,
34-
python,
35-
version: String::new(),
36-
});
35+
return Ok(Self {
36+
py,
37+
python,
38+
version: String::new(),
39+
});
40+
}
41+
}
42+
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message))?,
43+
_ => Err(ProcessError::Response)?,
3744
}
3845

3946
let response = django::GetProjectInfoRequest::execute(&mut python)?;
@@ -77,8 +84,6 @@ pub enum ProjectError {
7784
DjangoNotFound,
7885
#[error("IO error: {0}")]
7986
Io(#[from] std::io::Error),
80-
#[error("GIS error: {0}")]
81-
Gis(#[from] GISError),
8287
#[error("JSON parsing error: {0}")]
8388
Json(#[from] serde_json::Error),
8489
#[error(transparent)]

crates/djls-django/src/gis.rs

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

crates/djls-django/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
mod apps;
22
mod django;
3-
mod gis;
43
mod templates;
54

65
pub use django::DjangoProject;

crates/djls-ipc/src/commands.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ impl IpcCommand for v1::check::HealthRequest {
2929
}
3030
}
3131

32+
impl IpcCommand for v1::check::GeoDjangoPrereqsRequest {
33+
fn into_request(&self) -> messages::Request {
34+
messages::Request {
35+
command: Some(messages::request::Command::CheckGeodjangoPrereqs(*self)),
36+
}
37+
}
38+
39+
fn from_response(response: messages::Response) -> Result<messages::Response, ProcessError> {
40+
match response.result {
41+
Some(messages::response::Result::CheckGeodjangoPrereqs(_)) => Ok(response),
42+
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message)),
43+
_ => Err(ProcessError::Response),
44+
}
45+
}
46+
}
47+
3248
impl IpcCommand for v1::python::GetEnvironmentRequest {
3349
fn into_request(&self) -> messages::Request {
3450
messages::Request {

proto/v1/check.proto

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ message HealthResponse {
88
optional string error = 2;
99
}
1010

11-
message AppInstalledRequest {
12-
string app_name = 1;
13-
}
14-
message AppInstalledResponse {
11+
message GeoDjangoPrereqsRequest {}
12+
message GeoDjangoPrereqsResponse {
1513
bool passed = 1;
1614
optional string error = 2;
1715
}

proto/v1/messages.proto

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import "v1/python.proto";
99
message Request {
1010
oneof command {
1111
check.HealthRequest check__health = 1;
12-
check.AppInstalledRequest check__app_installed = 2;
12+
check.GeoDjangoPrereqsRequest check__geodjango_prereqs = 2;
1313
python.GetEnvironmentRequest python__get_environment = 1000;
1414
django.GetProjectInfoRequest django__get_project_info = 2000;
1515
}
@@ -18,7 +18,7 @@ message Request {
1818
message Response {
1919
oneof result {
2020
check.HealthResponse check__health = 1;
21-
check.AppInstalledResponse check__app_installed = 2;
21+
check.GeoDjangoPrereqsResponse check__geodjango_prereqs = 2;
2222
python.GetEnvironmentResponse python__get_environment = 1000;
2323
django.GetProjectInfoResponse django__get_project_info = 2000;
2424
Error error = 9000;

python/djls/handlers.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import importlib.metadata
44
import inspect
55
import os
6+
import subprocess
67
import sys
78
import sysconfig
89
import traceback
@@ -91,16 +92,23 @@ async def check__health(_request: check_pb2.HealthRequest) -> check_pb2.HealthRe
9192
return check_pb2.HealthResponse(passed=True)
9293

9394

94-
@proto_handler(
95-
check_pb2.AppInstalledRequest,
96-
error=messages_pb2.Error(
97-
code=messages_pb2.Error.DJANGO_ERROR, message="App is not in INSTALLED_APPS"
98-
),
99-
)
100-
async def check__app_installed(
101-
request: check_pb2.AppInstalledRequest,
102-
) -> check_pb2.AppInstalledResponse:
103-
return check_pb2.AppInstalledResponse(passed=apps.is_installed(request.app_name))
95+
@proto_handler(check_pb2.GeoDjangoPrereqsRequest)
96+
async def check__geodjango_prereqs(
97+
request: check_pb2.GeoDjangoPrereqsRequest,
98+
) -> check_pb2.GeoDjangoPrereqsResponse:
99+
has_geodjango = apps.is_installed("django.contrib.gis")
100+
101+
try:
102+
gdal_process = subprocess.run(
103+
["gdalinfo", "--version"], capture_output=True, check=False
104+
)
105+
gdal_is_installed = gdal_process.returncode == 0
106+
except FileNotFoundError:
107+
gdal_is_installed = False
108+
109+
return check_pb2.GeoDjangoPrereqsResponse(
110+
passed=(not has_geodjango) or gdal_is_installed
111+
)
104112

105113

106114
@proto_handler(python_pb2.GetEnvironmentRequest)

python/djls/proto/v1/check_pb2.py

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

2929

3030

31-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ev1/check.proto\x12\rdjls.v1.check\"\x0f\n\rHealthRequest\">\n\x0eHealthResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\'\n\x13\x41ppInstalledRequest\x12\x10\n\x08\x61pp_name\x18\x01 \x01(\t\"D\n\x14\x41ppInstalledResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_errorb\x06proto3')
31+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ev1/check.proto\x12\rdjls.v1.check\"\x0f\n\rHealthRequest\">\n\x0eHealthResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x19\n\x17GeoDjangoPrereqsRequest\"H\n\x18GeoDjangoPrereqsResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_errorb\x06proto3')
3232

3333
_globals = globals()
3434
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -39,8 +39,8 @@
3939
_globals['_HEALTHREQUEST']._serialized_end=48
4040
_globals['_HEALTHRESPONSE']._serialized_start=50
4141
_globals['_HEALTHRESPONSE']._serialized_end=112
42-
_globals['_APPINSTALLEDREQUEST']._serialized_start=114
43-
_globals['_APPINSTALLEDREQUEST']._serialized_end=153
44-
_globals['_APPINSTALLEDRESPONSE']._serialized_start=155
45-
_globals['_APPINSTALLEDRESPONSE']._serialized_end=223
42+
_globals['_GEODJANGOPREREQSREQUEST']._serialized_start=114
43+
_globals['_GEODJANGOPREREQSREQUEST']._serialized_end=139
44+
_globals['_GEODJANGOPREREQSRESPONSE']._serialized_start=141
45+
_globals['_GEODJANGOPREREQSRESPONSE']._serialized_end=213
4646
# @@protoc_insertion_point(module_scope)

python/djls/proto/v1/check_pb2.pyi

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ class HealthResponse(_message.Message):
2020
error: str
2121
def __init__(self, passed: bool = ..., error: _Optional[str] = ...) -> None: ...
2222

23-
class AppInstalledRequest(_message.Message):
24-
__slots__ = ("app_name",)
25-
APP_NAME_FIELD_NUMBER: _ClassVar[int]
26-
app_name: str
27-
def __init__(self, app_name: _Optional[str] = ...) -> None: ...
23+
class GeoDjangoPrereqsRequest(_message.Message):
24+
__slots__ = ()
25+
def __init__(self) -> None: ...
2826

29-
class AppInstalledResponse(_message.Message):
27+
class GeoDjangoPrereqsResponse(_message.Message):
3028
__slots__ = ("passed", "error")
3129
PASSED_FIELD_NUMBER: _ClassVar[int]
3230
ERROR_FIELD_NUMBER: _ClassVar[int]

0 commit comments

Comments
 (0)