nc-py-api 0.18.1__py3-none-any.whl → 0.19.0__py3-none-any.whl

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.
nc_py_api/_session.py CHANGED
@@ -12,6 +12,7 @@ from json import loads
12
12
  from os import environ
13
13
 
14
14
  from httpx import AsyncClient, Client, Headers, Limits, ReadTimeout, Request, Response
15
+ from httpx import __version__ as httpx_version
15
16
  from starlette.requests import HTTPConnection
16
17
 
17
18
  from . import options
@@ -477,7 +478,6 @@ class NcSessionAppBasic(ABC):
477
478
 
478
479
  def sign_check(self, request: HTTPConnection) -> str:
479
480
  headers = {
480
- "AA-VERSION": request.headers.get("AA-VERSION", ""),
481
481
  "EX-APP-ID": request.headers.get("EX-APP-ID", ""),
482
482
  "EX-APP-VERSION": request.headers.get("EX-APP-VERSION", ""),
483
483
  "AUTHORIZATION-APP-API": request.headers.get("AUTHORIZATION-APP-API", ""),
@@ -511,6 +511,7 @@ class NcSessionApp(NcSessionAppBasic, NcSessionBasic):
511
511
  "AA-VERSION": self.cfg.aa_version,
512
512
  "EX-APP-ID": self.cfg.app_name,
513
513
  "EX-APP-VERSION": self.cfg.app_version,
514
+ "user-agent": f"ExApp/{self.cfg.app_name}/{self.cfg.app_version} (httpx/{httpx_version})",
514
515
  },
515
516
  )
516
517
 
@@ -535,6 +536,7 @@ class AsyncNcSessionApp(NcSessionAppBasic, AsyncNcSessionBasic):
535
536
  "AA-VERSION": self.cfg.aa_version,
536
537
  "EX-APP-ID": self.cfg.app_name,
537
538
  "EX-APP-VERSION": self.cfg.app_version,
539
+ "User-Agent": f"ExApp/{self.cfg.app_name}/{self.cfg.app_version} (httpx/{httpx_version})",
538
540
  },
539
541
  )
540
542
 
nc_py_api/_version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Version of nc_py_api."""
2
2
 
3
- __version__ = "0.18.1"
3
+ __version__ = "0.19.0"
@@ -10,7 +10,7 @@ from .integration_fastapi import (
10
10
  set_handlers,
11
11
  talk_bot_msg,
12
12
  )
13
- from .logging import setup_nextcloud_logging
13
+ from .logger import setup_nextcloud_logging
14
14
  from .misc import (
15
15
  get_computation_device,
16
16
  get_model_path,
@@ -241,7 +241,7 @@ class AppAPIAuthMiddleware:
241
241
 
242
242
  async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
243
243
  """Method that will be called by Starlette for each event."""
244
- if scope["type"] != "http":
244
+ if scope["type"] not in ("http", "websocket"):
245
245
  await self.app(scope, receive, send)
246
246
  return
247
247
 
@@ -86,6 +86,7 @@ class FsNodeInfo:
86
86
  is_version: bool
87
87
  """Flag indicating if the object is File Version representation"""
88
88
  _last_modified: datetime.datetime
89
+ _creation_date: datetime.datetime
89
90
  _trashbin: dict
90
91
 
91
92
  def __init__(self, **kwargs):
@@ -102,6 +103,10 @@ class FsNodeInfo:
102
103
  self.last_modified = kwargs.get("last_modified", datetime.datetime(1970, 1, 1))
103
104
  except (ValueError, TypeError):
104
105
  self.last_modified = datetime.datetime(1970, 1, 1)
106
+ try:
107
+ self.creation_date = kwargs.get("creation_date", datetime.datetime(1970, 1, 1))
108
+ except (ValueError, TypeError):
109
+ self.creation_date = datetime.datetime(1970, 1, 1)
105
110
  self._trashbin: dict[str, str | int] = {}
106
111
  for i in ("trashbin_filename", "trashbin_original_location", "trashbin_deletion_time"):
107
112
  if i in kwargs:
@@ -142,6 +147,18 @@ class FsNodeInfo:
142
147
  else:
143
148
  self._last_modified = value
144
149
 
150
+ @property
151
+ def creation_date(self) -> datetime.datetime:
152
+ """Time when the object was created."""
153
+ return self._creation_date
154
+
155
+ @creation_date.setter
156
+ def creation_date(self, value: str | datetime.datetime):
157
+ if isinstance(value, str):
158
+ self._creation_date = email.utils.parsedate_to_datetime(value)
159
+ else:
160
+ self._creation_date = value
161
+
145
162
  @property
146
163
  def in_trash(self) -> bool:
147
164
  """Returns ``True`` if the object is in trash."""
nc_py_api/files/_files.py CHANGED
@@ -16,6 +16,7 @@ from . import FsNode, SystemTag
16
16
  PROPFIND_PROPERTIES = [
17
17
  "d:resourcetype",
18
18
  "d:getlastmodified",
19
+ "d:creationdate",
19
20
  "d:getcontentlength",
20
21
  "d:getcontenttype",
21
22
  "d:getetag",
@@ -45,6 +46,7 @@ SEARCH_PROPERTIES_MAP = {
45
46
  "name": "d:displayname", # like, eq
46
47
  "mime": "d:getcontenttype", # like, eq
47
48
  "last_modified": "d:getlastmodified", # gt, eq, lt
49
+ "creation_date": "d:creationdate", # gt, eq, lt
48
50
  "size": "oc:size", # gt, gte, eq, lt
49
51
  "favorite": "oc:favorite", # eq
50
52
  "fileid": "oc:fileid", # eq
@@ -286,6 +288,8 @@ def _parse_record(full_path: str, prop_stats: list[dict]) -> FsNode: # noqa pyl
286
288
  fs_node_args["etag"] = prop["d:getetag"]
287
289
  if "d:getlastmodified" in prop_keys:
288
290
  fs_node_args["last_modified"] = prop["d:getlastmodified"]
291
+ if "d:creationdate" in prop_keys:
292
+ fs_node_args["creation_date"] = prop["d:creationdate"]
289
293
  if "d:getcontenttype" in prop_keys:
290
294
  fs_node_args["mimetype"] = prop["d:getcontenttype"]
291
295
  if "oc:permissions" in prop_keys:
nc_py_api/nextcloud.py CHANGED
@@ -29,7 +29,7 @@ from ._talk_api import _AsyncTalkAPI, _TalkAPI
29
29
  from ._theming import ThemingInfo, get_parsed_theme
30
30
  from .activity import _ActivityAPI, _AsyncActivityAPI
31
31
  from .apps import _AppsAPI, _AsyncAppsAPI
32
- from .calendar import _CalendarAPI
32
+ from .calendar_api import _CalendarAPI
33
33
  from .ex_app.defs import LogLvl
34
34
  from .ex_app.events_listener import AsyncEventsListenerAPI, EventsListenerAPI
35
35
  from .ex_app.occ_commands import AsyncOccCommandsAPI, OccCommandsAPI
nc_py_api/options.py CHANGED
@@ -33,11 +33,22 @@ NPA_NC_CERT: bool | str
33
33
  SSL certificates (a.k.a CA bundle) used to verify the identity of requested hosts. Either **True** (default CA bundle),
34
34
  a path to an SSL certificate file, or **False** (which will disable verification)."""
35
35
  str_val = environ.get("NPA_NC_CERT", "True")
36
- NPA_NC_CERT = True
36
+ # https://github.com/encode/httpx/issues/302
37
+ # when "httpx" will switch to use "truststore" by default - uncomment next line
38
+ # NPA_NC_CERT = True
37
39
  if str_val.lower() in ("false", "0"):
38
40
  NPA_NC_CERT = False
39
41
  elif str_val.lower() not in ("true", "1"):
40
42
  NPA_NC_CERT = str_val
43
+ else:
44
+ # Temporary workaround, see comment above.
45
+ # Use system certificate stores
46
+
47
+ import ssl
48
+
49
+ import truststore
50
+
51
+ NPA_NC_CERT = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
41
52
 
42
53
  CHUNKED_UPLOAD_V2 = environ.get("CHUNKED_UPLOAD_V2", True)
43
54
  """Option to enable/disable **version 2** chunked upload(better Object Storages support).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nc-py-api
3
- Version: 0.18.1
3
+ Version: 0.19.0
4
4
  Summary: Nextcloud Python Framework
5
5
  Project-URL: Changelog, https://github.com/cloud-py-api/nc_py_api/blob/main/CHANGELOG.md
6
6
  Project-URL: Documentation, https://cloud-py-api.github.io/nc_py_api/
@@ -34,6 +34,7 @@ Requires-Dist: fastapi>=0.109.2
34
34
  Requires-Dist: httpx>=0.25.2
35
35
  Requires-Dist: pydantic>=2.1.1
36
36
  Requires-Dist: python-dotenv>=1
37
+ Requires-Dist: truststore==0.10
37
38
  Requires-Dist: xmltodict>=0.13
38
39
  Provides-Extra: app
39
40
  Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'app'
@@ -86,7 +87,7 @@ Description-Content-Type: text/markdown
86
87
  [![Docs](https://github.com/cloud-py-api/nc_py_api/actions/workflows/docs.yml/badge.svg)](https://cloud-py-api.github.io/nc_py_api/)
87
88
  [![codecov](https://codecov.io/github/cloud-py-api/nc_py_api/branch/main/graph/badge.svg?token=C91PL3FYDQ)](https://codecov.io/github/cloud-py-api/nc_py_api)
88
89
 
89
- ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-27%20%7C%2028%20%7C%2029%20%7C%2030-blue)
90
+ ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-%2028%20%7C%2029%20%7C%2030%20%7C%2031-blue)
90
91
  ![PythonVersion](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)
91
92
  ![impl](https://img.shields.io/pypi/implementation/nc_py_api)
92
93
  ![pypi](https://img.shields.io/pypi/v/nc_py_api.svg)
@@ -94,6 +95,7 @@ Description-Content-Type: text/markdown
94
95
  Python library that provides a robust and well-documented API that allows developers to interact with and extend Nextcloud's functionality.
95
96
 
96
97
  ### The key features are:
98
+
97
99
  * **Fast**: High performance, and as low-latency as possible.
98
100
  * **Intuitive**: Fast to code, easy to use.
99
101
  * **Reliable**: Minimum number of incompatible changes.
@@ -101,24 +103,6 @@ Python library that provides a robust and well-documented API that allows develo
101
103
  * **Easy**: Designed to be easy to use with excellent documentation.
102
104
  * **Sync + Async**: Provides both sync and async APIs.
103
105
 
104
- ### Capabilities
105
- | **_Capability_** | Nextcloud 27 | Nextcloud 28 | Nextcloud 29 | Nextcloud 30 |
106
- |------------------------------|:------------:|:------------:|:------------:|:------------:|
107
- | Calendar | ✅ | ✅ | ✅ | ✅ |
108
- | File System & Tags | ✅ | ✅ | ✅ | ✅ |
109
- | Nextcloud Talk | ✅ | ✅ | ✅ | ✅ |
110
- | Notifications | ✅ | ✅ | ✅ | ✅ |
111
- | Shares | ✅ | ✅ | ✅ | ✅ |
112
- | Users & Groups | ✅ | ✅ | ✅ | ✅ |
113
- | User & Weather status | ✅ | ✅ | ✅ | ✅ |
114
- | Other APIs** | ✅ | ✅ | ✅ | ✅ |
115
- | Talk Bot API* | ✅ | ✅ | ✅ | ✅ |
116
- | Settings UI API* | N/A | N/A | ✅ | ✅ |
117
- | TaskProcessing Provider API* | N/A | N/A | N/A | ✅ |
118
-
119
- &ast;_available only for **NextcloudApp**_<br>
120
- &ast;&ast;_Activity, Notes_
121
-
122
106
  ### Differences between the Nextcloud and NextcloudApp classes
123
107
 
124
108
  The **Nextcloud** class functions as a standard Nextcloud client,
@@ -135,8 +119,6 @@ but NextcloudApp has a broader selection since applications typically require ac
135
119
  Any code written for the Nextcloud class can easily be adapted for use with the NextcloudApp class,
136
120
  as long as it doesn't involve calls that require user password verification.
137
121
 
138
- **NextcloudApp** avalaible only from Nextcloud 27.1.2 and greater version with installed **AppAPI**.
139
-
140
122
  ### Nextcloud skeleton app in Python
141
123
 
142
124
  ```python3
@@ -4,18 +4,18 @@ nc_py_api/_exceptions.py,sha256=7vbUECaLmD7RJBCU27t4fuP6NmQK6r4508u_gS4szhI,2298
4
4
  nc_py_api/_misc.py,sha256=dUzCP9VmyhtICTsn1aexlFAYUioBm40k6Zh-YE5WwCY,3333
5
5
  nc_py_api/_preferences.py,sha256=OtovFZuGHnHYKjdDjSnUappO795tW8Oxj7qVaejHWpQ,2479
6
6
  nc_py_api/_preferences_ex.py,sha256=tThj6U0ZZMaBZ-jUkjrbaI0xDnafWsBowQKsC6gjOQs,7179
7
- nc_py_api/_session.py,sha256=ZD0TKrL-tOpxYtV6AO0cwRrYzbnjBr_ylCEUirrykjU,20242
7
+ nc_py_api/_session.py,sha256=mIxppN59t4u0mSqcZjRWqiVPl4EBt_ZK0c1Q-Vi6cec,20438
8
8
  nc_py_api/_talk_api.py,sha256=0Uo7OduYniuuX3UQPb468RyGJJ-PWBCgJ5HoPuz5Qa0,51068
9
9
  nc_py_api/_theming.py,sha256=hTr3nuOemSuRFZaPy9iXNmBM7rDgQHECH43tHMWGqEY,1870
10
- nc_py_api/_version.py,sha256=vPHaIX0sBYHr1ilh-YTVqasI6cM7TDtyHmVDvps_3zY,52
10
+ nc_py_api/_version.py,sha256=pjQIAjVuhhl9yT96je-tolLueZcoR9gYqLvoFS2QzH0,52
11
11
  nc_py_api/activity.py,sha256=t9VDSnnaXRNOvALqOSGCeXSQZ-426pCOMSfQ96JHys4,9574
12
12
  nc_py_api/apps.py,sha256=Us2y2lszdxXlD8t6kxwd5_Nrrmazc0EvZXIH9O-ol80,9315
13
- nc_py_api/calendar.py,sha256=-T6CJ8cRbJZTLtxSEDWuuYpD29DMJGCTfLONmtxZV9w,1445
13
+ nc_py_api/calendar_api.py,sha256=-T6CJ8cRbJZTLtxSEDWuuYpD29DMJGCTfLONmtxZV9w,1445
14
14
  nc_py_api/loginflow_v2.py,sha256=UjkK3gMouzNrIS7BFhjbmB_9m4fP2UY5sfpmvJ2EXWk,5760
15
- nc_py_api/nextcloud.py,sha256=Uc4hOtLNkvl8sjKmAGS-vyKdiA1gEZwRr1wj0Sd_ONk,23005
15
+ nc_py_api/nextcloud.py,sha256=MTuskKYKu3nSaP2uwR-IoC714ejV_HqtfdO71Ro4-iI,23009
16
16
  nc_py_api/notes.py,sha256=ljO3TOe-Qg0bJ0mlFQwjg--Pxmj-XFknoLbcbJmII0A,15106
17
17
  nc_py_api/notifications.py,sha256=WgzV21TuLOhLk-UEjhBSbMsIi2isa5MmAx6cbe0pc2Y,9187
18
- nc_py_api/options.py,sha256=K5co-fIfFVbwF6r3sqWsJF3cKgAbS2CjLAXdyTOkP9s,1717
18
+ nc_py_api/options.py,sha256=ZKJqVLhWVwJ6YxAKzGWlPXJhd1vg9GluyFzr-jX4Jp0,2038
19
19
  nc_py_api/talk.py,sha256=OZFemYkDOaM6o4xAK3EvQbjMFiK75E5qnsCDyihIElg,29368
20
20
  nc_py_api/talk_bot.py,sha256=_RuImwb3jYvUKX3ywcX095ucOjECCxsuc59heIxNoTM,16725
21
21
  nc_py_api/user_status.py,sha256=I101nwYS8X1WvC8AnLa2f3qJUCPDPHrbq-ke0h1VT4E,13282
@@ -23,11 +23,11 @@ nc_py_api/users.py,sha256=SQG8Agplaxy7XJgguK-rxV-azpc-QdktbDmLmQtJkXo,15476
23
23
  nc_py_api/users_groups.py,sha256=IPxw-Ks5NjCm6r8_HC9xmf3IYptH00ulITbp5iazhAo,6289
24
24
  nc_py_api/weather_status.py,sha256=wAkjuJPjxc0Rxe4za0BzfwB0XeUmkCXoisJtTH3-qdQ,7582
25
25
  nc_py_api/webhooks.py,sha256=14nAMy-tnOvmRnJbo42zUHyjX-z6kc9OMDUVKzNmplY,7769
26
- nc_py_api/ex_app/__init__.py,sha256=hFbu6wTXs-wmjs1tavm_HYLwiqgrp7_qJe-stzCiqfI,692
26
+ nc_py_api/ex_app/__init__.py,sha256=6Lwid4bBXOSrZf_ocf5m8qkkO1OgYxG0GTs4q6Nw72o,691
27
27
  nc_py_api/ex_app/defs.py,sha256=FaQInH3jLugKxDUqpwrXdkMT-lBxmoqWmXJXc11fa6A,727
28
28
  nc_py_api/ex_app/events_listener.py,sha256=pgQ4hSQV39NuP9F9IDWxo0Qle6oG15-Ol2FlItnIBGY,4682
29
- nc_py_api/ex_app/integration_fastapi.py,sha256=xh-gSxYH6_FE8GluajlrVAHZg1HZeaAxJ-jIUP6uot4,11022
30
- nc_py_api/ex_app/logging.py,sha256=nAHLObuPvl3UBLrlqZulgoxxVaAJ661iP4F6bTW-V-Y,1475
29
+ nc_py_api/ex_app/integration_fastapi.py,sha256=a3mhbBFrv_IaRqaYfKa26duiufZL-hSDFqcPDr59Vts,11041
30
+ nc_py_api/ex_app/logger.py,sha256=nAHLObuPvl3UBLrlqZulgoxxVaAJ661iP4F6bTW-V-Y,1475
31
31
  nc_py_api/ex_app/misc.py,sha256=c7B0uE8isaIi4SQbxURGUuWjZaaXiLg3Ov6cqvRYplE,2298
32
32
  nc_py_api/ex_app/occ_commands.py,sha256=hb2BJuvFKIigvLycSCyAe9v6hedq4Gfu2junQZTaK_M,5219
33
33
  nc_py_api/ex_app/persist_transformers_cache.py,sha256=ZoEBb1RnNaQrtxK_CjSZ8LZ36Oakz2Xciau_ZpNp8Ic,213
@@ -41,13 +41,13 @@ nc_py_api/ex_app/ui/resources.py,sha256=Vwx69oZ93Ouh6HJtGUqaKFUr4Reo74H4vT1YCpb-
41
41
  nc_py_api/ex_app/ui/settings.py,sha256=f0R17lGhBfo2JQULVw_hFxhpfoPw_CW7vBu0Rb1ABJw,6623
42
42
  nc_py_api/ex_app/ui/top_menu.py,sha256=oCgGtIoMYbp-5iN5aXEbT7Q88HtccR7hg6IBFgbbyX4,5118
43
43
  nc_py_api/ex_app/ui/ui.py,sha256=OqFHKn6oIZli8T1wnv6YtQ4glNfeNb90WwGCvtWI1Z4,1632
44
- nc_py_api/files/__init__.py,sha256=uSjqZyYAq9x3xOb_yz15KNNAcPo1PhbpPLtPz_ej-Eo,17303
45
- nc_py_api/files/_files.py,sha256=_s_f8xbzQPEH2F2LNwomI9CxscYHryus1pMZ_vW00C4,13666
44
+ nc_py_api/files/__init__.py,sha256=aN6Lhc0km5eAIGFA8YoG-xXDOzIJILV2izCzHeC-a78,17949
45
+ nc_py_api/files/_files.py,sha256=l1oGcXIKmuhlNthXkwL8qbINQgiMJ9wmFega9IP-wNk,13850
46
46
  nc_py_api/files/files.py,sha256=7x4hfnVa2y1R5bxK9f8cdggi1gPnpUYnsBj0e4p-4qc,24926
47
47
  nc_py_api/files/files_async.py,sha256=nyDeWiGx_8CHuVrNThSgfZy0l-WlC4El-TzJONo0TsM,25773
48
48
  nc_py_api/files/sharing.py,sha256=VRZCl-TYK6dbu9rUHPs3_jcVozu1EO8bLGZwoRpiLsU,14439
49
- nc_py_api-0.18.1.dist-info/METADATA,sha256=kNiYxJLCeclDF7NYY0B3sa9nXkqqm7T1yfZfE4Yx7GE,9502
50
- nc_py_api-0.18.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
- nc_py_api-0.18.1.dist-info/licenses/AUTHORS,sha256=B2Q9q9XH3PAxJp0V3GiKQc1l0z7vtGDpDHqda-ISWKM,616
52
- nc_py_api-0.18.1.dist-info/licenses/LICENSE.txt,sha256=OLEMh401fAumGHfRSna365MLIfnjdTcdOHZ6QOzMjkg,1551
53
- nc_py_api-0.18.1.dist-info/RECORD,,
49
+ nc_py_api-0.19.0.dist-info/METADATA,sha256=JdeWl1GIKzsGQc3n7I0_WmT_OkPPFOJD15Qkr9MTUyQ,8055
50
+ nc_py_api-0.19.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
+ nc_py_api-0.19.0.dist-info/licenses/AUTHORS,sha256=B2Q9q9XH3PAxJp0V3GiKQc1l0z7vtGDpDHqda-ISWKM,616
52
+ nc_py_api-0.19.0.dist-info/licenses/LICENSE.txt,sha256=OLEMh401fAumGHfRSna365MLIfnjdTcdOHZ6QOzMjkg,1551
53
+ nc_py_api-0.19.0.dist-info/RECORD,,
File without changes
File without changes