@@ -380,6 +380,48 @@ def save(self):
380
380
)
381
381
)
382
382
383
+ @property
384
+ def server_url (self ):
385
+ """
386
+ The server URL to use for an external orca server, or None if orca
387
+ should be managed locally
388
+
389
+ Overrides executable, port, timeout, mathjax, topojson,
390
+ and mapbox_access_token
391
+
392
+ Returns
393
+ -------
394
+ str or None
395
+ """
396
+ return self ._props .get ("server_url" , None )
397
+
398
+ @server_url .setter
399
+ def server_url (self , val ):
400
+
401
+ if val is None :
402
+ self ._props .pop ("server_url" , None )
403
+ return
404
+ if not isinstance (val , str ):
405
+ raise ValueError (
406
+ """
407
+ The server_url property must be a string, but received value of type {typ}.
408
+ Received value: {val}""" .format (
409
+ typ = type (val ), val = val
410
+ )
411
+ )
412
+
413
+ if not val .startswith ("http://" ) and not val .startswith ("https://" ):
414
+ val = "http://" + val
415
+
416
+ shutdown_server ()
417
+ self .executable = None
418
+ self .port = None
419
+ self .timeout = None
420
+ self .mathjax = None
421
+ self .topojson = None
422
+ self .mapbox_access_token = None
423
+ self ._props ["server_url" ] = val
424
+
383
425
@property
384
426
def port (self ):
385
427
"""
@@ -777,6 +819,7 @@ def __repr__(self):
777
819
return """\
778
820
orca configuration
779
821
------------------
822
+ server_url: {server_url}
780
823
executable: {executable}
781
824
port: {port}
782
825
timeout: {timeout}
@@ -795,6 +838,7 @@ def __repr__(self):
795
838
config_file: {config_file}
796
839
797
840
""" .format (
841
+ server_url = self .server_url ,
798
842
port = self .port ,
799
843
executable = self .executable ,
800
844
timeout = self .timeout ,
@@ -1344,62 +1388,65 @@ def ensure_server():
1344
1388
if status .state == "unvalidated" :
1345
1389
validate_executable ()
1346
1390
1347
- # Acquire lock to make sure that we keep the properties of orca_state
1348
- # consistent across threads
1349
- with orca_lock :
1350
- # Cancel the current shutdown timer, if any
1351
- if orca_state ["shutdown_timer" ] is not None :
1352
- orca_state ["shutdown_timer" ].cancel ()
1391
+ if not config .server_url :
1392
+ # Acquire lock to make sure that we keep the properties of orca_state
1393
+ # consistent across threads
1394
+ with orca_lock :
1395
+ # Cancel the current shutdown timer, if any
1396
+ if orca_state ["shutdown_timer" ] is not None :
1397
+ orca_state ["shutdown_timer" ].cancel ()
1398
+
1399
+ # Start a new server process if none is active
1400
+ if orca_state ["proc" ] is None :
1401
+
1402
+ # Determine server port
1403
+ if config .port is None :
1404
+ orca_state ["port" ] = find_open_port ()
1405
+ else :
1406
+ orca_state ["port" ] = config .port
1407
+
1408
+ # Build orca command list
1409
+ cmd_list = status ._props ["executable_list" ] + [
1410
+ "serve" ,
1411
+ "-p" ,
1412
+ str (orca_state ["port" ]),
1413
+ "--plotly" ,
1414
+ config .plotlyjs ,
1415
+ "--graph-only" ,
1416
+ ]
1353
1417
1354
- # Start a new server process if none is active
1355
- if orca_state [ "proc" ] is None :
1418
+ if config . topojson :
1419
+ cmd_list . extend ([ "--topojson" , config . topojson ])
1356
1420
1357
- # Determine server port
1358
- if config .port is None :
1359
- orca_state ["port" ] = find_open_port ()
1360
- else :
1361
- orca_state ["port" ] = config .port
1362
-
1363
- # Build orca command list
1364
- cmd_list = status ._props ["executable_list" ] + [
1365
- "serve" ,
1366
- "-p" ,
1367
- str (orca_state ["port" ]),
1368
- "--plotly" ,
1369
- config .plotlyjs ,
1370
- "--graph-only" ,
1371
- ]
1372
-
1373
- if config .topojson :
1374
- cmd_list .extend (["--topojson" , config .topojson ])
1375
-
1376
- if config .mathjax :
1377
- cmd_list .extend (["--mathjax" , config .mathjax ])
1378
-
1379
- if config .mapbox_access_token :
1380
- cmd_list .extend (["--mapbox-access-token" , config .mapbox_access_token ])
1381
-
1382
- # Create subprocess that launches the orca server on the
1383
- # specified port.
1384
- DEVNULL = open (os .devnull , "wb" )
1385
- with orca_env ():
1386
- orca_state ["proc" ] = subprocess .Popen (cmd_list , stdout = DEVNULL )
1387
-
1388
- # Update orca.status so the user has an accurate view
1389
- # of the state of the orca server
1390
- status ._props ["state" ] = "running"
1391
- status ._props ["pid" ] = orca_state ["proc" ].pid
1392
- status ._props ["port" ] = orca_state ["port" ]
1393
- status ._props ["command" ] = cmd_list
1394
-
1395
- # Create new shutdown timer if a timeout was specified
1396
- if config .timeout is not None :
1397
- t = threading .Timer (config .timeout , shutdown_server )
1398
- # Make it a daemon thread so that exit won't wait for timer to
1399
- # complete
1400
- t .daemon = True
1401
- t .start ()
1402
- orca_state ["shutdown_timer" ] = t
1421
+ if config .mathjax :
1422
+ cmd_list .extend (["--mathjax" , config .mathjax ])
1423
+
1424
+ if config .mapbox_access_token :
1425
+ cmd_list .extend (
1426
+ ["--mapbox-access-token" , config .mapbox_access_token ]
1427
+ )
1428
+
1429
+ # Create subprocess that launches the orca server on the
1430
+ # specified port.
1431
+ DEVNULL = open (os .devnull , "wb" )
1432
+ with orca_env ():
1433
+ orca_state ["proc" ] = subprocess .Popen (cmd_list , stdout = DEVNULL )
1434
+
1435
+ # Update orca.status so the user has an accurate view
1436
+ # of the state of the orca server
1437
+ status ._props ["state" ] = "running"
1438
+ status ._props ["pid" ] = orca_state ["proc" ].pid
1439
+ status ._props ["port" ] = orca_state ["port" ]
1440
+ status ._props ["command" ] = cmd_list
1441
+
1442
+ # Create new shutdown timer if a timeout was specified
1443
+ if config .timeout is not None :
1444
+ t = threading .Timer (config .timeout , shutdown_server )
1445
+ # Make it a daemon thread so that exit won't wait for timer to
1446
+ # complete
1447
+ t .daemon = True
1448
+ t .start ()
1449
+ orca_state ["shutdown_timer" ] = t
1403
1450
1404
1451
1405
1452
@retrying .retry (wait_random_min = 5 , wait_random_max = 10 , stop_max_delay = 60000 )
@@ -1410,9 +1457,12 @@ def request_image_with_retrying(**kwargs):
1410
1457
"""
1411
1458
from requests import post
1412
1459
1413
- server_url = "http://{hostname}:{port}" .format (
1414
- hostname = "localhost" , port = orca_state ["port" ]
1415
- )
1460
+ if config .server_url :
1461
+ server_url = config .server_url
1462
+ else :
1463
+ server_url = "http://{hostname}:{port}" .format (
1464
+ hostname = "localhost" , port = orca_state ["port" ]
1465
+ )
1416
1466
1417
1467
request_params = {k : v for k , v , in kwargs .items () if v is not None }
1418
1468
json_str = json .dumps (request_params , cls = _plotly_utils .utils .PlotlyJSONEncoder )
@@ -1513,29 +1563,41 @@ def to_image(fig, format=None, width=None, height=None, scale=None, validate=Tru
1513
1563
# Get current status string
1514
1564
status_str = repr (status )
1515
1565
1516
- # Check if the orca server process exists
1517
- pid_exists = psutil .pid_exists (status .pid )
1518
-
1519
- # Raise error message based on whether the server process existed
1520
- if pid_exists :
1566
+ if config .server_url :
1521
1567
raise ValueError (
1522
1568
"""
1569
+ Plotly.py was unable to communicate with the orca server at {server_url}
1570
+
1571
+ Please check that the server is running and accessible.
1572
+ """ .format (
1573
+ server_url = config .server_url
1574
+ )
1575
+ )
1576
+
1577
+ else :
1578
+ # Check if the orca server process exists
1579
+ pid_exists = psutil .pid_exists (status .pid )
1580
+
1581
+ # Raise error message based on whether the server process existed
1582
+ if pid_exists :
1583
+ raise ValueError (
1584
+ """
1523
1585
For some reason plotly.py was unable to communicate with the
1524
1586
local orca server process, even though the server process seems to be running.
1525
1587
1526
1588
Please review the process and connection information below:
1527
1589
1528
1590
{info}
1529
1591
""" .format (
1530
- info = status_str
1592
+ info = status_str
1593
+ )
1531
1594
)
1532
- )
1533
- else :
1534
- # Reset the status so that if the user tries again, we'll try to
1535
- # start the server again
1536
- reset_status ()
1537
- raise ValueError (
1538
- """
1595
+ else :
1596
+ # Reset the status so that if the user tries again, we'll try to
1597
+ # start the server again
1598
+ reset_status ()
1599
+ raise ValueError (
1600
+ """
1539
1601
For some reason the orca server process is no longer running.
1540
1602
1541
1603
Please review the process and connection information below:
@@ -1544,9 +1606,9 @@ def to_image(fig, format=None, width=None, height=None, scale=None, validate=Tru
1544
1606
plotly.py will attempt to start the local server process again the next time
1545
1607
an image export operation is performed.
1546
1608
""" .format (
1547
- info = status_str
1609
+ info = status_str
1610
+ )
1548
1611
)
1549
- )
1550
1612
1551
1613
# Check response
1552
1614
# --------------
0 commit comments