-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from Ingenjorsarbete-For-Klimatet/feature/extr…
…action-script Feature/extraction script
- Loading branch information
Showing
28 changed files
with
823 additions
and
1,239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,16 @@ readme = "README.md" | |
authors = [ | ||
{ name = "Mladen Gibanica", email = "[email protected]" }, | ||
] | ||
requires-python = ">=3.9" | ||
dependencies = ["geopandas ~= 0.14", "pyogrio ~= 0.7.0", "pyarrow ~= 14.0"] | ||
requires-python = ">=3.10,<3.12" | ||
dependencies = [ | ||
"geopandas ~= 0.14", | ||
"pyogrio ~= 0.7", | ||
"pyarrow ~= 16.0", | ||
"unidecode ~= 1.3", | ||
"tqdm ~= 4.66", | ||
"typer ~= 0.12", | ||
"ray ~= 2.20" | ||
] | ||
|
||
[project.optional-dependencies] | ||
lint = [ | ||
|
@@ -35,6 +43,9 @@ dev = [ | |
"ipykernel ~= 6.26", | ||
] | ||
|
||
[project.scripts] | ||
ifk-lantmateriet = "lantmateriet.cli:app" | ||
|
||
[tool.setuptools.packages.find] | ||
where = ["src"] | ||
exclude = ["material"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
"""API module.""" | ||
|
||
import io | ||
import json | ||
import logging | ||
import os | ||
import zipfile | ||
from pathlib import Path | ||
|
||
import requests | ||
from tqdm import tqdm | ||
|
||
STATUS_OK = 200 | ||
BLOCK_SIZE = 1024 | ||
REQUEST_TIMEOUT = 200 | ||
ORDER_URL = "https://api.lantmateriet.se" | ||
DOWNLOAD_URL = "https://download-geotorget.lantmateriet.se" | ||
TOKEN = os.environ["LANTMATERIET_API_TOKEN"] | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def get_request(url: str) -> requests.Response: | ||
"""Get request from url. | ||
Args: | ||
url: url to request from | ||
Returns: | ||
response | ||
Raises: | ||
ValueError | ||
requests.exceptions.HTTPError | ||
""" | ||
logger.debug(f"Fetching from {url}.") | ||
|
||
headers = {"Authorization": f"Bearer {TOKEN}"} | ||
response = requests.get(url, headers=headers, timeout=REQUEST_TIMEOUT, stream=True) | ||
|
||
if response.status_code != STATUS_OK: | ||
raise requests.exceptions.HTTPError(f"Could not request from {url}.") | ||
|
||
logger.debug(f"Successful request from {url}.") | ||
|
||
return response | ||
|
||
|
||
class Lantmateriet: | ||
"""Lantmäteriet class.""" | ||
|
||
def __init__(self, order_id: str, save_path: str): | ||
"""Initialise Lantmäteriet. | ||
Args: | ||
order_id: order id to fetch data from | ||
save_path: path to save downloaded files to | ||
""" | ||
order_url = ORDER_URL + f"/geotorget/orderhanterare/v2/{order_id}" | ||
download_url = DOWNLOAD_URL + f"/download/{order_id}/files" | ||
self._save_path = save_path | ||
|
||
Path(save_path).mkdir(exist_ok=True) | ||
self._order_enpoint = json.loads(get_request(order_url).content) | ||
available_files = json.loads(get_request(download_url).content) | ||
self._available_files_enpoint = { | ||
item["title"]: item for item in available_files | ||
} | ||
|
||
@property | ||
def order(self) -> dict[str, str]: | ||
"""Get order information.""" | ||
return self._order_enpoint | ||
|
||
@property | ||
def available_files(self) -> list[str]: | ||
"""Get available files.""" | ||
return list(self._available_files_enpoint.keys()) | ||
|
||
def download(self, title: str) -> None: | ||
"""Download file by title. | ||
Args: | ||
title: title of file to download | ||
""" | ||
logger.info(f"Started downloading {title}") | ||
|
||
url = self._available_files_enpoint[title]["href"] | ||
response = get_request(url) | ||
buffer = self._download(response) | ||
|
||
if zipfile.is_zipfile(buffer) is True: | ||
self._unzip(buffer) | ||
|
||
logger.info(f"Downloaded and unpacked {title} to {self._save_path}") | ||
|
||
def _download(self, response: requests.Response) -> io.BytesIO: | ||
"""Download file from url. | ||
Args: | ||
response: requests response object | ||
Returns: | ||
bytesio buffer | ||
""" | ||
file_size = int(response.headers.get("Content-Length", 0)) | ||
buffer = io.BytesIO() | ||
with tqdm.wrapattr( | ||
response.raw, "read", total=file_size, desc="Downloading" | ||
) as r_raw: | ||
while True: | ||
chunk = buffer.write(r_raw.read(BLOCK_SIZE)) | ||
if not chunk: | ||
break | ||
|
||
return buffer | ||
|
||
def _unzip(self, buffer: io.BytesIO): | ||
"""Extract zip and save to disk. | ||
Args: | ||
buffer: buffer of downloaded content | ||
""" | ||
with zipfile.ZipFile(buffer) as zip: | ||
for member in tqdm(zip.infolist(), desc="Extracting"): | ||
try: | ||
zip.extract(member, self._save_path) | ||
except zipfile.error: | ||
logger.error("Can't unzip {member}.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
"""CLI module.""" | ||
|
||
import typer | ||
from lantmateriet.api import Lantmateriet | ||
from lantmateriet.extract import extract | ||
from tqdm import tqdm | ||
|
||
app = typer.Typer() | ||
|
||
|
||
@app.callback() | ||
def callback(): | ||
"""Lantmäteriet CLI client.""" | ||
|
||
|
||
@app.command() | ||
def download_all(order_id: str, save_path: str): | ||
"""Download files. | ||
Args: | ||
order_id: lantmäteriet order id | ||
save_path: path to save files to | ||
""" | ||
client = Lantmateriet(order_id, save_path) | ||
all_files = client.available_files | ||
for file in tqdm(all_files): | ||
client.download(file) | ||
|
||
|
||
@app.command() | ||
def extract_all(source_path: str, target_path): | ||
"""Extract geojson from gpkg files. | ||
Args: | ||
source_path: path to search for files | ||
target_path: path to save extracted files to | ||
""" | ||
extract(source_path, target_path) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.