Skip to content

Commit 7256d86

Browse files
committed
update the prefix and root default, all test passes.
1 parent d82eee2 commit 7256d86

File tree

8 files changed

+159
-92
lines changed

8 files changed

+159
-92
lines changed

ml_logger/README

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ The logging server uses the ``sanic`` framework, which means defaults to
7575
``sanic``, such as maximum request size are carried over.
7676

7777
When using ``ml-logger`` to save and load **very
78-
large** ``pytorch`` checkpoints, you need  to raise ``sanic``\ ’s
78+
large** ``pytorch`` checkpoints, you need  to raise \ ``sanic``\ ’s
7979
default request size limit from 100MB to something like a gigabyte or
8080
even larger. The file upload is done using multi-part form upload, where
8181
each query is kept small. However sanic will throw if the overall size
8282
of the query exceeds this
83-
parameter ``SANIC_REQUEST_MAX_SIZE=1000_000_000``. The default is
83+
parameter \ ``SANIC_REQUEST_MAX_SIZE=1000_000_000``. The default is
8484
``100_000_000``, or 100MB.
8585

8686
Use ssh tunnel if you are running on a managed cluster.

ml_logger/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.7.6
1+
0.7.8

ml_logger/ml_logger/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from .struts import ALLOWED_TYPES
2-
from .log_client import LogClient
3-
from .helpers.print_utils import PrintHelper
41
from .caches.summary_cache import SummaryCache
2+
from .helpers.print_utils import PrintHelper
3+
from .log_client import LogClient
54
from .ml_logger import *
5+
from .struts import ALLOWED_TYPES
6+

ml_logger/ml_logger/log_client.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class LogClient:
4545
sync_pool = None
4646
async_pool = None
4747

48-
def __init__(self, url: str = None, asynchronous=None, max_workers=None):
48+
def __init__(self, root: str = None, user=None, access_token=None, asynchronous=None, max_workers=None):
4949
"""
5050
When max_workers is 0, the HTTP requests are synchronous. This allows one to make
5151
synchronous requests procedurally.
@@ -54,24 +54,25 @@ def __init__(self, url: str = None, asynchronous=None, max_workers=None):
5454
Mujoco-py for example, would have trouble with forked processes if multiple
5555
threads are started before forking the subprocesses.
5656
57-
:param url:
57+
:param root:
5858
:param asynchronous: If this is not None, we create a request pool. This way
5959
we can use the (A)SyncContext call right after construction.
6060
:param max_workers:
6161
"""
6262
if asynchronous is not None:
6363
self.set_session(asynchronous, max_workers)
6464

65-
if url.startswith("file://"):
66-
self.local_server = LoggingServer(data_dir=url[6:], silent=True)
67-
elif os.path.isabs(url):
68-
self.local_server = LoggingServer(data_dir=url, silent=True)
69-
elif url.startswith('http://'):
65+
if root.startswith("file://"):
66+
self.local_server = LoggingServer(cwd=root[6:], silent=True)
67+
elif os.path.isabs(root):
68+
self.local_server = LoggingServer(cwd=root, silent=True)
69+
elif root.startswith('http://'):
7070
self.local_server = None # remove local server to use sessions.
71-
self.url = url
72-
self.stream_url = os.path.join(url, "stream")
73-
self.ping_url = os.path.join(url, "ping")
74-
self.glob_url = os.path.join(url, "glob")
71+
self.url = os.path.join(root, user)
72+
self.access_token = access_token
73+
self.stream_url = os.path.join(root, user, "stream")
74+
self.ping_url = os.path.join(root, user, "ping")
75+
self.glob_url = os.path.join(root, user, "glob")
7576
# when setting sessions the first time, default to use Asynchronous Session.
7677
if self.session is None:
7778
asynchronous = True if asynchronous is None else asynchronous

ml_logger/ml_logger/ml_logger.py

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
from .helpers.print_utils import PrintHelper
2525
from .log_client import LogClient
2626

27+
# environment defaults
28+
CWD = os.environ["PWD"]
29+
USER = os.environ["USER"]
30+
31+
# ML_Logger defaults
32+
ROOT = os.environ.get("ML_LOGGER_ROOT", CWD)
33+
USER = os.environ.get("ML_LOGGER_USER", USER)
34+
ACCESS_TOKEN = os.environ.get("ML_LOGGER_ACCESS_TOKEN", None)
35+
2736

2837
def pJoin(*args):
2938
from os.path import join
@@ -198,7 +207,9 @@ def __repr__(self):
198207
# noinspection PyInitNewSignature
199208
# todo: use prefixes as opposed to prefix. (add *prefixae after prefix=None)
200209
# todo: resolve path segment with $env variables.
201-
def __init__(self, root_dir: str = None, prefix=None, *prefixae, buffer_size=2048, max_workers=None,
210+
def __init__(self, prefix="", *prefixae,
211+
log_dir=ROOT, user=USER, access_token=ACCESS_TOKEN,
212+
buffer_size=2048, max_workers=None,
202213
asynchronous=None, summary_cache_opts: dict = None):
203214
""" logger constructor.
204215
@@ -213,8 +224,11 @@ def __init__(self, root_dir: str = None, prefix=None, *prefixae, buffer_size=204
213224
| 1. prefix="causal_infogan" => logs to "/tmp/some_dir/causal_infogan"
214225
| 2. prefix="" => logs to "/tmp/some_dir"
215226
216-
:param root_dir: the server host and port number
217227
:param prefix: the prefix path
228+
:param **prefixae: the rest of the prefix arguments
229+
:param log_dir: the server host and port number
230+
:param user: environment $ML_LOGGER_USER
231+
:param access_token: environment $ML_LOGGER_ACCESS_TOKEN
218232
:param asynchronous: When this is not None, we create a http thread pool.
219233
:param buffer_size: The string buffer size for the print buffer.
220234
:param max_workers: the number of request-session workers for the async http requests.
@@ -236,18 +250,19 @@ def __init__(self, root_dir: str = None, prefix=None, *prefixae, buffer_size=204
236250
self.summary_caches = defaultdict(partial(SummaryCache, **(summary_cache_opts or {})))
237251

238252
# todo: add https support
239-
self.root_dir = interpolate(root_dir) or "/"
240-
self.prefix = interpolate(prefix) or os.getcwd()[1:]
241-
if prefix is not None:
242-
self.prefix = os.path.join(*[interpolate(p) for p in (prefix, *prefixae) if p is not None])
253+
self.root_dir = interpolate(log_dir) or ROOT
243254

244-
# logger client contains thread pools, should not be re-created lightly.
245-
self.client = LogClient(url=self.root_dir, asynchronous=asynchronous, max_workers=max_workers)
255+
prefixae = [interpolate(p) for p in (prefix or "", *prefixae) if p is not None]
256+
self.prefix = os.path.join(*prefixae) if prefixae else ""
257+
self.client = LogClient(root=self.root_dir, user=user, access_token=access_token,
258+
asynchronous=asynchronous, max_workers=max_workers)
246259

247260
def configure(self,
248-
root_dir: str = None,
249261
prefix=None,
250262
*prefixae,
263+
log_dir: str = None,
264+
user=None,
265+
access_token=None,
251266
asynchronous=None,
252267
max_workers=None,
253268
buffer_size=None,
@@ -293,8 +308,11 @@ def configure(self,
293308
todo: the table at the moment seems a bit verbose. I'm considering making this
294309
just a single line print.
295310
296-
:param log_directory:
297-
:param prefix:
311+
:param prefix: the first prefix
312+
:param *prefixae: a list of prefix segments
313+
:param log_dir:
314+
:param user:
315+
:param access_token:
298316
:param buffer_size:
299317
:param summary_cache_opts:
300318
:param asynchronous:
@@ -305,9 +323,11 @@ def configure(self,
305323
"""
306324

307325
# path logic
308-
root_dir = interpolate(root_dir) or os.getcwd()
326+
log_dir = interpolate(log_dir) or os.getcwd()
309327
if prefix is not None:
310-
self.prefix = os.path.join(*[interpolate(p) for p in (prefix, *prefixae) if p is not None])
328+
prefixae = [interpolate(p) for p in (prefix, *prefixae) if p is not None]
329+
if prefixae is not None:
330+
self.prefix = os.path.join(*prefixae)
311331

312332
if buffer_size is not None:
313333
self.print_buffer_size = buffer_size
@@ -318,17 +338,18 @@ def configure(self,
318338
self.summary_caches.clear()
319339
self.summary_caches = defaultdict(partial(SummaryCache, **(summary_cache_opts or {})))
320340

321-
if root_dir != self.root_dir or asynchronous is not None or max_workers is not None:
322-
# note: logger.configure shouldn't be called too often, so it is okay to assume
323-
# that we can discard the old logClient.
324-
# To quickly switch back and forth between synchronous and asynchronous calls,
325-
# use the `SyncContext` and `AsyncContext` instead.
341+
if log_dir:
342+
self.root_dir = interpolate(log_dir) or ROOT
343+
if log_dir or asynchronous is not None or max_workers is not None:
344+
# note: logger.configure shouldn't be called too often. To quickly switch back
345+
# and forth between synchronous and asynchronous calls, use the `SyncContext`
346+
# and `AsyncContext` instead.
326347
if not silent:
327-
cprint('creating new logging client...', color='yellow', end=' ')
328-
self.root_dir = root_dir
329-
self.client.__init__(url=self.root_dir, asynchronous=asynchronous, max_workers=max_workers)
348+
cprint('creating new logging client...', color='yellow', end='\r')
349+
self.client.__init__(root=self.root_dir, user=user, access_token=access_token,
350+
asynchronous=asynchronous, max_workers=max_workers)
330351
if not silent:
331-
cprint('✓ done', color="green")
352+
cprint('✓ created a new logging client', color="green")
332353

333354
if not silent:
334355
from urllib.parse import quote

0 commit comments

Comments
 (0)