xlwings-utils 25.0.7.post0__py3-none-any.whl → 25.0.8__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.

Potentially problematic release.


This version of xlwings-utils might be problematic. Click here for more details.

@@ -5,7 +5,7 @@
5
5
  # /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
6
6
  # |___/ |_____|
7
7
 
8
- __version__ = "25.0.7"
8
+ __version__ = "25.0.8"
9
9
 
10
10
 
11
11
  import dropbox
@@ -20,20 +20,48 @@ Pythonista = sys.platform == "ios"
20
20
  try:
21
21
  import xlwings
22
22
 
23
+ xlwings = True
24
+
23
25
  except ImportError:
24
26
  xlwings = False
25
27
 
26
28
  missing = object()
27
29
 
28
30
 
31
+ def pythonista_environ():
32
+ """
33
+ tries to update environment variables from the file environ.toml at top level.
34
+ should only be used under Pythonista
35
+ """
36
+ try:
37
+ import tomlib
38
+ except ModuleNotFoundError:
39
+ import tomli as tomlib
40
+ from pathlib import Path
41
+ import os
42
+
43
+ environ_file = Path("~/Documents").expanduser() / "environ.toml"
44
+ with open(environ_file, "rb") as f:
45
+ d0 = tomlib.load(f)
46
+ d1 = {}
47
+ for k0, v0 in d0.items():
48
+ if isinstance(v0, dict):
49
+ for k1, v1 in v0.items():
50
+ d1[f"{k0}.{k1}".upper()] = v1
51
+ else:
52
+ d1[k0.upper()] = v0
53
+
54
+ os.environ.update(d1)
55
+
56
+
29
57
  def dropbox_init(refresh_token=missing, app_key=missing, app_secret=missing, **kwargs):
30
58
  """
31
59
  dropbox initialize
32
60
 
33
61
  This function may to be called prior to using any dropbox function
34
62
  to specify the request token, app key and app secret.
35
- If these are specified as REFRESH_TOKEN, APP_KEY and APP_SECRET
36
- environment variables, it is no necessary to call dropbox_init().
63
+ If these are specified as DROPBOX.REFRESH_TOKEN, DROPBOX.APP_KEY and DROPBOX.APP_SECRET
64
+ environment variables, it is not necessary to call dropbox_init().
37
65
 
38
66
  Parameters
39
67
  ----------
@@ -55,47 +83,41 @@ def dropbox_init(refresh_token=missing, app_key=missing, app_secret=missing, **k
55
83
 
56
84
  Returns
57
85
  -------
58
- -
86
+ dropbox object
59
87
  """
60
88
  global dbx
61
89
 
62
90
  if Pythonista:
63
- # under Pythonista, the environ is updated from the .environ.toml file, if present
64
- environ_file = Path(os.environ["HOME"]) / "Documents" / ".environ.toml"
65
-
66
- if environ_file.is_file():
67
- with open(environ_file, "r") as f:
68
- import toml
69
-
70
- d = toml.load(f)
71
- os.environ.update(d)
91
+ pythonista_environ()
72
92
 
73
93
  if refresh_token is missing:
74
- if "REFRESH_TOKEN" in os.environ:
75
- refresh_token = os.environ["REFRESH_TOKEN"]
94
+ if "DROPBOX.REFRESH_TOKEN" in os.environ:
95
+ refresh_token = os.environ["DROPBOX.REFRESH_TOKEN"]
76
96
  else:
77
- raise ValueError("no REFRESH_TOKEN found in environment.")
97
+ raise ValueError("no DROPBOX.REFRESH_TOKEN found in environment.")
78
98
  if app_key is missing:
79
- if "APP_KEY" in os.environ:
80
- app_key = os.environ["APP_KEY"]
99
+ if "DROPBOX.APP_KEY" in os.environ:
100
+ app_key = os.environ["DROPBOX.APP_KEY"]
81
101
  else:
82
- raise ValueError("no APP_KEY found in environment.")
102
+ raise ValueError("no DROPBOX.APP_KEY found in environment.")
83
103
  if app_secret is missing:
84
- if "APP_SECRET" in os.environ:
85
- app_secret = os.environ["APP_SECRET"]
104
+ if "DROPBOX.APP_SECRET" in os.environ:
105
+ app_secret = os.environ["DROPBOX.APP_SECRET"]
86
106
  else:
87
- raise ValueError("no APP_SECRET found in environment.")
107
+ raise ValueError("no DROPBOX.APP_SECRET found in environment.")
88
108
 
89
- dbx = dropbox.Dropbox(oauth2_refresh_token=refresh_token, app_key=app_key, app_secret=app_secret, **kwargs)
109
+ _dbx = dropbox.Dropbox(oauth2_refresh_token=refresh_token, app_key=app_key, app_secret=app_secret, **kwargs)
90
110
  try:
91
- dbx.files_list_folder(path="") # just to test proper credentials
111
+ _dbx.files_list_folder(path="") # just to test proper credentials
92
112
  except dropbox.exceptions.AuthError:
93
113
  raise ValueError("invalid dropbox credentials")
114
+ return _dbx
94
115
 
95
116
 
96
117
  def _login_dbx():
118
+ global dbx
97
119
  if dbx is None:
98
- dropbox_init() # use environment
120
+ dbx = dropbox_init() # use environment
99
121
 
100
122
 
101
123
  def list_dropbox(path="", recursive=False, show_files=True, show_folders=False):
@@ -110,7 +132,7 @@ def list_dropbox(path="", recursive=False, show_files=True, show_folders=False):
110
132
  path from which to list all files (default: '')
111
133
 
112
134
  recursive : bool
113
- if True, recursively list files. if False (default) no recursion
135
+ if True, recursively list files and folders. if False (default) no recursion
114
136
 
115
137
  show_files : bool
116
138
  if True (default), show file entries
@@ -124,10 +146,6 @@ def list_dropbox(path="", recursive=False, show_files=True, show_folders=False):
124
146
  -------
125
147
  files : list
126
148
 
127
- Note
128
- ----
129
- Directory entries are never returned
130
-
131
149
  Note
132
150
  ----
133
151
  If REFRESH_TOKEN, APP_KEY and APP_SECRET environment variables are specified,
@@ -290,6 +308,11 @@ class block:
290
308
  self.number_of_rows = number_of_rows
291
309
  self.number_of_columns = number_of_columns
292
310
 
311
+ def __eq__(self, other):
312
+ if isinstance(other, block):
313
+ return self.value == other.value
314
+ return False
315
+
293
316
  @classmethod
294
317
  def from_value(cls, value, column_like=False):
295
318
  """
@@ -297,18 +320,12 @@ class block:
297
320
 
298
321
  Parameters
299
322
  ----------
300
- value : scaler, list of scalars, list of lists of scalars or block
323
+ value : scalar, list of scalars, list of lists of scalars or block
301
324
  value to be used in block, possibly expanded to a list of lists of scalars
302
325
 
303
326
  column_like : boolean
304
327
  if value is a list of scalars, values is interpreted as a column if True, as a row otherwise
305
328
 
306
- number_of_rows : int
307
- if given, expand or shrink to the given number of rows
308
-
309
- number_of_columns : int
310
- if given, expand or shrink to the given number of columns
311
-
312
329
  Returns
313
330
  -------
314
331
  block : block
@@ -328,7 +345,7 @@ class block:
328
345
  for column, item in enumerate(row_contents, 1):
329
346
  if item and not (isinstance(item, float) and math.isnan(item)):
330
347
  bl.dict[row, column] = item
331
- bl._number_of_columns = max(bl.number_of_columns, column)
348
+ bl._number_of_columns = max(bl.number_of_columns, column)
332
349
  return bl
333
350
 
334
351
  @classmethod
@@ -341,19 +358,12 @@ class block:
341
358
  rng : xlwings.Range
342
359
  range to be used be used in block
343
360
 
344
- number_of_rows : int
345
- if given, expand or shrink to the given number of rows
346
-
347
- number_of_columns : int
348
- if given, expand or shrink to the given number of columns
349
-
350
361
  Returns
351
362
  -------
352
363
  block : block
353
364
  """
354
365
  number_of_rows, number_of_columns = rng.shape
355
- bl = cls.from_value(rng.value, column_like=(number_of_columns == 1))
356
- return bl
366
+ return cls.from_value(rng.value, column_like=(number_of_columns == 1))
357
367
 
358
368
  @classmethod
359
369
  def from_xlrd_sheet(cls, sheet):
@@ -365,12 +375,6 @@ class block:
365
375
  sheet : xlrd sheet
366
376
  sheet to be used be used in block
367
377
 
368
- number_of_rows : int
369
- if given, expand or shrink to the given number of rows
370
-
371
- number_of_columns : int
372
- if given, expand or shrink to the given number of columns
373
-
374
378
  Returns
375
379
  -------
376
380
  block : block
@@ -380,6 +384,18 @@ class block:
380
384
 
381
385
  @classmethod
382
386
  def from_openpyxl_sheet(cls, sheet):
387
+ """
388
+ makes a block from an openpyxl sheet
389
+
390
+ Parameters
391
+ ----------
392
+ sheet : xlrd sheet
393
+ sheet to be used be used in block
394
+
395
+ Returns
396
+ -------
397
+ block : block
398
+ """
383
399
  v = [[cell.value for cell in row] for row in sheet.iter_rows()]
384
400
  return cls.from_value(v)
385
401
 
@@ -393,12 +409,6 @@ class block:
393
409
  filename : str
394
410
  file to be used be used in block
395
411
 
396
- number_of_rows : int
397
- if given, expand or shrink to the given number of rows
398
-
399
- number_of_columns : int
400
- if given, expand or shrink to the given number of columns
401
-
402
412
  Returns
403
413
  -------
404
414
  block : block
@@ -417,12 +427,6 @@ class block:
417
427
  df : pandas dataframe
418
428
  dataframe to be used be used in block
419
429
 
420
- number_of_rows : int
421
- if given, expand or shrink to the given number of rows
422
-
423
- number_of_columns : int
424
- if given, expand or shrink to the given number of columns
425
-
426
430
  Returns
427
431
  -------
428
432
  block : block
@@ -432,18 +436,12 @@ class block:
432
436
 
433
437
  def to_openpyxl_sheet(self, sheet):
434
438
  """
435
- makes a block from a given openpyxl sheet
439
+ appends a block to a given openpyxl sheet
436
440
 
437
441
  Parameters
438
442
  ----------
439
443
  sheet: openpyxl sheet
440
- sheet to be used be used in block
441
-
442
- number_of_rows : int
443
- if given, expand or shrink to the given number of rows
444
-
445
- number_of_columns : int
446
- if given, expand or shrink to the given number of columns
444
+ sheet to be used be used
447
445
 
448
446
  Returns
449
447
  -------
@@ -488,7 +486,11 @@ class block:
488
486
  raise IndexError(f"row must be between 1 and {self.number_of_rows} not {row}")
489
487
  if column < 1 or column > self.number_of_columns:
490
488
  raise IndexError(f"column must be between 1 and {self.number_of_columns} not {column}")
491
- self.dict[row, column] = value
489
+ if value is None:
490
+ if (row, column) in self.dict:
491
+ del self.dict[row, column]
492
+ else:
493
+ self.dict[row, column] = value
492
494
 
493
495
  def __getitem__(self, row_column):
494
496
  row, column = row_column
@@ -562,7 +564,7 @@ class block:
562
564
  if column > self.number_of_columns:
563
565
  raise ValueError(f"{name}={column} > number_of_columns={self.number_of_columns}")
564
566
 
565
- def transpose(self):
567
+ def transposed(self):
566
568
  """
567
569
  transpose block
568
570
 
@@ -827,7 +829,16 @@ class block:
827
829
 
828
830
  def decode_to_files(self):
829
831
  """
830
- decode the block with encoded file(s) to individual pyoidide files
832
+ decode the block with encoded file(s) to individual pyoidide file(s)
833
+
834
+ Returns
835
+ -------
836
+ count : int
837
+ number of files decoded
838
+
839
+ Note
840
+ ----
841
+ if the block does not contain an encode file, the method just returns 0
831
842
  """
832
843
  count = 0
833
844
  for column in range(1, self.number_of_columns + 1):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlwings_utils
3
- Version: 25.0.7.post0
3
+ Version: 25.0.8
4
4
  Summary: xlwings_utils
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/salabim/xlwings_utils
@@ -51,7 +51,9 @@ The xlwings lite system does not provide access to the local file system. With t
51
51
 
52
52
  Currently, it is only possible to use full-access Dropbox apps.
53
53
 
54
- The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables. Instructions on how to get these variables can be found here.
54
+ The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add DROPBOX.REFRESH_TOKEN,
55
+ DROPBOX.APP_KEY and DROPBOX.APP_SECRET with their corresponding values to the environment variables.
56
+ Instructions on how to get these variables can be found here.
55
57
 
56
58
  In order to make a Dropbox app, and get the required environment variables, just execute this line from the command line (shell).
57
59
 
@@ -60,7 +62,7 @@ python -c "exec(__import__('requests').get('https://salabim.org/dropbox setup.py
60
62
  ```
61
63
 
62
64
  Then, it is possible to list all files in a specified folder using the list_dropbox function.
63
- It is also possible to get the folders and to access all underlying folders.
65
+ It is also possible to get at all folders and to access all underlying folders.
64
66
 
65
67
  The `read_dropbox` function can be used to read the contents (bytes) of a Dropbox file. As reading from Dropbox under pyodide is rather unreliable, xlwings_utils automatically retries several times (by default 100 times). The actual number of retries can be found with `read_dropbox.retries`.
66
68
 
@@ -0,0 +1,6 @@
1
+ xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
+ xlwings_utils/xlwings_utils.py,sha256=HNip6tVo2sxhlysNm2zWVRY2bciWUujpzN-NmISUOiM,28690
3
+ xlwings_utils-25.0.8.dist-info/METADATA,sha256=KwS8dQNtM4n95zj2EXYaQfZFXMGga8MkQKVchmCQO9w,12447
4
+ xlwings_utils-25.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ xlwings_utils-25.0.8.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
+ xlwings_utils-25.0.8.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
- xlwings_utils/xlwings_utils.py,sha256=f13mQGcZ6syg7vkU97iYEHXj4Mlai6gPZd0XhOkxiwY,28717
3
- xlwings_utils-25.0.7.post0.dist-info/METADATA,sha256=vsTv_WzSM6miRYN5OltUUr2i5YkybpepE9crGXMZrZk,12424
4
- xlwings_utils-25.0.7.post0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- xlwings_utils-25.0.7.post0.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
- xlwings_utils-25.0.7.post0.dist-info/RECORD,,