Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ printf "==== Running flake8\n"
python -m flake8
printf "==== Running mypy\n"
mypy src examples
printf "==== Running black\n"
black --check --diff src
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
long_description = (this_directory / "README.md").read_text()

if sys.version_info >= (3, 8):
lint_deps = ["flake8", "mypy==1.8.0", "types-requests"]
lint_deps = ["flake8", "mypy==1.8.0", "types-requests", "black"]
else:
lint_deps = ["flake8", "mypy==1.4.1", "types-requests"]
lint_deps = ["flake8", "mypy==1.4.1", "types-requests", "black"]
test_deps = ["pytest==7.1", "responses==0.22", "httpretty"]

setup(
Expand Down
11 changes: 10 additions & 1 deletion src/picterra/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@
from .tracer_client import TracerClient
from .tracer_client import TracerClient as PlotsAnalysisPlatformClient

__all__ = ["APIClient", "DetectorPlatformClient", "ForgeClient", "PlotsAnalysisPlatformClient", "TracerClient", "nongeo_result_to_pixel", "APIError", "ResultsPage"]
__all__ = [
"APIClient",
"DetectorPlatformClient",
"ForgeClient",
"PlotsAnalysisPlatformClient",
"TracerClient",
"nongeo_result_to_pixel",
"APIError",
"ResultsPage",
]
44 changes: 26 additions & 18 deletions src/picterra/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,35 @@
# allow injecting an non-existing package name to test the fallback behavior
# of _get_ua in tests (see test_headers_user_agent_version__fallback)
def _get_distr_name():
return 'picterra'
return "picterra"


def _get_ua():
import platform

pkg = _get_distr_name()
if sys.version_info >= (3, 8):
from importlib.metadata import PackageNotFoundError, version

try:
ver = version(pkg)
except PackageNotFoundError:
ver = 'no_version'
ver = "no_version"
else:
import pkg_resources # type: ignore[import]

try:
ver = pkg_resources.require(pkg)[0].version
except pkg_resources.DistributionNotFound:
ver = 'no_version'
ver = "no_version"
o_s = " ".join([os.name, platform.system(), platform.release()])
v_info = sys.version_info
py = "Python " + str(v_info.major) + "." + str(v_info.minor)
return "picterra-python/%s (%s %s)" % (ver, py, o_s,)
return "picterra-python/%s (%s %s)" % (
ver,
py,
o_s,
)


class APIError(Exception):
Expand All @@ -66,9 +73,7 @@ def __init__(self, *args, **kwargs):
self.timeout = kwargs.pop("timeout")
super().__init__(*args, **kwargs)
self.headers.update(
{
"User-Agent": "%s - %s" % (_get_ua(), self.headers["User-Agent"])
}
{"User-Agent": "%s - %s" % (_get_ua(), self.headers["User-Agent"])}
)

def request(self, *args, **kwargs):
Expand Down Expand Up @@ -108,14 +113,14 @@ def _upload_file_to_blobstore(upload_url: str, filename: str):
def multipolygon_to_polygon_feature_collection(mp):
return {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": p
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {"type": "Polygon", "coordinates": p},
}
} for p in mp["coordinates"]]
for p in mp["coordinates"]
],
}


Expand Down Expand Up @@ -147,6 +152,7 @@ class ResultsPage(Generic[T]):

You can also get a specific page passing the page number to the ``list_XX`` function
"""

_fetch: Callable[[str], requests.Response]
_next_url: str | None
_prev_url: str | None
Expand Down Expand Up @@ -205,7 +211,11 @@ class BaseAPIClient:
"""

def __init__(
self, api_url: str, timeout: int = 30, max_retries: int = 3, backoff_factor: int = 10
self,
api_url: str,
timeout: int = 30,
max_retries: int = 3,
backoff_factor: int = 10,
):
"""
Args:
Expand All @@ -216,9 +226,7 @@ def __init__(
retry_strategy comment below
backoff_factor: factor used nin the backoff algorithm; see retry_strategy comment below
"""
base_url = os.environ.get(
"PICTERRA_BASE_URL", "https://app.picterra.ch/"
)
base_url = os.environ.get("PICTERRA_BASE_URL", "https://app.picterra.ch/")
api_key = os.environ.get("PICTERRA_API_KEY", None)
if not api_key:
raise APIError("PICTERRA_API_KEY environment variable is not defined")
Expand Down
14 changes: 7 additions & 7 deletions src/picterra/forge_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Note that Forge is separate from Tracer and so an API key which is valid for
one may encounter permissions issues if used with the other
"""

from __future__ import annotations

import json
Expand Down Expand Up @@ -602,16 +603,14 @@ def download_result_to_feature_collection(self, operation_id: str, filename: str
for class_result in results["by_class"]:
with tempfile.NamedTemporaryFile() as f:
self.download_vector_layer_to_file(
class_result["result"]["vector_layer_id"], f.name)
class_result["result"]["vector_layer_id"], f.name
)
with open(f.name) as fr:
vl_polygon_fc: FeatureCollection = json.load(fr)
mp_feature: Feature = {
"type": "Feature",
"properties": {"class_name": class_result["class"]["name"]},
"geometry": {
"type": "MultiPolygon",
"coordinates": []
}
"geometry": {"type": "MultiPolygon", "coordinates": []},
}
for poly_feat in vl_polygon_fc["features"]:
mp_feature["geometry"]["coordinates"].append(
Expand Down Expand Up @@ -845,7 +844,9 @@ def download_vector_layer_to_file(self, vector_layer_id: str, filename: str):
vector_layer_id: The id of the vector layer to download
filename: existing file to save the vector layer in, as a feature collection of polygons
"""
resp = self.sess.post(self._full_url("vector_layers/%s/download/" % vector_layer_id))
resp = self.sess.post(
self._full_url("vector_layers/%s/download/" % vector_layer_id)
)
if not resp.ok:
raise APIError(resp.text)
op = self._wait_until_operation_completes(resp.json())
Expand Down Expand Up @@ -998,7 +999,6 @@ def list_detector_rasters(
url = "detectors/%s/training_rasters/" % detector_id
return self._return_results_page(url, params)


def create_folder(self, name: str) -> str:
"""
Creates a new folder with the given name
Expand Down
Loading
Loading