meshtrade 0.0.7__py3-none-any.whl → 0.0.10__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 meshtrade might be problematic. Click here for more details.
- buf/validate/validate_pb2.py +450 -0
- buf/validate/validate_pb2.pyi +627 -0
- meshtrade/common/__init__.py +28 -0
- meshtrade/common/config.py +30 -0
- meshtrade/common/grpc_client.py +202 -0
- meshtrade/compliance/client/v1/__init__.py +89 -0
- meshtrade/compliance/client/v1/client_pb2.py +2 -2
- meshtrade/compliance/client/v1/client_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/company_pb2.py +2 -2
- meshtrade/compliance/client/v1/company_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/company_representative_pb2.py +2 -2
- meshtrade/compliance/client/v1/company_representative_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/company_representative_role_pb2.py +2 -2
- meshtrade/compliance/client/v1/company_representative_role_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/fund_pb2.py +2 -2
- meshtrade/compliance/client/v1/fund_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/identification_document_type_pb2.py +2 -2
- meshtrade/compliance/client/v1/identification_document_type_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/industry_classification_pb2.py +2 -2
- meshtrade/compliance/client/v1/industry_classification_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/natural_person_connection_type_pb2.py +2 -2
- meshtrade/compliance/client/v1/natural_person_connection_type_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/natural_person_pb2.py +2 -2
- meshtrade/compliance/client/v1/natural_person_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/pep_status_pb2.py +2 -2
- meshtrade/compliance/client/v1/pep_status_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/service_meshpy.py +186 -0
- meshtrade/compliance/client/v1/service_options_meshpy.py +65 -0
- meshtrade/compliance/client/v1/service_pb2.py +20 -10
- meshtrade/compliance/client/v1/service_pb2.pyi +8 -0
- meshtrade/compliance/client/v1/service_pb2_grpc.py +192 -0
- meshtrade/compliance/client/v1/source_of_income_and_wealth_pb2.py +2 -2
- meshtrade/compliance/client/v1/source_of_income_and_wealth_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/tax_residency_pb2.py +2 -2
- meshtrade/compliance/client/v1/tax_residency_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/trust_pb2.py +2 -2
- meshtrade/compliance/client/v1/trust_pb2_grpc.py +4 -0
- meshtrade/compliance/client/v1/verification_status_pb2.py +2 -2
- meshtrade/compliance/client/v1/verification_status_pb2_grpc.py +4 -0
- meshtrade/iam/api_user/v1/__init__.py +99 -0
- meshtrade/iam/api_user/v1/api_credentials.py +156 -0
- meshtrade/iam/api_user/v1/api_credentials_pb2.py +42 -0
- meshtrade/iam/api_user/v1/api_credentials_pb2.pyi +14 -0
- meshtrade/iam/api_user/v1/api_credentials_pb2_grpc.py +4 -0
- meshtrade/iam/api_user/v1/api_user_pb2.py +48 -0
- meshtrade/iam/api_user/v1/api_user_pb2.pyi +49 -0
- meshtrade/iam/api_user/v1/api_user_pb2_grpc.py +4 -0
- meshtrade/iam/api_user/v1/service.py +58 -0
- meshtrade/iam/api_user/v1/service_meshpy.py +255 -0
- meshtrade/iam/api_user/v1/service_options_meshpy.py +65 -0
- meshtrade/iam/api_user/v1/service_pb2.py +77 -0
- meshtrade/iam/api_user/v1/service_pb2.pyi +63 -0
- meshtrade/iam/api_user/v1/service_pb2_grpc.py +458 -0
- meshtrade/iam/group/v1/__init__.py +63 -0
- meshtrade/iam/group/v1/group_pb2.py +2 -2
- meshtrade/iam/group/v1/group_pb2_grpc.py +4 -0
- meshtrade/iam/group/v1/service_meshpy.py +187 -0
- meshtrade/iam/group/v1/service_options_meshpy.py +65 -0
- meshtrade/iam/group/v1/service_pb2.py +22 -6
- meshtrade/iam/group/v1/service_pb2.pyi +29 -1
- meshtrade/iam/group/v1/service_pb2_grpc.py +170 -0
- meshtrade/iam/role/v1/__init__.py +44 -0
- meshtrade/iam/role/v1/role.py +23 -0
- meshtrade/iam/role/v1/role_pb2.py +40 -0
- meshtrade/{option/v1/auth_pb2.pyi → iam/role/v1/role_pb2.pyi} +16 -0
- meshtrade/iam/role/v1/role_pb2_grpc.py +4 -0
- meshtrade/iam/user/v1/__init__.py +53 -0
- meshtrade/iam/user/v1/service_meshpy.py +151 -0
- meshtrade/iam/user/v1/service_options_meshpy.py +65 -0
- meshtrade/iam/user/v1/service_pb2.py +51 -0
- meshtrade/iam/user/v1/service_pb2.pyi +19 -0
- meshtrade/iam/user/v1/service_pb2_grpc.py +82 -0
- meshtrade/{issuance_hub/instrument/v1/instrument_pb2.py → iam/user/v1/user_pb2.py} +7 -7
- meshtrade/iam/user/v1/user_pb2.pyi +15 -0
- meshtrade/iam/user/v1/user_pb2_grpc.py +4 -0
- meshtrade/ledger/transaction/v1/__init__.py +41 -0
- meshtrade/ledger/transaction/v1/transaction_action_pb2.py +2 -2
- meshtrade/ledger/transaction/v1/transaction_action_pb2_grpc.py +4 -0
- meshtrade/ledger/transaction/v1/transaction_state_pb2.py +2 -2
- meshtrade/ledger/transaction/v1/transaction_state_pb2_grpc.py +4 -0
- meshtrade/option/v1/__init__.py +39 -0
- meshtrade/option/v1/{service_type_pb2.py → method_type_pb2.py} +7 -7
- meshtrade/option/v1/method_type_pb2.pyi +17 -0
- meshtrade/option/v1/method_type_pb2_grpc.py +4 -0
- meshtrade/trading/limit_order/v1/__init__.py +53 -0
- meshtrade/trading/limit_order/v1/limit_order_pb2.py +2 -2
- meshtrade/trading/limit_order/v1/limit_order_pb2_grpc.py +4 -0
- meshtrade/trading/limit_order/v1/service_meshpy.py +151 -0
- meshtrade/trading/limit_order/v1/service_options_meshpy.py +65 -0
- meshtrade/trading/limit_order/v1/service_pb2.py +10 -6
- meshtrade/trading/limit_order/v1/service_pb2.pyi +2 -0
- meshtrade/trading/limit_order/v1/service_pb2_grpc.py +78 -0
- meshtrade/trading/market_order/v1/__init__.py +53 -0
- meshtrade/trading/{direct_order/v1/direct_order_pb2.py → market_order/v1/market_order_pb2.py} +7 -7
- meshtrade/{issuance_hub/instrument/v1/instrument_pb2.pyi → trading/market_order/v1/market_order_pb2.pyi} +1 -1
- meshtrade/trading/market_order/v1/market_order_pb2_grpc.py +4 -0
- meshtrade/trading/market_order/v1/service_meshpy.py +151 -0
- meshtrade/trading/market_order/v1/service_options_meshpy.py +65 -0
- meshtrade/trading/market_order/v1/service_pb2.py +44 -0
- meshtrade/trading/{spot → market_order}/v1/service_pb2.pyi +4 -2
- meshtrade/trading/market_order/v1/service_pb2_grpc.py +78 -0
- meshtrade/type/v1/__init__.py +120 -4
- meshtrade/type/v1/address_pb2.py +2 -2
- meshtrade/type/v1/address_pb2_grpc.py +4 -0
- meshtrade/type/v1/amount.py +2 -8
- meshtrade/type/v1/amount_pb2.py +2 -2
- meshtrade/type/v1/amount_pb2_grpc.py +4 -0
- meshtrade/type/v1/contact_details_pb2.py +2 -2
- meshtrade/type/v1/contact_details_pb2_grpc.py +4 -0
- meshtrade/type/v1/date.py +373 -0
- meshtrade/{trading/spot/v1/spot_pb2.py → type/v1/date_pb2.py} +7 -7
- meshtrade/type/v1/date_pb2.pyi +15 -0
- meshtrade/type/v1/date_pb2_grpc.py +4 -0
- meshtrade/type/v1/decimal_built_in_conversions.py +1 -1
- meshtrade/type/v1/decimal_pb2.py +2 -2
- meshtrade/type/v1/decimal_pb2_grpc.py +4 -0
- meshtrade/type/v1/ledger.py +2 -3
- meshtrade/type/v1/ledger_pb2.py +2 -2
- meshtrade/type/v1/ledger_pb2_grpc.py +4 -0
- meshtrade/type/v1/time_of_day.py +265 -0
- meshtrade/type/v1/time_of_day_pb2.py +37 -0
- meshtrade/type/v1/time_of_day_pb2.pyi +17 -0
- meshtrade/type/v1/time_of_day_pb2_grpc.py +4 -0
- meshtrade/type/v1/token_pb2.py +2 -2
- meshtrade/type/v1/token_pb2_grpc.py +4 -0
- meshtrade/wallet/account/v1/__init__.py +65 -0
- meshtrade/wallet/account/v1/account_pb2.py +2 -2
- meshtrade/wallet/account/v1/account_pb2_grpc.py +4 -0
- meshtrade/wallet/account/v1/service_meshpy.py +204 -0
- meshtrade/wallet/account/v1/service_options_meshpy.py +65 -0
- meshtrade/wallet/account/v1/service_pb2.py +18 -27
- meshtrade/wallet/account/v1/service_pb2.pyi +2 -3
- meshtrade/wallet/account/v1/service_pb2_grpc.py +222 -0
- meshtrade-0.0.10.dist-info/METADATA +95 -0
- meshtrade-0.0.10.dist-info/RECORD +173 -0
- {meshtrade-0.0.7.dist-info → meshtrade-0.0.10.dist-info}/top_level.txt +1 -0
- meshtrade/issuance_hub/instrument/v1/service_pb2.py +0 -49
- meshtrade/issuance_hub/instrument/v1/service_pb2.pyi +0 -46
- meshtrade/option/v1/auth_pb2.py +0 -40
- meshtrade/option/v1/service_type_pb2.pyi +0 -17
- meshtrade/trading/direct_order/v1/__init__.py +0 -0
- meshtrade/trading/direct_order/v1/direct_order_pb2.pyi +0 -11
- meshtrade/trading/direct_order/v1/service_pb2.py +0 -40
- meshtrade/trading/direct_order/v1/service_pb2.pyi +0 -12
- meshtrade/trading/spot/__init__.py +0 -0
- meshtrade/trading/spot/v1/__init__.py +0 -0
- meshtrade/trading/spot/v1/service_pb2.py +0 -40
- meshtrade/trading/spot/v1/spot_pb2.pyi +0 -11
- meshtrade-0.0.7.dist-info/METADATA +0 -35
- meshtrade-0.0.7.dist-info/RECORD +0 -102
- meshtrade-0.0.7.dist-info/licenses/LICENSE +0 -10
- /meshtrade/{iam/role → ledger}/__init__.py +0 -0
- /meshtrade/{trading/direct_order → ledger/transaction}/__init__.py +0 -0
- {meshtrade-0.0.7.dist-info → meshtrade-0.0.10.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides helper functions for working with Date protobuf messages.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from datetime import date as python_date
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
from .date_pb2 import Date
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def new_date(year: int, month: int, day: int) -> Date:
|
|
12
|
+
"""Creates a new Date from year, month, and day values.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
year: Year value (1-9999)
|
|
16
|
+
month: Month value (1-12)
|
|
17
|
+
day: Day value (1-31)
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A Date protobuf message
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ValueError: If the date values are invalid
|
|
24
|
+
"""
|
|
25
|
+
_validate_date(year, month, day)
|
|
26
|
+
return Date(year=year, month=month, day=day)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def new_date_from_python_date(python_date_obj: python_date) -> Date:
|
|
30
|
+
"""Creates a Date from a Python date object.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
python_date_obj: A Python datetime.date object
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
A Date protobuf message
|
|
37
|
+
"""
|
|
38
|
+
return Date(year=python_date_obj.year, month=python_date_obj.month, day=python_date_obj.day)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def new_date_from_datetime(datetime_obj: datetime) -> Date:
|
|
42
|
+
"""Creates a Date from a Python datetime object.
|
|
43
|
+
Only extracts the date components, ignoring the time.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
datetime_obj: A Python datetime.datetime object
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
A Date protobuf message
|
|
50
|
+
"""
|
|
51
|
+
return new_date_from_python_date(datetime_obj.date())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def date_to_python_date(date_obj: Date) -> python_date:
|
|
55
|
+
"""Converts a Date protobuf message to a Python date object.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
date_obj: A Date protobuf message
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
A Python datetime.date object
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
ValueError: If the date is invalid
|
|
65
|
+
"""
|
|
66
|
+
if not date_obj:
|
|
67
|
+
raise ValueError("Date object is None")
|
|
68
|
+
|
|
69
|
+
if not date_is_valid(date_obj):
|
|
70
|
+
raise ValueError(f"Invalid date: year={date_obj.year}, month={date_obj.month}, day={date_obj.day}")
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
return python_date(date_obj.year, date_obj.month, date_obj.day)
|
|
74
|
+
except ValueError as e:
|
|
75
|
+
raise ValueError(f"Invalid date values: {e}") from e
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def date_is_valid(date_obj: Date | None) -> bool:
|
|
79
|
+
"""Checks if a Date has valid values according to the protobuf constraints.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
date_obj: A Date protobuf message or None
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
True if the date is valid, False otherwise
|
|
86
|
+
"""
|
|
87
|
+
if not date_obj:
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
_validate_date(date_obj.year, date_obj.month, date_obj.day)
|
|
92
|
+
return True
|
|
93
|
+
except ValueError:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def date_is_complete(date_obj: Date | None) -> bool:
|
|
98
|
+
"""Returns True if the date has non-zero year, month, and day values.
|
|
99
|
+
Since only full dates are valid, this is equivalent to is_valid().
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
date_obj: A Date protobuf message or None
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
True if the date is complete, False otherwise
|
|
106
|
+
"""
|
|
107
|
+
if not date_obj:
|
|
108
|
+
return False
|
|
109
|
+
return date_obj.year != 0 and date_obj.month != 0 and date_obj.day != 0
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def date_to_string(date_obj: Date | None) -> str:
|
|
113
|
+
"""Returns a string representation of the date.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
date_obj: A Date protobuf message or None
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
String representation of the date
|
|
120
|
+
"""
|
|
121
|
+
if not date_obj:
|
|
122
|
+
return "<undefined>"
|
|
123
|
+
|
|
124
|
+
if date_is_valid(date_obj):
|
|
125
|
+
return f"{date_obj.year:04d}-{date_obj.month:02d}-{date_obj.day:02d}"
|
|
126
|
+
else:
|
|
127
|
+
return f"Date(year={date_obj.year}, month={date_obj.month}, day={date_obj.day}) [INVALID]"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def date_is_before(date1: Date | None, date2: Date | None) -> bool:
|
|
131
|
+
"""Returns True if date1 is before date2.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
date1: First Date protobuf message or None
|
|
135
|
+
date2: Second Date protobuf message or None
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
True if date1 is before date2, False otherwise
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
ValueError: If either date is None or incomplete
|
|
142
|
+
"""
|
|
143
|
+
if not date1 or not date2:
|
|
144
|
+
raise ValueError("Both dates must be provided")
|
|
145
|
+
|
|
146
|
+
if not date_is_valid(date1) or not date_is_valid(date2):
|
|
147
|
+
raise ValueError("Both dates must be valid for comparison")
|
|
148
|
+
|
|
149
|
+
# Compare year first
|
|
150
|
+
if date1.year != date2.year:
|
|
151
|
+
return date1.year < date2.year
|
|
152
|
+
|
|
153
|
+
# Compare month if years are equal
|
|
154
|
+
if date1.month != date2.month:
|
|
155
|
+
return date1.month < date2.month
|
|
156
|
+
|
|
157
|
+
# Compare day if years and months are equal
|
|
158
|
+
return date1.day < date2.day
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def date_is_after(date1: Date | None, date2: Date | None) -> bool:
|
|
162
|
+
"""Returns True if date1 is after date2.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
date1: First Date protobuf message or None
|
|
166
|
+
date2: Second Date protobuf message or None
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
True if date1 is after date2, False otherwise
|
|
170
|
+
|
|
171
|
+
Raises:
|
|
172
|
+
ValueError: If either date is None or incomplete
|
|
173
|
+
"""
|
|
174
|
+
if not date1 or not date2:
|
|
175
|
+
raise ValueError("Both dates must be provided")
|
|
176
|
+
|
|
177
|
+
if not date_is_valid(date1) or not date_is_valid(date2):
|
|
178
|
+
raise ValueError("Both dates must be valid for comparison")
|
|
179
|
+
|
|
180
|
+
# Compare year first
|
|
181
|
+
if date1.year != date2.year:
|
|
182
|
+
return date1.year > date2.year
|
|
183
|
+
|
|
184
|
+
# Compare month if years are equal
|
|
185
|
+
if date1.month != date2.month:
|
|
186
|
+
return date1.month > date2.month
|
|
187
|
+
|
|
188
|
+
# Compare day if years and months are equal
|
|
189
|
+
return date1.day > date2.day
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def date_is_equal(date1: Date | None, date2: Date | None) -> bool:
|
|
193
|
+
"""Returns True if date1 is equal to date2.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
date1: First Date protobuf message or None
|
|
197
|
+
date2: Second Date protobuf message or None
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
True if date1 is equal to date2, False otherwise
|
|
201
|
+
"""
|
|
202
|
+
if not date1 and not date2:
|
|
203
|
+
return True
|
|
204
|
+
|
|
205
|
+
if not date1 or not date2:
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
return date1.year == date2.year and date1.month == date2.month and date1.day == date2.day
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def date_is_before_or_equal(date1: Date | None, date2: Date | None) -> bool:
|
|
212
|
+
"""Returns True if date1 is before or equal to date2.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
date1: First Date protobuf message or None
|
|
216
|
+
date2: Second Date protobuf message or None
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
True if date1 is before or equal to date2, False otherwise
|
|
220
|
+
|
|
221
|
+
Raises:
|
|
222
|
+
ValueError: If either date is None or incomplete
|
|
223
|
+
"""
|
|
224
|
+
return date_is_before(date1, date2) or date_is_equal(date1, date2)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def date_is_after_or_equal(date1: Date | None, date2: Date | None) -> bool:
|
|
228
|
+
"""Returns True if date1 is after or equal to date2.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
date1: First Date protobuf message or None
|
|
232
|
+
date2: Second Date protobuf message or None
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
True if date1 is after or equal to date2, False otherwise
|
|
236
|
+
|
|
237
|
+
Raises:
|
|
238
|
+
ValueError: If either date is None or incomplete
|
|
239
|
+
"""
|
|
240
|
+
return date_is_after(date1, date2) or date_is_equal(date1, date2)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def date_add_days(date_obj: Date, days: int) -> Date:
|
|
244
|
+
"""Adds a specified number of days to a date.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
date_obj: A Date protobuf message
|
|
248
|
+
days: Number of days to add (can be negative to subtract)
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
A new Date protobuf message with the days added
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
ValueError: If the date is None or incomplete
|
|
255
|
+
"""
|
|
256
|
+
if not date_obj:
|
|
257
|
+
raise ValueError("Date object is None")
|
|
258
|
+
|
|
259
|
+
if not date_is_valid(date_obj):
|
|
260
|
+
raise ValueError("Date must be valid to add days")
|
|
261
|
+
|
|
262
|
+
# Convert to Python date, add days, then convert back
|
|
263
|
+
py_date = date_to_python_date(date_obj)
|
|
264
|
+
from datetime import timedelta
|
|
265
|
+
|
|
266
|
+
new_py_date = py_date + timedelta(days=days)
|
|
267
|
+
|
|
268
|
+
return new_date_from_python_date(new_py_date)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def date_add_months(date_obj: Date, months: int) -> Date:
|
|
272
|
+
"""Adds a specified number of months to a date.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
date_obj: A Date protobuf message
|
|
276
|
+
months: Number of months to add (can be negative to subtract)
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
A new Date protobuf message with the months added
|
|
280
|
+
|
|
281
|
+
Raises:
|
|
282
|
+
ValueError: If the date is None or incomplete, or if the result is invalid
|
|
283
|
+
"""
|
|
284
|
+
if not date_obj:
|
|
285
|
+
raise ValueError("Date object is None")
|
|
286
|
+
|
|
287
|
+
if not date_is_valid(date_obj):
|
|
288
|
+
raise ValueError("Date must be valid to add months")
|
|
289
|
+
|
|
290
|
+
# Calculate new year and month
|
|
291
|
+
total_months = date_obj.year * 12 + date_obj.month - 1 + months
|
|
292
|
+
new_year = total_months // 12
|
|
293
|
+
new_month = (total_months % 12) + 1
|
|
294
|
+
|
|
295
|
+
# Validate that the resulting year is within valid range
|
|
296
|
+
if new_year < 1 or new_year > 9999:
|
|
297
|
+
raise ValueError(f"Resulting year {new_year} is outside valid range [1, 9999]")
|
|
298
|
+
|
|
299
|
+
# Handle day overflow (e.g., Jan 31 + 1 month should be Feb 28/29)
|
|
300
|
+
new_day = date_obj.day
|
|
301
|
+
|
|
302
|
+
# Check if the day is valid for the new month
|
|
303
|
+
import calendar
|
|
304
|
+
|
|
305
|
+
max_day = calendar.monthrange(new_year, new_month)[1]
|
|
306
|
+
if new_day > max_day:
|
|
307
|
+
new_day = max_day
|
|
308
|
+
|
|
309
|
+
return new_date(new_year, new_month, new_day)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def date_add_years(date_obj: Date, years: int) -> Date:
|
|
313
|
+
"""Adds a specified number of years to a date.
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
date_obj: A Date protobuf message
|
|
317
|
+
years: Number of years to add (can be negative to subtract)
|
|
318
|
+
|
|
319
|
+
Returns:
|
|
320
|
+
A new Date protobuf message with the years added
|
|
321
|
+
|
|
322
|
+
Raises:
|
|
323
|
+
ValueError: If the date is None or incomplete, or if the result is invalid
|
|
324
|
+
"""
|
|
325
|
+
if not date_obj:
|
|
326
|
+
raise ValueError("Date object is None")
|
|
327
|
+
|
|
328
|
+
if not date_is_valid(date_obj):
|
|
329
|
+
raise ValueError("Date must be valid to add years")
|
|
330
|
+
|
|
331
|
+
new_year = date_obj.year + years
|
|
332
|
+
new_month = date_obj.month
|
|
333
|
+
new_day = date_obj.day
|
|
334
|
+
|
|
335
|
+
# Handle leap year edge case (Feb 29 + 1 year when next year is not leap)
|
|
336
|
+
if new_month == 2 and new_day == 29:
|
|
337
|
+
import calendar
|
|
338
|
+
|
|
339
|
+
if not calendar.isleap(new_year):
|
|
340
|
+
new_day = 28
|
|
341
|
+
|
|
342
|
+
return new_date(new_year, new_month, new_day)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _validate_date(year: int, month: int, day: int) -> None:
|
|
346
|
+
"""Validates the year, month, and day values according to Date constraints.
|
|
347
|
+
Only full dates are valid - all fields must be non-zero.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
year: Year value
|
|
351
|
+
month: Month value
|
|
352
|
+
day: Day value
|
|
353
|
+
|
|
354
|
+
Raises:
|
|
355
|
+
ValueError: If the date values are invalid
|
|
356
|
+
"""
|
|
357
|
+
# Year validation - must be non-zero
|
|
358
|
+
if year < 1 or year > 9999:
|
|
359
|
+
raise ValueError(f"Year must be between 1 and 9999, got {year}")
|
|
360
|
+
|
|
361
|
+
# Month validation - must be non-zero
|
|
362
|
+
if month < 1 or month > 12:
|
|
363
|
+
raise ValueError(f"Month must be between 1 and 12, got {month}")
|
|
364
|
+
|
|
365
|
+
# Day validation - must be non-zero
|
|
366
|
+
if day < 1 or day > 31:
|
|
367
|
+
raise ValueError(f"Day must be between 1 and 31, got {day}")
|
|
368
|
+
|
|
369
|
+
# Check if the day is valid for the given month and year
|
|
370
|
+
try:
|
|
371
|
+
python_date(year, month, day)
|
|
372
|
+
except ValueError as e:
|
|
373
|
+
raise ValueError(f"Invalid date: {year}-{month:02d}-{day:02d}: {e}") from e
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
-
# source: meshtrade/
|
|
4
|
+
# source: meshtrade/type/v1/date.proto
|
|
5
5
|
# Protobuf Python Version: 6.31.1
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
@@ -15,7 +15,7 @@ _runtime_version.ValidateProtobufRuntimeVersion(
|
|
|
15
15
|
31,
|
|
16
16
|
1,
|
|
17
17
|
'',
|
|
18
|
-
'meshtrade/
|
|
18
|
+
'meshtrade/type/v1/date.proto'
|
|
19
19
|
)
|
|
20
20
|
# @@protoc_insertion_point(imports)
|
|
21
21
|
|
|
@@ -24,14 +24,14 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cmeshtrade/type/v1/date.proto\x12\x11meshtrade.type.v1\"B\n\x04\x44\x61te\x12\x12\n\x04year\x18\x01 \x01(\x05R\x04year\x12\x14\n\x05month\x18\x02 \x01(\x05R\x05month\x12\x10\n\x03\x64\x61y\x18\x03 \x01(\x05R\x03\x64\x61yBF\n\x18\x63o.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1b\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
-
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtrade.
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtrade.type.v1.date_pb2', _globals)
|
|
32
32
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
33
|
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
-
_globals['DESCRIPTOR']._serialized_options = b'
|
|
35
|
-
_globals['
|
|
36
|
-
_globals['
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'\n\030co.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1'
|
|
35
|
+
_globals['_DATE']._serialized_start=51
|
|
36
|
+
_globals['_DATE']._serialized_end=117
|
|
37
37
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from google.protobuf import descriptor as _descriptor
|
|
2
|
+
from google.protobuf import message as _message
|
|
3
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional
|
|
4
|
+
|
|
5
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
6
|
+
|
|
7
|
+
class Date(_message.Message):
|
|
8
|
+
__slots__ = ("year", "month", "day")
|
|
9
|
+
YEAR_FIELD_NUMBER: _ClassVar[int]
|
|
10
|
+
MONTH_FIELD_NUMBER: _ClassVar[int]
|
|
11
|
+
DAY_FIELD_NUMBER: _ClassVar[int]
|
|
12
|
+
year: int
|
|
13
|
+
month: int
|
|
14
|
+
day: int
|
|
15
|
+
def __init__(self, year: _Optional[int] = ..., month: _Optional[int] = ..., day: _Optional[int] = ...) -> None: ...
|
|
@@ -26,4 +26,4 @@ def decimal_to_built_in(decimal_value: Decimal) -> decimal.Decimal:
|
|
|
26
26
|
:param decimal_value: The decimal_pb2.Decimal object to convert.
|
|
27
27
|
:return: The converted decimal.Decimal object.
|
|
28
28
|
"""
|
|
29
|
-
return decimal.Decimal(
|
|
29
|
+
return decimal.Decimal(decimal_value.value if decimal_value.value != "" else "0")
|
meshtrade/type/v1/decimal_pb2.py
CHANGED
|
@@ -24,14 +24,14 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtrade/type/v1/decimal.proto\x12\x11meshtrade.type.v1\"\x1f\n\x07\x44\x65\x63imal\x12\x14\n\x05value\x18\x01 \x01(\tR\
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtrade/type/v1/decimal.proto\x12\x11meshtrade.type.v1\"\x1f\n\x07\x44\x65\x63imal\x12\x14\n\x05value\x18\x01 \x01(\tR\x05valueBF\n\x18\x63o.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1b\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
31
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtrade.type.v1.decimal_pb2', _globals)
|
|
32
32
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
33
|
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
-
_globals['DESCRIPTOR']._serialized_options = b'
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'\n\030co.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1'
|
|
35
35
|
_globals['_DECIMAL']._serialized_start=54
|
|
36
36
|
_globals['_DECIMAL']._serialized_end=85
|
|
37
37
|
# @@protoc_insertion_point(module_scope)
|
meshtrade/type/v1/ledger.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
from typing import Dict
|
|
2
|
-
|
|
3
1
|
from .ledger_pb2 import Ledger
|
|
4
2
|
|
|
5
|
-
_ledger_decimal_places:
|
|
3
|
+
_ledger_decimal_places: dict[Ledger, int] = {
|
|
6
4
|
Ledger.LEDGER_STELLAR: 7,
|
|
7
5
|
Ledger.LEDGER_SA_STOCK_BROKERS: 2,
|
|
8
6
|
}
|
|
9
7
|
|
|
8
|
+
|
|
10
9
|
class UnsupportedLedgerError(Exception):
|
|
11
10
|
"""Exception raised for unsupported Ledger values."""
|
|
12
11
|
|
meshtrade/type/v1/ledger_pb2.py
CHANGED
|
@@ -24,14 +24,14 @@ _sym_db = _symbol_database.Default()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtrade/type/v1/ledger.proto\x12\x11meshtrade.type.v1*\xb0\x01\n\x06Ledger\x12\x16\n\x12LEDGER_UNSPECIFIED\x10\x00\x12\x12\n\x0eLEDGER_STELLAR\x10\x03\x12\x12\n\x0eLEDGER_BITCOIN\x10\x05\x12\x13\n\x0fLEDGER_LITECOIN\x10\x07\x12\x13\n\x0fLEDGER_ETHEREUM\x10\t\x12\x0e\n\nLEDGER_XRP\x10\x0b\x12\x1b\n\x17LEDGER_SA_STOCK_BROKERS\x10\x0f\x12\x0f\n\x0bLEDGER_NULL\x10\x10\x42
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtrade/type/v1/ledger.proto\x12\x11meshtrade.type.v1*\xb0\x01\n\x06Ledger\x12\x16\n\x12LEDGER_UNSPECIFIED\x10\x00\x12\x12\n\x0eLEDGER_STELLAR\x10\x03\x12\x12\n\x0eLEDGER_BITCOIN\x10\x05\x12\x13\n\x0fLEDGER_LITECOIN\x10\x07\x12\x13\n\x0fLEDGER_ETHEREUM\x10\t\x12\x0e\n\nLEDGER_XRP\x10\x0b\x12\x1b\n\x17LEDGER_SA_STOCK_BROKERS\x10\x0f\x12\x0f\n\x0bLEDGER_NULL\x10\x10\x42\x46\n\x18\x63o.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1b\x06proto3')
|
|
28
28
|
|
|
29
29
|
_globals = globals()
|
|
30
30
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
31
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtrade.type.v1.ledger_pb2', _globals)
|
|
32
32
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
33
|
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
-
_globals['DESCRIPTOR']._serialized_options = b'
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'\n\030co.meshtrade.api.type.v1Z*github.com/meshtrade/api/go/type/v1;typev1'
|
|
35
35
|
_globals['_LEDGER']._serialized_start=54
|
|
36
36
|
_globals['_LEDGER']._serialized_end=230
|
|
37
37
|
# @@protoc_insertion_point(module_scope)
|