kystdatahuset-python-lib 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. kystdatahuset_python_lib-0.1.0/LICENSE +21 -0
  2. kystdatahuset_python_lib-0.1.0/PKG-INFO +26 -0
  3. kystdatahuset_python_lib-0.1.0/README.md +3 -0
  4. kystdatahuset_python_lib-0.1.0/pyproject.toml +45 -0
  5. kystdatahuset_python_lib-0.1.0/setup.cfg +4 -0
  6. kystdatahuset_python_lib-0.1.0/src/__init__.py +0 -0
  7. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/__init__.py +0 -0
  8. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/api_client.py +103 -0
  9. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/auth.py +30 -0
  10. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/const.py +1 -0
  11. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/file_storage.py +54 -0
  12. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/logging.py +13 -0
  13. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/models/AuthData.py +10 -0
  14. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/models/FileListing.py +33 -0
  15. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/models/WebServiceResponse.py +11 -0
  16. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/models/__init__.py +3 -0
  17. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/types/PandasFrequency.py +8 -0
  18. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/types/UploadFileType.py +18 -0
  19. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/types/__init__.py +2 -0
  20. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/utils/__init__.py +0 -0
  21. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/utils/date_range.py +14 -0
  22. kystdatahuset_python_lib-0.1.0/src/kystdatahuset/voyages.py +0 -0
  23. kystdatahuset_python_lib-0.1.0/src/kystdatahuset_python_lib.egg-info/PKG-INFO +26 -0
  24. kystdatahuset_python_lib-0.1.0/src/kystdatahuset_python_lib.egg-info/SOURCES.txt +27 -0
  25. kystdatahuset_python_lib-0.1.0/src/kystdatahuset_python_lib.egg-info/dependency_links.txt +1 -0
  26. kystdatahuset_python_lib-0.1.0/src/kystdatahuset_python_lib.egg-info/requires.txt +3 -0
  27. kystdatahuset_python_lib-0.1.0/src/kystdatahuset_python_lib.egg-info/top_level.txt +2 -0
  28. kystdatahuset_python_lib-0.1.0/tests/test_auth.py +8 -0
  29. kystdatahuset_python_lib-0.1.0/tests/test_file_storage.py +16 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kystverket
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: kystdatahuset-python-lib
3
+ Version: 0.1.0
4
+ Summary: A python library for accessing and querying data from Kystdatahuset
5
+ Author-email: Kystdatahuset developer team <support@kystdatahuset.no>, "(Stein) Runar Bergheim" <runar.bergheim@avinet.no>, Sigve Bergh <sigve.bergh@kystverket.no>, Hermann Klaus Kurt von Lupfert <hermann.lupfert@kystverket.no>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Kystverket/kystdatahuset-python-lib
8
+ Project-URL: Repository, https://github.com/Kystverket/kystdatahuset-python-lib
9
+ Project-URL: Issues, https://github.com/Kystverket/kystdatahuset-python-lib/issues
10
+ Keywords: spatial,analytics,visualization,geodata
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries
14
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy>=1.24
20
+ Requires-Dist: pandas>=2.0
21
+ Requires-Dist: pydantic>=2.0
22
+ Dynamic: license-file
23
+
24
+ # Kystdatahuset Python Library
25
+
26
+ A library to access and query Kystdatahuset
@@ -0,0 +1,3 @@
1
+ # Kystdatahuset Python Library
2
+
3
+ A library to access and query Kystdatahuset
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "kystdatahuset-python-lib"
7
+ version = "0.1.0"
8
+ description = "A python library for accessing and querying data from Kystdatahuset"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name="Kystdatahuset developer team", email="support@kystdatahuset.no" },
14
+ { name="(Stein) Runar Bergheim", email="runar.bergheim@avinet.no" },
15
+ { name="Sigve Bergh", email="sigve.bergh@kystverket.no" },
16
+ { name="Hermann Klaus Kurt von Lupfert", email="hermann.lupfert@kystverket.no" },
17
+ ]
18
+ classifiers = [
19
+ # 3 - Alpha
20
+ # 4 - Beta
21
+ # 5 - Production/Stable
22
+ "Development Status :: 4 - Beta",
23
+ # Indicate who your project is intended for
24
+ "Intended Audience :: Developers",
25
+ "Topic :: Software Development :: Libraries",
26
+ "Topic :: Scientific/Engineering :: Information Analysis",
27
+ # Specify the Python versions you support here.
28
+ "Programming Language :: Python :: 3.10",
29
+ ]
30
+ license-files = ["LICEN[CS]E*"]
31
+ keywords = ["spatial", "analytics", "visualization", "geodata"]
32
+ dependencies = [
33
+ "numpy>=1.24",
34
+ "pandas>=2.0",
35
+ "pydantic>=2.0",
36
+ ]
37
+
38
+ [project.urls]
39
+ Homepage = "https://github.com/Kystverket/kystdatahuset-python-lib"
40
+ Repository = "https://github.com/Kystverket/kystdatahuset-python-lib"
41
+ Issues = "https://github.com/Kystverket/kystdatahuset-python-lib/issues"
42
+
43
+ [tool.pytest.ini_options]
44
+ pythonpath = ["src"]
45
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,103 @@
1
+ from typing import Any, Dict, List, Tuple, Optional
2
+
3
+ from kystdatahuset.models import WebServiceResponse
4
+ from .const import API_URL
5
+ import requests
6
+ from kystdatahuset.logging import logger
7
+
8
+ def get_headers(jwt_token: Optional[str] = None, json: bool = False) -> Dict[str, str]:
9
+ """
10
+ Build headers for API requests.
11
+ """
12
+ headers: Dict[str, str] = {}
13
+ if jwt_token:
14
+ headers["Authorization"] = f"Bearer {jwt_token}"
15
+ if json:
16
+ headers["Content-Type"] = "application/json"
17
+ headers["Accept"] = "application/json"
18
+ return headers
19
+
20
+
21
+ def post_api_formdata(jwt_token: str, fragment: str, data: List[Tuple[str, Any]], filename: str) -> WebServiceResponse:
22
+ """
23
+ POST multipart/form-data with a file and form fields.
24
+ """
25
+ url = f"{API_URL}/{fragment}"
26
+
27
+ with open(filename, "rb") as f:
28
+ files = {"file": (filename, f, "application/octet-stream")}
29
+ response = requests.post(url, headers=get_headers(jwt_token), data=data, files=files)
30
+
31
+ if response.ok:
32
+ try:
33
+ logger.info(f"✅ POST (FormData) {url} successful!")
34
+ data = response.json()
35
+ return data
36
+ except ValueError:
37
+ return WebServiceResponse[Any](**{"success": True, "msg": response.text, "data": None})
38
+ else:
39
+ logger.error(f"❌ POST (FormData) {url} failed with {response.status_code}")
40
+ logger.debug(response.text)
41
+ raise Exception(f"API POST (FormData) failed with status code {response.status_code}: {response.text}")
42
+
43
+
44
+ def get_api(jwt_token: str, fragment: str, params: Optional[Dict[str, Any]] = None) -> WebServiceResponse:
45
+ """
46
+ Perform a GET request and parse JSON response.
47
+ """
48
+ url = f"{API_URL}/{fragment}"
49
+ response = requests.get(url, headers=get_headers(jwt_token, json=True), params=params)
50
+
51
+ if response.ok:
52
+ logger.info(f"✅ GET {url} successful!")
53
+ try:
54
+ data = response.json()
55
+ logger.debug(f"Response JSON: {data}")
56
+ return data
57
+ except ValueError:
58
+ return WebServiceResponse[str](**{"success": True, "msg": response.text, "data": None})
59
+ else:
60
+ logger.error(f"❌ GET {url} failed with {response.status_code}")
61
+ logger.debug(response.text)
62
+ raise Exception(f"API GET failed with status code {response.status_code}: {response.text}")
63
+
64
+ def delete_api(jwt_token: str, fragment: str, params: Optional[Dict[str, Any]] = None) -> WebServiceResponse:
65
+ """
66
+ Perform a DELETE request and parse the JSON response.
67
+ """
68
+ url = f"{API_URL}/{fragment}"
69
+ response = requests.delete(url, headers=get_headers(jwt_token, json=True), params=params)
70
+
71
+ if response.ok:
72
+ logger.info(f"✅ DELETE {url} successful!")
73
+ try:
74
+ data = response.json()
75
+ logger.debug(f"Response JSON: {data}")
76
+ return data
77
+ except ValueError:
78
+ return WebServiceResponse[str](**{"success": True, "msg": response.text, "data": None})
79
+ else:
80
+ logger.error(f"❌ GET {url} failed with {response.status_code}")
81
+ logger.debug(response.text)
82
+ raise Exception(f"API GET failed with status code {response.status_code}: {response.text}")
83
+
84
+
85
+ def post_api_json(jwt_token: str, fragment: str, payload: Dict[str, Any]) -> WebServiceResponse:
86
+ """
87
+ Perform a POST request with a JSON body and parse JSON response.
88
+ """
89
+ url = f"{API_URL}/{fragment}"
90
+ response = requests.post(url, headers=get_headers(jwt_token, json=True), json=payload)
91
+
92
+ if response.ok:
93
+ logger.info(f"✅ JSON POST to {url} successful!")
94
+ try:
95
+ data = response.json()
96
+ logger.debug(f"Response JSON: {data}")
97
+ return data
98
+ except ValueError:
99
+ return WebServiceResponse[str](**{"success": True, "message": response.text, "data": None})
100
+ else:
101
+ logger.error(f"❌ JSON POST to {url} failed with {response.status_code}")
102
+ logger.debug(response.text)
103
+ raise Exception(f"API JSON POST failed with status code {response.status_code}: {response.text}")
@@ -0,0 +1,30 @@
1
+ import requests
2
+ import json
3
+
4
+ from kystdatahuset.models import AuthData, WebServiceResponse
5
+ from kystdatahuset.logging import logger
6
+ from .const import API_URL
7
+
8
+ def login(username: str, password: str) -> WebServiceResponse[AuthData]:
9
+ reqUrl = f"{API_URL}/api/auth/login"
10
+
11
+ headersList = {
12
+ "User-Agent": "Kystdatahuset Python Library (https://your-client.com)",
13
+ "accept": "*/*",
14
+ "Content-Type": "application/json"
15
+ }
16
+
17
+ payload = json.dumps({
18
+ "username": username,
19
+ "password": password
20
+ })
21
+
22
+ response = requests.request("POST", reqUrl, data=payload, headers=headersList)
23
+
24
+ if response.status_code == 200:
25
+ logger.info("✅ Login successful!")
26
+ return WebServiceResponse[AuthData](**response.json())
27
+ else:
28
+ logger.error(f"❌ Login failed with status code {response.status_code}")
29
+ logger.debug(response.text)
30
+ raise Exception(f"Login failed with status code {response.status_code}: {response.text}")
@@ -0,0 +1 @@
1
+ API_URL="https://kystdatahuset.no/ws"
@@ -0,0 +1,54 @@
1
+ from uuid import UUID
2
+ from typing import Sequence, List
3
+ from kystdatahuset.models import FileListing, WebServiceResponse
4
+ from kystdatahuset.types import UploadFileType
5
+ import os
6
+ from kystdatahuset.api_client import post_api_formdata, get_api, delete_api
7
+
8
+ def list(*, jwt_token: str, resource_uuid: UUID) -> List[FileListing]:
9
+ """
10
+ Placeholder for listing files in storage.
11
+ """
12
+ list_res = get_api(jwt_token, f"api/file-storage/list/{resource_uuid}")
13
+ file_listings = WebServiceResponse[List[FileListing]](**list_res)
14
+ return file_listings.data
15
+
16
+ def delete(* , jwt_token: str, file_uuid: UUID) -> bool:
17
+ """
18
+ Placeholder for deleting a file in storage.
19
+ """
20
+ delete_res = delete_api(jwt_token, f"api/file-storage/delete/{file_uuid}")
21
+ return delete_res.success
22
+
23
+ def publish(
24
+ *,
25
+ jwt_token: str,
26
+ resource_uuid: UUID,
27
+ file_path: str,
28
+ title: str,
29
+ upload_file_type: UploadFileType,
30
+ description: str = "",
31
+ categories: Sequence[str] = "",
32
+ compressed: bool = False,
33
+ ) -> bool:
34
+ """
35
+ Upload a file and metadata to the Kystdatahuset API.
36
+ """
37
+
38
+ if not os.path.exists(file_path):
39
+ raise FileNotFoundError(f"File not found: {file_path}")
40
+
41
+ # Convert categories to multiple form fields (ASP.NET supports repeated keys)
42
+ # or as a JSON-like string, depending on the API’s binding expectations.
43
+ # The safe bet for ASP.NET [FromForm(Name="categories")] string[] is to repeat the key.
44
+ data = [
45
+ ("title", title),
46
+ ("description", description),
47
+ ("type", upload_file_type),
48
+ ("compressed", str(compressed).lower()), # ASP.NET expects 'true'/'false'
49
+ ] + [("categories", c) for c in categories]
50
+
51
+ response = post_api_formdata(jwt_token, f"api/file-storage/publish/{resource_uuid}", data, file_path)
52
+ return response.success
53
+
54
+
@@ -0,0 +1,13 @@
1
+ import logging
2
+
3
+ logger_name = __name__.split(".")[0]
4
+ # Create a logger specific to your library
5
+ logger = logging.getLogger(logger_name)
6
+ logger.addHandler(logging.NullHandler())
7
+
8
+ def enable_default_logging(level=logging.INFO):
9
+ handler = logging.StreamHandler()
10
+ formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s")
11
+ handler.setFormatter(formatter)
12
+ logger.addHandler(handler)
13
+ logger.setLevel(level)
@@ -0,0 +1,10 @@
1
+ from pydantic import BaseModel, Field
2
+ from datetime import datetime
3
+
4
+
5
+ class AuthData(BaseModel):
6
+ JWT: str = Field(..., description="JSON Web Token for authentication")
7
+ Username: str = Field(..., description="User's email or username")
8
+ Timestamp: datetime = Field(..., description="Timestamp when the token was issued")
9
+
10
+
@@ -0,0 +1,33 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import List
3
+ from uuid import UUID
4
+
5
+
6
+ class FileListing(BaseModel):
7
+ uuid: UUID = Field(..., description="Unique identifier for this file record")
8
+ title: str = Field(..., description="Title or display name of the uploaded file")
9
+ description: str = Field(..., description="Descriptive text about the file contents")
10
+ categories: List[str] = Field(..., description="List of category tags assigned to the file")
11
+ filetype: str = Field(..., description="Type or format of the uploaded file, e.g. csv, pdf")
12
+ compressed: bool = Field(..., description="True if the file was uploaded as compressed archive")
13
+ filename: str = Field(..., description="Server-side absolute file path")
14
+ origFilename: str = Field(..., description="Original filename on the client before upload")
15
+ resourceUuid: UUID = Field(..., description="UUID of the resource to which this file belongs")
16
+
17
+
18
+ # # ✅ Example usage:
19
+ # example_json = {
20
+ # 'uuid': '69d47723-206c-4a89-8d67-654f23706e24',
21
+ # 'title': 'Test Upload',
22
+ # 'description': 'This is a test upload',
23
+ # 'categories': ['test', 'upload'],
24
+ # 'filetype': 'csv',
25
+ # 'compressed': True,
26
+ # 'filename': r'E:\storage\kystdathuset\catalog\2025\11\64\12\7f\64127fc2-2644-4ed9-b886-fecfb914c4b5\C_Users_runar.bergheim_Documents_Development_kystdatahuset-python-lib_test_data_content.txt',
27
+ # 'origFilename': r'C:\\Users\\runar.bergheim\\Documents\\Development\\kystdatahuset-python-lib\\test_data\\content.txt',
28
+ # 'resourceUuid': '64127fc2-2644-4ed9-b886-fecfb914c4b5'
29
+ # }
30
+
31
+ # listing = FileListing(**example_json)
32
+ # print(listing.title)
33
+ # print(listing.resourceUuid)
@@ -0,0 +1,11 @@
1
+ from pydantic import Field, BaseModel
2
+ from typing import Generic, TypeVar, Optional
3
+
4
+ T = TypeVar("T")
5
+
6
+ class WebServiceResponse(BaseModel, Generic[T]):
7
+ success: bool = Field(..., description="Indicates if the request was successful")
8
+ msg: str = Field(..., description="Optional message from the API")
9
+ data: Optional[T] = Field(None, description="Container for typed response data")
10
+ time: Optional[float] = Field(None, description="Processing time in milliseconds or seconds")
11
+ executionTime: Optional[float] = Field(None, description="Processing time in milliseconds or seconds")
@@ -0,0 +1,3 @@
1
+ from .AuthData import AuthData
2
+ from .WebServiceResponse import WebServiceResponse
3
+ from .FileListing import FileListing
@@ -0,0 +1,8 @@
1
+ from typing import Literal, TypeAlias
2
+
3
+ PandasFreqency: TypeAlias = Literal[
4
+ "B", "C", "D", "W", "W-MON", "W-TUE", "W-WED", "W-THU", "W-FRI", "W-SAT", "W-SUN",
5
+ "M", "MS", "Q", "QS", "A", "AS",
6
+ "H", "T", "min", "S", "L", "ms", "U", "us", "N",
7
+ "BH", "CBH", "BQS", "BA", "BAS", "BYS", "BY"
8
+ ]
@@ -0,0 +1,18 @@
1
+ from typing import Literal, TypeAlias
2
+
3
+ UploadFileType: TypeAlias = Literal[
4
+ "csv", # Comma Separated Variables
5
+ "shp-compressed", # Compressed ESRI Shapefile
6
+ "fgdb-compressed", # Compressed ESRI filegeodatabase
7
+ "json", # JSON file
8
+ "geojson", # GeoJSON file
9
+ "png", # Portable Network Graphics image
10
+ "jpg", # JPEG image
11
+ "pdf", # Portable Document Format
12
+ "xlsx", # Microsoft Excel spreadsheet
13
+ "xml", # XML file
14
+ "docx", # Microsoft Word document
15
+ "NetCDF", # Network Common Data Form (NetCDF)
16
+ "tiff", # Tagged Image File Format (*.tif)
17
+ "geotiff", # Georeferenced Tagged Image File Format (*.tif)
18
+ ]
@@ -0,0 +1,2 @@
1
+ from .PandasFrequency import PandasFreqency
2
+ from .UploadFileType import UploadFileType
@@ -0,0 +1,14 @@
1
+ from typing import List, Optional, Tuple
2
+
3
+ from datetime import datetime, timedelta
4
+ from kystdatahuset.types import PandasFreqency
5
+
6
+ def date_range2(start_date: datetime, end_date: datetime, freq: PandasFreqency) -> List[datetime]:
7
+ """
8
+ Generate a list of dates from start_date to end_date, inclusive.
9
+ """
10
+ if start_date > end_date:
11
+ raise ValueError("start_date must be less than or equal to end_date")
12
+
13
+ delta = end_date - start_date
14
+ return [start_date + timedelta(days=i) for i in range(delta.days + 1)]
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: kystdatahuset-python-lib
3
+ Version: 0.1.0
4
+ Summary: A python library for accessing and querying data from Kystdatahuset
5
+ Author-email: Kystdatahuset developer team <support@kystdatahuset.no>, "(Stein) Runar Bergheim" <runar.bergheim@avinet.no>, Sigve Bergh <sigve.bergh@kystverket.no>, Hermann Klaus Kurt von Lupfert <hermann.lupfert@kystverket.no>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Kystverket/kystdatahuset-python-lib
8
+ Project-URL: Repository, https://github.com/Kystverket/kystdatahuset-python-lib
9
+ Project-URL: Issues, https://github.com/Kystverket/kystdatahuset-python-lib/issues
10
+ Keywords: spatial,analytics,visualization,geodata
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries
14
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy>=1.24
20
+ Requires-Dist: pandas>=2.0
21
+ Requires-Dist: pydantic>=2.0
22
+ Dynamic: license-file
23
+
24
+ # Kystdatahuset Python Library
25
+
26
+ A library to access and query Kystdatahuset
@@ -0,0 +1,27 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/__init__.py
5
+ src/kystdatahuset/__init__.py
6
+ src/kystdatahuset/api_client.py
7
+ src/kystdatahuset/auth.py
8
+ src/kystdatahuset/const.py
9
+ src/kystdatahuset/file_storage.py
10
+ src/kystdatahuset/logging.py
11
+ src/kystdatahuset/voyages.py
12
+ src/kystdatahuset/models/AuthData.py
13
+ src/kystdatahuset/models/FileListing.py
14
+ src/kystdatahuset/models/WebServiceResponse.py
15
+ src/kystdatahuset/models/__init__.py
16
+ src/kystdatahuset/types/PandasFrequency.py
17
+ src/kystdatahuset/types/UploadFileType.py
18
+ src/kystdatahuset/types/__init__.py
19
+ src/kystdatahuset/utils/__init__.py
20
+ src/kystdatahuset/utils/date_range.py
21
+ src/kystdatahuset_python_lib.egg-info/PKG-INFO
22
+ src/kystdatahuset_python_lib.egg-info/SOURCES.txt
23
+ src/kystdatahuset_python_lib.egg-info/dependency_links.txt
24
+ src/kystdatahuset_python_lib.egg-info/requires.txt
25
+ src/kystdatahuset_python_lib.egg-info/top_level.txt
26
+ tests/test_auth.py
27
+ tests/test_file_storage.py
@@ -0,0 +1,3 @@
1
+ numpy>=1.24
2
+ pandas>=2.0
3
+ pydantic>=2.0
@@ -0,0 +1,8 @@
1
+ from kystdatahuset.auth import login
2
+ import os
3
+
4
+ def test_login_success():
5
+ response = login(os.getenv("TEST_USERNAME"), os.getenv("TEST_PASSWORD"))
6
+ assert response is not None, "Expected a response, got None"
7
+ assert response.data is not None, "Response does not contain 'data'"
8
+ assert response.data.JWT is not None, "Response 'data' does not contain 'JWT'"
@@ -0,0 +1,16 @@
1
+ from kystdatahuset.file_storage import publish, list, delete
2
+ from uuid import UUID
3
+ from typing import List
4
+
5
+ def test_list(auth_jwt):
6
+ list_res = list(jwt_token=auth_jwt, resource_uuid=UUID("64127fc2-2644-4ed9-b886-fecfb914c4b5"))
7
+ assert isinstance(list_res, List) and len(list_res) >= 0, "Expected non-empty file list"
8
+
9
+ def test_publish(upload_filename, auth_jwt):
10
+ publish_res = publish(jwt_token=auth_jwt, resource_uuid=UUID("64127fc2-2644-4ed9-b886-fecfb914c4b5"), file_path=upload_filename, title="Test Upload", upload_file_type="csv", description="This is a test upload", categories=["test", "upload"], compressed=True)
11
+ assert publish_res is not None, "Expected publish to return True"
12
+
13
+ def test_delete(auth_jwt):
14
+ list_res = list(jwt_token=auth_jwt, resource_uuid=UUID("64127fc2-2644-4ed9-b886-fecfb914c4b5"))
15
+ delete_res = delete(jwt_token=auth_jwt, file_uuid=list_res[0].uuid)
16
+ assert delete_res == True, "Expected delete to return True"