Skip to content

Commit 5e3717b

Browse files
committed
Upgrade to 0.0.9
1 parent b3cca20 commit 5e3717b

File tree

12 files changed

+130
-15
lines changed

12 files changed

+130
-15
lines changed

changelogs.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
v0.0.9 - Aug 5, 2021
2+
- Modifications to LazyRPC
3+
- Lots of other fun stuff.
4+
15
v0.0.81 - July 28, 2021
26

37
- Add API for LazyHFModel

lazyops/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from lazyops.cache.asyncish import lazy_async
12
import os
23
import warnings
34

@@ -13,8 +14,8 @@
1314
from .models import LazyData, LazyTime, LazyDate, LazyFormatter, LazyTimer, LazyObject
1415
from .common import lazylibs, lazy_init, run_cmd, clone_repo, File
1516
from .utils import find_binary_in_path, timed_cache, latest_tf_ckpt, require_module
16-
from .utils import build_chunks, retryable, list_to_dict
17-
from .mp import lazy_parallelize, lazyproc, lazymultiproc, LazyProcs, LazyProc
17+
from .utils import build_chunks, retryable, list_to_dict, create_uuid
18+
from .mp import lazy_parallelize, lazyproc, lazymultiproc, LazyProcs, LazyProc, async_to_sync
1819
from .apis import LazyAPI, LazyAPIConfig
1920

2021

@@ -29,6 +30,7 @@
2930
fio = File
3031
lazyapi = LazyAPI
3132
lazyapiconfig = LazyAPIConfig
33+
lazy_async = async_to_sync
3234

3335
from .lazyio import LazyHFModel
3436

@@ -65,6 +67,8 @@
6567
'lazyproc',
6668
'lazymultiproc',
6769
'LazyProcs',
68-
'LazyProc'
70+
'LazyProc',
71+
'lazy_async',
72+
'async_to_sync'
6973
]
7074
#from . import lazyrpc

lazyops/envs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def exit_handler(cls, signum, frame):
188188
for thread in EnvChecker.threads:
189189
thread.join()
190190
EnvChecker.set_dead()
191-
#sys.exit(0)
191+
sys.exit(0)
192192

193193
@classmethod
194194
def enable_watcher(cls):

lazyops/lazyio/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .models import (
2+
LazyFile,
23
LazyJson,
34
LazyPickler,
45
LazyIOBase,
@@ -8,14 +9,18 @@
89
LazyIOPickle,
910
LazyIOType,
1011
LazyHFModel,
12+
gfile,
13+
File,
14+
json,
1115
)
1216

1317

1418
lazypickler = LazyPickler
1519
lazypkler = LazyPickler
1620
lazyjson = LazyJson
1721

18-
lazyfile = LazyIOBase
22+
#lazyfile = LazyIOBase
23+
lazyfile = LazyFile
1924
lazyiojson = LazyIOJson
2025
lazyjsonlines = LazyIOJsonLines
2126
lazyjlines = LazyIOJsonLines
@@ -25,6 +30,7 @@
2530

2631

2732
__all__ = [
33+
'LazyFile',
2834
'LazyJson',
2935
'LazyPickler',
3036
'LazyIOBase',
@@ -43,6 +49,9 @@
4349
'lazyjlines',
4450
'lazyjl',
4551
'lazypickle',
46-
'lazypkl'
52+
'lazypkl',
53+
'File',
54+
'gfile',
55+
'json'
4756
]
4857

lazyops/lazyio/_base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
import simdjson as json
66
import os
77

8+
from pathlib import Path
89
from enum import Enum
910
from abc import ABCMeta
1011
from typing import Union, List, Any, TypeVar, Optional, Dict
1112
from fileio import File, gfile
13+
from tempfile import TemporaryFile, NamedTemporaryFile
14+
from io import BytesIO
1215

1316
logger = get_logger(name='LazyIO')

lazyops/lazyio/models.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
11
from ._base import *
22

3+
# make stuff compatible and compliant with posix
4+
# https://www.tensorflow.org/datasets/api_docs/python/tfds/core/ReadWritePath?hl=en
5+
6+
class LazyFile:
7+
def __init__(self, filename, method='tmp', overwrite=True, cleanup=True):
8+
self._dest_filename = filename
9+
self._method = method
10+
self.overwrite = overwrite
11+
self.cleanup = cleanup
12+
self._tmp_file = NamedTemporaryFile(delete=False) if method == 'tmp' else BytesIO()
13+
14+
@property
15+
def tmpfile(self):
16+
return self._tmp_file
17+
18+
@property
19+
def tmpfile_path(self):
20+
if self._tmp_file and self._method == 'tmp':
21+
return self._tmp_file.name
22+
return None
23+
24+
@property
25+
def is_closed(self):
26+
return bool(self._tmp_file is not None)
27+
28+
def write(self):
29+
assert not self.is_closed
30+
assert File.exists(self._dest_filename) is False or self.overwrite is True
31+
if self._method == 'tmp':
32+
data = gfile(self._tmp_file.name, 'rb').read()
33+
else:
34+
data = self._tmp_file.getvalue()
35+
with gfile(self._dest_filename, 'wb') as f:
36+
f.write(data)
37+
if self.cleanup and self._method == 'tmp':
38+
os.remove(self._tmp_file.name)
39+
self._tmp_file = None
40+
41+
42+
343
class LazyJson:
444
serializer = json
545
parser = json.Parser()

lazyops/lazyrpc/_base.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from json import JSONDecodeError
1616
from types import FunctionType, CoroutineType
1717
from typing import List, Union, Any, Callable, Type, Optional, Dict, Sequence, Awaitable, Tuple
18-
from contextlib import AsyncExitStack, AbstractAsyncContextManager, asynccontextmanager
18+
from contextlib import AsyncExitStack, AbstractAsyncContextManager, asynccontextmanager, contextmanager
1919

2020
# noinspection PyProtectedMember
2121
from pydantic import DictError
@@ -65,6 +65,13 @@ def __get__(self, obj, cls):
6565
value = obj.__dict__[self.func.__name__] = self.func(obj)
6666
return value
6767

68+
try:
69+
import sentry_sdk
70+
from sentry_sdk.utils import transaction_from_function as sentry_transaction_from_function
71+
except ImportError:
72+
sentry_sdk = None
73+
sentry_transaction_from_function = None
74+
6875
def sjson_loads(data, *args, **kwargs):
6976
try:
7077
return _JSON_PARSER.parse(data, recursive=kwargs.get('recursive', False))

lazyops/lazyrpc/core.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,16 @@ def __init__(
8989
http_request: Request,
9090
background_tasks: BackgroundTasks,
9191
http_response: Response,
92-
json_rpc_request_class: Type[JsonRpcRequest] = JsonRpcRequest
92+
json_rpc_request_class: Type[JsonRpcRequest] = JsonRpcRequest,
93+
method_route: Optional['MethodRoute'] = None,
9394
):
9495
self.entrypoint: Entrypoint = entrypoint
9596
self.raw_request: Any = raw_request
9697
self.http_request: Request = http_request
9798
self.background_tasks: BackgroundTasks = background_tasks
9899
self.http_response: Response = http_response
99100
self.request_class: Type[JsonRpcRequest] = json_rpc_request_class
101+
self.method_route: Optional[MethodRoute] = method_route
100102
self._raw_response: Optional[dict] = None
101103
self.exception: Optional[Exception] = None
102104
self.is_unhandled_exception: bool = False
@@ -142,6 +144,8 @@ def request(self) -> JsonRpcRequest:
142144
async def __aenter__(self):
143145
assert self.exit_stack is None
144146
self.exit_stack = await AsyncExitStack().__aenter__()
147+
if sentry_sdk is not None:
148+
self.exit_stack.enter_context(self._fix_sentry_scope())
145149
await self.exit_stack.enter_async_context(self._handle_exception(reraise=False))
146150
self.jsonrpc_context_token = _jsonrpc_context.set(self)
147151
return self
@@ -174,6 +178,23 @@ async def _handle_exception(self, reraise=True):
174178
if self.exception is not None and self.is_unhandled_exception:
175179
logger.exception(str(self.exception), exc_info=self.exception)
176180

181+
def _make_sentry_event_processor(self):
182+
def event_processor(event, _):
183+
if self.method_route is not None:
184+
event['transaction'] = sentry_transaction_from_function(self.method_route.func)
185+
return event
186+
187+
return event_processor
188+
189+
@contextmanager
190+
def _fix_sentry_scope(self):
191+
hub = sentry_sdk.Hub.current
192+
with sentry_sdk.Hub(hub) as hub:
193+
with hub.configure_scope() as scope:
194+
scope.clear_breadcrumbs()
195+
scope.add_event_processor(self._make_sentry_event_processor())
196+
yield
197+
177198
async def enter_middlewares(self, middlewares: Sequence['JsonRpcMiddleware']):
178199
for mw in middlewares:
179200
cm = mw(self)
@@ -354,6 +375,7 @@ async def handle_req_to_resp(
354375
) -> dict:
355376
async with JsonRpcContext(
356377
entrypoint=self.entrypoint,
378+
method_route=self,
357379
raw_request=req,
358380
http_request=http_request,
359381
background_tasks=background_tasks,
@@ -714,6 +736,7 @@ async def handle_req(
714736
for route in self.entrypoint.routes: # type: MethodRoute
715737
match, child_scope = route.matches(http_request_shadow.scope)
716738
if match == Match.FULL:
739+
ctx.method_route = route
717740
# http_request is a transport layer and it is common for all JSON-RPC requests in a batch
718741
return await route.handle_req(
719742
http_request_shadow, background_tasks, sub_response, ctx,
@@ -823,6 +846,7 @@ def add_method_route(
823846
**kwargs,
824847
) -> None:
825848
name = name or func.__name__
849+
#name = self.entrypoint_route.name + ' - ' + (name or func.__name__)
826850
route = self.method_route_class(
827851
self,
828852
self.entrypoint_route.path + '/' + name,

lazyops/lazyrpc/exceptions.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from ._base import *
22
from .models import component_name, rename_if_scope_child_component
3+
from fastapi import status
34

45
class BaseError(Exception):
56
CODE = None
@@ -158,33 +159,38 @@ class ErrorModel(BaseModel):
158159

159160
class ParseError(BaseError):
160161
"""Invalid JSON was received by the server"""
161-
CODE = -32700
162+
CODE = status.HTTP_422_UNPROCESSABLE_ENTITY
163+
#CODE = -32700
162164
MESSAGE = "Parse error"
163165

164166

165167
class InvalidRequest(BaseError):
166168
"""The JSON sent is not a valid Request object"""
167-
CODE = -32600
169+
#CODE = -32600
170+
CODE = status.HTTP_400_BAD_REQUEST
168171
MESSAGE = "Invalid Request"
169172
error_model = ErrorModel
170173

171174

172175
class MethodNotFound(BaseError):
173176
"""The method does not exist / is not available"""
174-
CODE = -32601
177+
#CODE = -32601
178+
CODE = status.HTTP_405_METHOD_NOT_ALLOWED
175179
MESSAGE = "Method not found"
176180

177181

178182
class InvalidParams(BaseError):
179183
"""Invalid method parameter(s)"""
180-
CODE = -32602
184+
#CODE = -32602
185+
CODE = status.HTTP_424_FAILED_DEPENDENCY
181186
MESSAGE = "Invalid params"
182187
error_model = ErrorModel
183188

184189

185190
class InternalError(BaseError):
186191
"""Internal JSON-RPC error"""
187-
CODE = -32603
192+
#CODE = -32603
193+
CODE = status.HTTP_500_INTERNAL_SERVER_ERROR
188194
MESSAGE = "Internal error"
189195

190196

@@ -196,10 +202,19 @@ def errors_responses(errors: Sequence[Type[BaseError]] = None):
196202
if errors:
197203
cnt = 1
198204
for error_cls in errors:
199-
responses[f'200{" " * cnt}'] = {
205+
#responses[404] = {
206+
# 'model': error_cls.get_resp_model(),
207+
# 'description': error_cls.get_description(),
208+
#}
209+
responses[error_cls.CODE] = {
200210
'model': error_cls.get_resp_model(),
201211
'description': error_cls.get_description(),
202212
}
213+
214+
#responses[f'200{" " * cnt}'] = {
215+
# 'model': error_cls.get_resp_model(),
216+
# 'description': error_cls.get_description(),
217+
#}
203218
cnt += 1
204219
return responses
205220

lazyops/mp.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
from functools import lru_cache, wraps
33
from typing import List, Optional, Dict
4+
from asgiref.sync import async_to_sync
45
from .mp_utils import multiproc, _MAX_PROCS, lazy_parallelize
56

67
class LazyProc:

0 commit comments

Comments
 (0)