Skip to content

Conversation

nicopace
Copy link
Contributor

@nicopace nicopace commented Oct 1, 2025

Adds a script to fetch layers from ArcGIS Feature Services anonymously, based on a previously written script.

TODO:

  • Run tests locally
  • Run the script locally
  • Validate whether the data being fetched is newer than the already available, and decide what to do (overwrite, snapshot, skip)

@nicopace nicopace requested a review from rudokemper October 1, 2025 18:57
@rudokemper
Copy link
Member

Actually @nicopace it appears you are not done yet, right? I'll move this back to "In Progress" and wait to hear from you when you want to me to look at it.

Copy link
Member

@rudokemper rudokemper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This first review is mostly intended as an orientation to get your code in-line with conventions across the repo, and clarifying why your tests are failing. I have otherwise not done a thorough, line-by-line code review.

A few additional things (I know this is still WIP, but just for purposes of comprehensive orientation):

  • Add this new script to tox.ini to test using tox (see "Running Tests" in the main README). I think you may have been using pytest directly and that is now how testing is set up in this repo. I also recommend you look at the test code for some of the other scripts, most salient of all the existing arcgis_feature_layer script.
  • You need an arcgis_download_feature_anonymous.script.yaml file to pass the params via Windmill. Please have a look at some other script yaml files in the repo to get a sense of how this works.
  • The script.lock file corresponding to each script is generated by Windmill when run. You can sync pull it and then commit it to your branch. I can show you how to set up the Windmill CLI if you haven't already.
  • Please also describe this script in the f/arcgis/ README.


# Configure module logger
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this addition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preventing unwanted log output from libraries: When developing a library, it is considered good practice to add a NullHandler to the library's loggers. This prevents the library's log messages from being propagated to the root logger of an application that uses the library, and thus prevents them from appearing in the application's logs unless the application explicitly configures a handler for that specific library's logger. This helps keep the application's logs clean and focused on application-specific events.

Basically, logs will not propagate when importing the library, unless you explicitly want to log those as user of the library.

Comment on lines 37 to 71
def _create_test_session(monkeypatch, metadata_resp: Dict[str, Any], query_resp: Dict[str, Any]):
"""Helper to create a fake session by monkeypatching requests.Session.get"""
class DummyResp:
def __init__(self, data, status=200):
self._data = data
self.status_code = status

def raise_for_status(self):
if self.status_code >= 400:
raise requests.HTTPError(f"{self.status_code} error")

def json(self):
return self._data

def iter_content(self, chunk_size=8192):
yield b"abc"

class DummySession:
def __init__(self):
self.calls = []

def get(self, url, params=None, **kwargs):
self.calls.append((url, params))
if url.endswith("?f=pjson"):
return DummyResp(metadata_resp)
if "/query" in url:
return DummyResp(query_resp)
# attachments info or download
if url.endswith("/attachments"):
return DummyResp({"attachmentInfos": []})
if "/attachments/" in url:
return DummyResp(b"binarycontent")
return DummyResp({}, status=404)

return DummySession()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to do this. Please see conftest.py in this directory to see how we are already mocking an ArcGIS server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are already passing with this code.
Will finish with the rest of the reviews first.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests may be passing, but it would be good to use the same patterns as elsewhere in this repository, to improve maintainability and developer experience. If every script (and its tests) has a somewhat different way of doing things, then it becomes harder to make changes across the board.

However, if you'd like, I can take it from here and bring your script in-line with repo-wide patterns. (And also make an effort to make those more explicit.)

@nicopace
Copy link
Contributor Author

nicopace commented Oct 8, 2025

Gone through all your comments. Agree with them. Will do changes and update this branch, then will quote you again for review. Thanks

@nicopace nicopace requested a review from rudokemper October 9, 2025 15:58
@rudokemper
Copy link
Member

@nicopace maybe one more thing to add is information in the README on where to get the params. In particular, it could be tricky to find the layer ids.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants