tallyfy 1.0.7__tar.gz → 1.0.9__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.

Potentially problematic release.


This version of tallyfy might be problematic. Click here for more details.

Files changed (40) hide show
  1. {tallyfy-1.0.7 → tallyfy-1.0.9}/CHANGELOG.md +1 -1
  2. {tallyfy-1.0.7/tallyfy.egg-info → tallyfy-1.0.9}/PKG-INFO +2 -2
  3. {tallyfy-1.0.7 → tallyfy-1.0.9}/README.md +1 -1
  4. {tallyfy-1.0.7 → tallyfy-1.0.9}/pyproject.toml +1 -1
  5. {tallyfy-1.0.7 → tallyfy-1.0.9}/setup.py +1 -1
  6. tallyfy-1.0.9/tallyfy/organization_management/__init__.py +26 -0
  7. tallyfy-1.0.9/tallyfy/organization_management/base.py +76 -0
  8. tallyfy-1.0.9/tallyfy/organization_management/retrieval.py +39 -0
  9. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/analysis.py +9 -3
  10. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/automation.py +1 -1
  11. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/health_assessment.py +40 -10
  12. {tallyfy-1.0.7 → tallyfy-1.0.9/tallyfy.egg-info}/PKG-INFO +2 -2
  13. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy.egg-info/SOURCES.txt +3 -0
  14. {tallyfy-1.0.7 → tallyfy-1.0.9}/.github/workflows/build-whl.yml +0 -0
  15. {tallyfy-1.0.7 → tallyfy-1.0.9}/LICENSE +0 -0
  16. {tallyfy-1.0.7 → tallyfy-1.0.9}/setup.cfg +0 -0
  17. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/__init__.py +0 -0
  18. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/core.py +0 -0
  19. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/form_fields_management/__init__.py +0 -0
  20. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/form_fields_management/base.py +0 -0
  21. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/form_fields_management/crud_operations.py +0 -0
  22. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/form_fields_management/options_management.py +0 -0
  23. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/form_fields_management/suggestions.py +0 -0
  24. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/models.py +0 -0
  25. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/task_management/__init__.py +0 -0
  26. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/task_management/base.py +0 -0
  27. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/task_management/creation.py +0 -0
  28. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/task_management/retrieval.py +0 -0
  29. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/task_management/search.py +0 -0
  30. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/__init__.py +0 -0
  31. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/base.py +0 -0
  32. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/template_management/basic_operations.py +0 -0
  33. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/user_management/__init__.py +0 -0
  34. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/user_management/base.py +0 -0
  35. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/user_management/invitation.py +0 -0
  36. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy/user_management/retrieval.py +0 -0
  37. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy.egg-info/dependency_links.txt +0 -0
  38. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy.egg-info/not-zip-safe +0 -0
  39. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy.egg-info/requires.txt +0 -0
  40. {tallyfy-1.0.7 → tallyfy-1.0.9}/tallyfy.egg-info/top_level.txt +0 -0
@@ -5,7 +5,7 @@ All notable changes to the Tallyfy SDK will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.0.7] - 2025-07-29
8
+ ## [1.0.9] - 2025-09-21
9
9
 
10
10
  ### Changed
11
11
  - **BREAKING**: Refactored user management from monolithic to modular architecture
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tallyfy
3
- Version: 1.0.7
3
+ Version: 1.0.9
4
4
  Summary: A comprehensive Python SDK for interacting with the Tallyfy API
5
5
  Home-page: https://github.com/tallyfy/tallyfy-sdk
6
6
  Author: Tallyfy
@@ -738,5 +738,5 @@ For bugs, feature requests, or questions:
738
738
  2. Contact us at: support@tallyfy.com
739
739
  ---
740
740
 
741
- **Version:** 1.0.7
741
+ **Version:** 1.0.9
742
742
  **Last Updated:** 2025
@@ -693,5 +693,5 @@ For bugs, feature requests, or questions:
693
693
  2. Contact us at: support@tallyfy.com
694
694
  ---
695
695
 
696
- **Version:** 1.0.7
696
+ **Version:** 1.0.9
697
697
  **Last Updated:** 2025
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tallyfy"
7
- version = "1.0.7"
7
+ version = "1.0.9"
8
8
  description = "A comprehensive Python SDK for interacting with the Tallyfy API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -17,7 +17,7 @@ def get_version():
17
17
  for line in f:
18
18
  if line.startswith('__version__'):
19
19
  return line.split('=')[1].strip().strip('"').strip("'")
20
- return '1.0.7'
20
+ return '1.0.9'
21
21
 
22
22
  setup(
23
23
  name='tallyfy',
@@ -0,0 +1,26 @@
1
+ """
2
+ Organization management module for Tallyfy SDK
3
+ """
4
+
5
+ from .base import OrganizationManagerBase
6
+ from .retrieval import OrganizationRetrieval
7
+
8
+ class OrganizationManager(OrganizationRetrieval):
9
+ """
10
+ Complete organization management interface combining all functionality.
11
+
12
+ This class provides access to:
13
+ - Organization retrieval operations
14
+
15
+ Example:
16
+ >>> from tallyfy import TallyfySDK
17
+ >>> sdk = TallyfySDK(api_key="your_api_key")
18
+ >>> orgs = sdk.organizations.get_current_user_organizations()
19
+ >>> print(f"User belongs to {len(orgs.data)} organizations")
20
+ """
21
+ pass
22
+
23
+ # Maintain backward compatibility
24
+ OrganizationManagement = OrganizationManager
25
+
26
+ __all__ = ['OrganizationManager', 'OrganizationManagement', 'OrganizationRetrieval', 'OrganizationManagerBase']
@@ -0,0 +1,76 @@
1
+ """
2
+ Base class for organization management operations
3
+ """
4
+
5
+ import logging
6
+ from typing import Dict, Any, List, Optional
7
+ from ..models import TallyfyError
8
+
9
+
10
+ class OrganizationManagerBase:
11
+ """Base class providing common functionality for organization management operations"""
12
+
13
+ def __init__(self, sdk):
14
+ """
15
+ Initialize the organization manager base.
16
+
17
+ Args:
18
+ sdk: The main Tallyfy SDK instance
19
+ """
20
+ self.sdk = sdk
21
+ self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
22
+
23
+ def _extract_data(self, response_data: Dict[str, Any], default_empty: bool = True) -> Any:
24
+ """
25
+ Extract data from API response.
26
+
27
+ Args:
28
+ response_data: Raw API response
29
+ default_empty: Return empty list if no data found
30
+
31
+ Returns:
32
+ Extracted data
33
+ """
34
+ if not response_data:
35
+ return [] if default_empty else None
36
+
37
+ # Handle direct data responses
38
+ if 'data' in response_data:
39
+ return response_data['data']
40
+
41
+ # Handle responses where the main content is directly available
42
+ # This is common for single item responses
43
+ return response_data if not default_empty else []
44
+
45
+ def _handle_api_error(self, error: Exception, operation: str, **context) -> None:
46
+ """
47
+ Handle and log API errors consistently.
48
+
49
+ Args:
50
+ error: The exception that occurred
51
+ operation: Description of the operation that failed
52
+ **context: Additional context for debugging
53
+ """
54
+ context_str = ", ".join([f"{k}={v}" for k, v in context.items()])
55
+ error_message = f"Failed to {operation}"
56
+ if context_str:
57
+ error_message += f" ({context_str})"
58
+
59
+ self.logger.error(f"{error_message}: {str(error)}")
60
+
61
+ if isinstance(error, TallyfyError):
62
+ raise error
63
+ else:
64
+ raise TallyfyError(f"{error_message}: {str(error)}")
65
+
66
+ def _build_query_params(self, **kwargs) -> Dict[str, Any]:
67
+ """
68
+ Build query parameters for API requests.
69
+
70
+ Args:
71
+ **kwargs: Parameters to include in the query string
72
+
73
+ Returns:
74
+ Dictionary of query parameters with None values filtered out
75
+ """
76
+ return {key: value for key, value in kwargs.items() if value is not None}
@@ -0,0 +1,39 @@
1
+ """
2
+ Organization retrieval operations
3
+ """
4
+
5
+ from typing import List, Optional
6
+ from .base import OrganizationManagerBase
7
+ from ..models import Organization, OrganizationsList, TallyfyError
8
+
9
+
10
+ class OrganizationRetrieval(OrganizationManagerBase):
11
+ """Handles organization retrieval operations"""
12
+
13
+ def get_current_user_organizations(self, page: int = 1, per_page: int = 10) -> OrganizationsList:
14
+ """
15
+ Get all organizations the current member is a part of.
16
+
17
+ Args:
18
+ page: Page number (default: 1)
19
+ per_page: Number of results per page (default: 10, max: 100)
20
+
21
+ Returns:
22
+ OrganizationsList object containing organizations and pagination metadata
23
+
24
+ Raises:
25
+ TallyfyError: If the request fails
26
+ """
27
+ try:
28
+ endpoint = "me/organizations"
29
+ params = self._build_query_params(page=page, per_page=min(per_page, 100))
30
+
31
+ response_data = self.sdk._make_request('GET', endpoint, params=params)
32
+
33
+ # Return the structured response with pagination
34
+ return OrganizationsList.from_dict(response_data)
35
+
36
+ except TallyfyError:
37
+ raise
38
+ except Exception as e:
39
+ self._handle_api_error(e, "get my organizations", page=page, per_page=per_page)
@@ -514,15 +514,21 @@ class TemplateAnalysis(TemplateManagerBase):
514
514
  raise TallyfyError("Unable to retrieve template data for kickoff field analysis")
515
515
 
516
516
  template_title = template_data.get('title', '').lower()
517
- template_summary = template_data.get('summary', '').lower()
517
+ try:
518
+ template_summary = template_data.get('summary', '').lower()
519
+ except:
520
+ template_summary = ''
518
521
  steps = template_data.get('steps', [])
519
522
  existing_prerun = template_data.get('prerun', [])
520
523
 
521
524
  # Collect all step content for analysis
522
525
  all_step_content = ""
523
- for step in steps:
526
+ for step in steps['data']:
524
527
  step_title = step.get('title', '').lower()
525
- step_summary = step.get('summary', '').lower()
528
+ try:
529
+ step_summary = step.get('summary', '').lower()
530
+ except:
531
+ step_summary = ''
526
532
  all_step_content += f" {step_title} {step_summary}"
527
533
 
528
534
  combined_content = f"{template_title} {template_summary} {all_step_content}"
@@ -360,7 +360,7 @@ class TemplateAutomation(TemplateManagerBase):
360
360
  steps = template_data.get('steps', [])
361
361
 
362
362
  # Create step lookup
363
- step_lookup = {step.get('id'): step.get('title', 'Unknown') for step in steps}
363
+ step_lookup = {step.get('id'): step.get('title', 'Unknown') for step in steps['data']}
364
364
 
365
365
  analysis = {
366
366
  'redundant_rules': [],
@@ -165,9 +165,12 @@ class TemplateHealthAssessment(TemplateManagerBase):
165
165
  score += 3
166
166
  else:
167
167
  score += 5
168
-
168
+
169
169
  # Check summary/description quality (5 points)
170
- summary = template_data.get('summary', '').strip()
170
+ try:
171
+ summary = template_data.get('summary', '').strip()
172
+ except:
173
+ summary = None
171
174
  if not summary:
172
175
  issues.append({
173
176
  'category': 'metadata',
@@ -189,7 +192,11 @@ class TemplateHealthAssessment(TemplateManagerBase):
189
192
  score += 5
190
193
 
191
194
  # Check guidance quality (5 points)
192
- guidance = template_data.get('guidance', '').strip()
195
+ try:
196
+ guidance = template_data.get('guidance', '').strip()
197
+ except:
198
+ guidance = None
199
+
193
200
  if not guidance:
194
201
  issues.append({
195
202
  'category': 'metadata',
@@ -243,8 +250,15 @@ class TemplateHealthAssessment(TemplateManagerBase):
243
250
  very_short_titles = 0
244
251
 
245
252
  for step in steps:
246
- step_title = step.get('title', '').strip()
247
- step_summary = step.get('summary', '').strip()
253
+ try:
254
+ step_title = step.get('title', '').strip()
255
+ except:
256
+ step_title = None
257
+
258
+ try:
259
+ step_summary = step.get('summary', '').strip()
260
+ except:
261
+ step_summary = None
248
262
 
249
263
  # Check title clarity
250
264
  if not step_title:
@@ -371,9 +385,22 @@ class TemplateHealthAssessment(TemplateManagerBase):
371
385
  # Check if steps might need forms
372
386
  form_keywords = ['input', 'enter', 'provide', 'fill', 'complete', 'details', 'information']
373
387
  steps_needing_forms = 0
374
-
375
- for step in steps:
376
- step_text = (step.get('title', '') + " " + step.get('summary', '')).lower()
388
+ for step in steps['data']:
389
+ try:
390
+ step_title = step.get('title', '').lower()
391
+ if not step_title:
392
+ step_title = ""
393
+ except:
394
+ step_title = ""
395
+
396
+ try:
397
+ step_summary = step.get('summary', '').lower()
398
+ if not step_summary:
399
+ step_summary = ""
400
+ except:
401
+ step_summary = ""
402
+
403
+ step_text = (step_title + " " + step_summary).lower()
377
404
  if any(keyword in step_text for keyword in form_keywords):
378
405
  steps_needing_forms += 1
379
406
 
@@ -496,7 +523,10 @@ class TemplateHealthAssessment(TemplateManagerBase):
496
523
  unreasonable_deadlines = 0
497
524
 
498
525
  for step in steps:
499
- deadline = step.get('deadline')
526
+ try:
527
+ deadline = step.get('deadline')
528
+ except:
529
+ deadline = None
500
530
  if deadline:
501
531
  steps_with_deadlines += 1
502
532
 
@@ -597,7 +627,7 @@ class TemplateHealthAssessment(TemplateManagerBase):
597
627
  score += 2
598
628
  else:
599
629
  score += 3
600
-
630
+ steps = steps['data']
601
631
  # Check step positioning and logic (5 points)
602
632
  positions = [step.get('position', 0) for step in steps]
603
633
  unique_positions = len(set(positions))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tallyfy
3
- Version: 1.0.7
3
+ Version: 1.0.9
4
4
  Summary: A comprehensive Python SDK for interacting with the Tallyfy API
5
5
  Home-page: https://github.com/tallyfy/tallyfy-sdk
6
6
  Author: Tallyfy
@@ -738,5 +738,5 @@ For bugs, feature requests, or questions:
738
738
  2. Contact us at: support@tallyfy.com
739
739
  ---
740
740
 
741
- **Version:** 1.0.7
741
+ **Version:** 1.0.9
742
742
  **Last Updated:** 2025
@@ -18,6 +18,9 @@ tallyfy/form_fields_management/base.py
18
18
  tallyfy/form_fields_management/crud_operations.py
19
19
  tallyfy/form_fields_management/options_management.py
20
20
  tallyfy/form_fields_management/suggestions.py
21
+ tallyfy/organization_management/__init__.py
22
+ tallyfy/organization_management/base.py
23
+ tallyfy/organization_management/retrieval.py
21
24
  tallyfy/task_management/__init__.py
22
25
  tallyfy/task_management/base.py
23
26
  tallyfy/task_management/creation.py
File without changes
File without changes
File without changes
File without changes
File without changes